Library to send and receive data using RF12B transceiver modules Big thanks to the tutorial at https://loee.jottit.com/rfm12b_and_avr_-_quick_start and madcowswe

Dependents:   Measure_system Quadcopter_copy

Revision:
4:2a295db9ba1a
Parent:
3:e72ad65868ab
Child:
5:a92c3f6d1711
diff -r e72ad65868ab -r 2a295db9ba1a RF12B.cpp
--- a/RF12B.cpp	Thu Mar 10 13:14:48 2011 +0000
+++ b/RF12B.cpp	Thu Mar 10 17:26:42 2011 +0000
@@ -1,89 +1,81 @@
 #include "RF12B.h"
 
-RF12B::RF12B(PinName SDI,
-             PinName SDO,
-             PinName SCK,
-             PinName NCS,
-             PinName NIRQ):spi(SDI, SDO, SCK),
-        NCS(NCS), NIRQ(NIRQ) {
-    this->initialized = false;
-    this->trans = false;
+RF12B::RF12B(PinName _SDI,
+             PinName _SDO,
+             PinName _SCK,
+             PinName _NCS,
+             PinName _NIRQ):spi(_SDI, _SDO, _SCK),
+        NCS(_NCS), NIRQ(_NIRQ), NIRQ_in(_NIRQ) {
 
-    this->spi.format(16,0);
-    this->spi.frequency(2000000);
-    this->NCS = 1;
+    /* SPI frequency, word lenght, polarity and phase */
+    spi.format(16,0);
+    spi.frequency(2000000);
+
+    /* Set ~CS high */
+    NCS = 1;
 
+    /* Initialise RF Module */
     init();
-    mode(false);// Receiver
-    flush();
+    resetRX();
+
+    /* Setup interrupt to happen on falling edge of NIRQ */
+    NIRQ.fall(this, &RF12B::rxISR);
 }
 
+/* Returns true if receive buffer contains data */
+bool RF12B::available() {
+    return !fifo.empty();
+}
 
-/* Reads a byte of data from the RF module's buffer
-    This is a blocking call */
+/* Reads a byte of data from the receive buffer */
 unsigned char RF12B::read() {
-    if (!initialized || trans) {
-        mode(false); //Receiver
-        trans = false;
-        initialized = true;
-    }
-
-    unsigned int data;
-    while (1) {
-        data = writeCmd(0x0000);
-        if ( (data&0x8000) ) {
-            data = writeCmd(0xB000);
-            return (data&0x00FF);
-        }
+    if (available()) {
+        unsigned char data = fifo.front();
+        fifo.pop();
+        return data;
+    } else {
+        return 0xFF; // Error val although could also be data...
     }
 }
 
 /* Sends a byte of data to the RF module for transmission */
-void RF12B::write(unsigned char *data, unsigned int length) {
-    if (!initialized || !trans) {
-        mode(true); //Transmitter
-        trans = true;
-        initialized = true;
-    }
+void RF12B::write(unsigned char *data, unsigned char length) {
+    /* Transmitter mode */
+    changeMode(TX);
+
     writeCmd(0x0000);
     send(0xAA); // PREAMBLE
     send(0xAA);
     send(0xAA);
     send(0x2D); // SYNC
     send(0xD4);
-    for (int i=0; i<length; i++) {
+    /* Packet Length */
+    send(length);
+    /* Packet Data */
+    for (unsigned char i=0; i<length; i++) {
         send(data[i]);
     }
     send(0xAA); // DUMMY BYTES
     send(0xAA);
     send(0xAA);
 
-    mode(false);
-    trans = false;
+    /* Back to receiver mode */
+    changeMode(RX);
 }
 
-void RF12B::send(unsigned char data) {
-    while (NIRQ);
-    writeCmd(0xB800 + data);
+/* Transmit a 1-byte data packet */
+void RF12B::write(unsigned char data) {
+    write(&data, 1);
 }
 
-/* Flushes all data from the RF module's buffer */
-void RF12B::flush() {
-    if (!trans) {
-        writeCmd(0xCA81);
-        writeCmd(0xCA83);
-    }
-};
+/**********************************************************************
+ *  PRIVATE FUNCTIONS
+ *********************************************************************/
 
-/* Initialises the RF12B module as transmitter
-    or receiver. This should be called after the
-    RF module has fully started up (give it a
-    few hundred ms) */
+/* Initialises the RF12B module */
 void RF12B::init() {
-
     writeCmd(0x80E7); //EL,EF,868band,12.0pF
-    mode(false);
-    trans = false;
+    changeMode(RX);
     writeCmd(0xA640); //frequency select
     writeCmd(0xC647); //4.8kbps
     writeCmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
@@ -92,26 +84,61 @@
     writeCmd(0xCED4); //SYNC=2DD4
     writeCmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
     writeCmd(0x9850); //!mp,90kHz,MAX OUT
-    writeCmd(0xCC17); //OB1, COB0, LPX, Iddy, CDDITCBW0
+    writeCmd(0xCC17); //OB1, COB0, LPX, Iddy, CDDIT�CBW0
     writeCmd(0xE000); //NOT USED
     writeCmd(0xC800); //NOT USED
     writeCmd(0xC040); //1.66MHz,2.2V
+}
 
-    initialized = true;
+/* Write a command to the RF Module */
+unsigned int RF12B::writeCmd(unsigned int cmd) {
+    NCS = 0;
+    unsigned int recv = spi.write(cmd);
+    NCS = 1;
+    return recv;
 }
 
-void RF12B::mode(bool trans) {
-    if (trans) {
+/* Sends a byte of data across RF */
+void RF12B::send(unsigned char data) {
+    while (NIRQ);
+    writeCmd(0xB800 + data);
+}
+
+/* Change the mode of the RF module to Transmitting or Receiving */
+void RF12B::changeMode(rfmode_t mode) {
+    if (mode == TX) {
         writeCmd(0x8239); //!er,!ebb,ET,ES,EX,!eb,!ew,DC
-    } else {
+    } else { /* mode == RX */
         writeCmd(0x8299); //er,!ebb,ET,ES,EX,!eb,!ew,DC
     }
 }
 
-unsigned int RF12B::writeCmd(unsigned int cmd) {
-    unsigned int recv;
-    NCS = 0;
-    recv = spi.write(cmd);
-    NCS = 1;
-    return recv;
+/* Interrupt routine for data reception */
+void RF12B::rxISR() {
+    unsigned int data = 0, i = 0;
+    unsigned char packet_length = 0;
+
+    /* Grab the packet's length byte */
+    data = writeCmd(0x0000);
+    if ( (data&0x8000) ) {
+        data = writeCmd(0xB000);
+        packet_length = (data&0x00FF);
+    }
+    
+    /* Grab the packet's data */
+    while ((++i) < packet_length) {
+        data = writeCmd(0x0000);
+        if ( (data&0x8000) ) {
+            data = writeCmd(0xB000);
+            fifo.push(data&0x00FF);
+        }
+    }
+    /* Tell RF Module we are finished */
+    resetRX();
 }
+
+/* Tell the RF Module this packet is received and wait for the next */
+void RF12B::resetRX() {
+    writeCmd(0xCA81);
+    writeCmd(0xCA83);
+};
\ No newline at end of file