* fix "state not acquired error" * add InterruptTypeComparatorTrigger to interrupt mgr, use interrupt mgr in irda app * separate init irda timer * capture events buffer by app * irda common decoder * irda nec decoder realization * finished work with decoder * fix app path * fix widget remove on exit * nec receive, store and send * init some packets
		
			
				
	
	
		
			146 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#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;
 | 
						|
} |