Infrared: RCA protocol support (#2823)

* RCA protocol support
* Add unit test

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
MMX 2023-07-11 11:39:07 +03:00 committed by GitHub
parent 136114890f
commit 14fc960246
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 332 additions and 0 deletions

View file

@ -425,6 +425,7 @@ MU_TEST(infrared_test_decoder_mixed) {
infrared_test_run_decoder(InfraredProtocolSamsung32, 1);
infrared_test_run_decoder(InfraredProtocolSIRC, 3);
infrared_test_run_decoder(InfraredProtocolKaseikyo, 1);
infrared_test_run_decoder(InfraredProtocolRCA, 1);
}
MU_TEST(infrared_test_decoder_nec) {
@ -499,6 +500,15 @@ MU_TEST(infrared_test_decoder_kaseikyo) {
infrared_test_run_decoder(InfraredProtocolKaseikyo, 6);
}
MU_TEST(infrared_test_decoder_rca) {
infrared_test_run_decoder(InfraredProtocolRCA, 1);
infrared_test_run_decoder(InfraredProtocolRCA, 2);
infrared_test_run_decoder(InfraredProtocolRCA, 3);
infrared_test_run_decoder(InfraredProtocolRCA, 4);
infrared_test_run_decoder(InfraredProtocolRCA, 5);
infrared_test_run_decoder(InfraredProtocolRCA, 6);
}
MU_TEST(infrared_test_encoder_decoder_all) {
infrared_test_run_encoder_decoder(InfraredProtocolNEC, 1);
infrared_test_run_encoder_decoder(InfraredProtocolNECext, 1);
@ -509,6 +519,7 @@ MU_TEST(infrared_test_encoder_decoder_all) {
infrared_test_run_encoder_decoder(InfraredProtocolRC5, 1);
infrared_test_run_encoder_decoder(InfraredProtocolSIRC, 1);
infrared_test_run_encoder_decoder(InfraredProtocolKaseikyo, 1);
infrared_test_run_encoder_decoder(InfraredProtocolRCA, 1);
}
MU_TEST_SUITE(infrared_test) {
@ -527,6 +538,7 @@ MU_TEST_SUITE(infrared_test) {
MU_RUN_TEST(infrared_test_decoder_samsung32);
MU_RUN_TEST(infrared_test_decoder_necext1);
MU_RUN_TEST(infrared_test_decoder_kaseikyo);
MU_RUN_TEST(infrared_test_decoder_rca);
MU_RUN_TEST(infrared_test_decoder_mixed);
MU_RUN_TEST(infrared_test_encoder_decoder_all);
}

View file

@ -0,0 +1,105 @@
Filetype: IR tests file
Version: 1
#
name: decoder_input1
type: raw
data: 1000000 3994 3969 552 1945 551 1945 552 1945 551 1945 552 946 551 947 550 1947 548 951 546 1953 542 979 518 1979 517 981 492 1006 491 1006 492 1006 492 1006 492 2005 492 2005 492 1006 492 2005 492 1006 492 2005 492 1006 492 2006 491
#
name: decoder_expected1
type: parsed_array
count: 1
#
protocol: RCA
address: 0F 00 00 00
command: 54 00 00 00
repeat: false
#
name: decoder_input2
type: raw
data: 1000000 4055 3941 605 1891 551 1947 550 1946 551 1946 551 947 551 947 550 1947 549 949 548 1951 545 1977 519 1978 519 1979 518 980 518 980 518 980 518 980 518 1979 518 1979 518 981 517 1979 518 980 518 980 518 980 518 980 518
#
name: decoder_expected2
type: parsed_array
count: 1
#
protocol: RCA
address: 0F 00 00 00
command: F4 00 00 00
repeat: false
#
name: decoder_input3
type: raw
data: 1000000 4027 3970 551 1946 550 1946 551 1946 551 1946 551 946 551 947 550 1947 549 949 547 1951 545 1978 518 1979 492 1006 492 1007 491 1006 492 1006 492 1006 492 2006 491 2006 491 1006 492 2006 491 1007 491 1007 491 1006 492 2006 491
#
name: decoder_expected3
type: parsed_array
count: 1
#
protocol: RCA
address: 0F 00 00 00
command: 74 00 00 00
repeat: false
#
name: decoder_input4
type: raw
data: 1000000 4021 3941 551 1946 550 1946 551 1946 551 1945 552 946 551 947 550 1947 549 950 547 1952 544 1977 519 979 519 1979 518 980 518 980 518 980 518 980 518 1979 518 1979 518 980 518 1979 518 980 518 980 518 1979 518 980 518
#
name: decoder_expected4
type: parsed_array
count: 1
#
protocol: RCA
address: 0F 00 00 00
command: B4 00 00 00
repeat: false
#
name: decoder_input5
type: raw
data: 1000000 4022 3941 551 1946 551 1946 577 1919 578 1919 578 920 552 946 551 1946 550 947 550 1949 547 1952 544 978 520 979 519 980 518 980 518 980 518 980 518 1979 518 1979 518 980 518 1979 518 980 518 980 518 1979 518 1980 517
#
name: decoder_expected5
type: parsed_array
count: 1
#
protocol: RCA
address: 0F 00 00 00
command: 34 00 00 00
repeat: false
#
name: decoder_input6
type: raw
data: 1000000 3995 3968 552 1944 552 1946 550 1946 550 1946 551 947 550 948 549 1947 549 1949 547 1952 544 1978 518 1979 492 2005 492 1006 492 1006 492 1006 492 1006 492 2005 492 2005 492 1006 492 1006 492 1006 492 1006 492 1006 492 1006 492
#
name: decoder_expected6
type: parsed_array
count: 1
#
protocol: RCA
address: 0F 00 00 00
command: FC 00 00 00
repeat: false
#
name: encoder_decoder_input1
type: parsed_array
count: 4
#
protocol: RCA
address: 0F 00 00 00
command: 74 00 00 00
repeat: false
#
protocol: RCA
address: 0F 00 00 00
command: B4 00 00 00
repeat: false
#
protocol: RCA
address: 0F 00 00 00
command: 34 00 00 00
repeat: false
#
protocol: RCA
address: 0F 00 00 00
command: FC 00 00 00
repeat: false
#

View file

@ -1,5 +1,22 @@
# Infrared Flipper File Formats
## Supported protocols list for `type: parsed`
```
NEC
NECext
NEC42
NEC42ext
Samsung32
RC6
RC5
RC5X
SIRC
SIRC15
SIRC20
Kaseikyo
RCA
```
## Infrared Remote File Format
### Example

View file

@ -11,6 +11,7 @@
#include "rc6/infrared_protocol_rc6.h"
#include "sirc/infrared_protocol_sirc.h"
#include "kaseikyo/infrared_protocol_kaseikyo.h"
#include "rca/infrared_protocol_rca.h"
typedef struct {
InfraredAlloc alloc;
@ -127,6 +128,20 @@ static const InfraredEncoderDecoder infrared_encoder_decoder[] = {
.free = infrared_encoder_kaseikyo_free},
.get_protocol_variant = infrared_protocol_kaseikyo_get_variant,
},
{
.decoder =
{.alloc = infrared_decoder_rca_alloc,
.decode = infrared_decoder_rca_decode,
.reset = infrared_decoder_rca_reset,
.check_ready = infrared_decoder_rca_check_ready,
.free = infrared_decoder_rca_free},
.encoder =
{.alloc = infrared_encoder_rca_alloc,
.encode = infrared_encoder_rca_encode,
.reset = infrared_encoder_rca_reset,
.free = infrared_encoder_rca_free},
.get_protocol_variant = infrared_protocol_rca_get_variant,
},
};
static int infrared_find_index_by_protocol(InfraredProtocol protocol);

View file

@ -33,6 +33,7 @@ typedef enum {
InfraredProtocolSIRC15,
InfraredProtocolSIRC20,
InfraredProtocolKaseikyo,
InfraredProtocolRCA,
InfraredProtocolMAX,
} InfraredProtocol;

View file

@ -0,0 +1,45 @@
#include "infrared_protocol_rca_i.h"
#include <core/check.h>
InfraredMessage* infrared_decoder_rca_check_ready(void* ctx) {
return infrared_common_decoder_check_ready(ctx);
}
bool infrared_decoder_rca_interpret(InfraredCommonDecoder* decoder) {
furi_assert(decoder);
uint32_t* data = (void*)&decoder->data;
uint8_t address = (*data & 0xF);
uint8_t command = (*data >> 4) & 0xFF;
uint8_t address_inverse = (*data >> 12) & 0xF;
uint8_t command_inverse = (*data >> 16) & 0xFF;
uint8_t inverse_address_inverse = (uint8_t)~address_inverse & 0xF;
uint8_t inverse_command_inverse = (uint8_t)~command_inverse;
if((command == inverse_command_inverse) && (address == inverse_address_inverse)) {
decoder->message.protocol = InfraredProtocolRCA;
decoder->message.address = address;
decoder->message.command = command;
decoder->message.repeat = false;
return true;
}
return false;
}
void* infrared_decoder_rca_alloc(void) {
return infrared_common_decoder_alloc(&infrared_protocol_rca);
}
InfraredMessage* infrared_decoder_rca_decode(void* decoder, bool level, uint32_t duration) {
return infrared_common_decode(decoder, level, duration);
}
void infrared_decoder_rca_free(void* decoder) {
infrared_common_decoder_free(decoder);
}
void infrared_decoder_rca_reset(void* decoder) {
infrared_common_decoder_reset(decoder);
}

View file

@ -0,0 +1,37 @@
#include "infrared_protocol_rca_i.h"
#include <core/check.h>
void infrared_encoder_rca_reset(void* encoder_ptr, const InfraredMessage* message) {
furi_assert(encoder_ptr);
furi_assert(message);
InfraredCommonEncoder* encoder = encoder_ptr;
infrared_common_encoder_reset(encoder);
uint32_t* data = (void*)encoder->data;
uint8_t address = message->address;
uint8_t address_inverse = ~address;
uint8_t command = message->command;
uint8_t command_inverse = ~command;
*data = address & 0xF;
*data |= command << 4;
*data |= (address_inverse & 0xF) << 12;
*data |= command_inverse << 16;
encoder->bits_to_encode = encoder->protocol->databit_len[0];
}
void* infrared_encoder_rca_alloc(void) {
return infrared_common_encoder_alloc(&infrared_protocol_rca);
}
void infrared_encoder_rca_free(void* encoder_ptr) {
infrared_common_encoder_free(encoder_ptr);
}
InfraredStatus infrared_encoder_rca_encode(void* encoder_ptr, uint32_t* duration, bool* level) {
return infrared_common_encode(encoder_ptr, duration, level);
}

View file

@ -0,0 +1,40 @@
#include "infrared_protocol_rca_i.h"
const InfraredCommonProtocolSpec infrared_protocol_rca = {
.timings =
{
.preamble_mark = INFRARED_RCA_PREAMBLE_MARK,
.preamble_space = INFRARED_RCA_PREAMBLE_SPACE,
.bit1_mark = INFRARED_RCA_BIT1_MARK,
.bit1_space = INFRARED_RCA_BIT1_SPACE,
.bit0_mark = INFRARED_RCA_BIT0_MARK,
.bit0_space = INFRARED_RCA_BIT0_SPACE,
.preamble_tolerance = INFRARED_RCA_PREAMBLE_TOLERANCE,
.bit_tolerance = INFRARED_RCA_BIT_TOLERANCE,
.silence_time = INFRARED_RCA_SILENCE,
.min_split_time = INFRARED_RCA_MIN_SPLIT_TIME,
},
.databit_len[0] = 24,
.no_stop_bit = false,
.decode = infrared_common_decode_pdwm,
.encode = infrared_common_encode_pdwm,
.interpret = infrared_decoder_rca_interpret,
.decode_repeat = NULL,
.encode_repeat = NULL,
};
static const InfraredProtocolVariant infrared_protocol_variant_rca = {
.name = "RCA",
.address_length = 4,
.command_length = 8,
.frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
.duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
.repeat_count = INFRARED_RCA_REPEAT_COUNT_MIN,
};
const InfraredProtocolVariant* infrared_protocol_rca_get_variant(InfraredProtocol protocol) {
if(protocol == InfraredProtocolRCA)
return &infrared_protocol_variant_rca;
else
return NULL;
}

View file

@ -0,0 +1,30 @@
#pragma once
#include "../infrared_i.h"
/***************************************************************************************************
* RCA protocol description
* https://www.sbprojects.net/knowledge/ir/rca.php
****************************************************************************************************
* Preamble Preamble Pulse Distance/Width Pause Preamble Preamble
* mark space Modulation up to period repeat repeat
* mark space
*
* 4000 4000 24 bit ...8000 4000 4000
* __________ _ _ _ _ _ _ _ _ _ _ _ _ _ ___________
* ____ __________ _ _ _ __ __ __ _ _ __ __ _ _ ________________ ___________
*
***************************************************************************************************/
void* infrared_decoder_rca_alloc(void);
void infrared_decoder_rca_reset(void* decoder);
void infrared_decoder_rca_free(void* decoder);
InfraredMessage* infrared_decoder_rca_check_ready(void* decoder);
InfraredMessage* infrared_decoder_rca_decode(void* decoder, bool level, uint32_t duration);
void* infrared_encoder_rca_alloc(void);
InfraredStatus infrared_encoder_rca_encode(void* encoder_ptr, uint32_t* duration, bool* level);
void infrared_encoder_rca_reset(void* encoder_ptr, const InfraredMessage* message);
void infrared_encoder_rca_free(void* encoder_ptr);
const InfraredProtocolVariant* infrared_protocol_rca_get_variant(InfraredProtocol protocol);

View file

@ -0,0 +1,30 @@
#pragma once
#include "../common/infrared_common_i.h"
#define INFRARED_RCA_PREAMBLE_MARK 4000
#define INFRARED_RCA_PREAMBLE_SPACE 4000
#define INFRARED_RCA_BIT1_MARK 500
#define INFRARED_RCA_BIT1_SPACE 2000
#define INFRARED_RCA_BIT0_MARK 500
#define INFRARED_RCA_BIT0_SPACE 1000
#define INFRARED_RCA_REPEAT_PERIOD 8000
#define INFRARED_RCA_SILENCE INFRARED_RCA_REPEAT_PERIOD
#define INFRARED_RCA_MIN_SPLIT_TIME INFRARED_RCA_REPEAT_PAUSE_MIN
#define INFRARED_RCA_REPEAT_PAUSE_MIN 4000
#define INFRARED_RCA_REPEAT_PAUSE_MAX 150000
#define INFRARED_RCA_REPEAT_COUNT_MIN 1
#define INFRARED_RCA_REPEAT_MARK INFRARED_RCA_PREAMBLE_MARK
#define INFRARED_RCA_REPEAT_SPACE INFRARED_RCA_PREAMBLE_SPACE
#define INFRARED_RCA_PREAMBLE_TOLERANCE 200 // us
#define INFRARED_RCA_BIT_TOLERANCE 120 // us
extern const InfraredCommonProtocolSpec infrared_protocol_rca;
bool infrared_decoder_rca_interpret(InfraredCommonDecoder* decoder);
InfraredStatus infrared_decoder_rca_decode_repeat(InfraredCommonDecoder* decoder);
InfraredStatus infrared_encoder_rca_encode_repeat(
InfraredCommonEncoder* encoder,
uint32_t* duration,
bool* level);