[FL-1800] IRDA: enc/decoder refactoring, Add NEC42 (#705)

* WIP: IRDA: multilen protocol refactoring, NEC42
* IRDA: Refactoring encoder/decoder

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Albert Kharisov
2021-09-15 20:22:58 +03:00
committed by GitHub
parent 4768177cf5
commit 4f233ff0a3
21 changed files with 551 additions and 437 deletions

View File

@@ -1,3 +1,4 @@
#include "common/irda_common_i.h"
#include "irda.h"
#include "irda_protocol_defs_i.h"
#include <stdbool.h>
@@ -6,26 +7,55 @@
#include "../irda_i.h"
IrdaMessage* irda_decoder_nec_check_ready(void* ctx) {
return irda_common_decoder_check_ready(ctx);
}
bool irda_decoder_nec_interpret(IrdaCommonDecoder* decoder) {
furi_assert(decoder);
bool result = false;
uint8_t address = decoder->data[0];
uint8_t address_inverse = decoder->data[1];
uint8_t command = decoder->data[2];
uint8_t command_inverse = decoder->data[3];
if (command == (uint8_t) ~command_inverse) {
if (address == (uint8_t) ~address_inverse) {
if (decoder->databit_cnt == 32) {
uint8_t address = decoder->data[0];
uint8_t address_inverse = decoder->data[1];
uint8_t command = decoder->data[2];
uint8_t command_inverse = decoder->data[3];
if ((command == (uint8_t) ~command_inverse) && (address == (uint8_t) ~address_inverse)) {
decoder->message.protocol = IrdaProtocolNEC;
decoder->message.address = address;
decoder->message.command = command;
decoder->message.repeat = false;
result = true;
} else {
decoder->message.protocol = IrdaProtocolNECext;
decoder->message.address = decoder->data[0] | (decoder->data[1] << 8);
decoder->message.command = decoder->data[2] | (decoder->data[3] << 8);
decoder->message.repeat = false;
result = true;
}
} else if (decoder->databit_cnt == 42) {
uint32_t* data1 = (void*) decoder->data;
uint16_t* data2 = (void*) (data1 + 1);
uint16_t address = *data1 & 0x1FFF;
uint16_t address_inverse = (*data1 >> 13) & 0x1FFF;
uint16_t command = ((*data1 >> 26) & 0x3F) | ((*data2 & 0x3) << 6);
uint16_t command_inverse = (*data2 >> 2) & 0xFF;
if ((address == (~address_inverse & 0x1FFF))
&& (command == (~command_inverse & 0xFF))) {
decoder->message.protocol = IrdaProtocolNEC42;
decoder->message.address = address;
decoder->message.command = command;
decoder->message.repeat = false;
result = true;
} else {
decoder->message.protocol = IrdaProtocolNEC42ext;
decoder->message.address = address | (address_inverse << 13);
decoder->message.command = command | (command_inverse << 8);
decoder->message.repeat = false;
result = true;
}
decoder->message.command = command;
decoder->message.repeat = false;
result = true;
}
return result;

View File

@@ -20,26 +20,45 @@ void irda_encoder_nec_reset(void* encoder_ptr, const IrdaMessage* message) {
IrdaCommonEncoder* encoder = encoder_ptr;
irda_common_encoder_reset(encoder);
uint8_t address = message->address;
uint8_t address_inverse = ~address;
uint8_t command = message->command;
uint8_t command_inverse = ~command;
uint32_t* data = (void*) encoder->data;
uint32_t* data1 = (void*) encoder->data;
uint32_t* data2 = data1 + 1;
if (message->protocol == IrdaProtocolNEC) {
*data = (address | (address_inverse << 8));
uint8_t address = message->address;
uint8_t address_inverse = ~address;
uint8_t command = message->command;
uint8_t command_inverse = ~command;
*data1 = address;
*data1 |= address_inverse << 8;
*data1 |= command << 16;
*data1 |= command_inverse << 24;
encoder->bits_to_encode = 32;
} else if (message->protocol == IrdaProtocolNECext) {
*data = (uint16_t) message->address;
*data1 = (uint16_t) message->address;
*data1 |= (message->command & 0xFFFF) << 16;
encoder->bits_to_encode = 32;
} else if (message->protocol == IrdaProtocolNEC42) {
/* 13 address + 13 inverse address + 8 command + 8 inv command */
*data1 = message->address & 0x1FFFUL;
*data1 |= (~message->address & 0x1FFFUL) << 13;
*data1 |= ((message->command & 0x3FUL) << 26);
*data2 = (message->command & 0xC0UL) >> 6;
*data2 |= (~message->command & 0xFFUL) << 2;
encoder->bits_to_encode = 42;
} else if (message->protocol == IrdaProtocolNEC42ext) {
*data1 = message->address & 0x3FFFFFF;
*data1 |= ((message->command & 0x3F) << 26);
*data2 = (message->command & 0xFFC0) >> 6;
encoder->bits_to_encode = 42;
} else {
furi_assert(0);
}
*data |= command << 16;
*data |= command_inverse << 24;
}
IrdaStatus irda_encoder_nec_encode_repeat(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) {
furi_assert(encoder);
/* space + 2 timings preambule + payload + stop bit */
uint32_t timings_encoded_up_to_repeat = 1 + 2 + encoder->protocol->databit_len * 2 + 1;
uint32_t timings_encoded_up_to_repeat = 1 + 2 + encoder->bits_to_encode * 2 + 1;
uint32_t repeat_cnt = encoder->timings_encoded - timings_encoded_up_to_repeat;
furi_assert(encoder->timings_encoded >= timings_encoded_up_to_repeat);

View File

@@ -12,16 +12,36 @@ static const IrdaProtocolSpecification irda_nec_protocol_specification = {
static const IrdaProtocolSpecification irda_necext_protocol_specification = {
.name = "NECext",
.address_length = 16,
.command_length = 16,
.frequency = IRDA_COMMON_CARRIER_FREQUENCY,
.duty_cycle = IRDA_COMMON_DUTY_CYCLE,
};
static const IrdaProtocolSpecification irda_nec42_protocol_specification = {
.name = "NEC42",
.address_length = 13,
.command_length = 8,
.frequency = IRDA_COMMON_CARRIER_FREQUENCY,
.duty_cycle = IRDA_COMMON_DUTY_CYCLE,
};
static const IrdaProtocolSpecification irda_nec42ext_protocol_specification = {
.name = "NEC42ext",
.address_length = 26,
.command_length = 16,
.frequency = IRDA_COMMON_CARRIER_FREQUENCY,
.duty_cycle = IRDA_COMMON_DUTY_CYCLE,
};
const IrdaProtocolSpecification* irda_nec_get_spec(IrdaProtocol protocol) {
if (protocol == IrdaProtocolNEC)
return &irda_nec_protocol_specification;
else if (protocol == IrdaProtocolNECext)
return &irda_necext_protocol_specification;
else if (protocol == IrdaProtocolNEC42)
return &irda_nec42_protocol_specification;
else if (protocol == IrdaProtocolNEC42ext)
return &irda_nec42ext_protocol_specification;
else
return NULL;
}