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
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 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
2022-11-17 08:06:10 +08:00
// 7 command bits
2022-08-28 02:22:58 +08:00
+ 1300 , - 450 + 1350 , - 450 + 1300 , - 450 + 700 , - 450
+ 700 , - 450 + 750 , - 450 + 700 , - 400
2023-02-24 09:40:21 +08:00
// (5,8,) 13 address bits
2022-08-28 02:22:58 +08:00
+ 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
*/
2023-02-24 09:40:21 +08:00
/*
* Sony is the only protocol using the pulse width encoding , which requires no stop bit
*/
2021-11-08 03:44:07 +08:00
// see https://www.sbprojects.net/knowledge/ir/sirc.php
2023-02-24 09:40:21 +08:00
// https://www.mikrocontroller.net/articles/IRMP_-_english#SIRCS
2022-12-14 17:15:41 +08:00
// Frames are repeated every 45ms (measured from start to start) for as long as the key on the remote control is held down.
// This leads to a 15 ms gap for a Sony20 protocol!
// Here http://picprojects.org.uk/projects/sirc/ it is claimed, that many Sony remotes send each frame a minimum of 3 times. But 1 repeat (2 sends) has also been seen in real life.
2021-11-08 03:44:07 +08:00
// 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.
2022-11-12 02:53:54 +08:00
# define SONY_MAXIMUM_REPEAT_DISTANCE (SONY_REPEAT_PERIOD - SONY_AVERAGE_DURATION_MIN) // 24 ms
2021-11-08 03:44:07 +08:00
2022-11-10 05:49:55 +08:00
struct PulseDistanceWidthProtocolConstants SonyProtocolConstants = { SONY , SONY_KHZ , SONY_HEADER_MARK , SONY_SPACE , SONY_ONE_MARK ,
2023-02-24 09:40:21 +08:00
SONY_SPACE , SONY_ZERO_MARK , SONY_SPACE , PROTOCOL_IS_LSB_FIRST , ( SONY_REPEAT_PERIOD / MICROS_IN_ONE_MILLI ) , NULL } ;
2022-08-31 19:25:29 +08:00
/************************************
* Start of send and decode functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* @ param numberOfBits should be one of SIRCS_12_PROTOCOL , SIRCS_15_PROTOCOL , SIRCS_20_PROTOCOL . Not checked ! 20 - > send 13 address bits
2021-11-08 03:44:07 +08:00
*/
2022-08-31 19:25:29 +08:00
void IRsend : : sendSony ( uint16_t aAddress , uint8_t aCommand , int_fast8_t aNumberOfRepeats , uint8_t numberOfBits ) {
2022-11-08 07:36:44 +08:00
uint32_t tData = ( uint32_t ) aAddress < < 7 | ( aCommand & 0x7F ) ;
2022-08-28 02:22:58 +08:00
// send 5, 8, 13 address bits LSB first
2022-08-31 19:25:29 +08:00
sendPulseDistanceWidth ( & SonyProtocolConstants , tData , numberOfBits , aNumberOfRepeats ) ;
2021-11-08 03:44:07 +08:00
}
bool IRrecv : : decodeSony ( ) {
2022-08-31 19:25:29 +08:00
if ( ! checkHeader ( & SonyProtocolConstants ) ) {
2021-11-08 03:44:07 +08:00
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
2024-02-24 02:28:33 +08:00
if ( decodedIRData . rawlen ! = ( 2 * SONY_BITS_MIN ) + 2 & & decodedIRData . rawlen ! = ( 2 * SONY_BITS_MAX ) + 2
& & decodedIRData . rawlen ! = ( 2 * SONY_BITS_15 ) + 2 ) {
2022-05-19 15:51:34 +08:00
IR_DEBUG_PRINT ( F ( " Sony: " ) ) ;
IR_DEBUG_PRINT ( F ( " Data length= " ) ) ;
2024-02-24 02:28:33 +08:00
IR_DEBUG_PRINT ( decodedIRData . 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
2024-02-24 02:28:33 +08:00
if ( ! decodePulseDistanceWidthData ( & SonyProtocolConstants , ( decodedIRData . rawlen - 1 ) / 2 , 3 ) ) {
2022-11-12 06:24:46 +08:00
# if defined(LOCAL_DEBUG)
Serial . print ( F ( " Sony: " ) ) ;
Serial . println ( F ( " Decode failed " ) ) ;
# endif
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
2022-08-31 19:25:29 +08:00
decodedIRData . command = decodedIRData . decodedRawData & 0x7F ; // first 7 bits
decodedIRData . address = decodedIRData . decodedRawData > > 7 ; // next 5 or 8 or 13 bits
2024-02-24 02:28:33 +08:00
decodedIRData . numberOfBits = ( decodedIRData . rawlen - 1 ) / 2 ;
2022-08-31 19:25:29 +08:00
decodedIRData . protocol = SONY ;
2021-11-08 03:44:07 +08:00
2022-08-31 20:07:41 +08:00
//Check for repeat
2023-01-02 22:19:42 +08:00
checkForRepeatSpaceTicksAndSetFlag ( SONY_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 deprecated functions , kept for backward compatibility to old 2.0 tutorials
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Old version with MSB first data
*/
2021-11-08 03:44:07 +08:00
# 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-11-12 06:24:46 +08:00
# if defined(LOCAL_DEBUG)
Serial . println ( F ( " IR Gap found " ) ) ;
# endif
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
*/
2024-05-24 22:23:22 +08:00
void IRsend : : sendSonyMSB ( unsigned long data , int nbits ) {
2021-11-08 03:44:07 +08:00
// Set IR carrier frequency
2022-08-31 20:07:41 +08:00
enableIROut ( SONY_KHZ ) ;
2021-11-08 03:44:07 +08:00
// Header
mark ( SONY_HEADER_MARK ) ;
space ( SONY_SPACE ) ;
// Old version with MSB first Data
2023-02-24 09:40:21 +08:00
sendPulseDistanceWidthData ( SONY_ONE_MARK , SONY_SPACE , SONY_ZERO_MARK , SONY_SPACE , data , nbits , PROTOCOL_IS_MSB_FIRST ) ;
2021-11-08 03:44:07 +08:00
}
2024-05-24 22:23:22 +08:00
void IRsend : : sendSony ( unsigned long data , int nbits ) {
sendSonyMSB ( data , nbits ) ;
}
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_SONY_HPP