-/* Supported modulation types */
-#define OOK_PWM_D 1 /* Pulses are of the same length, the distance varies */
-#define OOK_PWM_P 2 /* The length of the pulses varies */
-
-
-typedef struct {
- unsigned int id;
- char name[256];
- unsigned int modulation;
- unsigned int short_limit;
- unsigned int long_limit;
- unsigned int reset_limit;
- int (*json_callback)(uint8_t bits_buffer[BITBUF_ROWS][BITBUF_COLS]) ;
-} r_device;
-
-static int debug_callback(uint8_t bb[BITBUF_ROWS][BITBUF_COLS]) {
- int i,j,k;
- fprintf(stderr, "\n");
- for (i=0 ; i<BITBUF_ROWS ; i++) {
- fprintf(stderr, "[%02d] ",i);
- for (j=0 ; j<BITBUF_COLS ; j++) {
- fprintf(stderr, "%02x ", bb[i][j]);
- }
- fprintf(stderr, ": ");
- for (j=0 ; j<BITBUF_COLS ; j++) {
- for (k=7 ; k>=0 ; k--) {
- if (bb[i][j] & 1<<k)
- fprintf(stderr, "1");
- else
- fprintf(stderr, "0");
- }
- fprintf(stderr, " ");
- }
- fprintf(stderr, "\n");
- }
- fprintf(stderr, "\n");
-
- return 0;
-}
-
-uint8_t crc8( uint8_t *addr, uint8_t len)
-{
- uint8_t crc = 0;
-
- // Indicated changes are from reference CRC-8 function in OneWire library
- while (len--) {
- uint8_t inbyte = *addr++;
- int i;
- for (i = 8; i; i--) {
- uint8_t mix = (crc ^ inbyte) & 0x80; // changed from & 0x01
- crc <<= 1; // changed from right shift
- if (mix) crc ^= 0x31;// changed from 0x8C;
- inbyte <<= 1; // changed from right shift
- }
- }
- return crc;
-}
-
-void printBits(size_t const size, void const * const ptr)
-{
- unsigned char *b = (unsigned char*) ptr;
- unsigned char byte;
- int i, j;
-
- for (i=0;i<size;i++) {
-
- fprintf(stderr,"%2x:",b[i]);
-
- for (j=0;j<7;j++) {
- byte = b[i] & (1<<j);
- byte >>= j;
- fprintf(stderr,"%u", byte);
- }
- fprintf(stderr," ");
- }
- fprintf(stderr,"\n");
-}
-
-static int wh2_callback(uint8_t bb[BITBUF_ROWS][BITBUF_COLS]) {
- int i,j,k;
-
- uint8_t payload[4];
- int received_crc8,payload_crc8;
-
- int wh2_id;
- float wh2_temp;
- float wh2_humidity;
-
- if (bb[0][0] != 0xFE) return 0;
-
- payload[0] = bb[0][1]>>1;
- payload[1] = bb[0][2]>>1 | ((bb[0][1]&1) << 7 );
- payload[2] = bb[0][3]>>1 | ((bb[0][2]&1) << 7 );
- payload[3] = bb[0][4]>>1 | ((bb[0][3]&1) << 7 );
-
- received_crc8 = (bb[0][5]>>1) | ((bb[0][4]&1) << 7 );
-
- payload_crc8 = crc8(payload,4);
-
- if (payload_crc8 != received_crc8) {
- fprintf(stderr,"Bad WH2 payload CRC, skipping...\n");
- return 0;
- }
-
- wh2_id = (payload[0] << 4) + (payload[1] >> 4);
- wh2_temp = ((payload[1] & 0x7) << 8) + payload[2];
- if (payload[1] & 0x8) {
- wh2_temp = -wh2_temp;
- }
- wh2_temp = wh2_temp/10;
-
- wh2_humidity = payload[3];
-
- fprintf(stdout, "SENSOR:TYPE=WH2,ID=%X,HUMIDITY=%g,TEMPERATURE=%g\n",wh2_id,wh2_humidity,wh2_temp);
-
- return 1;
-
-}
-
-static int silvercrest_callback(uint8_t bb[BITBUF_ROWS][BITBUF_COLS]) {
- /* FIXME validate the received message better */
- if (bb[1][0] == 0xF8 &&
- bb[2][0] == 0xF8 &&
- bb[3][0] == 0xF8 &&
- bb[4][0] == 0xF8 &&
- bb[1][1] == 0x4d &&
- bb[2][1] == 0x4d &&
- bb[3][1] == 0x4d &&
- bb[4][1] == 0x4d) {
- /* Pretty sure this is a Silvercrest remote */
- fprintf(stdout, "BUTTON:TYPE=SILVERCREST,CODE=%02x-%02x-%02x-%02x-%02x\n",bb[1][0],bb[0][1],bb[0][2],bb[0][3],bb[0][4]);
-
- if (debug_output)
- debug_callback(bb);
-
- return 1;
- }
- return 0;
-}
-
-static int rubicson_callback(uint8_t bb[BITBUF_ROWS][BITBUF_COLS]) {
- int temperature_before_dec;
- int temperature_after_dec;
- int16_t temp;
- float ftemp;
-
- /* FIXME validate the received message better, figure out crc */
- if (bb[1][0] == bb[2][0] && bb[2][0] == bb[3][0] && bb[3][0] == bb[4][0] &&
- bb[4][0] == bb[5][0] && bb[5][0] == bb[6][0] && bb[6][0] == bb[7][0] && bb[7][0] == bb[8][0] &&
- bb[8][0] == bb[9][0] && (bb[5][0] != 0 && bb[5][1] != 0 && bb[5][2] != 0)) {
-
- /* Nible 3,4,5 contains 12 bits of temperature
- * The temperature is signed and scaled by 10 */
- temp = (int16_t)((uint16_t)(bb[0][1] << 12) | (bb[0][2] << 4));
- temp = temp >> 4;
- ftemp = (float)temp/10;
-
- fprintf(stdout, "SENSOR:TYPE=RUBICSON,ID=%X,TEMPERATURE=%f\n",bb[0][0],ftemp);
-
- if (debug_output)
- debug_callback(bb);
-
- return 1;
- }
- return 0;
-}
-
-static int prologue_callback(uint8_t bb[BITBUF_ROWS][BITBUF_COLS]) {
- int rid;
-
- int16_t temp2;
- float ftemp;
-
- /* FIXME validate the received message better */
- if (((bb[1][0]&0xF0) == 0x90 && (bb[2][0]&0xF0) == 0x90 && (bb[3][0]&0xF0) == 0x90 && (bb[4][0]&0xF0) == 0x90 &&
- (bb[5][0]&0xF0) == 0x90 && (bb[6][0]&0xF0) == 0x90) ||
- ((bb[1][0]&0xF0) == 0x50 && (bb[2][0]&0xF0) == 0x50 && (bb[3][0]&0xF0) == 0x50 && (bb[4][0]&0xF0) == 0x50)) {
-
- /* Prologue sensor */
- temp2 = (int16_t)((uint16_t)(bb[1][2] << 8) | (bb[1][3]&0xF0));
- temp2 = temp2 >> 4;
- ftemp = (float)temp2/10;
- rid = ((bb[1][0]&0x0F)<<4)|(bb[1][1]&0xF0)>>4;
- fprintf(stdout,
- "SENSOR:TYPE=PROLOGUE,BUTTON=%d,BATTERY=%s,TEMPERATURE=%f,HUMIDITY=%d,CHANNEL=%d,ID=%d,RID=%02x\n",
- bb[1][1]&0x04?1:0,
- bb[1][1]&0x08?"Ok":"Low",
- ftemp,
- ((bb[1][3]&0x0F)<<4)|(bb[1][4]>>4),
- (int)((bb[1][1]&0x03)+1),
- (int)((bb[1][0]&0xF0)>>4),
- rid);
-
- if (debug_output)
- debug_callback(bb);
-
- return 1;
- }
- return 0;
-}
-
-static int waveman_callback(uint8_t bb[BITBUF_ROWS][BITBUF_COLS]) {
- /* Two bits map to 2 states, 0 1 -> 0 and 1 1 -> 1 */
- int i;
- uint8_t nb[3] = {0};
-
- if (((bb[0][0]&0x55)==0x55) && ((bb[0][1]&0x55)==0x55) && ((bb[0][2]&0x55)==0x55) && ((bb[0][3]&0x55)==0x00)) {
- for (i=0 ; i<3 ; i++) {
- nb[i] |= ((bb[0][i]&0xC0)==0xC0) ? 0x00 : 0x01;
- nb[i] |= ((bb[0][i]&0x30)==0x30) ? 0x00 : 0x02;
- nb[i] |= ((bb[0][i]&0x0C)==0x0C) ? 0x00 : 0x04;
- nb[i] |= ((bb[0][i]&0x03)==0x03) ? 0x00 : 0x08;
- }
-
- fprintf(stdout,
- "BUTTON:TYPE=WAVEMAN,ID=%c,CHANNEL=%d,BUTTON=%d,STATE=%s\n",
- 'A'+nb[0],
- (int)((nb[1]>>2)+1),
- (int)((nb[1]&3)+1),
- ((nb[2]==0xe) ? "on" : "off"));
-
- if (debug_output)
- debug_callback(bb);
-
- return 1;
- }
- return 0;
-}
-
-static int steffen_callback(uint8_t bb[BITBUF_ROWS][BITBUF_COLS]) {
-
- if (bb[0][0]==0x00 && ((bb[1][0]&0x07)==0x07) && bb[1][0]==bb[2][0] && bb[2][0]==bb[3][0]) {
-
- fprintf(stdout, "BUTTON:TYPE=STEFFAN,CODE=%d%d%d%d%d,",(bb[1][0]&0x80)>>7, (bb[1][0]&0x40)>>6, (bb[1][0]&0x20)>>5, (bb[1][0]&0x10)>>4, (bb[1][0]&0x08)>>3);
-
- if ((bb[1][2]&0x0f)==0x0e)
- fprintf(stdout, "BUTTON=A,");
- else if ((bb[1][2]&0x0f)==0x0d)
- fprintf(stdout, "BUTTON=B,");
- else if ((bb[1][2]&0x0f)==0x0b)
- fprintf(stdout, "BUTTON=C,");
- else if ((bb[1][2]&0x0f)==0x07)
- fprintf(stdout, "BUTTON=D,");
- else if ((bb[1][2]&0x0f)==0x0f)
- fprintf(stdout, "BUTTON=ALL,");
- else
- fprintf(stdout, "BUTTON=UNKNOWN,");
-
- if ((bb[1][2]&0xf0)==0xf0) {
- fprintf(stdout, "STATE=OFF\n");
- } else {
- fprintf(stdout, "STATE=ON\n");
- }
-
- if (debug_output)
- debug_callback(bb);
-
- return 1;
- }
- return 0;
-}
-
-
-uint16_t AD_POP(uint8_t bb[BITBUF_COLS], uint8_t bits, uint8_t bit) {
- uint16_t val = 0;
- uint8_t i, byte_no, bit_no;
- for (i=0;i<bits;i++) {
- byte_no= (bit+i)/8 ;
- bit_no =7-((bit+i)%8);
- if (bb[byte_no]&(1<<bit_no)) val = val | (1<<i);
- }
- return val;
-}
-
-static int em1000_callback(uint8_t bb[BITBUF_ROWS][BITBUF_COLS]) {
- // based on fs20.c
- uint8_t dec[10];
- uint8_t bytes=0;
- uint8_t bit=18; // preamble
- uint8_t bb_p[14];
- char* types[] = {"S", "?", "GZ"};
- uint8_t checksum_calculated = 0;
- uint8_t i;
- uint8_t stopbit;
- uint8_t checksum_received;
-
- // check and combine the 3 repetitions
- for (i = 0; i < 14; i++) {
- if(bb[0][i]==bb[1][i] || bb[0][i]==bb[2][i]) bb_p[i]=bb[0][i];
- else if(bb[1][i]==bb[2][i]) bb_p[i]=bb[1][i];
- else return 0;
- }
-
- // read 9 bytes with stopbit ...
- for (i = 0; i < 9; i++) {
- dec[i] = AD_POP (bb_p, 8, bit); bit+=8;
- stopbit=AD_POP (bb_p, 1, bit); bit+=1;
- if (!stopbit) {
-// fprintf(stderr, "!stopbit: %i\n", i);
- return 0;
- }
- checksum_calculated ^= dec[i];
- bytes++;
- }
-
- // Read checksum
- checksum_received = AD_POP (bb_p, 8, bit); bit+=8;
- if (checksum_received != checksum_calculated) {
-// fprintf(stderr, "checksum_received != checksum_calculated: %d %d\n", checksum_received, checksum_calculated);
- return 0;
- }
-
-//for (i = 0; i < bytes; i++) fprintf(stderr, "%02X ", dec[i]); fprintf(stderr, "\n");
-
- // based on 15_CUL_EM.pm
- fprintf(stdout, "SENSOR:TYPE=ELV-EM-1000,MODEL=%s,CODE=%d,SEQNO=%d,TOTAL=%d,CURRENT=%d,PEAK=%d\n",dec[0]>=1&&dec[0]<=3?types[dec[0]-1]:"?",dec[1],dec[2],dec[3]|dec[4]<<8,dec[5]|dec[6]<<8,dec[7]|dec[8]<<8);
-
- return 1;
-}
-
-static int ws2000_callback(uint8_t bb[BITBUF_ROWS][BITBUF_COLS]) {
- // based on http://www.dc3yc.privat.t-online.de/protocol.htm
- uint8_t dec[13];
- uint8_t nibbles=0;
- uint8_t bit=11; // preamble
- char* types[]={"!AS3", "AS2000/ASH2000/S2000/S2001A/S2001IA/ASH2200/S300IA", "!S2000R", "!S2000W", "S2001I/S2001ID", "!S2500H", "!Pyrano", "!KS200/KS300"};
- uint8_t check_calculated=0, sum_calculated=0;
- uint8_t i;
- uint8_t stopbit;
- uint8_t sum_received;
-
- dec[0] = AD_POP (bb[0], 4, bit); bit+=4;
- stopbit= AD_POP (bb[0], 1, bit); bit+=1;
- if (!stopbit) {
-//fprintf(stderr, "!stopbit\n");
- return 0;
- }
- check_calculated ^= dec[0];
- sum_calculated += dec[0];
-
- // read nibbles with stopbit ...
- for (i = 1; i <= (dec[0]==4?12:8); i++) {
- dec[i] = AD_POP (bb[0], 4, bit); bit+=4;
- stopbit= AD_POP (bb[0], 1, bit); bit+=1;
- if (!stopbit) {
-//fprintf(stderr, "!stopbit %i\n", i);
- return 0;
- }
- check_calculated ^= dec[i];
- sum_calculated += dec[i];
- nibbles++;
- }
-
- if (check_calculated) {
-//fprintf(stderr, "check_calculated (%d) != 0\n", check_calculated);
- return 0;
- }
-
- // Read sum
- sum_received = AD_POP (bb[0], 4, bit); bit+=4;
- sum_calculated+=5;
- sum_calculated&=0xF;
- if (sum_received != sum_calculated) {
-//fprintf(stderr, "sum_received (%d) != sum_calculated (%d) ", sum_received, sum_calculated);
- return 0;
- }
-
-//for (i = 0; i < nibbles; i++) fprintf(stderr, "%02X ", dec[i]); fprintf(stderr, "\n");
-
- fprintf(stdout, "SENSOR:TYPE=ELV-WS-2000,MODEL=%s,CODE=%d,TEMPERATURE=%s%d.%d,HUMIDITY=%d.%d",dec[0]<=7?types[dec[0]]:"?",dec[1]&7,dec[1]&8?"-":"",dec[4]*10+dec[3],dec[2],dec[7]*10+dec[6], dec[5]);
- if(dec[0]==4) {
- fprintf(stdout, "PRESSURE=%d\n", 200+dec[10]*100+dec[9]*10+dec[8]);
- } else {
- fprintf(stdout, "\n");
- }
-
- return 1;
-}
-
-// ** Acurite 5n1 functions **
-
-const float acurite_winddirections[] =
- { 337.5, 315.0, 292.5, 270.0, 247.5, 225.0, 202.5, 180,
- 157.5, 135.0, 112.5, 90.0, 67.5, 45.0, 22.5, 0.0 };
-
-static int acurite_raincounter = 0;
-
-static int acurite_crc(uint8_t row[BITBUF_COLS], int cols) {
- // sum of first n-1 bytes modulo 256 should equal nth byte
- int i;
- int sum = 0;
- for ( i=0; i < cols; i++)
- sum += row[i];
- if ( sum % 256 == row[cols] )
- return 1;
- else
- return 0;
-}
-
-static int acurite_detect(uint8_t *pRow) {
- int i;
- if ( pRow[0] != 0x00 ) {
- // invert bits due to wierd issue
- for (i = 0; i < 8; i++)
- pRow[i] = ~pRow[i] & 0xFF;
- pRow[0] |= pRow[8]; // fix first byte that has mashed leading bit
-
- if (acurite_crc(pRow, 7))
- return 1; // passes crc check
- }
- return 0;
-}
-
-static float acurite_getTemp (uint8_t highbyte, uint8_t lowbyte) {
- // range -40 to 158 F
- int highbits = (highbyte & 0x0F) << 7 ;
- int lowbits = lowbyte & 0x7F;
- int rawtemp = highbits | lowbits;
- float temp = (rawtemp - 400) / 10.0;
- return temp;
-}
-
-static int acurite_getWindSpeed (uint8_t highbyte, uint8_t lowbyte) {
- // range: 0 to 159 kph
- int highbits = ( highbyte & 0x1F) << 3;
- int lowbits = ( lowbyte & 0x70 ) >> 4;
- int speed = highbits | lowbits;
- return speed;
-}
-
-static float acurite_getWindDirection (uint8_t byte) {
- // 16 compass points, ccw from (NNW) to 15 (N)
- int direction = byte & 0x0F;
- return acurite_winddirections[direction];
-}
-
-static int acurite_getHumidity (uint8_t byte) {
- // range: 1 to 99 %RH
- int humidity = byte & 0x7F;
- return humidity;
-}
-
-static int acurite_getRainfallCounter (uint8_t highbyte, uint8_t lowbyte) {
- // range: 0 to 99.99 in, 0.01 in incr., rolling counter?
- int highbits = (highbyte & 0x3F) << 7 ;
- int lowbits = lowbyte & 0x7F;
- int raincounter = highbits | lowbits;
- return raincounter;
-}
-
-static int acurite5n1_callback(uint8_t bb[BITBUF_ROWS][BITBUF_COLS]) {
- // acurite 5n1 weather sensor decoding for rtl_433
- // Jens Jensen 2014
- int i;
- uint8_t *buf = NULL;
- // run through rows til we find one with good crc (brute force)
- for (i=0; i < BITBUF_ROWS; i++) {
- if (acurite_detect(bb[i])) {
- buf = bb[i];
- break; // done
- }
- }
-
- if (buf) {
- // decode packet here
- fprintf(stdout, "SENSOR:TYPE=ACURITE");
- if (debug_output) {
- for (i=0; i < 8; i++)
- fprintf(stderr, "%02X ", buf[i]);
- fprintf(stderr, "CRC OK\n");
- }
-
- if ((buf[2] & 0x0F) == 1) {
- // wind speed, wind direction, rainfall
-
- float rainfall = 0.00;
- int raincounter = 0;
- if (acurite_raincounter > 0) {
- // track rainfall difference after first run
- raincounter = acurite_getRainfallCounter(buf[5], buf[6]);
- rainfall = ( raincounter - acurite_raincounter ) * 0.01;
- } else {
- // capture starting counter
- acurite_raincounter = raincounter;
- }
-
- fprintf(stdout, ",WINDSPEED=%d",
- acurite_getWindSpeed(buf[3], buf[4]));
- fprintf(stdout, ",WINDDIRECTION=%0.1f",
- acurite_getWindDirection(buf[4]));
- fprintf(stdout, ",RAINGAUGE: %0.2f\n", rainfall);
-
- } else if ((buf[2] & 0x0F) == 8) {
- // wind speed, temp, RH
- fprintf(stdout, ",WINDSPEED=%d",
- acurite_getWindSpeed(buf[3], buf[4]));
- fprintf(stdout, ",TEMPERATURE=%2.1f",
- acurite_getTemp(buf[4], buf[5]));
- fprintf(stdout, ",HUMIDITY=%d\n",
- acurite_getHumidity(buf[6]));
- } else {
- fprintf(stdout,",DATA=UNKNOWN\n");
- }
- }
- //if (debug_output)
- // debug_callback(bb);
- return 1;
-}
-
-
-// timings based on samp_rate=1024000
-r_device rubicson = {
- /* .id = */ 1,
- /* .name = */ "Rubicson Temperature Sensor",
- /* .modulation = */ OOK_PWM_D,
- /* .short_limit = */ 1744/4,
- /* .long_limit = */ 3500/4,
- /* .reset_limit = */ 5000/4,
- /* .json_callback = */ &rubicson_callback,
-};
-
-r_device prologue = {
- /* .id = */ 2,
- /* .name = */ "Prologue Temperature Sensor",
- /* .modulation = */ OOK_PWM_D,
- /* .short_limit = */ 3500/4,
- /* .long_limit = */ 7000/4,
- /* .reset_limit = */ 15000/4,
- /* .json_callback = */ &prologue_callback,
-};
-
-r_device silvercrest = {
- /* .id = */ 3,
- /* .name = */ "Silvercrest Remote Control",
- /* .modulation = */ OOK_PWM_P,
- /* .short_limit = */ 600/4,
- /* .long_limit = */ 5000/4,
- /* .reset_limit = */ 15000/4,
- /* .json_callback = */ &silvercrest_callback,
-};
-
-r_device tech_line_fws_500 = {
- /* .id = */ 4,
- /* .name = */ "Tech Line FWS-500 Sensor",
- /* .modulation = */ OOK_PWM_D,
- /* .short_limit = */ 3500/4,
- /* .long_limit = */ 7000/4,
- /* .reset_limit = */ 15000/4,
- /* .json_callback = */ &rubicson_callback,
-};
-
-r_device generic_hx2262 = {
- /* .id = */ 5,
- /* .name = */ "Window/Door sensor",
- /* .modulation = */ OOK_PWM_P,
- /* .short_limit = */ 1300/4,
- /* .long_limit = */ 10000/4,
- /* .reset_limit = */ 40000/4,
- /* .json_callback = */ &silvercrest_callback,
-};
-
-r_device technoline_ws9118 = {
- /* .id = */ 6,
- /* .name = */ "Technoline WS9118",
- /* .modulation = */ OOK_PWM_D,
- /* .short_limit = */ 1800/4,
- /* .long_limit = */ 3500/4,
- /* .reset_limit = */ 15000/4,
- /* .json_callback = */ &debug_callback,
-};
-
-
-r_device elv_em1000 = {
- /* .id = */ 7,
- /* .name = */ "ELV EM 1000",
- /* .modulation = */ OOK_PWM_D,
- /* .short_limit = */ 750/4,
- /* .long_limit = */ 7250/4,
- /* .reset_limit = */ 30000/4,
- /* .json_callback = */ &em1000_callback,
-};
-
-r_device elv_ws2000 = {
- /* .id = */ 8,
- /* .name = */ "ELV WS 2000",
- /* .modulation = */ OOK_PWM_D,
- /* .short_limit = */ (602+(1155-602)/2)/4,
- /* .long_limit = */ ((1755635-1655517)/2)/4, // no repetitions
- /* .reset_limit = */ ((1755635-1655517)*2)/4,
- /* .json_callback = */ &ws2000_callback,
-};
-
-r_device waveman = {
- /* .id = */ 6,
- /* .name = */ "Waveman Switch Transmitter",
- /* .modulation = */ OOK_PWM_P,
- /* .short_limit = */ 1000/4,
- /* .long_limit = */ 8000/4,
- /* .reset_limit = */ 30000/4,
- /* .json_callback = */ &waveman_callback,
-};
-
-r_device steffen = {
- /* .id = */ 9,
- /* .name = */ "Steffen Switch Transmitter",
- /* .modulation = */ OOK_PWM_D,
- /* .short_limit = */ 140,
- /* .long_limit = */ 270,
- /* .reset_limit = */ 1500,
- /* .json_callback = */ &steffen_callback,
-};
-
-r_device acurite5n1 = {
- /* .id = */ 10,
- /* .name = */ "Acurite 5n1 Weather Station",
- /* .modulation = */ OOK_PWM_P,
- /* .short_limit = */ 75,
- /* .long_limit = */ 220,
- /* .reset_limit = */ 20000,
- /* .json_callback = */ &acurite5n1_callback,
-};
-
-r_device wh2 = {
- /* .id = */ 11,
- /* .name = */ "WH2 Weather Station",
- /* .modulation = */ OOK_PWM_P,
- /* .short_limit = */ 150,
- /* .long_limit = */ 400,
- /* .reset_limit = */ 20000,
- /* .json_callback = */ &wh2_callback,
-};
-
-struct protocol_state {
- int (*callback)(uint8_t bits_buffer[BITBUF_ROWS][BITBUF_COLS]);
-
- /* bits state */
- int bits_col_idx;
- int bits_row_idx;
- int bits_bit_col_idx;
- uint8_t bits_buffer[BITBUF_ROWS][BITBUF_COLS];
- int16_t bits_per_row[BITBUF_ROWS];
- int bit_rows;
- unsigned int modulation;
-
- /* demod state */
- int pulse_length;
- int pulse_count;
- int pulse_distance;
- int sample_counter;
- int start_c;
-
- int packet_present;
- int pulse_start;
- int real_bits;
- int start_bit;
- /* pwm limits */
- int short_limit;
- int long_limit;
- int reset_limit;
-
-
-};