 d65e9b04ce
			
		
	
	
		d65e9b04ce
		
			
		
	
	
	
	
		
			
			* 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;
 | |
| } |