Karl Zweimüller
/
eth_comfort_test
Programm for decoding radio-signals sent by a ETH-Window-Shutter-Contact, received with a RFM12B-module
Embed:
(wiki syntax)
Show/hide line numbers
eth_comfort.cpp
Go to the documentation of this file.
00001 /** module for receiving data from eth comfort window sensor by ELV(R) with a RFM12 transceiver module by Hope 00002 00003 Details see discussion on http://www.mikrocontroller.net/topic/172034 00004 Frequenz 868,3 00005 Modulation FSK 00006 Hub +/- 15kHz 00007 Datenrate 10kbit Manchester 00008 00009 das Protokoll ist Machester codiert 00010 0x7e zz ll aa aa aa cmd crc crc 00011 00012 zz ist ein fortlaufender Zaehler 00013 ll die Blocklaenge 10,20,30 (20 = 9 Byte, 10= 10Byte ,30= ?) 00014 aa 3 Byte Adresse 00015 cmd der Befehl 00016 crc 16 bit checksumme 00017 00018 die Reihenfolge der Bits im Byte ist verdreht. 00019 00020 */ 00021 /*! 00022 * \file eth_comfort.cpp 00023 * \brief Read the messages from the ETH-Radio-Shutter 00024 * \author Karl Zweimüller based on code from WED 6.9.2009 00025 */ 00026 00027 00028 #include "eth_comfort.h" 00029 00030 /* orig AVR-values 00031 #define BIT_MAX 0x90 00032 #define BIT_MIN 0x10 00033 #define LEN_2T 0x44 00034 */ 00035 00036 //working: 300-80-200 00037 // nominal values are: 208-104-208 for 9600 bits/sec 00038 #define BIT_MAX 300 // maximum allowed time for one or two bits high or low 00039 #define BIT_MIN 80 // minimum allowed time for one or two bits high or low 00040 #define LEN_2T 200 // time-value to differentiate one or two bit length 00041 00042 00043 // Timer for bit-length-measurement 00044 Timer BitTime; 00045 00046 00047 eth_comfort::eth_comfort(PinName mosi, PinName miso, PinName sclk, PinName nsel, PinName rxdata, PinName rxled) { 00048 00049 rfm12b_spi = new rfm12b(mosi,miso,sclk,nsel,rxdata); 00050 00051 // the ReceiveLED 00052 rxLED = new DigitalOut(rxled); 00053 00054 // init the eth_receiver 00055 init(); 00056 00057 // Interrupt on every bit-change 00058 rfm12b_spi->attachISR(this, ð_comfort::ISR); 00059 00060 // Init the RFM12B 00061 rfm12b_spi->RFM_init(); 00062 00063 }; 00064 //------------------------------------------------------------------------- 00065 // calcCRC16r() 00066 //------------------------------------------------------------------------- 00067 /** 00068 * @brief calculate reverse CRC 00069 * @param c 16bit value for crc 00070 * @param crc old crc value 00071 * @param mask crc polynom 00072 * @return crc value 00073 */ 00074 uint16_t eth_comfort::calcCRC16r( uint16_t c,uint16_t crc, uint16_t mask) { // reverse crc!!!!!! 00075 uint8_t i; 00076 for (i=0;i<8;i++) { 00077 if ((crc ^ c) & 1) { 00078 crc=(crc>>1)^mask; 00079 } else crc>>=1; 00080 c>>=1; 00081 }; 00082 return(crc); 00083 } 00084 00085 // initialize eth_receiver 00086 void eth_comfort::init() { 00087 00088 rbyte=0; 00089 bit_cnt=0; 00090 buffer_cnt=0; 00091 decode=0; 00092 pack_ok=0; 00093 00094 // start timer for bit-length-measurement 00095 BitTime.start(); 00096 message_received = false; 00097 // init the buffer 00098 last_message.cnt = 0; 00099 last_message.len = 0; 00100 last_message.adr = 0; 00101 last_message.cmd = 0; 00102 last_message.data = 0; 00103 last_message.xdata = 0; 00104 last_message.crc = 0; 00105 00106 new_message = last_message; 00107 } 00108 00109 00110 // is a new message readable 00111 bool eth_comfort::readable() { 00112 return(message_received); 00113 } 00114 00115 // read a eth-messsage 00116 eth_message eth_comfort::getMessage() { 00117 if (readable()) { 00118 last_message = new_message; 00119 message_received = false; 00120 return(new_message); 00121 } else 00122 // we should return nothing here! 00123 return(last_message); 00124 } 00125 00126 /** ISR Interrupt routine for received data 00127 * triggers on every pin change high/low and low/high 00128 * does all the encoding of the signal including manchester decoding! 00129 * as the eth doesn't send a good signal, which the rfm12 could decode for himself 00130 * didn't test for myself - just got the code from someone else and ported to mbed! 00131 */ 00132 void eth_comfort::ISR() { // pin change on rxin ->interrupt 00133 //led2=!led2; 00134 b=BitTime.read_us(); // time since last change 00135 BitTime.reset(); 00136 00137 if ((b>BIT_MAX)||(b<BIT_MIN)) { // is bit time in range? 00138 state=0; 00139 } else { 00140 00141 00142 if (state==0) { // wait for first bitchange 2T 00143 if (b>LEN_2T)state=1; 00144 //if((rxin)!=0)state=0; // level should be low 00145 } else if (state<=10) { // wait for 5 fullbit without bitchange 10 shortbits 00146 if (b<LEN_2T)state++; 00147 else state=1; // bitchange found back to state 1 00148 } else if (state==11) { // now expecting bitchange (last bit in 7e is 0) 00149 if (b<LEN_2T) { 00150 state=0; // no bitchange -> back to search 00151 }; 00152 state=20; // now we found 7e sync finished 00153 rbyte=0x7e; // set shift value to 0 00154 bit_cnt=8; // clear bitcounter 00155 buffer_cnt=0; // clear buffercounter 00156 bcnt=0; 00157 lastbit=0; 00158 00159 } else if (state==20) { 00160 if (b>LEN_2T) { // check for bitchange 00161 if (lastbit!=0) { 00162 rbyte=(rbyte>>1); // last bit was 1 new is 0 00163 bcnt=0; 00164 lastbit=0; 00165 } else { 00166 rbyte=(rbyte>>1)|0x80; // last bit was 0 new is 1 00167 bcnt++; 00168 lastbit=1; 00169 } 00170 state=20; // fullbit compleate 00171 bit_cnt++; // increase bit counter 00172 } else { 00173 state=21; // bit is halfbit, wait for next halfbit 00174 }; 00175 } else if (state==21) { // no bitchange 00176 if (b<LEN_2T) { // next bit must be a halfbit 00177 if (lastbit==0) { 00178 rbyte=(rbyte>>1); // last bit was 0 new is 0 00179 lastbit=0; 00180 bcnt=0; 00181 } else { 00182 rbyte=(rbyte>>1)|0x80; // last bit was 1 new is 1 00183 lastbit=1; 00184 bcnt++; 00185 } 00186 state=20; 00187 bit_cnt++; 00188 } else { 00189 state=0; // bit is no halfbit -> Manchester violation 00190 // state=20; 00191 }; 00192 } else if (state==22) { // after 5 bit 1 skip one bit 0 00193 if (b>LEN_2T) { // check for bitchange (next bit 0) 00194 lastbit=0; 00195 state=20; 00196 } else { 00197 00198 lastbit=1; 00199 //state=11; 00200 state=21; 00201 } 00202 bcnt=0; 00203 00204 00205 } 00206 if (bcnt==5)state=22; 00207 00208 if (bit_cnt>7) { // wait for 8 bits 00209 buf[buffer_cnt]=rbyte; // save value into buffer 00210 if (buffer_cnt<1020) { 00211 buffer_cnt++; 00212 }; 00213 pack_ok=1; // set receiveflag 00214 bit_cnt=0; // clear bitcounter 00215 *rxLED = ! *rxLED; //show received byte 00216 ////////////////////////////////////////////////////////////////////////////////////////////////////////// 00217 //here we received another byte 00218 00219 // we have to check if we are ready with the message 00220 if (buffer_cnt>8) { 00221 if (buf[2]==0x10) blocklength=10; 00222 else if (buf[2]==0x20) blocklength=9; 00223 else blocklength=99; 00224 j=0; 00225 crc_ok = false; 00226 for (i=0;i<=buffer_cnt;i++) { 00227 //pc.printf("%02X ",buf[i]); 00228 j++; 00229 if (j==blocklength) { 00230 //check crc 00231 if (blocklength==9) { 00232 crc=0xbdb7; 00233 for (k=0;k<7;k++) { // crc over first 7 byte 00234 crc=calcCRC16r(buf[k],crc,0x8408); 00235 } 00236 //swap the two crc-bytes 00237 swapped = ((crc >> 8) & 0xff) | ((crc << 8) & 0xff00); 00238 //pc.printf("CRC: %04X ",swapped); 00239 if (((buf[7]<<8) | buf[8]) == swapped) crc_ok = true; 00240 else crc_ok = false; 00241 //pc.printf("%s", (crc_ok==true) ? "OK" : "Not OK"); 00242 if (crc_ok) { 00243 /* 00244 pc.printf("\n\rCounter: %02X\n\r",buf[1]); 00245 pc.printf( " Dev-ID: %02X %02X %02X\n\r",buf[3],buf[4],buf[5]); 00246 //pc.printf( "Battery: %s\n\r", (buf[6]&0x80 != 0x00) ? "WEAK" : "GOOD"); 00247 pc.printf( "Window : %s\n\r\n\r", (buf[6]&0x01 != 0x00) ? "OPEN" : "CLOSE"); 00248 lcd.cls(); 00249 lcd.printf("#:%02X ID: %02X%02X%02X\n",buf[1],buf[3],buf[4],buf[5]); 00250 lcd.printf("Window : %s\n", (buf[6]&0x01 != 0x00) ? "OPEN" : "CLOSE"); 00251 */ 00252 00253 // insert buf into message 00254 new_message.cnt = buf[1]; 00255 new_message.len = buf[2]; 00256 new_message.adr = buf[3]<<16 | buf[4]<<8 | buf[5]; 00257 new_message.cmd = buf[6]; 00258 new_message.data = buf[7]; 00259 new_message.xdata = 0; 00260 new_message.crc = swapped; 00261 00262 //is the new message different from the old message? 00263 if (new_message.cnt != last_message.cnt) { 00264 last_message = new_message; 00265 message_received = true; 00266 } 00267 00268 } //crc_ok 00269 } //block_length = 9 00270 } //j==blocklength 00271 } //for 00272 00273 00274 //start receive from beginning 00275 buffer_cnt=0; 00276 bit_cnt=0; 00277 startbit=0; 00278 state=0; 00279 //pc.printf("\n\r-----------------------------\n\r"); 00280 //clear the buffer 00281 for (i=0;i<1023;i++)buf[i]=0; 00282 *rxLED = 0; //turn off receive led 00283 } //buffer_cnt >8 00284 ////////////////////////////////////////////////////////////////////////////////////////////////////////// 00285 // 00286 } 00287 } 00288 00289 } 00290 00291 00292 00293
Generated on Thu Jul 14 2022 01:29:01 by 1.7.2