Program for decoding radio-signals sent by a ETH-Window-Shutter-Contact, received with a RFM12B-module. The messages are sent to KNX via a freebus rs-interface. Details see http://mbed.org/users/charly/notebook/connecting-a-radio-window-shutter-contact-to-knx/
Dependencies: TextLCD mbed ConfigFile
Revision 0:b79cb3278583, committed 2011-04-27
- Comitter:
- charly
- Date:
- Wed Apr 27 19:02:00 2011 +0000
- Commit message:
Changed in this revision
diff -r 000000000000 -r b79cb3278583 ConfigFile.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ConfigFile.lib Wed Apr 27 19:02:00 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/shintamainjp/code/ConfigFile/#f6ceafabe9f8
diff -r 000000000000 -r b79cb3278583 TextLCD.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TextLCD.lib Wed Apr 27 19:02:00 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/simon/code/TextLCD/#44f34c09bd37
diff -r 000000000000 -r b79cb3278583 eth_comfort.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eth_comfort.cpp Wed Apr 27 19:02:00 2011 +0000 @@ -0,0 +1,294 @@ +/** 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. + +*/ +/*! + * \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 +#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 + + +// 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() +//------------------------------------------------------------------------- +/** + * @brief calculate reverse CRC + * @param c 16bit value for crc + * @param crc old crc value + * @param mask crc polynom + * @return crc value + */ +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_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 + * 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 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; + + } 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 + *rxLED = ! *rxLED; //show received byte + ////////////////////////////////////////////////////////////////////////////////////////////////////////// + //here we received another byte + + // 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"); + */ + + // 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? + // or is another sender on air? + if ((new_message.cnt != last_message.cnt) || (new_message.adr != last_message.adr)) { + last_message = new_message; + message_received = true; + } + + } //crc_ok + } //block_length = 9 + } //j==blocklength + } //for + + + //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 + ////////////////////////////////////////////////////////////////////////////////////////////////////////// + // + } + } + +} + + + +
diff -r 000000000000 -r b79cb3278583 eth_comfort.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eth_comfort.h Wed Apr 27 19:02:00 2011 +0000 @@ -0,0 +1,98 @@ +#ifndef ETH_COMFORT_H +#define ETH_COMFORT_H + +/*! + * \file eth_comfort.h + * \brief Read the messages from the ETH-Radio-Shutter + * \author Karl Zweimüller + */ + + +#include "mbed.h" + +#include "rfm12b.h" + +// a message from the eth-Device +struct eth_message { + uint8_t cnt; //message-counter + uint8_t len; //message-length + uint32_t adr; // unique address of device + uint8_t cmd; // the command + uint8_t data; // optional data + uint8_t xdata; // optional extra data + uint16_t crc; // crc fro the message +}; + +/** + * Class for the ETH-Window shutter by ELV(R) + * Uses the rfm12B to receive the signals sent by the radio-shutter + * + */ +class eth_comfort { + +public: + + /** + * Constructor. + * + * @param mosi SPI-Interface. One of the 2 PSI-Interfaces of mbed. Pin p5 or p11 + * @param miso SPI-Interface. One of the 2 PSI-Interfaces of mbed. Pin p6 or p12 + * @param sclk SPI-Interface. One of the 2 PSI-Interfaces of mbed. Pin p7 or p13 + * @param nsel Chip-Select. A Digial Output of mbed + * @param rxdata Data-Pin for received data. A DigitalIn of mbed + * @param rxled LED1 - LED4 for showing received bytes + */ + eth_comfort(PinName mosi, PinName miso, PinName sclk, PinName nsel, PinName rxdata, PinName rxled); + + +// initialize eth_comfort-receiver + void init(); + +// is a new message readable - non blocking + bool readable(); + +// read a eth-messsage - non blocking, shows the old message if no new is available + eth_message getMessage(); + + + +private: + +// Interrupt Routine + void ISR(); + +// the last received message + eth_message last_message; + +// new meeesage + eth_message new_message; + +// is a new message in the buffer? + bool message_received; + +// calcualte the crc for eth + uint16_t calcCRC16r( uint16_t c,uint16_t crc, uint16_t mask); + + volatile uint8_t bit_cnt; + volatile uint16_t buffer_cnt; + + 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; + volatile uint16_t b; + volatile uint8_t blocklength; + int i,j,k; + bool crc_ok; + uint16_t crc, swapped; + + rfm12b *rfm12b_spi; + + DigitalOut *rxLED; + +}; + +#endif +
diff -r 000000000000 -r b79cb3278583 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Apr 27 19:02:00 2011 +0000 @@ -0,0 +1,128 @@ +#include "mbed.h" + +# include "string.h" + +#include "TextLCD.h" + +#include "ConfigFile.h" + +#include "eth_comfort.h" +#include "rfm.h" +#include "rfm12b.h" + +/*! + * \file main.cpp + * \brief Read messages from ETH-Radio-Shutters and send On/Off-Commands to KNX (via freebus-rs-interface) + * \author Karl Zweimüller + */ + +TextLCD lcd(p30, p29, p28, p27, p26, p25, TextLCD::LCD16x2); // rs, e, d0-d3 + +eth_comfort eth_comf(p11, p12, p13, p14, p18, LED4); // mosi, miso, sclk, cs, rxdata, rxled + +Serial pc(USBTX, USBRX); // tx, rx + +//Freebus-RS-Interface connected to serial +Serial knxrs(p9, p10); // tx, rx + +// Filesystem for Config-File +LocalFileSystem local("local"); + +ConfigFile cfg; + +// mbed LEDs +/* +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); +*/ + +//--------------------------------------------------------------------- +// +//--------------------------------------------------------------------- + +int main() { + + char group[255]; // the KNX-Group-address + char ethid[255]; //the ETH-ID as string + char command[255]; // a command to send to the freebus rs-interface + + eth_message message; // holds a message from the ETH-window-shutter + + pc.baud(115200); + + pc.printf("\n\rConnected to mbed\n\r"); + lcd.printf("ETH-Freebus: OK\n"); + + /* + * Read the configuration file from mbed. + */ + if (!cfg.read("/local/knx.cfg")) { + pc.printf("Failure to read configuration file knx.cfg.\n\r"); + } + + + // initialize freebus-rs-interface + // 115.200 Baud,n,8,1 + knxrs.baud(115200); + + knxrs.printf("fbecho=0\r"); //switch off echo + + + do { + // anything new? + if (eth_comf.readable()) { + // read the new message and display + message = eth_comf.getMessage(); + pc.printf("\n\rCounter: %02X\n\r",message.cnt); + pc.printf( " Dev-ID: %06X\n\r",message.adr); + pc.printf( " cmd: %0X\n\r",message.cmd); + //pc.printf( "cmd&0x80: %0X\n\r",message.cmd&0x80); + // why doesn't work the following?????????????? + //pc.printf( "Battery: "); + //if (message.cmd&0x80 == 0x00) pc.printf("GOOD\n\r"); else pc.printf("WEAK\n\r"); + + pc.printf( "Window : %s\n\r\n\r", (message.cmd&0x01 != 0x00) ? "OPEN" : "CLOSE"); + lcd.cls(); + lcd.printf("#:%02X ID: %06X\n",message.cnt,message.adr); + lcd.printf("Window : %s\n", (message.cmd&0x01 != 0x00) ? "OPEN" : "CLOSE"); + pc.printf("\n\r"); + + + // convert id to string + sprintf(ethid,"%06X",message.adr); + /* + * Get the group address from configuration value. + */ + if (cfg.getValue(ethid, &group[0], sizeof(group))) { + pc.printf("Config-File: '%s'='%s'\n\r", ethid,group ); + } else { + strcpy(group ,""); + } + + + if (strlen(group) > 0) { + sprintf(command, "fbs01/%s=%s\r",group,(message.cmd&0x01 != 0x00) ? "1" : "0"); // EIS01 on Group-address group : Open=1 Close=0 + // Send a KNX-Telegramm + knxrs.printf("%s",command); + pc.printf("%s\n\r",command); + } else { + // device not in config file, so add it + // add the new device to the config and write file + pc.printf("new unknown device!\n\r"); + /* we don't write the file, as all comments are lost + if (!cfg.setValue(ethid, "")) { + error("Failure to set a value.\n\r"); + } + if (!cfg.write("/local/knx.cfg")) { + error("Failure to write the configuration file.\n\r"); + } + */ + } + } + } while (1==1); + +} + +
diff -r 000000000000 -r b79cb3278583 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Apr 27 19:02:00 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912
diff -r 000000000000 -r b79cb3278583 rfm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rfm.h Wed Apr 27 19:02:00 2011 +0000 @@ -0,0 +1,502 @@ +/* + * Open HR20 + * + * target: ATmega169 @ 4 MHz in Honnywell Rondostat HR20E + * + * compiler: WinAVR-20071221 + * avr-libc 1.6.0 + * GCC 4.2.2 + * + * copyright: 2008 Dario Carluccio (hr20-at-carluccio-dot-de) + * 2008 Jiri Dobry (jdobry-at-centrum-dot-cz) + * 2008 Mario Fischer (MarioFischer-at-gmx-dot-net) + * 2007 Michael Smola (Michael-dot-Smola-at-gmx-dot-net) + * + * license: This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http:*www.gnu.org/licenses + */ + +/*! + * \file rfm.h + * \brief functions to control the RFM12 Radio Transceiver Module + * \author Mario Fischer <MarioFischer-at-gmx-dot-net>; Michael Smola <Michael-dot-Smola-at-gmx-dot-net> + * \date $Date: 2010/04/17 17:57:02 $ + * $Rev: 260 $ + */ + +//#pragma once // multi-iclude prevention. gcc knows this pragma +#ifndef rfm_H +#define rfm_H + + +#define RFM_SPI_16(OUTVAL) rfm_spi16(OUTVAL) //<! a function that gets a uint16_t (clocked out value) and returns a uint16_t (clocked in value) + +#define RFM_CLK_OUTPUT 0 + + +#define RFM_TESTPIN_INIT +#define RFM_TESTPIN_ON +#define RFM_TESTPIN_OFF +#define RFM_TESTPIN_TOG + +#define RFM_CONFIG_DISABLE 0x00 //<! RFM_CONFIG_*** are combinable flags, what the RFM shold do +#define RFM_CONFIG_BROADCASTSTATUS 0x01 //<! Flag that enables the HR20's status broadcast every minute + +#define RFM_CONFIG_ENABLEALL 0xff + + +/////////////////////////////////////////////////////////////////////////////// +// +// RFM status bits +// +/////////////////////////////////////////////////////////////////////////////// + +// Interrupt bits, latched //////////////////////////////////////////////////// + +#define RFM_STATUS_FFIT 0x8000 // RX FIFO reached the progr. number of bits + // Cleared by any FIFO read method + +#define RFM_STATUS_RGIT 0x8000 // TX register is ready to receive + // Cleared by TX write + +#define RFM_STATUS_POR 0x4000 // Power On reset + // Cleared by read status + +#define RFM_STATUS_RGUR 0x2000 // TX register underrun, register over write + // Cleared by read status + +#define RFM_STATUS_FFOV 0x2000 // RX FIFO overflow + // Cleared by read status + +#define RFM_STATUS_WKUP 0x1000 // Wake up timer overflow + // Cleared by read status + +#define RFM_STATUS_EXT 0x0800 // Interupt changed to low + // Cleared by read status + +#define RFM_STATUS_LBD 0x0400 // Low battery detect + +// Status bits //////////////////////////////////////////////////////////////// + +#define RFM_STATUS_FFEM 0x0200 // FIFO is empty +#define RFM_STATUS_ATS 0x0100 // TX mode: Strong enough RF signal +#define RFM_STATUS_RSSI 0x0100 // RX mode: signal strength above programmed limit +#define RFM_STATUS_DQD 0x0080 // Data Quality detector output +#define RFM_STATUS_CRL 0x0040 // Clock recovery lock +#define RFM_STATUS_ATGL 0x0020 // Toggling in each AFC cycle + +/////////////////////////////////////////////////////////////////////////////// +// +// 1. Configuration Setting Command +// +/////////////////////////////////////////////////////////////////////////////// + +#define RFM_CONFIG 0x8000 + +#define RFM_CONFIG_EL 0x8080 // Enable TX Register +#define RFM_CONFIG_EF 0x8040 // Enable RX FIFO buffer +#define RFM_CONFIG_BAND_315 0x8000 // Frequency band +#define RFM_CONFIG_BAND_433 0x8010 +#define RFM_CONFIG_BAND_868 0x8020 +#define RFM_CONFIG_BAND_915 0x8030 +#define RFM_CONFIG_X_8_5pf 0x8000 // Crystal Load Capacitor +#define RFM_CONFIG_X_9_0pf 0x8001 +#define RFM_CONFIG_X_9_5pf 0x8002 +#define RFM_CONFIG_X_10_0pf 0x8003 +#define RFM_CONFIG_X_10_5pf 0x8004 +#define RFM_CONFIG_X_11_0pf 0x8005 +#define RFM_CONFIG_X_11_5pf 0x8006 +#define RFM_CONFIG_X_12_0pf 0x8007 +#define RFM_CONFIG_X_12_5pf 0x8008 +#define RFM_CONFIG_X_13_0pf 0x8009 +#define RFM_CONFIG_X_13_5pf 0x800A +#define RFM_CONFIG_X_14_0pf 0x800B +#define RFM_CONFIG_X_14_5pf 0x800C +#define RFM_CONFIG_X_15_0pf 0x800D +#define RFM_CONFIG_X_15_5pf 0x800E +#define RFM_CONFIG_X_16_0pf 0x800F + +/////////////////////////////////////////////////////////////////////////////// +// +// 2. Power Management Command +// +/////////////////////////////////////////////////////////////////////////////// + +#define RFM_POWER_MANAGEMENT 0x8200 + +#define RFM_POWER_MANAGEMENT_ER 0x8280 // Enable receiver +#define RFM_POWER_MANAGEMENT_EBB 0x8240 // Enable base band block +#define RFM_POWER_MANAGEMENT_ET 0x8220 // Enable transmitter +#define RFM_POWER_MANAGEMENT_ES 0x8210 // Enable synthesizer +#define RFM_POWER_MANAGEMENT_EX 0x8208 // Enable crystal oscillator +#define RFM_POWER_MANAGEMENT_EB 0x8204 // Enable low battery detector +#define RFM_POWER_MANAGEMENT_EW 0x8202 // Enable wake-up timer +#define RFM_POWER_MANAGEMENT_DC 0x8201 // Disable clock output of CLK pin + +#ifndef RFM_CLK_OUTPUT + #error RFM_CLK_OUTPUT must be defined to 0 or 1 +#endif +#if RFM_CLK_OUTPUT + #define RFM_TX_ON_PRE() RFM_SPI_16( \ + RFM_POWER_MANAGEMENT_ES | \ + RFM_POWER_MANAGEMENT_EX ) + #define RFM_TX_ON() RFM_SPI_16( \ + RFM_POWER_MANAGEMENT_ET | \ + RFM_POWER_MANAGEMENT_ES | \ + RFM_POWER_MANAGEMENT_EX ) + #define RFM_RX_ON() RFM_SPI_16( \ + RFM_POWER_MANAGEMENT_ER | \ + RFM_POWER_MANAGEMENT_EBB | \ + RFM_POWER_MANAGEMENT_ES | \ + RFM_POWER_MANAGEMENT_EX ) + #define RFM_OFF() RFM_SPI_16( \ + RFM_POWER_MANAGEMENT_EX ) +#else + #define RFM_TX_ON_PRE() RFM_SPI_16( \ + RFM_POWER_MANAGEMENT_DC | \ + RFM_POWER_MANAGEMENT_ES | \ + RFM_POWER_MANAGEMENT_EX ) + #define RFM_TX_ON() RFM_SPI_16( \ + RFM_POWER_MANAGEMENT_DC | \ + RFM_POWER_MANAGEMENT_ET | \ + RFM_POWER_MANAGEMENT_ES | \ + RFM_POWER_MANAGEMENT_EX ) + #define RFM_RX_ON() RFM_SPI_16( \ + RFM_POWER_MANAGEMENT_DC | \ + RFM_POWER_MANAGEMENT_ER | \ + RFM_POWER_MANAGEMENT_EBB | \ + RFM_POWER_MANAGEMENT_ES | \ + RFM_POWER_MANAGEMENT_EX ) + #define RFM_OFF() RFM_SPI_16(RFM_POWER_MANAGEMENT_DC) +#endif +/////////////////////////////////////////////////////////////////////////////// +// +// 3. Frequency Setting Command +// +/////////////////////////////////////////////////////////////////////////////// + +#define RFM_FREQUENCY 0xA000 + +#define RFM_FREQ_315Band(v) (uint16_t)((v/10.0-31)*4000) +#define RFM_FREQ_433Band(v) (uint16_t)((v/10.0-43)*4000) +#define RFM_FREQ_868Band(v) (uint16_t)((v/20.0-43)*4000) +#define RFM_FREQ_915Band(v) (uint16_t)((v/30.0-30)*4000) + +/////////////////////////////////////////////////////////////////////////////// +// +// 4. Data Rate Command +// +///////////////////////////////////////////////////////////////////////////////// + +#define RFM_BAUD_RATE 9600 + +#define RFM_DATA_RATE 0xC600 + +#define RFM_DATA_RATE_CS 0xC680 +#define RFM_DATA_RATE_4800 0xC647 +#define RFM_DATA_RATE_9600 0xC623 +#define RFM_DATA_RATE_19200 0xC611 +#define RFM_DATA_RATE_38400 0xC608 +#define RFM_DATA_RATE_57600 0xC605 + +#define RFM_SET_DATARATE(baud) ( ((baud)<5400) ? (RFM_DATA_RATE_CS|((43104/(baud))-1)) : (RFM_DATA_RATE|((344828UL/(baud))-1)) ) + +/////////////////////////////////////////////////////////////////////////////// +// +// 5. Receiver Control Command +// +/////////////////////////////////////////////////////////////////////////////// + +#define RFM_RX_CONTROL 0x9000 + +#define RFM_RX_CONTROL_P20_INT 0x9000 // Pin20 = ExternalInt +#define RFM_RX_CONTROL_P20_VDI 0x9400 // Pin20 = VDI out + +#define RFM_RX_CONTROL_VDI_FAST 0x9000 // fast VDI Response time +#define RFM_RX_CONTROL_VDI_MED 0x9100 // medium +#define RFM_RX_CONTROL_VDI_SLOW 0x9200 // slow +#define RFM_RX_CONTROL_VDI_ON 0x9300 // Always on + +#define RFM_RX_CONTROL_BW_400 0x9020 // bandwidth 400kHz +#define RFM_RX_CONTROL_BW_340 0x9040 // bandwidth 340kHz +#define RFM_RX_CONTROL_BW_270 0x9060 // bandwidth 270kHz +#define RFM_RX_CONTROL_BW_200 0x9080 // bandwidth 200kHz +#define RFM_RX_CONTROL_BW_134 0x90A0 // bandwidth 134kHz +#define RFM_RX_CONTROL_BW_67 0x90C0 // bandwidth 67kHz + +#define RFM_RX_CONTROL_GAIN_0 0x9000 // LNA gain 0db +#define RFM_RX_CONTROL_GAIN_6 0x9008 // LNA gain -6db +#define RFM_RX_CONTROL_GAIN_14 0x9010 // LNA gain -14db +#define RFM_RX_CONTROL_GAIN_20 0x9018 // LNA gain -20db + +#define RFM_RX_CONTROL_RSSI_103 0x9000 // DRSSI threshold -103dbm +#define RFM_RX_CONTROL_RSSI_97 0x9001 // DRSSI threshold -97dbm +#define RFM_RX_CONTROL_RSSI_91 0x9002 // DRSSI threshold -91dbm +#define RFM_RX_CONTROL_RSSI_85 0x9003 // DRSSI threshold -85dbm +#define RFM_RX_CONTROL_RSSI_79 0x9004 // DRSSI threshold -79dbm +#define RFM_RX_CONTROL_RSSI_73 0x9005 // DRSSI threshold -73dbm +//#define RFM_RX_CONTROL_RSSI_67 0x9006 // DRSSI threshold -67dbm // RF12B reserved +//#define RFM_RX_CONTROL_RSSI_61 0x9007 // DRSSI threshold -61dbm // RF12B reserved + +#define RFM_RX_CONTROL_BW(baud) (((baud)<8000) ? \ + RFM_RX_CONTROL_BW_67 : \ + ( \ + ((baud)<30000) ? \ + RFM_RX_CONTROL_BW_134 : \ + RFM_RX_CONTROL_BW_200 \ + )) + +/////////////////////////////////////////////////////////////////////////////// +// +// 6. Data Filter Command +// +/////////////////////////////////////////////////////////////////////////////// + +#define RFM_DATA_FILTER 0xC228 + +#define RFM_DATA_FILTER_AL 0xC2A8 // clock recovery auto-lock +#define RFM_DATA_FILTER_ML 0xC268 // clock recovery fast mode +#define RFM_DATA_FILTER_DIG 0xC228 // data filter type digital +#define RFM_DATA_FILTER_ANALOG 0xC238 // data filter type analog +#define RFM_DATA_FILTER_DQD(level) (RFM_DATA_FILTER | (level & 0x7)) + +/////////////////////////////////////////////////////////////////////////////// +// +// 7. FIFO and Reset Mode Command +// +/////////////////////////////////////////////////////////////////////////////// + +#define RFM_FIFO 0xCA00 + +#define RFM_FIFO_AL 0xCA04 // FIFO Start condition sync-word/always +#define RFM_FIFO_FF 0xCA02 // Enable FIFO fill +#define RFM_FIFO_DR 0xCA01 // Disable hi sens reset mode +#define RFM_FIFO_IT(level) (RFM_FIFO | (( (level) & 0xF)<<4)) + +#define RFM_FIFO_OFF() RFM_SPI_16(RFM_FIFO_IT(8) | RFM_FIFO_DR) +#define RFM_FIFO_ON() RFM_SPI_16(RFM_FIFO_IT(8) | RFM_FIFO_FF | RFM_FIFO_DR) + +///////////////////////////////////////////////////////////////////////////// +// +// 8. Receiver FIFO Read +// +///////////////////////////////////////////////////////////////////////////// + +#define RFM_READ_FIFO() (RFM_SPI_16(0xB000) & 0xFF) + +///////////////////////////////////////////////////////////////////////////// +// +// 9. AFC Command +// +///////////////////////////////////////////////////////////////////////////// + +#define RFM_AFC 0xC400 + +#define RFM_AFC_EN 0xC401 +#define RFM_AFC_OE 0xC402 +#define RFM_AFC_FI 0xC404 +#define RFM_AFC_ST 0xC408 + +// Limits the value of the frequency offset register to the next values: + +#define RFM_AFC_RANGE_LIMIT_NO 0xC400 // 0: No restriction +#define RFM_AFC_RANGE_LIMIT_15_16 0xC410 // 1: +15 fres to -16 fres +#define RFM_AFC_RANGE_LIMIT_7_8 0xC420 // 2: +7 fres to -8 fres +#define RFM_AFC_RANGE_LIMIT_3_4 0xC430 // 3: +3 fres to -4 fres + +// fres=2.5 kHz in 315MHz and 433MHz Bands +// fres=5.0 kHz in 868MHz Band +// fres=7.5 kHz in 915MHz Band + +#define RFM_AFC_AUTO_OFF 0xC400 // 0: Auto mode off (Strobe is controlled by microcontroller) +#define RFM_AFC_AUTO_ONCE 0xC440 // 1: Runs only once after each power-up +#define RFM_AFC_AUTO_VDI 0xC480 // 2: Keep the foffset only during receiving(VDI=high) +#define RFM_AFC_AUTO_INDEPENDENT 0xC4C0 // 3: Keep the foffset value independently trom the state of the VDI signal + +/////////////////////////////////////////////////////////////////////////////// +// +// 10. TX Configuration Control Command +// +/////////////////////////////////////////////////////////////////////////////// + +#define RFM_TX_CONTROL 0x9800 + +#define RFM_TX_CONTROL_POW_0 0x9800 +#define RFM_TX_CONTROL_POW_3 0x9801 +#define RFM_TX_CONTROL_POW_6 0x9802 +#define RFM_TX_CONTROL_POW_9 0x9803 +#define RFM_TX_CONTROL_POW_12 0x9804 +#define RFM_TX_CONTROL_POW_15 0x9805 +#define RFM_TX_CONTROL_POW_18 0x9806 +#define RFM_TX_CONTROL_POW_21 0x9807 +#define RFM_TX_CONTROL_MOD_15 0x9800 +#define RFM_TX_CONTROL_MOD_30 0x9810 +#define RFM_TX_CONTROL_MOD_45 0x9820 +#define RFM_TX_CONTROL_MOD_60 0x9830 +#define RFM_TX_CONTROL_MOD_75 0x9840 +#define RFM_TX_CONTROL_MOD_90 0x9850 +#define RFM_TX_CONTROL_MOD_105 0x9860 +#define RFM_TX_CONTROL_MOD_120 0x9870 +#define RFM_TX_CONTROL_MOD_135 0x9880 +#define RFM_TX_CONTROL_MOD_150 0x9890 +#define RFM_TX_CONTROL_MOD_165 0x98A0 +#define RFM_TX_CONTROL_MOD_180 0x98B0 +#define RFM_TX_CONTROL_MOD_195 0x98C0 +#define RFM_TX_CONTROL_MOD_210 0x98D0 +#define RFM_TX_CONTROL_MOD_225 0x98E0 +#define RFM_TX_CONTROL_MOD_240 0x98F0 +#define RFM_TX_CONTROL_MP 0x9900 + +#define RFM_TX_CONTROL_MOD(baud) (((baud)<8000) ? \ + RFM_TX_CONTROL_MOD_45 : \ + ( \ + ((baud)<20000) ? \ + RFM_TX_CONTROL_MOD_60 : \ + ( \ + ((baud)<30000) ? \ + RFM_TX_CONTROL_MOD_75 : \ + ( \ + ((baud)<40000) ? \ + RFM_TX_CONTROL_MOD_90 : \ + RFM_TX_CONTROL_MOD_120 \ + ) \ + ) \ + )) + +///////////////////////////////////////////////////////////////////////////// +// +// 11. Transmitter Register Write Command +// +///////////////////////////////////////////////////////////////////////////// + +//#define RFM_WRITE(byte) RFM_SPI_16(0xB800 | ((byte) & 0xFF)) +#define RFM_WRITE(byte) RFM_SPI_16(0xB800 | (byte) ) + +/////////////////////////////////////////////////////////////////////////////// +// +// 12. Wake-up Timer Command +// +/////////////////////////////////////////////////////////////////////////////// + +#define RFM_WAKEUP_TIMER 0xE000 +#define RFM_WAKEUP_SET(time) RFM_SPI_16(RFM_WAKEUP_TIMER | (time)) + +#define RFM_WAKEUP_480s (RFM_WAKEUP_TIMER |(11 << 8)| 234) +#define RFM_WAKEUP_240s (RFM_WAKEUP_TIMER |(10 << 8)| 234) +#define RFM_WAKEUP_120s (RFM_WAKEUP_TIMER |(9 << 8)| 234) +#define RFM_WAKEUP_119s (RFM_WAKEUP_TIMER |(9 << 8)| 232) + +#define RFM_WAKEUP_60s (RFM_WAKEUP_TIMER |(8 << 8) | 235) +#define RFM_WAKEUP_59s (RFM_WAKEUP_TIMER |(8 << 8) | 230) + +#define RFM_WAKEUP_30s (RFM_WAKEUP_TIMER |(7 << 8) | 235) +#define RFM_WAKEUP_29s (RFM_WAKEUP_TIMER |(7 << 8) | 227) + +#define RFM_WAKEUP_8s (RFM_WAKEUP_TIMER |(5 << 8) | 250) +#define RFM_WAKEUP_7s (RFM_WAKEUP_TIMER |(5 << 8) | 219) +#define RFM_WAKEUP_6s (RFM_WAKEUP_TIMER |(6 << 8) | 94) +#define RFM_WAKEUP_5s (RFM_WAKEUP_TIMER |(5 << 8) | 156) +#define RFM_WAKEUP_4s (RFM_WAKEUP_TIMER |(5 << 8) | 125) +#define RFM_WAKEUP_1s (RFM_WAKEUP_TIMER |(2 << 8) | 250) +#define RFM_WAKEUP_900ms (RFM_WAKEUP_TIMER |(2 << 8) | 225) +#define RFM_WAKEUP_800ms (RFM_WAKEUP_TIMER |(2 << 8) | 200) +#define RFM_WAKEUP_700ms (RFM_WAKEUP_TIMER |(2 << 8) | 175) +#define RFM_WAKEUP_600ms (RFM_WAKEUP_TIMER |(2 << 8) | 150) +#define RFM_WAKEUP_500ms (RFM_WAKEUP_TIMER |(2 << 8) | 125) +#define RFM_WAKEUP_400ms (RFM_WAKEUP_TIMER |(2 << 8) | 100) +#define RFM_WAKEUP_300ms (RFM_WAKEUP_TIMER |(2 << 8) | 75) +#define RFM_WAKEUP_200ms (RFM_WAKEUP_TIMER |(2 << 8) | 50) +#define RFM_WAKEUP_100ms (RFM_WAKEUP_TIMER |(2 << 8) | 25) + +/////////////////////////////////////////////////////////////////////////////// +// +// 13. Low Duty-Cycle Command +// +/////////////////////////////////////////////////////////////////////////////// + +#define RFM_LOW_DUTY_CYCLE 0xC800 + +/////////////////////////////////////////////////////////////////////////////// +// +// 14. Low Battery Detector Command +// +/////////////////////////////////////////////////////////////////////////////// + +#define RFM_LOW_BATT_DETECT 0xC000 +#define RFM_LOW_BATT_DETECT_D_1MHZ 0xC000 +#define RFM_LOW_BATT_DETECT_D_1_25MHZ 0xC020 +#define RFM_LOW_BATT_DETECT_D_1_66MHZ 0xC040 +#define RFM_LOW_BATT_DETECT_D_2MHZ 0xC060 +#define RFM_LOW_BATT_DETECT_D_2_5MHZ 0xC080 +#define RFM_LOW_BATT_DETECT_D_3_33MHZ 0xC0A0 +#define RFM_LOW_BATT_DETECT_D_5MHZ 0xC0C0 +#define RFM_LOW_BATT_DETECT_D_10MHZ 0xC0E0 + +/////////////////////////////////////////////////////////////////////////////// +// +// 15. Status Read Command +// +/////////////////////////////////////////////////////////////////////////////// + +#define RFM_READ_STATUS() RFM_SPI_16(0x0000) +#define RFM_READ_STATUS_FFIT() SPI_1 (0x00) +#define RFM_READ_STATUS_RGIT RFM_READ_STATUS_FFIT + +/////////////////////////////////////////////////////////////////////////////// + +#include <stdint.h> +void RFM_init(void); +uint16_t rfm_spi16(uint16_t outval); + +/////////////////////////////////////////////////////////////////////////////// + +// RFM air protocol flags: + +#define RFMPROTO_FLAGS_BITASK_PACKETTYPE 0b11000000 //!< the uppermost 2 bits of the flags field encode the packettype +#define RFMPROTO_FLAGS_PACKETTYPE_BROADCAST 0b00000000 //!< broadcast packettype (message from hr20, protocol; step 1) +#define RFMPROTO_FLAGS_PACKETTYPE_COMMAND 0b01000000 //!< command packettype (message to hr20, protocol; step 2) +#define RFMPROTO_FLAGS_PACKETTYPE_REPLY 0b10000000 //!< reply packettype (message from hr20, protocol; step 3) +#define RFMPROTO_FLAGS_PACKETTYPE_SPECIAL 0b11000000 //!< currently unused packettype + +#define RFMPROTO_FLAGS_BITASK_DEVICETYPE 0b00011111 //!< the lowermost 5 bytes denote the device type. this way other sensors and actors may coexist +#define RFMPROTO_FLAGS_DEVICETYPE_OPENHR20 0b00010100 //!< topen HR20 device type. 10100 is for decimal 20 + +#define RFMPROTO_IS_PACKETTYPE_BROADCAST(FLAGS) ( RFMPROTO_FLAGS_PACKETTYPE_BROADCAST == ((FLAGS) & RFMPROTO_FLAGS_BITASK_PACKETTYPE) ) +#define RFMPROTO_IS_PACKETTYPE_COMMAND(FLAGS) ( RFMPROTO_FLAGS_PACKETTYPE_COMMAND == ((FLAGS) & RFMPROTO_FLAGS_BITASK_PACKETTYPE) ) +#define RFMPROTO_IS_PACKETTYPE_REPLY(FLAGS) ( RFMPROTO_FLAGS_PACKETTYPE_REPLY == ((FLAGS) & RFMPROTO_FLAGS_BITASK_PACKETTYPE) ) +#define RFMPROTO_IS_PACKETTYPE_SPECIAL(FLAGS) ( RFMPROTO_FLAGS_PACKETTYPE_SPECIAL == ((FLAGS) & RFMPROTO_FLAGS_BITASK_PACKETTYPE) ) +#define RFMPROTO_IS_DEVICETYPE_OPENHR20(FLAGS) ( RFMPROTO_FLAGS_DEVICETYPE_OPENHR20 == ((FLAGS) & RFMPROTO_FLAGS_BITASK_DEVICETYPE) ) + +/////////////////////////////////////////////////////////////////////////////// + +// RFM send and receive buffer: + +#define RFM_FRAME_MAX 80 + +typedef enum {rfmmode_stop=0, + rfmmode_start_tx=1, + rfmmode_tx=2, + rfmmode_tx_done=3, + rfmmode_rx=4, + rfmmode_rx_owf=5, + } rfm_mode_t; + +extern uint8_t rfm_framebuf[RFM_FRAME_MAX]; +extern uint8_t rfm_framesize; +extern uint8_t rfm_framepos; +extern rfm_mode_t rfm_mode; + +#define rfm_start_tx() +// (rfm_mode=rfmmode_start_tx) + +#endif
diff -r 000000000000 -r b79cb3278583 rfm12b.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rfm12b.cpp Wed Apr 27 19:02:00 2011 +0000 @@ -0,0 +1,150 @@ +#include "mbed.h" +#include "rfm12b.h" +#include "rfm.h" + +/*! + * \file rfm12b.cpp + * \brief class for rfm2b in rawmode - only receive part implemented + * \author Karl Zweimüller based on code from WED 6.9.2009 + */ + + +/** Class rfm12b for RFM12B transceiver module + http://www.hoperf.com/rf_fsk/rfm12b.htm +*/ + +/** rfm12b object +*/ +rfm12b::rfm12b(PinName mosi, PinName miso, PinName sclk, PinName nsel, PinName rxdata) { + + rfm12b_spi = new SPI(mosi, miso, sclk); // mosi, miso, sclk + cs = new DigitalOut(nsel); // nsel for chipselect + m_pinRXData = new InterruptIn(rxdata); // rxData- generates interrupts + + init_spi(); // init the spi-device +} + +/** init the spi-communication +*/ +void rfm12b::init_spi() { + // Setup the spi for 16 bit data : 1RW-bit 7 adressbit, 8 databit + // second edge capture, with a 5MHz clock rate + rfm12b_spi->format(16,0); + rfm12b_spi->frequency(5000000); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// Initialise RF module +// This are parameters for ETH Comfort by ELV +/////////////////////////////////////////////////////////////////////////////// +void rfm12b::RFM_init(void) { + + // 0. Init the SPI backend + //RFM_TESTPIN_INIT; + + //RFM_READ_STATUS(); + + // 1. Configuration Setting Command + RFM_SPI_16( + //RFM_CONFIG_EL | + //RFM_CONFIG_EF | + RFM_CONFIG_BAND_868 | + RFM_CONFIG_X_11_0pf + ); + + // 2. Power Management Command + //RFM_SPI_16( + // RFM_POWER_MANAGEMENT // switch all off + // ); + + // 3. Frequency Setting Command + RFM_SPI_16( + RFM_FREQUENCY | + RFM_FREQ_868Band(868.30) + ); + + // 4. Data Rate Command + RFM_SPI_16(RFM_DATA_RATE_9600); + + // 5. Receiver Control Command + RFM_SPI_16( + RFM_RX_CONTROL_P20_VDI | + RFM_RX_CONTROL_VDI_FAST | + //RFM_RX_CONTROL_BW(RFM_BAUD_RATE) | + RFM_RX_CONTROL_BW_134 | + RFM_RX_CONTROL_GAIN_0 | + RFM_RX_CONTROL_RSSI_73 + ); + + // 6. Data Filter Command + RFM_SPI_16( + //RFM_DATA_FILTER_AL | + //RFM_DATA_FILTER_ML | + //RFM_DATA_FILTER_DQD(3) + RFM_DATA_FILTER_ANALOG + ); + + // 7. FIFO and Reset Mode Command + RFM_SPI_16( + RFM_FIFO_IT(8) | + RFM_FIFO_DR + ); + + // 8. Receiver FIFO Read + + // 9. AFC Command + RFM_SPI_16( + RFM_AFC_AUTO_VDI | + RFM_AFC_RANGE_LIMIT_7_8 | + RFM_AFC_EN | + RFM_AFC_OE | + RFM_AFC_FI + ); + + // 10. TX Configuration Control Command + RFM_SPI_16( + RFM_TX_CONTROL_MOD_30 | + RFM_TX_CONTROL_POW_0 + ); + + // 11. Transmitter Register Write Command + + // 12. Wake-Up Timer Command + + // 13. Low Duty-Cycle Command + + // 14. Low Battery Detector Command + + //RFM_SPI_16( + // RFM_LOW_BATT_DETECT | + // 3 // 2.2V + v * 0.1V + // ); + + // 15. Status Read Command + //RFM_SPI_16(RFM_TX_ON()); + RFM_SPI_16(RFM_RX_ON()); + +} + +/////////////////////////////////////////////////////////////////////////////// + + + +/** write and read 16 bit to device +*/ +uint16_t rfm12b::rfm_spi16(uint16_t outval) { + + uint16_t readval; + // Select the device by seting chip select low + cs->write(0); + wait_ms(1); // wait before going on + //write and read + readval = rfm12b_spi->write(outval); + // Deselect the device + cs->write(1); + wait_ms(1); // wait before going on + return(readval); +} + +
diff -r 000000000000 -r b79cb3278583 rfm12b.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rfm12b.h Wed Apr 27 19:02:00 2011 +0000 @@ -0,0 +1,79 @@ +#ifndef rfm12B_H +#define rfm12B_H + +#include <mbed.h> + +/*! + * \file rfm12b.h + * \brief class for rfm2b in rawmode - only receive part implemented + * \author Karl Zweimüller based on code from WED 6.9.2009 + */ + +typedef unsigned char Byte; // used to be uint8_t : something a byte wide, whatever .... + +/** This Class handles a rfm12b transceiver + * see http://www.hoperf.com/rf_fsk/rfm12b.htm + * +*/ +class rfm12b { +public: + /** Create a rfm12b object + * + * @param mosi SPI-Interface. One of the 2 PSI-Interfaces of mbed. Pin p5 or p11 + * @param miso SPI-Interface. One of the 2 PSI-Interfaces of mbed. Pin p6 or p12 + * @param sclk SPI-Interface. One of the 2 PSI-Interfaces of mbed. Pin p7 or p13 + * @param nsel Chip-Select. A Digial Output of mbed + * @param rxdata Data-Pin for received data. A DigitalIn of mbed + */ + rfm12b(PinName mosi, PinName miso, PinName sclk, PinName nsel, PinName rxdata); + + /** init the spi-interface + */ + void init_spi(); + + /** initialize the device + */ + void RFM_init(void); + + /** write and read 16 bit + */ + uint16_t rfm_spi16(uint16_t outval); + + /** attach a function to be called when the data-pin changes from 0->1 and from 1->0 + * this function has to do all the decoding + * keep this function short, as no interrrupts can occour within + * + * @param fptr Pointer to callback-function + */ + void attachISR(void (*fptr)(void)) { + m_pinRXData->fall(fptr); + m_pinRXData->rise(fptr); + } + + template<typename T> + /** attach an object member function to be called when the data-pin changes from 0->1 and from 1->0 + * + * @param tptr pointer to object + * @param mprt pointer ro member function + * + */ + void attachISR(T* tptr, void (T::*mptr)(void)) { + if ((mptr != NULL) && (tptr != NULL)) { + m_pinRXData->fall(tptr, mptr); + m_pinRXData->rise(tptr, mptr); + } + } + + + +private: + + + DigitalOut *cs; //chipselect + InterruptIn *m_pinRXData; //rx data pin + SPI *rfm12b_spi; //spi-interface + + +}; + +#endif