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

Files at this revision

API Documentation at this revision

Comitter:
charly
Date:
Wed Apr 27 19:02:00 2011 +0000
Commit message:

Changed in this revision

ConfigFile.lib Show annotated file Show diff for this revision Revisions of this file
TextLCD.lib Show annotated file Show diff for this revision Revisions of this file
eth_comfort.cpp Show annotated file Show diff for this revision Revisions of this file
eth_comfort.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
rfm.h Show annotated file Show diff for this revision Revisions of this file
rfm12b.cpp Show annotated file Show diff for this revision Revisions of this file
rfm12b.h Show annotated file Show diff for this revision Revisions of this file
--- /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
--- /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
--- /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, &eth_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
+            //////////////////////////////////////////////////////////////////////////////////////////////////////////
+            //
+        }
+    }
+
+}
+
+
+
+
--- /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
+
--- /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);
+
+}
+
+
--- /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
--- /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
--- /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);
+}
+
+
--- /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