Karl Zweimüller
/
eth_comfort_test
Programm for decoding radio-signals sent by a ETH-Window-Shutter-Contact, received with a RFM12B-module
Diff: eth_comfort.cpp
- Revision:
- 1:fc72e0bdb693
- Parent:
- 0:96794c9fc5a3
--- a/eth_comfort.cpp Wed Mar 02 20:46:57 2011 +0000 +++ b/eth_comfort.cpp Thu Apr 07 19:54:09 2011 +0000 @@ -5,7 +5,7 @@ Modulation FSK Hub +/- 15kHz Datenrate 10kbit Manchester - + das Protokoll ist Machester codiert 0x7e zz ll aa aa aa cmd crc crc @@ -18,15 +18,15 @@ die Reihenfolge der Bits im Byte ist verdreht. */ - - -// WED 6.9.2009 -// extended and adapeted to mbed by Karl Zweimueller 1/2011 +/*! + * \file eth_comfort.cpp + * \brief Read the messages from the ETH-Radio-Shutter + * \author Karl Zweimüller based on code from WED 6.9.2009 + */ #include "eth_comfort.h" - /* orig AVR-values #define BIT_MAX 0x90 #define BIT_MIN 0x10 @@ -40,23 +40,27 @@ #define LEN_2T 200 // time-value to differentiate one or two bit length -volatile uint16_t b; - -volatile uint8_t transmit,bit_cnt; -volatile uint16_t buffer_cnt; - - -volatile unsigned char old ; -volatile uint8_t rbyte; - -volatile uint8_t buf[1024]; -volatile uint8_t pack_ok,startbit; -volatile uint8_t decode,bcnt,lastbit; -volatile uint8_t state; - // Timer for bit-length-measurement Timer BitTime; + +eth_comfort::eth_comfort(PinName mosi, PinName miso, PinName sclk, PinName nsel, PinName rxdata, PinName rxled) { + + rfm12b_spi = new rfm12b(mosi,miso,sclk,nsel,rxdata); + + // the ReceiveLED + rxLED = new DigitalOut(rxled); + + // init the eth_receiver + init(); + + // Interrupt on every bit-change + rfm12b_spi->attachISR(this, ð_comfort::ISR); + + // Init the RFM12B + rfm12b_spi->RFM_init(); + +}; //------------------------------------------------------------------------- // calcCRC16r() //------------------------------------------------------------------------- @@ -67,29 +71,57 @@ * @param mask crc polynom * @return crc value */ -uint16_t calcCRC16r( uint16_t c,uint16_t crc, uint16_t mask) // reverser crc!!!!!! -{ -uint8_t i; - for(i=0;i<8;i++) - { - if((crc ^ c) & 1) { crc=(crc>>1)^mask; } - else crc>>=1; - c>>=1; - }; - return(crc); +uint16_t eth_comfort::calcCRC16r( uint16_t c,uint16_t crc, uint16_t mask) { // reverse crc!!!!!! + uint8_t i; + for (i=0;i<8;i++) { + if ((crc ^ c) & 1) { + crc=(crc>>1)^mask; + } else crc>>=1; + c>>=1; + }; + return(crc); } // initialize eth_receiver -void eth_init() -{ - // start timer for bit-length-measurement - BitTime.start(); +void eth_comfort::init() { + + rbyte=0; + bit_cnt=0; + buffer_cnt=0; + decode=0; + pack_ok=0; + // start timer for bit-length-measurement + BitTime.start(); + message_received = false; + // init the buffer + last_message.cnt = 0; + last_message.len = 0; + last_message.adr = 0; + last_message.cmd = 0; + last_message.data = 0; + last_message.xdata = 0; + last_message.crc = 0; + + new_message = last_message; } -// -// -// + +// is a new message readable +bool eth_comfort::readable() { + return(message_received); +} + +// read a eth-messsage +eth_message eth_comfort::getMessage() { + if (readable()) { + last_message = new_message; + message_received = false; + return(new_message); + } else + // we should return nothing here! + return(last_message); +} /** ISR Interrupt routine for received data * triggers on every pin change high/low and low/high @@ -97,106 +129,163 @@ * as the eth doesn't send a good signal, which the rfm12 could decode for himself * didn't test for myself - just got the code from someone else and ported to mbed! */ -void ISR() // pin change on rxin ->interrupt -{ - //led2=!led2; - b=BitTime.read_us(); // time since last change - BitTime.reset(); +void eth_comfort::ISR() { // pin change on rxin ->interrupt + //led2=!led2; + b=BitTime.read_us(); // time since last change + BitTime.reset(); + + if ((b>BIT_MAX)||(b<BIT_MIN)) { // is bit time in range? + state=0; + } else { + + + if (state==0) { // wait for first bitchange 2T + if (b>LEN_2T)state=1; + //if((rxin)!=0)state=0; // level should be low + } else if (state<=10) { // wait for 5 fullbit without bitchange 10 shortbits + if (b<LEN_2T)state++; + else state=1; // bitchange found back to state 1 + } else if (state==11) { // now expecting bitchange (last bit in 7e is 0) + if (b<LEN_2T) { + state=0; // no bitchange -> back to search + }; + state=20; // now we found 7e sync finished + rbyte=0x7e; // set shift value to 0 + bit_cnt=8; // clear bitcounter + buffer_cnt=0; // clear buffercounter + bcnt=0; + lastbit=0; - if((b>BIT_MAX)||(b<BIT_MIN)){ // is bit time in range? - state=0; - } - else{ + } else if (state==20) { + if (b>LEN_2T) { // check for bitchange + if (lastbit!=0) { + rbyte=(rbyte>>1); // last bit was 1 new is 0 + bcnt=0; + lastbit=0; + } else { + rbyte=(rbyte>>1)|0x80; // last bit was 0 new is 1 + bcnt++; + lastbit=1; + } + state=20; // fullbit compleate + bit_cnt++; // increase bit counter + } else { + state=21; // bit is halfbit, wait for next halfbit + }; + } else if (state==21) { // no bitchange + if (b<LEN_2T) { // next bit must be a halfbit + if (lastbit==0) { + rbyte=(rbyte>>1); // last bit was 0 new is 0 + lastbit=0; + bcnt=0; + } else { + rbyte=(rbyte>>1)|0x80; // last bit was 1 new is 1 + lastbit=1; + bcnt++; + } + state=20; + bit_cnt++; + } else { + state=0; // bit is no halfbit -> Manchester violation + // state=20; + }; + } else if (state==22) { // after 5 bit 1 skip one bit 0 + if (b>LEN_2T) { // check for bitchange (next bit 0) + lastbit=0; + state=20; + } else { + + lastbit=1; + //state=11; + state=21; + } + bcnt=0; - if(state==0){ // wait for first bitchange 2T - if(b>LEN_2T)state=1; - //if((rxin)!=0)state=0; // level should be low - } - else if(state<=10){ // wait for 5 fullbit without bitchange 10 shortbits - if(b<LEN_2T)state++; - else state=1; // bitchange found back to state 1 - } - else if(state==11){ // now expecting bitchange (last bit in 7e is 0) - if(b<LEN_2T){ - state=0; // no bitchange -> back to search - }; - state=20; // now we found 7e sync finished - rbyte=0x7e; // set shift value to 0 - bit_cnt=8; // clear bitcounter - buffer_cnt=0; // clear buffercounter - bcnt=0; - lastbit=0; + } + if (bcnt==5)state=22; + + if (bit_cnt>7) { // wait for 8 bits + buf[buffer_cnt]=rbyte; // save value into buffer + if (buffer_cnt<1020) { + buffer_cnt++; + }; + pack_ok=1; // set receiveflag + bit_cnt=0; // clear bitcounter + *rxLED = ! *rxLED; //show received byte + ////////////////////////////////////////////////////////////////////////////////////////////////////////// + //here we received another byte - } - else if(state==20){ - if(b>LEN_2T){ // check for bitchange - if(lastbit!=0){ - rbyte=(rbyte>>1); // last bit was 1 new is 0 - bcnt=0; - lastbit=0; - } - else { - rbyte=(rbyte>>1)|0x80; // last bit was 0 new is 1 - bcnt++; - lastbit=1; - } - state=20; // fullbit compleate - bit_cnt++; // increase bit counter - } - else{ - state=21; // bit is halfbit, wait for next halfbit - }; - } - else if(state==21){ // no bitchange - if(b<LEN_2T){ // next bit must be a halfbit - if(lastbit==0){ - rbyte=(rbyte>>1); // last bit was 0 new is 0 - lastbit=0; - bcnt=0; - } - else { - rbyte=(rbyte>>1)|0x80; // last bit was 1 new is 1 - lastbit=1; - bcnt++; - } - state=20; - bit_cnt++; - } - else{ - state=0; // bit is no halfbit -> Manchester violation - // state=20; - }; - }else if(state==22){ // after 5 bit 1 skip one bit 0 - if(b>LEN_2T){ // check for bitchange (next bit 0) - lastbit=0; - state=20; - } - else{ + // we have to check if we are ready with the message + if (buffer_cnt>8) { + if (buf[2]==0x10) blocklength=10; + else if (buf[2]==0x20) blocklength=9; + else blocklength=99; + j=0; + crc_ok = false; + for (i=0;i<=buffer_cnt;i++) { + //pc.printf("%02X ",buf[i]); + j++; + if (j==blocklength) { + //check crc + if (blocklength==9) { + crc=0xbdb7; + for (k=0;k<7;k++) { // crc over first 7 byte + crc=calcCRC16r(buf[k],crc,0x8408); + } + //swap the two crc-bytes + swapped = ((crc >> 8) & 0xff) | ((crc << 8) & 0xff00); + //pc.printf("CRC: %04X ",swapped); + if (((buf[7]<<8) | buf[8]) == swapped) crc_ok = true; + else crc_ok = false; + //pc.printf("%s", (crc_ok==true) ? "OK" : "Not OK"); + if (crc_ok) { + /* + pc.printf("\n\rCounter: %02X\n\r",buf[1]); + pc.printf( " Dev-ID: %02X %02X %02X\n\r",buf[3],buf[4],buf[5]); + //pc.printf( "Battery: %s\n\r", (buf[6]&0x80 != 0x00) ? "WEAK" : "GOOD"); + pc.printf( "Window : %s\n\r\n\r", (buf[6]&0x01 != 0x00) ? "OPEN" : "CLOSE"); + lcd.cls(); + lcd.printf("#:%02X ID: %02X%02X%02X\n",buf[1],buf[3],buf[4],buf[5]); + lcd.printf("Window : %s\n", (buf[6]&0x01 != 0x00) ? "OPEN" : "CLOSE"); + */ - lastbit=1; - //state=11; - state=21; - } - bcnt=0; + // insert buf into message + new_message.cnt = buf[1]; + new_message.len = buf[2]; + new_message.adr = buf[3]<<16 | buf[4]<<8 | buf[5]; + new_message.cmd = buf[6]; + new_message.data = buf[7]; + new_message.xdata = 0; + new_message.crc = swapped; + + //is the new message different from the old message? + if (new_message.cnt != last_message.cnt) { + last_message = new_message; + message_received = true; + } + + } //crc_ok + } //block_length = 9 + } //j==blocklength + } //for - } - if(bcnt==5)state=22; + //start receive from beginning + buffer_cnt=0; + bit_cnt=0; + startbit=0; + state=0; + //pc.printf("\n\r-----------------------------\n\r"); + //clear the buffer + for (i=0;i<1023;i++)buf[i]=0; + *rxLED = 0; //turn off receive led + } //buffer_cnt >8 + ////////////////////////////////////////////////////////////////////////////////////////////////////////// + // + } + } - if(bit_cnt>7){ // wait for 8 bits - buf[buffer_cnt]=rbyte; // save value into buffer - if(buffer_cnt<1020){ - buffer_cnt++; - }; - pack_ok=1; // set receiveflag - bit_cnt=0; // clear bitcounter - led3= !led3; //show received byte - - // - }; - }; - }