2021-11-08 03:44:07 +08:00
/*
* ir_Sony . hpp
*
* Contains functions for receiving and sending SIRCS / Sony IR Protocol in " raw " and standard format with 5 bit address 7 bit command
*
* This file is part of Arduino - IRremote https : //github.com/Arduino-IRremote/Arduino-IRremote.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* MIT License
*
* 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 CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
2022-03-30 17:55:04 +08:00
# ifndef _IR_SONY_HPP
# define _IR_SONY_HPP
2021-11-08 03:44:07 +08:00
# include <Arduino.h>
//#define DEBUG // Activate this for lots of lovely debug output from this decoder.
2021-11-29 20:41:03 +08:00
# include "IRremoteInt.h" // evaluates the DEBUG for IR_DEBUG_PRINT
2021-11-08 03:44:07 +08:00
/** \addtogroup Decoder Decoders and encoders for different protocols
* @ {
*/
//==============================================================================
// SSSS OOO N N Y Y
// S O O NN N Y Y
// SSS O O N N N Y
// S O O N NN Y
// SSSS OOO N N Y
//==============================================================================
2022-08-28 02:22:58 +08:00
/*
* Protocol = Sony Address = 0x4B9 Command = 0x7 Raw - Data = 0x25C87 20 bits LSB first
+ 2550 , - 400
+ 1300 , - 450 + 1350 , - 450 + 1300 , - 450 + 700 , - 450
+ 700 , - 450 + 750 , - 450 + 700 , - 400
- - 13 address bits - -
+ 1300 , - 500
+ 700 , - 450 + 700 , - 450 + 1300 , - 500 + 1300 , - 450
+ 1300 , - 450 + 700 , - 450 + 1350 , - 400 + 750 , - 450
+ 700 , - 450 + 1300 , - 450 + 700 , - 450 + 700
Sum : 31100
*/
2021-11-08 03:44:07 +08:00
// see https://www.sbprojects.net/knowledge/ir/sirc.php
// Here http://picprojects.org.uk/projects/sirc/ it is claimed, that many Sony remotes repeat each frame a minimum of 3 times
// LSB first, start bit + 7 command + 5 to 13 address, no stop bit
2022-08-28 02:22:58 +08:00
// IRP: Sony12 {40k,600}<1,-1|2,-1>(4,-1,F:7,D:5,^45m)+ ==> 40 kHz, Unit is 600, LSB, One mark is 2 units, Start bit is 4 units, 7 bit Function, 5 bit Device, no Stop bit, every 45 milliseconds
// IRP: Sony15 {40k,600}<1,-1|2,-1>(4,-1,F:7,D:8,^45m)+ ==> 8 bit Device
// IRP: Sony20 {40k,600}<1,-1|2,-1>(4,-1,F:7,D:5,S:8,^45m)+ ==> 5 bit Device, 8 bit Subdevice
2021-11-08 03:44:07 +08:00
//
# define SONY_ADDRESS_BITS 5
# define SONY_COMMAND_BITS 7
# define SONY_EXTRA_BITS 8
# define SONY_BITS_MIN (SONY_COMMAND_BITS + SONY_ADDRESS_BITS) // 12 bits
# define SONY_BITS_15 (SONY_COMMAND_BITS + SONY_ADDRESS_BITS + 3) // 15 bits
# define SONY_BITS_MAX (SONY_COMMAND_BITS + SONY_ADDRESS_BITS + SONY_EXTRA_BITS) // 20 bits == SIRCS_20_PROTOCOL
# define SONY_UNIT 600 // 24 periods of 40kHz
2022-06-02 02:47:18 +08:00
# define SONY_HEADER_MARK (4 * SONY_UNIT) // 2400
2021-11-08 03:44:07 +08:00
# define SONY_ONE_MARK (2 * SONY_UNIT) // 1200
# define SONY_ZERO_MARK SONY_UNIT
# define SONY_SPACE SONY_UNIT
2022-08-28 02:22:58 +08:00
# define SONY_AVERAGE_DURATION_MIN 21000 // SONY_HEADER_MARK + SONY_SPACE + 12 * 2,5 * SONY_UNIT // 2.5 because we assume more zeros than ones
# define SONY_AVERAGE_DURATION_MAX 33000 // SONY_HEADER_MARK + SONY_SPACE + 20 * 2,5 * SONY_UNIT // 2.5 because we assume more zeros than ones
# define SONY_REPEAT_PERIOD 45000 // Commands are repeated every 45 ms (measured from start to start) for as long as the key on the remote control is held down.
# define SONY_REPEAT_SPACE_MAX (SONY_REPEAT_PERIOD - SONY_AVERAGE_DURATION_MIN) // 24 ms
2021-11-08 03:44:07 +08:00
/*
* Repeat commands should be sent in a 45 ms raster .
* There is NO delay after the last sent command / repeat !
* @ param numberOfBits if = = 20 send 13 address bits otherwise only 5 address bits
*/
void IRsend : : sendSony ( uint16_t aAddress , uint8_t aCommand , uint_fast8_t aNumberOfRepeats , uint8_t numberOfBits ) {
2022-08-28 02:22:58 +08:00
uint32_t tData = ( uint32_t ) aAddress < < 7 | aCommand ;
// send 5, 8, 13 address bits LSB first
sendPulseDistanceWidth ( SONY_KHZ , SONY_HEADER_MARK , SONY_SPACE , SONY_ONE_MARK , SONY_SPACE , SONY_ZERO_MARK , SONY_SPACE , tData ,
numberOfBits , PROTOCOL_IS_LSB_FIRST , SEND_NO_STOP_BIT , SONY_REPEAT_PERIOD / MICROS_IN_ONE_MILLI , aNumberOfRepeats ) ;
2021-11-08 03:44:07 +08:00
}
//+=============================================================================
bool IRrecv : : decodeSony ( ) {
// Check header "mark"
if ( ! matchMark ( decodedIRData . rawDataPtr - > rawbuf [ 1 ] , SONY_HEADER_MARK ) ) {
return false ;
}
// Check we have enough data. +2 for initial gap and start bit mark and space minus the last/MSB space. NO stop bit! 26, 32, 42
if ( decodedIRData . rawDataPtr - > rawlen ! = ( 2 * SONY_BITS_MIN ) + 2 & & decodedIRData . rawDataPtr - > rawlen ! = ( 2 * SONY_BITS_MAX ) + 2
& & decodedIRData . rawDataPtr - > rawlen ! = ( 2 * SONY_BITS_15 ) + 2 ) {
2021-11-29 20:41:03 +08:00
// ??? IR_TRACE_PRINT since I saw this too often
2022-05-19 15:51:34 +08:00
IR_DEBUG_PRINT ( F ( " Sony: " ) ) ;
IR_DEBUG_PRINT ( F ( " Data length= " ) ) ;
2021-11-29 20:41:03 +08:00
IR_DEBUG_PRINT ( decodedIRData . rawDataPtr - > rawlen ) ;
2022-05-19 15:51:34 +08:00
IR_DEBUG_PRINTLN ( F ( " is not 12, 15 or 20 " ) ) ;
2021-11-08 03:44:07 +08:00
return false ;
}
2022-06-02 02:47:18 +08:00
2021-11-08 03:44:07 +08:00
// Check header "space"
if ( ! matchSpace ( decodedIRData . rawDataPtr - > rawbuf [ 2 ] , SONY_SPACE ) ) {
2022-05-19 15:51:34 +08:00
IR_DEBUG_PRINT ( F ( " Sony: " ) ) ;
IR_DEBUG_PRINTLN ( F ( " Header space length is wrong " ) ) ;
2021-11-08 03:44:07 +08:00
return false ;
}
2022-05-21 00:54:51 +08:00
if ( ! decodePulseWidthData ( ( decodedIRData . rawDataPtr - > rawlen - 1 ) / 2 , 3 , SONY_ONE_MARK , SONY_ZERO_MARK , SONY_SPACE ,
2022-08-28 02:22:58 +08:00
PROTOCOL_IS_LSB_FIRST ) ) {
2022-05-19 15:51:34 +08:00
IR_DEBUG_PRINT ( F ( " Sony: " ) ) ;
IR_DEBUG_PRINTLN ( F ( " Decode failed " ) ) ;
2021-11-08 03:44:07 +08:00
return false ;
}
// Success
// decodedIRData.flags = IRDATA_FLAGS_IS_LSB_FIRST; // Not required, since this is the start value
uint8_t tCommand = decodedIRData . decodedRawData & 0x7F ; // first 7 bits
uint16_t tAddress = decodedIRData . decodedRawData > > 7 ; // next 5 or 8 or 13 bits
/*
* Check for repeat
*/
2022-08-28 02:22:58 +08:00
if ( decodedIRData . rawDataPtr - > rawbuf [ 0 ] < ( ( SONY_REPEAT_SPACE_MAX + ( SONY_REPEAT_SPACE_MAX / 4 ) ) / MICROS_PER_TICK ) ) {
2021-11-08 03:44:07 +08:00
decodedIRData . flags = IRDATA_FLAGS_IS_REPEAT | IRDATA_FLAGS_IS_LSB_FIRST ;
}
decodedIRData . command = tCommand ;
decodedIRData . address = tAddress ;
decodedIRData . numberOfBits = ( decodedIRData . rawDataPtr - > rawlen - 1 ) / 2 ;
decodedIRData . protocol = SONY ;
return true ;
}
# define SONY_DOUBLE_SPACE_USECS 500 // usually see 713 - not using ticks as get number wrap around
bool IRrecv : : decodeSonyMSB ( decode_results * aResults ) {
long data = 0 ;
uint8_t bits = 0 ;
unsigned int offset = 0 ; // Dont skip first space, check its size
if ( aResults - > rawlen < ( 2 * SONY_BITS_MIN ) + 2 ) {
return false ;
}
// Some Sony's deliver repeats fast after first
// unfortunately can't spot difference from of repeat from two fast clicks
if ( aResults - > rawbuf [ 0 ] < ( SONY_DOUBLE_SPACE_USECS / MICROS_PER_TICK ) ) {
2022-05-19 15:51:34 +08:00
IR_DEBUG_PRINTLN ( F ( " IR Gap found " ) ) ;
2021-11-08 03:44:07 +08:00
aResults - > bits = 0 ;
aResults - > value = 0xFFFFFFFF ;
decodedIRData . flags = IRDATA_FLAGS_IS_REPEAT ;
decodedIRData . protocol = SONY ;
return true ;
}
offset + + ;
// Check header "mark"
if ( ! matchMark ( aResults - > rawbuf [ offset ] , SONY_HEADER_MARK ) ) {
return false ;
}
offset + + ;
// MSB first - Not compatible to standard, which says LSB first :-(
while ( offset + 1 < aResults - > rawlen ) {
// First check for the constant space length, we do not have a space at the end of raw data
// we are lucky, since the start space is equal the data space.
if ( ! matchSpace ( aResults - > rawbuf [ offset ] , SONY_SPACE ) ) {
return false ;
}
offset + + ;
// bit value is determined by length of the mark
if ( matchMark ( aResults - > rawbuf [ offset ] , SONY_ONE_MARK ) ) {
data = ( data < < 1 ) | 1 ;
} else if ( matchMark ( aResults - > rawbuf [ offset ] , SONY_ZERO_MARK ) ) {
data = ( data < < 1 ) | 0 ;
} else {
return false ;
}
offset + + ;
bits + + ;
}
aResults - > bits = bits ;
aResults - > value = data ;
aResults - > decode_type = SONY ;
decodedIRData . protocol = SONY ;
return true ;
}
/**
* Old version with MSB first data
*/
void IRsend : : sendSony ( unsigned long data , int nbits ) {
// Set IR carrier frequency
enableIROut ( SONY_KHZ ) ;
// Header
mark ( SONY_HEADER_MARK ) ;
space ( SONY_SPACE ) ;
// Old version with MSB first Data
2022-08-28 02:22:58 +08:00
sendPulseDistanceWidthData ( SONY_ONE_MARK , SONY_SPACE , SONY_ZERO_MARK , SONY_SPACE , data , nbits , PROTOCOL_IS_MSB_FIRST ,
SEND_NO_STOP_BIT ) ;
2022-05-21 00:54:51 +08:00
IrReceiver . restartAfterSend ( ) ;
2021-11-08 03:44:07 +08:00
}
/** @}*/
2022-03-30 17:55:04 +08:00
# endif // _IR_SONY_HPP