| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- #include "irda-decoder-nec.h"
- #include "string.h"
- const uint32_t PREAMBULA_HIGH_MIN = 9000 - 900;
- const uint32_t PREAMBULA_HIGH_MAX = 9000 + 900;
- const uint32_t PREAMBULA_LOW_MIN = 4500 - 450;
- const uint32_t PREAMBULA_LOW_MAX = 4500 + 450;
- const uint32_t PREAMBULA_RETRY_LOW_MIN = 2500 - 350;
- const uint32_t PREAMBULA_RETRY_LOW_MAX = 2500 + 250;
- const uint32_t BIT_HIGH_MIN = 560 - 100;
- const uint32_t BIT_HIGH_MAX = 560 + 100;
- const uint32_t BIT_LOW_ONE_MIN = 1690 - 200;
- const uint32_t BIT_LOW_ONE_MAX = 1690 + 200;
- const uint32_t BIT_LOW_ZERO_MIN = 560 - 100;
- const uint32_t BIT_LOW_ZERO_MAX = 560 + 100;
- #define SET_STATE(_state) \
- { decoder->state = _state; }
- #define TIME_FIT(_prefix) ((time > _prefix##_MIN) && (time < _prefix##_MAX))
- #ifndef MIN
- #define MIN(a, b) ((a) < (b) ? (a) : (b))
- #endif
- bool save_decoder_nec_data(IrDANecDecoder* decoder, IrDADecoderOutputData* out) {
- bool result = false;
- if((decoder->data.simple.cmd + decoder->data.simple.cmd_inverse) == 0xFF) {
- if(out->data_length < sizeof(IrDANecDataType)) {
- out->flags |= IRDA_TOO_SHORT_BUFFER;
- }
- memcpy(out->data, &decoder->data.data, MIN(sizeof(IrDANecDataType), out->data_length));
- result = true;
- } else {
- reset_decoder_nec(decoder);
- }
- return result;
- }
- bool process_decoder_nec(
- IrDANecDecoder* decoder,
- bool polarity,
- uint32_t time,
- IrDADecoderOutputData* out) {
- bool error = true;
- bool result = false;
- switch(decoder->state) {
- case(WAIT_PREAMBULA_HIGH):
- if(polarity) {
- if(TIME_FIT(PREAMBULA_HIGH)) {
- SET_STATE(WAIT_PREAMBULA_LOW);
- }
- }
- // any values before preambula start is correct
- error = false;
- break;
- case(WAIT_PREAMBULA_LOW):
- if(!polarity) {
- if(TIME_FIT(PREAMBULA_LOW)) {
- // new data, reset storage
- reset_decoder_nec(decoder);
- SET_STATE(WAIT_BIT_HIGH);
- error = false;
- } else if(TIME_FIT(PREAMBULA_RETRY_LOW)) {
- // wait for data repeat command
- SET_STATE(WAIT_RETRY_HIGH);
- error = false;
- }
- }
- break;
- case(WAIT_RETRY_HIGH):
- if(polarity) {
- if(TIME_FIT(BIT_HIGH)) {
- SET_STATE(WAIT_PREAMBULA_HIGH);
- // repeat event
- result = save_decoder_nec_data(decoder, out);
- out->flags |= IRDA_REPEAT;
- error = false;
- }
- }
- break;
- case(WAIT_BIT_HIGH):
- if(polarity) {
- if(TIME_FIT(BIT_HIGH)) {
- SET_STATE(WAIT_BIT_LOW);
- error = false;
- }
- }
- break;
- case(WAIT_BIT_STOP_HIGH):
- if(polarity) {
- if(TIME_FIT(BIT_HIGH)) {
- SET_STATE(WAIT_PREAMBULA_HIGH);
- // message end event
- result = save_decoder_nec_data(decoder, out);
- error = false;
- }
- }
- break;
- case(WAIT_BIT_LOW):
- if(!polarity) {
- int8_t bit = -1;
- if(TIME_FIT(BIT_LOW_ZERO)) {
- SET_STATE(WAIT_BIT_HIGH);
- bit = 0;
- error = false;
- } else if(TIME_FIT(BIT_LOW_ONE)) {
- SET_STATE(WAIT_BIT_HIGH);
- bit = 1;
- error = false;
- }
- if(bit != -1) {
- decoder->data.data |= (bit << decoder->current_data_index);
- decoder->current_data_index++;
- if(decoder->current_data_index > 31) {
- decoder->current_data_index = 0;
- SET_STATE(WAIT_BIT_STOP_HIGH);
- }
- }
- }
- break;
- }
- if(error) reset_decoder_nec(decoder);
- return result;
- }
- void reset_decoder_nec(IrDANecDecoder* decoder) {
- decoder->state = WAIT_PREAMBULA_HIGH;
- decoder->data.data = 0;
- decoder->current_data_index = 0;
- }
|