Karl Zweimüller
/
eth_comfort_test
Programm for decoding radio-signals sent by a ETH-Window-Shutter-Contact, received with a RFM12B-module
eth_comfort.cpp@0:96794c9fc5a3, 2011-03-02 (annotated)
- Committer:
- charly
- Date:
- Wed Mar 02 20:46:57 2011 +0000
- Revision:
- 0:96794c9fc5a3
- Child:
- 1:fc72e0bdb693
Initial pre-beta version
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
charly | 0:96794c9fc5a3 | 1 | /** module for receiving data from eth comfort window sensor by ELV(R) with a RFM12 transceiver module by Hope |
charly | 0:96794c9fc5a3 | 2 | |
charly | 0:96794c9fc5a3 | 3 | Details see discussion on http://www.mikrocontroller.net/topic/172034 |
charly | 0:96794c9fc5a3 | 4 | Frequenz 868,3 |
charly | 0:96794c9fc5a3 | 5 | Modulation FSK |
charly | 0:96794c9fc5a3 | 6 | Hub +/- 15kHz |
charly | 0:96794c9fc5a3 | 7 | Datenrate 10kbit Manchester |
charly | 0:96794c9fc5a3 | 8 | |
charly | 0:96794c9fc5a3 | 9 | das Protokoll ist Machester codiert |
charly | 0:96794c9fc5a3 | 10 | 0x7e zz ll aa aa aa cmd crc crc |
charly | 0:96794c9fc5a3 | 11 | |
charly | 0:96794c9fc5a3 | 12 | zz ist ein fortlaufender Zaehler |
charly | 0:96794c9fc5a3 | 13 | ll die Blocklaenge 10,20,30 (20 = 9 Byte, 10= 10Byte ,30= ?) |
charly | 0:96794c9fc5a3 | 14 | aa 3 Byte Adresse |
charly | 0:96794c9fc5a3 | 15 | cmd der Befehl |
charly | 0:96794c9fc5a3 | 16 | crc 16 bit checksumme |
charly | 0:96794c9fc5a3 | 17 | |
charly | 0:96794c9fc5a3 | 18 | die Reihenfolge der Bits im Byte ist verdreht. |
charly | 0:96794c9fc5a3 | 19 | |
charly | 0:96794c9fc5a3 | 20 | */ |
charly | 0:96794c9fc5a3 | 21 | |
charly | 0:96794c9fc5a3 | 22 | |
charly | 0:96794c9fc5a3 | 23 | // WED 6.9.2009 |
charly | 0:96794c9fc5a3 | 24 | // extended and adapeted to mbed by Karl Zweimueller 1/2011 |
charly | 0:96794c9fc5a3 | 25 | |
charly | 0:96794c9fc5a3 | 26 | |
charly | 0:96794c9fc5a3 | 27 | #include "eth_comfort.h" |
charly | 0:96794c9fc5a3 | 28 | |
charly | 0:96794c9fc5a3 | 29 | |
charly | 0:96794c9fc5a3 | 30 | /* orig AVR-values |
charly | 0:96794c9fc5a3 | 31 | #define BIT_MAX 0x90 |
charly | 0:96794c9fc5a3 | 32 | #define BIT_MIN 0x10 |
charly | 0:96794c9fc5a3 | 33 | #define LEN_2T 0x44 |
charly | 0:96794c9fc5a3 | 34 | */ |
charly | 0:96794c9fc5a3 | 35 | |
charly | 0:96794c9fc5a3 | 36 | //working: 300-80-200 |
charly | 0:96794c9fc5a3 | 37 | // nominal values are: 208-104-208 for 9600 bits/sec |
charly | 0:96794c9fc5a3 | 38 | #define BIT_MAX 300 // maximum allowed time for one or two bits high or low |
charly | 0:96794c9fc5a3 | 39 | #define BIT_MIN 80 // minimum allowed time for one or two bits high or low |
charly | 0:96794c9fc5a3 | 40 | #define LEN_2T 200 // time-value to differentiate one or two bit length |
charly | 0:96794c9fc5a3 | 41 | |
charly | 0:96794c9fc5a3 | 42 | |
charly | 0:96794c9fc5a3 | 43 | volatile uint16_t b; |
charly | 0:96794c9fc5a3 | 44 | |
charly | 0:96794c9fc5a3 | 45 | volatile uint8_t transmit,bit_cnt; |
charly | 0:96794c9fc5a3 | 46 | volatile uint16_t buffer_cnt; |
charly | 0:96794c9fc5a3 | 47 | |
charly | 0:96794c9fc5a3 | 48 | |
charly | 0:96794c9fc5a3 | 49 | volatile unsigned char old ; |
charly | 0:96794c9fc5a3 | 50 | volatile uint8_t rbyte; |
charly | 0:96794c9fc5a3 | 51 | |
charly | 0:96794c9fc5a3 | 52 | volatile uint8_t buf[1024]; |
charly | 0:96794c9fc5a3 | 53 | volatile uint8_t pack_ok,startbit; |
charly | 0:96794c9fc5a3 | 54 | volatile uint8_t decode,bcnt,lastbit; |
charly | 0:96794c9fc5a3 | 55 | volatile uint8_t state; |
charly | 0:96794c9fc5a3 | 56 | |
charly | 0:96794c9fc5a3 | 57 | // Timer for bit-length-measurement |
charly | 0:96794c9fc5a3 | 58 | Timer BitTime; |
charly | 0:96794c9fc5a3 | 59 | |
charly | 0:96794c9fc5a3 | 60 | //------------------------------------------------------------------------- |
charly | 0:96794c9fc5a3 | 61 | // calcCRC16r() |
charly | 0:96794c9fc5a3 | 62 | //------------------------------------------------------------------------- |
charly | 0:96794c9fc5a3 | 63 | /** |
charly | 0:96794c9fc5a3 | 64 | * @brief calculate reverse CRC |
charly | 0:96794c9fc5a3 | 65 | * @param c 16bit value for crc |
charly | 0:96794c9fc5a3 | 66 | * @param crc old crc value |
charly | 0:96794c9fc5a3 | 67 | * @param mask crc polynom |
charly | 0:96794c9fc5a3 | 68 | * @return crc value |
charly | 0:96794c9fc5a3 | 69 | */ |
charly | 0:96794c9fc5a3 | 70 | uint16_t calcCRC16r( uint16_t c,uint16_t crc, uint16_t mask) // reverser crc!!!!!! |
charly | 0:96794c9fc5a3 | 71 | { |
charly | 0:96794c9fc5a3 | 72 | uint8_t i; |
charly | 0:96794c9fc5a3 | 73 | for(i=0;i<8;i++) |
charly | 0:96794c9fc5a3 | 74 | { |
charly | 0:96794c9fc5a3 | 75 | if((crc ^ c) & 1) { crc=(crc>>1)^mask; } |
charly | 0:96794c9fc5a3 | 76 | else crc>>=1; |
charly | 0:96794c9fc5a3 | 77 | c>>=1; |
charly | 0:96794c9fc5a3 | 78 | }; |
charly | 0:96794c9fc5a3 | 79 | return(crc); |
charly | 0:96794c9fc5a3 | 80 | } |
charly | 0:96794c9fc5a3 | 81 | |
charly | 0:96794c9fc5a3 | 82 | // initialize eth_receiver |
charly | 0:96794c9fc5a3 | 83 | void eth_init() |
charly | 0:96794c9fc5a3 | 84 | { |
charly | 0:96794c9fc5a3 | 85 | // start timer for bit-length-measurement |
charly | 0:96794c9fc5a3 | 86 | BitTime.start(); |
charly | 0:96794c9fc5a3 | 87 | |
charly | 0:96794c9fc5a3 | 88 | } |
charly | 0:96794c9fc5a3 | 89 | |
charly | 0:96794c9fc5a3 | 90 | // |
charly | 0:96794c9fc5a3 | 91 | // |
charly | 0:96794c9fc5a3 | 92 | // |
charly | 0:96794c9fc5a3 | 93 | |
charly | 0:96794c9fc5a3 | 94 | /** ISR Interrupt routine for received data |
charly | 0:96794c9fc5a3 | 95 | * triggers on every pin change high/low and low/high |
charly | 0:96794c9fc5a3 | 96 | * does all the encoding of the signal including manchester decoding! |
charly | 0:96794c9fc5a3 | 97 | * as the eth doesn't send a good signal, which the rfm12 could decode for himself |
charly | 0:96794c9fc5a3 | 98 | * didn't test for myself - just got the code from someone else and ported to mbed! |
charly | 0:96794c9fc5a3 | 99 | */ |
charly | 0:96794c9fc5a3 | 100 | void ISR() // pin change on rxin ->interrupt |
charly | 0:96794c9fc5a3 | 101 | { |
charly | 0:96794c9fc5a3 | 102 | //led2=!led2; |
charly | 0:96794c9fc5a3 | 103 | b=BitTime.read_us(); // time since last change |
charly | 0:96794c9fc5a3 | 104 | BitTime.reset(); |
charly | 0:96794c9fc5a3 | 105 | |
charly | 0:96794c9fc5a3 | 106 | if((b>BIT_MAX)||(b<BIT_MIN)){ // is bit time in range? |
charly | 0:96794c9fc5a3 | 107 | state=0; |
charly | 0:96794c9fc5a3 | 108 | } |
charly | 0:96794c9fc5a3 | 109 | else{ |
charly | 0:96794c9fc5a3 | 110 | |
charly | 0:96794c9fc5a3 | 111 | |
charly | 0:96794c9fc5a3 | 112 | if(state==0){ // wait for first bitchange 2T |
charly | 0:96794c9fc5a3 | 113 | if(b>LEN_2T)state=1; |
charly | 0:96794c9fc5a3 | 114 | //if((rxin)!=0)state=0; // level should be low |
charly | 0:96794c9fc5a3 | 115 | } |
charly | 0:96794c9fc5a3 | 116 | else if(state<=10){ // wait for 5 fullbit without bitchange 10 shortbits |
charly | 0:96794c9fc5a3 | 117 | if(b<LEN_2T)state++; |
charly | 0:96794c9fc5a3 | 118 | else state=1; // bitchange found back to state 1 |
charly | 0:96794c9fc5a3 | 119 | } |
charly | 0:96794c9fc5a3 | 120 | else if(state==11){ // now expecting bitchange (last bit in 7e is 0) |
charly | 0:96794c9fc5a3 | 121 | if(b<LEN_2T){ |
charly | 0:96794c9fc5a3 | 122 | state=0; // no bitchange -> back to search |
charly | 0:96794c9fc5a3 | 123 | }; |
charly | 0:96794c9fc5a3 | 124 | state=20; // now we found 7e sync finished |
charly | 0:96794c9fc5a3 | 125 | rbyte=0x7e; // set shift value to 0 |
charly | 0:96794c9fc5a3 | 126 | bit_cnt=8; // clear bitcounter |
charly | 0:96794c9fc5a3 | 127 | buffer_cnt=0; // clear buffercounter |
charly | 0:96794c9fc5a3 | 128 | bcnt=0; |
charly | 0:96794c9fc5a3 | 129 | lastbit=0; |
charly | 0:96794c9fc5a3 | 130 | |
charly | 0:96794c9fc5a3 | 131 | } |
charly | 0:96794c9fc5a3 | 132 | else if(state==20){ |
charly | 0:96794c9fc5a3 | 133 | if(b>LEN_2T){ // check for bitchange |
charly | 0:96794c9fc5a3 | 134 | if(lastbit!=0){ |
charly | 0:96794c9fc5a3 | 135 | rbyte=(rbyte>>1); // last bit was 1 new is 0 |
charly | 0:96794c9fc5a3 | 136 | bcnt=0; |
charly | 0:96794c9fc5a3 | 137 | lastbit=0; |
charly | 0:96794c9fc5a3 | 138 | } |
charly | 0:96794c9fc5a3 | 139 | else { |
charly | 0:96794c9fc5a3 | 140 | rbyte=(rbyte>>1)|0x80; // last bit was 0 new is 1 |
charly | 0:96794c9fc5a3 | 141 | bcnt++; |
charly | 0:96794c9fc5a3 | 142 | lastbit=1; |
charly | 0:96794c9fc5a3 | 143 | } |
charly | 0:96794c9fc5a3 | 144 | state=20; // fullbit compleate |
charly | 0:96794c9fc5a3 | 145 | bit_cnt++; // increase bit counter |
charly | 0:96794c9fc5a3 | 146 | } |
charly | 0:96794c9fc5a3 | 147 | else{ |
charly | 0:96794c9fc5a3 | 148 | state=21; // bit is halfbit, wait for next halfbit |
charly | 0:96794c9fc5a3 | 149 | }; |
charly | 0:96794c9fc5a3 | 150 | } |
charly | 0:96794c9fc5a3 | 151 | else if(state==21){ // no bitchange |
charly | 0:96794c9fc5a3 | 152 | if(b<LEN_2T){ // next bit must be a halfbit |
charly | 0:96794c9fc5a3 | 153 | if(lastbit==0){ |
charly | 0:96794c9fc5a3 | 154 | rbyte=(rbyte>>1); // last bit was 0 new is 0 |
charly | 0:96794c9fc5a3 | 155 | lastbit=0; |
charly | 0:96794c9fc5a3 | 156 | bcnt=0; |
charly | 0:96794c9fc5a3 | 157 | } |
charly | 0:96794c9fc5a3 | 158 | else { |
charly | 0:96794c9fc5a3 | 159 | rbyte=(rbyte>>1)|0x80; // last bit was 1 new is 1 |
charly | 0:96794c9fc5a3 | 160 | lastbit=1; |
charly | 0:96794c9fc5a3 | 161 | bcnt++; |
charly | 0:96794c9fc5a3 | 162 | } |
charly | 0:96794c9fc5a3 | 163 | state=20; |
charly | 0:96794c9fc5a3 | 164 | bit_cnt++; |
charly | 0:96794c9fc5a3 | 165 | } |
charly | 0:96794c9fc5a3 | 166 | else{ |
charly | 0:96794c9fc5a3 | 167 | state=0; // bit is no halfbit -> Manchester violation |
charly | 0:96794c9fc5a3 | 168 | // state=20; |
charly | 0:96794c9fc5a3 | 169 | }; |
charly | 0:96794c9fc5a3 | 170 | }else if(state==22){ // after 5 bit 1 skip one bit 0 |
charly | 0:96794c9fc5a3 | 171 | if(b>LEN_2T){ // check for bitchange (next bit 0) |
charly | 0:96794c9fc5a3 | 172 | lastbit=0; |
charly | 0:96794c9fc5a3 | 173 | state=20; |
charly | 0:96794c9fc5a3 | 174 | } |
charly | 0:96794c9fc5a3 | 175 | else{ |
charly | 0:96794c9fc5a3 | 176 | |
charly | 0:96794c9fc5a3 | 177 | lastbit=1; |
charly | 0:96794c9fc5a3 | 178 | //state=11; |
charly | 0:96794c9fc5a3 | 179 | state=21; |
charly | 0:96794c9fc5a3 | 180 | } |
charly | 0:96794c9fc5a3 | 181 | bcnt=0; |
charly | 0:96794c9fc5a3 | 182 | |
charly | 0:96794c9fc5a3 | 183 | |
charly | 0:96794c9fc5a3 | 184 | } |
charly | 0:96794c9fc5a3 | 185 | if(bcnt==5)state=22; |
charly | 0:96794c9fc5a3 | 186 | |
charly | 0:96794c9fc5a3 | 187 | if(bit_cnt>7){ // wait for 8 bits |
charly | 0:96794c9fc5a3 | 188 | buf[buffer_cnt]=rbyte; // save value into buffer |
charly | 0:96794c9fc5a3 | 189 | if(buffer_cnt<1020){ |
charly | 0:96794c9fc5a3 | 190 | buffer_cnt++; |
charly | 0:96794c9fc5a3 | 191 | }; |
charly | 0:96794c9fc5a3 | 192 | pack_ok=1; // set receiveflag |
charly | 0:96794c9fc5a3 | 193 | bit_cnt=0; // clear bitcounter |
charly | 0:96794c9fc5a3 | 194 | led3= !led3; //show received byte |
charly | 0:96794c9fc5a3 | 195 | |
charly | 0:96794c9fc5a3 | 196 | // |
charly | 0:96794c9fc5a3 | 197 | }; |
charly | 0:96794c9fc5a3 | 198 | }; |
charly | 0:96794c9fc5a3 | 199 | |
charly | 0:96794c9fc5a3 | 200 | } |
charly | 0:96794c9fc5a3 | 201 | |
charly | 0:96794c9fc5a3 | 202 | |
charly | 0:96794c9fc5a3 | 203 | |
charly | 0:96794c9fc5a3 | 204 |