Programm for decoding radio-signals sent by a ETH-Window-Shutter-Contact, received with a RFM12B-module

Dependencies:   TextLCD mbed

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, &eth_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
-                  
-                  //
-              };
-      };
-      
 }