Programm for decoding radio-signals sent by a ETH-Window-Shutter-Contact, received with a RFM12B-module
eth_comfort.cpp
- Committer:
- charly
- Date:
- 2011-03-02
- Revision:
- 0:96794c9fc5a3
- Child:
- 1:fc72e0bdb693
File content as of revision 0:96794c9fc5a3:
/** module for receiving data from eth comfort window sensor by ELV(R) with a RFM12 transceiver module by Hope
Details see discussion on http://www.mikrocontroller.net/topic/172034
Frequenz 868,3
Modulation FSK
Hub +/- 15kHz
Datenrate 10kbit Manchester
das Protokoll ist Machester codiert
0x7e zz ll aa aa aa cmd crc crc
zz ist ein fortlaufender Zaehler
ll die Blocklaenge 10,20,30 (20 = 9 Byte, 10= 10Byte ,30= ?)
aa 3 Byte Adresse
cmd der Befehl
crc 16 bit checksumme
die Reihenfolge der Bits im Byte ist verdreht.
*/
// WED 6.9.2009
// extended and adapeted to mbed by Karl Zweimueller 1/2011
#include "eth_comfort.h"
/* orig AVR-values
#define BIT_MAX 0x90
#define BIT_MIN 0x10
#define LEN_2T 0x44
*/
//working: 300-80-200
// nominal values are: 208-104-208 for 9600 bits/sec
#define BIT_MAX 300 // maximum allowed time for one or two bits high or low
#define BIT_MIN 80 // minimum allowed time for one or two bits high or low
#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;
//-------------------------------------------------------------------------
// calcCRC16r()
//-------------------------------------------------------------------------
/**
* @brief calculate reverse CRC
* @param c 16bit value for crc
* @param crc old crc value
* @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);
}
// initialize eth_receiver
void eth_init()
{
// start timer for bit-length-measurement
BitTime.start();
}
//
//
//
/** ISR Interrupt routine for received data
* triggers on every pin change high/low and low/high
* does all the encoding of the signal including manchester decoding!
* 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();
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;
}
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(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
led3= !led3; //show received byte
//
};
};
}