// File: RF.c //------------------------------------------------------------------------------ // Author: Giovanni de Sanctis // Email: info@lateral-technologies.com //------------------------------------------------------------------------------ // Date: Sep 2019 // RF remote decoder //------------------------------------------------------------------------------ #include "RF.h" #include "mcc_generated_files/tmr1.h" #define CODE_LEN 24u //Number of bits in the code (including start stop etc.; we don't care) #define BUT_MASK (0x000000FFul) #define CODE_MASK (0xFFFFFE00ul) #define CODE1 (0x00430000ul) //RF code1 to match (433) #define CODE2 (0x006AAA00ul) //RF code2 to match (315) #define CODE3 (0x00011200ul) //RF code3 to match (new 315) #define T_BASE_NS 500u //T1 Clock in ns #define T_START_MIN (8000000u/T_BASE_NS) //Min long space before code (8ms) #define T_MARK0_MIN ((0.8* 333333u)/T_BASE_NS) //Min 0 mark #define T_MARK0_MAX ((1.8* 333333u)/T_BASE_NS) //Max 0 mark #define T_MARK1_MIN ((0.8* 1000000u)/T_BASE_NS) //Min 0 mark #define T_MARK1_MAX ((1.8*1000000u)/T_BASE_NS) //Max 0 mark #define T_MARK_TOL 80000u/T_BASE_NS //Tolerance +/- 0.08ms #define N_LONG_PRESS 10 //# code matches for long press #define RF_A1 0x50 #define RF_B1 0x48 #define RF_C1 0x44 #define RF_D1 0x42 #define RF_A2 0x18 #define RF_B2 0x80 #define RF_C2 0x06 #define RF_D2 0x60 #define RF_A3 0x81 #define RF_B3 0x82 #define RF_C3 0x84 #define RF_D3 0x88 uint8_t bitPtr; //Number of bits received uint8_t matches; //Number of code matches (for button press length) uint8_t attempts; //Number of restarts before code detected uint8_t waitingRelease; uint32_t code; //Code being read uint32_t lastCode1; //Last code read uint32_t lastCode2; //2nd last code read uint16_t tMark0min,tMark0max,tMark1min,tMark1max; //Current durations for 1 and 0 codes void intHandler() { uint16_t t; t = TMR1_ReadTimer(); if (bitPtr==0) { TMR1G_Polarity(0); if (t>T_START_MIN) { code = 0; attempts++; bitPtr++; TMR1G_Polarity(1); //Looking for marks now } } else { if (bitPtr==1) { if ((t>T_MARK1_MIN) && (tT_MARK0_MIN) && (ttMark0min) && (ttMark1min)&&(ttMark1min) { code++; } } else { bitPtr=0; //If pulse too long or too short reset } } else { bitPtr = 0; attempts = 0; if (lastCode1) lastCode2 = lastCode1; lastCode1 = code; if (lastCode1 == lastCode2) matches++; } } TMR1_WriteTimer(0x0000); TMR1_StartSinglePulseAcquisition(); } void initRF() { bitPtr=0; TMR1G_Polarity(0); TMR1G_SetInterruptHandler(intHandler); TMR1_StartSinglePulseAcquisition(); matches = 0; code = 0; lastCode1 = 0; lastCode2 = 0; //waitingRelease = 0; attempts = 0; } uint8_t rfGetNewCode() { uint8_t res; uint32_t maskedCode = lastCode2 & CODE_MASK; if (lastCode2 == 0) return 0; if ((maskedCode!=CODE1)&&(maskedCode!=CODE2)&&(maskedCode!=CODE3)) return 0; if (matches<2) return 0; res=lastCode1 & BUT_MASK; switch (res) { case RF_A1: case RF_A2: case RF_A3: res = RF_A; break; case RF_B1: case RF_B2: case RF_B3: res = RF_B; break; case RF_C1: case RF_C2: case RF_C3: res = RF_C; break; case RF_D1: case RF_D2: case RF_D3: res = RF_D; break; } if (matches>N_LONG_PRESS) //Passed long press time { if (waitingRelease == 0) //..for the first time { waitingRelease = 1; return res|RF_LONG_MASK; } else res = 0; } if (attempts < 2) return 0; //Button still pressed else { lastCode1=lastCode2=code=0; matches = 0; waitingRelease = 0; } return res; } uint8_t isRFreceiving() { return (matches>0 && attempts<1); }