2021-11-08 03:44:07 +08:00
/*
* ir_Samsung . hpp
*
* Contains functions for receiving and sending Samsung IR Protocol in " raw " and standard format with 16 bit address and 16 or 32 bit command
*
* This file is part of Arduino - IRremote https : //github.com/Arduino-IRremote/Arduino-IRremote.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* MIT License
*
2024-02-24 02:28:33 +08:00
* Copyright ( c ) 2017 - 2024 Darryl Smith , Armin Joachimsmeyer
2021-11-08 03:44:07 +08:00
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the " Software " ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is furnished
* to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR IMPLIED ,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY , FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER LIABILITY , WHETHER IN AN ACTION OF
* CONTRACT , TORT OR OTHERWISE , ARISING FROM , OUT OF OR IN CONSAMSUNGTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
2022-03-30 17:55:04 +08:00
# ifndef _IR_SAMSUNG_HPP
# define _IR_SAMSUNG_HPP
2021-11-08 03:44:07 +08:00
2022-11-12 06:24:46 +08:00
# if defined(DEBUG) && !defined(LOCAL_DEBUG)
# define LOCAL_DEBUG
# else
//#define LOCAL_DEBUG // This enables debug output only for this file
# endif
2021-11-08 03:44:07 +08:00
/** \addtogroup Decoder Decoders and encoders for different protocols
* @ {
*/
//==============================================================================
// SSSS AAA MMM SSSS U U N N GGGG
// S A A M M M S U U NN N G
// SSS AAAAA M M M SSS U U N N N G GG
// S A A M M S U U N NN G G
// SSSS A A M M SSSS UUU N N GGG
//==============================================================================
2022-11-12 08:31:03 +08:00
/*
* Address = 0xFFF1 Command = 0x76 Raw - Data = 0x8976FFF1
+ 4500 , - 4400
+ 600 , - 1600 + 650 , - 500 + 600 , - 500 + 650 , - 500
+ 600 , - 1650 + 600 , - 1600 + 650 , - 1600 + 600 , - 1650
+ 600 , - 1600 + 600 , - 1650 + 600 , - 1650 + 600 , - 1600
+ 600 , - 1650 + 600 , - 1650 + 600 , - 1600 + 600 , - 1650
+ 600 , - 500 + 650 , - 1600 + 600 , - 1650 + 600 , - 500
+ 650 , - 1600 + 600 , - 1650 + 600 , - 1650 + 600 , - 500
+ 600 , - 1650 + 600 , - 500 + 600 , - 550 + 600 , - 1600
+ 600 , - 550 + 600 , - 550 + 550 , - 550 + 600 , - 1650
+ 550
Sum : 68750
*/
/*
2024-02-24 02:28:33 +08:00
* Samsung repeat frame can be the original frame again or a special short repeat frame ,
2022-11-12 08:31:03 +08:00
* then we call the protocol SamsungLG . They differ only in the handling of repeat ,
* so we can not decide for the first frame which protocol is used .
*/
2021-11-08 03:44:07 +08:00
// see http://www.hifi-remote.com/wiki/index.php?title=DecodeIR#Samsung
// https://www.mikrocontroller.net/articles/IRMP_-_english#SAMSUNG32
2022-12-27 23:59:32 +08:00
// https://www.mikrocontroller.net/articles/IRMP_-_english#SAMSUNG48
// LSB first, 1 start bit + 16 bit address + 16 or 32 bit data + 1 stop bit.
// Here https://forum.arduino.cc/t/klimaanlage-per-ir-steuern/1051381/10 the address (0xB24D) is also 8 bits and then 8 inverted bits
2024-01-20 03:39:19 +08:00
//
// Here https://github.com/flipperdevices/flipperzero-firmware/blob/master/lib/infrared/encoder_decoder/samsung/infrared_decoder_samsung.c#L18
2024-04-26 03:16:40 +08:00
// Address is 8 bit + same 8 bit if command is 8 bit and ~8 bit.
//
// So we assume 8 bit address, if command is 8 bit and ~8 bit!
2024-01-20 03:39:19 +08:00
//
2022-12-27 23:59:32 +08:00
// IRP notation: {38k,5553}<1,-1|1,-3>(8,-8,D:8,S:8,F:8,~F:8,1,^110)+ ==> 8 bit + 8 bit inverted data - Samsung32
// IRP notation: {38k,5553}<1,-1|1,-3>(8,-8,D:8,S:8,F:16,1,^110)+ ==> 16 bit data - still Samsung32
// IRP notation: {38k,5553}<1,-1|1,-3>(8,-8,D:8,S:8,F:8,~F:8,G:8,~G:8,1,^110)+ ==> 2 x (8 bit + 8 bit inverted data) - Samsung48
2022-08-28 02:22:58 +08:00
//
2021-11-08 03:44:07 +08:00
# define SAMSUNG_ADDRESS_BITS 16
# define SAMSUNG_COMMAND16_BITS 16
# define SAMSUNG_COMMAND32_BITS 32
# define SAMSUNG_BITS (SAMSUNG_ADDRESS_BITS + SAMSUNG_COMMAND16_BITS)
# define SAMSUNG48_BITS (SAMSUNG_ADDRESS_BITS + SAMSUNG_COMMAND32_BITS)
2022-08-28 02:22:58 +08:00
// except SAMSUNG_HEADER_MARK, values are like NEC
# define SAMSUNG_UNIT 560 // 21.28 periods of 38 kHz, 11.2 ticks TICKS_LOW = 8.358 TICKS_HIGH = 15.0
2024-01-20 03:39:19 +08:00
# define SAMSUNG_HEADER_MARK (8 * SAMSUNG_UNIT) // 4500 | 180 periods
2022-08-28 02:22:58 +08:00
# define SAMSUNG_HEADER_SPACE (8 * SAMSUNG_UNIT) // 4500
2021-11-08 03:44:07 +08:00
# define SAMSUNG_BIT_MARK SAMSUNG_UNIT
2022-08-28 02:22:58 +08:00
# define SAMSUNG_ONE_SPACE (3 * SAMSUNG_UNIT) // 1690 | 33.8 TICKS_LOW = 25.07 TICKS_HIGH = 45.0
2021-11-08 03:44:07 +08:00
# define SAMSUNG_ZERO_SPACE SAMSUNG_UNIT
# define SAMSUNG_AVERAGE_DURATION 55000 // SAMSUNG_HEADER_MARK + SAMSUNG_HEADER_SPACE + 32 * 2,5 * SAMSUNG_UNIT + SAMSUNG_UNIT // 2.5 because we assume more zeros than ones
2022-07-12 17:46:04 +08:00
# define SAMSUNG_REPEAT_DURATION (SAMSUNG_HEADER_MARK + SAMSUNG_HEADER_SPACE + SAMSUNG_BIT_MARK + SAMSUNG_ZERO_SPACE + SAMSUNG_BIT_MARK)
2021-11-08 03:44:07 +08:00
# define SAMSUNG_REPEAT_PERIOD 110000 // Commands are repeated every 110 ms (measured from start to start) for as long as the key on the remote control is held down.
2024-01-20 03:39:19 +08:00
# define SAMSUNG_MAXIMUM_REPEAT_DISTANCE (SAMSUNG_REPEAT_PERIOD + (SAMSUNG_REPEAT_PERIOD / 4)) // 137000 - Just a guess
2021-11-08 03:44:07 +08:00
2024-04-26 03:16:40 +08:00
// 19 byte RAM
2022-11-10 05:49:55 +08:00
struct PulseDistanceWidthProtocolConstants SamsungProtocolConstants = { SAMSUNG , SAMSUNG_KHZ , SAMSUNG_HEADER_MARK ,
2022-08-31 19:25:29 +08:00
SAMSUNG_HEADER_SPACE , SAMSUNG_BIT_MARK , SAMSUNG_ONE_SPACE , SAMSUNG_BIT_MARK , SAMSUNG_ZERO_SPACE , PROTOCOL_IS_LSB_FIRST ,
2024-02-24 02:28:33 +08:00
( SAMSUNG_REPEAT_PERIOD / MICROS_IN_ONE_MILLI ) , NULL } ;
2022-08-31 19:25:29 +08:00
2024-02-24 02:28:33 +08:00
struct PulseDistanceWidthProtocolConstants SamsungLGProtocolConstants = { SAMSUNGLG , SAMSUNG_KHZ , SAMSUNG_HEADER_MARK ,
SAMSUNG_HEADER_SPACE , SAMSUNG_BIT_MARK , SAMSUNG_ONE_SPACE , SAMSUNG_BIT_MARK , SAMSUNG_ZERO_SPACE , PROTOCOL_IS_LSB_FIRST ,
( SAMSUNG_REPEAT_PERIOD / MICROS_IN_ONE_MILLI ) , & sendSamsungLGSpecialRepeat } ;
2022-08-31 19:25:29 +08:00
/************************************
* Start of send and decode functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2021-11-08 03:44:07 +08:00
/**
* Send repeat
* Repeat commands should be sent in a 110 ms raster .
2022-08-31 19:25:29 +08:00
* This repeat was sent by an LG 6711 R1P071A remote
2021-11-08 03:44:07 +08:00
*/
2022-08-28 02:22:58 +08:00
void IRsend : : sendSamsungLGRepeat ( ) {
2022-08-31 20:07:41 +08:00
enableIROut ( SAMSUNG_KHZ ) ; // 38 kHz
2022-08-31 19:25:29 +08:00
mark ( SAMSUNG_HEADER_MARK ) ; // + 4500
space ( SAMSUNG_HEADER_SPACE ) ; // - 4500
mark ( SAMSUNG_BIT_MARK ) ; // + 560
space ( SAMSUNG_ZERO_SPACE ) ; // - 560
mark ( SAMSUNG_BIT_MARK ) ; // + 560
}
/**
2024-02-24 02:28:33 +08:00
* Like above , but implemented as a static function
* Used for sending special repeat frame .
2022-08-31 19:25:29 +08:00
* For use in ProtocolConstants . Saves up to 250 bytes compared to a member function .
*/
void sendSamsungLGSpecialRepeat ( ) {
IrSender . enableIROut ( SAMSUNG_KHZ ) ; // 38 kHz
IrSender . mark ( SAMSUNG_HEADER_MARK ) ; // + 4500
IrSender . space ( SAMSUNG_HEADER_SPACE ) ; // - 4500
IrSender . mark ( SAMSUNG_BIT_MARK ) ; // + 560
IrSender . space ( SAMSUNG_ZERO_SPACE ) ; // - 560
IrSender . mark ( SAMSUNG_BIT_MARK ) ; // + 560
2021-11-08 03:44:07 +08:00
}
2022-07-12 17:46:04 +08:00
/*
* Sent e . g . by an LG 6711 R1P071A remote
2022-08-31 19:25:29 +08:00
* @ param aNumberOfRepeats If < 0 then only a special repeat frame will be sent
2022-07-12 17:46:04 +08:00
*/
2022-08-31 19:25:29 +08:00
void IRsend : : sendSamsungLG ( uint16_t aAddress , uint16_t aCommand , int_fast8_t aNumberOfRepeats ) {
if ( aNumberOfRepeats < 0 ) {
2022-08-28 02:22:58 +08:00
sendSamsungLGRepeat ( ) ;
2022-07-12 17:46:04 +08:00
return ;
}
// send 16 bit address and 8 command bits and then 8 inverted command bits LSB first
2022-08-31 19:25:29 +08:00
LongUnion tRawData ;
tRawData . UWord . LowWord = aAddress ;
tRawData . UByte . MidHighByte = aCommand ;
tRawData . UByte . HighByte = ~ aCommand ;
2022-07-12 17:46:04 +08:00
2024-02-24 02:28:33 +08:00
sendPulseDistanceWidth ( & SamsungLGProtocolConstants , tRawData . ULong , SAMSUNG_BITS , aNumberOfRepeats ) ;
2022-07-12 17:46:04 +08:00
}
2022-12-27 23:59:32 +08:00
/**
* Here we send Samsung32
* If we get a command < 0x100 , we send command and then ~ command
2024-04-26 03:16:40 +08:00
* If we get an address < 0x100 , we send 8 bit address and then the same 8 bit address again , this makes it flipper IRDB compatible
2023-03-14 05:26:06 +08:00
* ! ! ! Be aware , that this is flexible , but makes it impossible to send e . g . 0x0042 as 16 bit value ! ! !
2024-04-26 03:16:40 +08:00
* To force send 16 bit address , use : sendSamsung16BitAddressAndCommand ( ) .
2023-03-14 05:26:06 +08:00
* @ param aNumberOfRepeats If < 0 then only a special repeat frame will be sent
2022-12-27 23:59:32 +08:00
*/
2022-11-12 08:31:03 +08:00
void IRsend : : sendSamsung ( uint16_t aAddress , uint16_t aCommand , int_fast8_t aNumberOfRepeats ) {
2022-12-27 23:59:32 +08:00
LongUnion tSendValue ;
2024-02-24 02:28:33 +08:00
if ( aAddress < 0x100 ) {
2024-04-26 03:16:40 +08:00
// This makes it flipper IRDB compatible:
2024-02-24 02:28:33 +08:00
// https://github.com/flipperdevices/flipperzero-firmware/blob/master/lib/infrared/encoder_decoder/samsung/infrared_decoder_samsung.c#L18
2024-04-26 03:16:40 +08:00
// Duplicate address byte, if address is only 8 bit
2024-02-24 02:28:33 +08:00
tSendValue . UBytes [ 1 ] = aAddress ;
tSendValue . UBytes [ 0 ] = aAddress ;
} else {
tSendValue . UWords [ 0 ] = aAddress ;
}
2022-12-27 23:59:32 +08:00
if ( aCommand < 0x100 ) {
2023-03-14 05:26:06 +08:00
// Send 8 command bits and then 8 inverted command bits LSB first
2022-12-27 23:59:32 +08:00
tSendValue . UBytes [ 2 ] = aCommand ;
tSendValue . UBytes [ 3 ] = ~ aCommand ;
2024-02-24 02:28:33 +08:00
2022-12-27 23:59:32 +08:00
} else {
2023-03-14 05:26:06 +08:00
// Send 16 command bits
2022-12-27 23:59:32 +08:00
tSendValue . UWords [ 1 ] = aCommand ;
}
2023-03-14 05:26:06 +08:00
sendPulseDistanceWidth ( & SamsungProtocolConstants , tSendValue . ULong , SAMSUNG_BITS , aNumberOfRepeats ) ;
2022-12-27 23:59:32 +08:00
}
2024-04-26 03:16:40 +08:00
/**
* Maybe no one needs it in the wild . . .
* As above , but we are able to send e . g . 0x0042 as 16 bit address
* @ param aNumberOfRepeats If < 0 then only a special repeat frame will be sent
*/
void IRsend : : sendSamsung16BitAddressAnd8BitCommand ( uint16_t aAddress , uint8_t aCommand , int_fast8_t aNumberOfRepeats ) {
LongUnion tSendValue ;
// send 16 bit address
tSendValue . UWords [ 0 ] = aAddress ;
// Send 8 command bits and then 8 inverted command bits LSB first
tSendValue . UBytes [ 2 ] = aCommand ;
tSendValue . UBytes [ 3 ] = ~ aCommand ;
sendPulseDistanceWidth ( & SamsungProtocolConstants , tSendValue . ULong , SAMSUNG_BITS , aNumberOfRepeats ) ;
}
2024-02-24 02:28:33 +08:00
/**
* Maybe no one needs it in the wild . . .
* As above , but we are able to send e . g . 0x0042 as 16 bit address
* @ param aNumberOfRepeats If < 0 then only a special repeat frame will be sent
*/
void IRsend : : sendSamsung16BitAddressAndCommand ( uint16_t aAddress , uint16_t aCommand , int_fast8_t aNumberOfRepeats ) {
LongUnion tSendValue ;
// send 16 bit address
tSendValue . UWords [ 0 ] = aAddress ;
// Send 16 command bits
tSendValue . UWords [ 1 ] = aCommand ;
sendPulseDistanceWidth ( & SamsungProtocolConstants , tSendValue . ULong , SAMSUNG_BITS , aNumberOfRepeats ) ;
}
2022-12-27 23:59:32 +08:00
/**
* Here we send Samsung48
* We send 2 x ( 8 bit command and then ~ command )
*/
2023-01-08 03:52:51 +08:00
void IRsend : : sendSamsung48 ( uint16_t aAddress , uint32_t aCommand , int_fast8_t aNumberOfRepeats ) {
2022-12-27 23:59:32 +08:00
// send 16 bit address and 2 x ( 8 command bits and then 8 inverted command bits) LSB first
2022-11-22 19:28:10 +08:00
# if __INT_WIDTH__ < 32
2022-12-27 23:59:32 +08:00
uint32_t tRawSamsungData [ 2 ] ; // prepare 2 long for Samsung48
2022-11-12 08:31:03 +08:00
LongUnion tSendValue ;
2022-11-22 19:28:10 +08:00
tSendValue . UWords [ 0 ] = aAddress ;
tSendValue . UBytes [ 2 ] = aCommand ;
tSendValue . UBytes [ 3 ] = ~ aCommand ;
2022-12-27 23:59:32 +08:00
uint8_t tUpper8BitsOfCommand = aCommand > > 8 ;
tRawSamsungData [ 1 ] = tUpper8BitsOfCommand | ( ~ tUpper8BitsOfCommand ) < < 8 ;
2022-11-12 08:31:03 +08:00
tRawSamsungData [ 0 ] = tSendValue . ULong ;
2022-12-27 23:59:32 +08:00
2023-03-14 05:26:06 +08:00
sendPulseDistanceWidthFromArray ( & SamsungProtocolConstants , & tRawSamsungData [ 0 ] , SAMSUNG48_BITS , aNumberOfRepeats ) ;
2022-11-22 19:28:10 +08:00
# else
LongLongUnion tSendValue ;
tSendValue . UWords [ 0 ] = aAddress ;
2022-12-27 23:59:32 +08:00
if ( aCommand < 0x10000 ) {
tSendValue . UBytes [ 2 ] = aCommand ;
tSendValue . UBytes [ 3 ] = ~ aCommand ;
uint8_t tUpper8BitsOfCommand = aCommand > > 8 ;
tSendValue . UBytes [ 4 ] = tUpper8BitsOfCommand ;
tSendValue . UBytes [ 5 ] = ~ tUpper8BitsOfCommand ;
2022-11-22 19:28:10 +08:00
} else {
2022-12-27 23:59:32 +08:00
tSendValue . ULongLong = aAddress | aCommand < < 16 ;
2022-11-22 19:28:10 +08:00
}
2023-03-14 05:26:06 +08:00
sendPulseDistanceWidth ( & SamsungProtocolConstants , tSendValue . ULongLong , SAMSUNG48_BITS , aNumberOfRepeats ) ;
2022-11-22 19:28:10 +08:00
# endif
2022-11-12 08:31:03 +08:00
}
2024-04-26 03:16:40 +08:00
/*
* We cannot decode frames with 8 command bits and then 8 inverted command bits LSB and 16 bit address ,
* because in this case we always assume 8 bit address .
* This is , because we did not see 8 bit command and real 16 bit address in the wild .
*/
2021-11-08 03:44:07 +08:00
bool IRrecv : : decodeSamsung ( ) {
// Check we have enough data (68). The +4 is for initial gap, start bit mark and space + stop bit mark
2024-02-24 02:28:33 +08:00
if ( decodedIRData . rawlen ! = ( ( 2 * SAMSUNG_BITS ) + 4 ) & & decodedIRData . rawlen ! = ( ( 2 * SAMSUNG48_BITS ) + 4 )
& & ( decodedIRData . rawlen ! = 6 ) ) {
2021-11-29 20:41:03 +08:00
IR_DEBUG_PRINT ( F ( " Samsung: " ) ) ;
2022-05-19 15:51:34 +08:00
IR_DEBUG_PRINT ( F ( " Data length= " ) ) ;
2024-02-24 02:28:33 +08:00
IR_DEBUG_PRINT ( decodedIRData . rawlen ) ;
2022-11-12 08:31:03 +08:00
IR_DEBUG_PRINTLN ( F ( " is not 6 or 68 or 100 " ) ) ;
2021-11-08 03:44:07 +08:00
return false ;
}
2022-08-31 19:25:29 +08:00
if ( ! checkHeader ( & SamsungProtocolConstants ) ) {
2021-11-08 03:44:07 +08:00
return false ;
}
2022-07-12 17:46:04 +08:00
// Check for SansungLG style repeat
2024-02-24 02:28:33 +08:00
if ( decodedIRData . rawlen = = 6 ) {
decodedIRData . flags = IRDATA_FLAGS_IS_REPEAT | IRDATA_FLAGS_IS_PROTOCOL_WITH_DIFFERENT_REPEAT | IRDATA_FLAGS_IS_LSB_FIRST ;
2022-07-12 17:46:04 +08:00
decodedIRData . address = lastDecodedAddress ;
decodedIRData . command = lastDecodedCommand ;
2024-02-24 02:28:33 +08:00
decodedIRData . protocol = SAMSUNGLG ;
2022-07-12 17:46:04 +08:00
return true ;
}
2022-08-31 19:25:29 +08:00
/*
* Decode first 32 bits
*/
2022-11-12 08:31:03 +08:00
if ( ! decodePulseDistanceWidthData ( & SamsungProtocolConstants , SAMSUNG_BITS , 3 ) ) {
2022-11-12 06:24:46 +08:00
# if defined(LOCAL_DEBUG)
Serial . print ( F ( " Samsung: " ) ) ;
Serial . println ( F ( " Decode failed " ) ) ;
# endif
2022-08-31 19:25:29 +08:00
return false ;
}
LongUnion tValue ;
tValue . ULong = decodedIRData . decodedRawData ;
decodedIRData . address = tValue . UWord . LowWord ;
2024-02-24 02:28:33 +08:00
if ( decodedIRData . rawlen = = ( 2 * SAMSUNG48_BITS ) + 4 ) {
2021-11-08 03:44:07 +08:00
/*
* Samsung48
*/
2022-08-31 19:25:29 +08:00
// decode additional 16 bit
2022-11-10 05:49:55 +08:00
if ( ! decodePulseDistanceWidthData ( & SamsungProtocolConstants , ( SAMSUNG_COMMAND32_BITS - SAMSUNG_COMMAND16_BITS ) ,
2022-11-12 08:31:03 +08:00
3 + ( 2 * SAMSUNG_BITS ) ) ) {
2022-11-12 06:24:46 +08:00
# if defined(LOCAL_DEBUG)
Serial . print ( F ( " Samsung: " ) ) ;
Serial . println ( F ( " Decode failed " ) ) ;
# endif
2021-11-08 03:44:07 +08:00
return false ;
}
2022-11-12 08:31:03 +08:00
/*
* LSB data is already in tValue . UWord . HighWord !
* Put latest ( MSB ) bits in LowWord , LSB first would have them expect in HighWord so keep this in mind for decoding below
*/
2022-12-27 23:59:32 +08:00
tValue . UWord . LowWord = decodedIRData . decodedRawData ; // We have only 16 bit in decodedRawData here
# if __INT_WIDTH__ >= 32
// workaround until complete refactoring for 64 bit
decodedIRData . decodedRawData = ( decodedIRData . decodedRawData < < 32 ) | tValue . UWord . HighWord < < 16 | decodedIRData . address ; // store all 48 bits in decodedRawData
# endif
2022-08-31 19:25:29 +08:00
/*
2022-12-27 23:59:32 +08:00
* Check parity of 32 bit command
2022-08-31 19:25:29 +08:00
*/
2021-11-08 03:44:07 +08:00
// receive 2 * (8 bits then 8 inverted bits) LSB first
2022-11-12 08:31:03 +08:00
if ( tValue . UByte . MidHighByte ! = ( uint8_t ) ( ~ tValue . UByte . HighByte )
& & tValue . UByte . LowByte ! = ( uint8_t ) ( ~ tValue . UByte . MidLowByte ) ) {
2021-11-08 03:44:07 +08:00
decodedIRData . flags = IRDATA_FLAGS_PARITY_FAILED | IRDATA_FLAGS_IS_LSB_FIRST ;
}
2022-08-31 19:25:29 +08:00
2022-11-12 08:31:03 +08:00
decodedIRData . command = tValue . UByte . LowByte < < 8 | tValue . UByte . MidHighByte ; // low and high word are swapped here, so fetch it this way
2021-11-08 03:44:07 +08:00
decodedIRData . numberOfBits = SAMSUNG48_BITS ;
2022-12-27 23:59:32 +08:00
decodedIRData . protocol = SAMSUNG48 ;
2021-11-08 03:44:07 +08:00
} else {
/*
* Samsung32
*/
2022-08-31 20:07:41 +08:00
if ( tValue . UByte . MidHighByte = = ( uint8_t ) ( ~ tValue . UByte . HighByte ) ) {
2024-04-26 03:16:40 +08:00
// 8 bit command protocol -> assume 8 bit address
2021-11-08 03:44:07 +08:00
decodedIRData . command = tValue . UByte . MidHighByte ; // first 8 bit
2024-04-26 03:16:40 +08:00
decodedIRData . address = tValue . UByte . LowByte ; // assume LowByte == MidLowByte
2021-11-08 03:44:07 +08:00
} else {
2024-04-26 03:16:40 +08:00
// 16 bit command protocol, address is filled above with the 16 bit value
2021-11-08 03:44:07 +08:00
decodedIRData . command = tValue . UWord . HighWord ; // first 16 bit
}
decodedIRData . numberOfBits = SAMSUNG_BITS ;
2022-12-27 23:59:32 +08:00
decodedIRData . protocol = SAMSUNG ;
2021-11-08 03:44:07 +08:00
}
2022-07-10 17:48:49 +08:00
// check for repeat
2023-01-02 22:19:42 +08:00
checkForRepeatSpaceTicksAndSetFlag ( SAMSUNG_MAXIMUM_REPEAT_DISTANCE / MICROS_PER_TICK ) ;
2021-11-08 03:44:07 +08:00
return true ;
}
2022-08-31 19:25:29 +08:00
// Old version with MSB first
2021-11-08 03:44:07 +08:00
bool IRrecv : : decodeSAMSUNG ( decode_results * aResults ) {
unsigned int offset = 1 ; // Skip first space
// Initial mark
if ( ! matchMark ( aResults - > rawbuf [ offset ] , SAMSUNG_HEADER_MARK ) ) {
return false ;
}
offset + + ;
2022-07-10 17:48:49 +08:00
// Check for repeat -- like a NEC repeat
2021-11-08 03:44:07 +08:00
if ( ( aResults - > rawlen = = 4 ) & & matchSpace ( aResults - > rawbuf [ offset ] , 2250 )
& & matchMark ( aResults - > rawbuf [ offset + 1 ] , SAMSUNG_BIT_MARK ) ) {
aResults - > bits = 0 ;
aResults - > value = 0xFFFFFFFF ;
decodedIRData . flags = IRDATA_FLAGS_IS_REPEAT ;
decodedIRData . protocol = SAMSUNG ;
return true ;
}
if ( aResults - > rawlen < ( 2 * SAMSUNG_BITS ) + 4 ) {
return false ;
}
2022-07-10 17:48:49 +08:00
// Initial space
2021-11-08 03:44:07 +08:00
if ( ! matchSpace ( aResults - > rawbuf [ offset ] , SAMSUNG_HEADER_SPACE ) ) {
return false ;
}
offset + + ;
2022-11-10 05:49:55 +08:00
if ( ! decodePulseDistanceWidthData ( SAMSUNG_BITS , offset , SAMSUNG_BIT_MARK , 0 , SAMSUNG_ONE_SPACE , SAMSUNG_ZERO_SPACE ,
2022-08-31 20:07:41 +08:00
PROTOCOL_IS_MSB_FIRST ) ) {
2021-11-08 03:44:07 +08:00
return false ;
}
2022-07-10 17:48:49 +08:00
// Success
2021-11-08 03:44:07 +08:00
aResults - > value = decodedIRData . decodedRawData ;
aResults - > bits = SAMSUNG_BITS ;
aResults - > decode_type = SAMSUNG ;
decodedIRData . protocol = SAMSUNG ;
return true ;
}
// Old version with MSB first
void IRsend : : sendSAMSUNG ( unsigned long data , int nbits ) {
// Set IR carrier frequency
2022-08-31 20:07:41 +08:00
enableIROut ( SAMSUNG_KHZ ) ;
2021-11-08 03:44:07 +08:00
// Header
mark ( SAMSUNG_HEADER_MARK ) ;
space ( SAMSUNG_HEADER_SPACE ) ;
// Old version with MSB first Data + stop bit
2022-05-21 00:54:51 +08:00
sendPulseDistanceWidthData ( SAMSUNG_BIT_MARK , SAMSUNG_ONE_SPACE , SAMSUNG_BIT_MARK , SAMSUNG_ZERO_SPACE , data , nbits ,
2023-02-24 09:40:21 +08:00
PROTOCOL_IS_MSB_FIRST ) ;
2021-11-08 03:44:07 +08:00
}
/** @}*/
2022-11-12 06:24:46 +08:00
# if defined(LOCAL_DEBUG)
# undef LOCAL_DEBUG
# endif
2022-03-30 17:55:04 +08:00
# endif // _IR_SAMSUNG_HPP