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
--- /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, ð_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