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:
6:98da0571ec31
Parent:
5:a92c3f6d1711
Child:
7:9f9e2a63a8a2
--- a/RF12B.cpp	Thu Mar 10 18:07:53 2011 +0000
+++ b/RF12B.cpp	Fri Mar 11 15:47:06 2011 +0000
@@ -1,5 +1,7 @@
 #include "RF12B.h"
 
+#include "RF_defs.h"
+
 DigitalOut rfled(LED3);
 
 RF12B::RF12B(PinName _SDI,
@@ -41,6 +43,7 @@
 
 /* Sends a packet of data to the RF module for transmission */
 void RF12B::write(unsigned char *data, unsigned char length) {
+    unsigned char crc = 0;
     /* Transmitter mode */
     changeMode(TX);
 
@@ -52,10 +55,13 @@
     send(0xD4);
     /* Packet Length */
     send(length);
+    crc = crc8(crc, length);
     /* Packet Data */
     for (unsigned char i=0; i<length; i++) {
         send(data[i]);
+        crc = crc8(crc, data[i]);
     }
+    send(crc);
     send(0xAA); // DUMMY BYTES
     send(0xAA);
     send(0xAA);
@@ -76,20 +82,101 @@
 
 /* Initialises the RF12B module */
 void RF12B::init() {
-    writeCmd(0x80E7); //EL,EF,868band,12.0pF
-    changeMode(RX);
-    writeCmd(0xA640); //frequency select
-    writeCmd(0xC647); //4.8kbps
-    writeCmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
-    writeCmd(0xC2AC); //AL,!ml,DIG,DQD4
-    writeCmd(0xCA81); //FIFO8,SYNC,!ff,DR
-    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(0xE000); //NOT USED
-    writeCmd(0xC800); //NOT USED
-    writeCmd(0xC040); //1.66MHz,2.2V
+    /* writeCmd(0x80E7); //EL,EF,868band,12.0pF
+     changeMode(RX);
+     writeCmd(0xA640); //frequency select
+     writeCmd(0xC647); //4.8kbps
+     writeCmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
+     writeCmd(0xC2AC); //AL,!ml,DIG,DQD4
+     writeCmd(0xCA81); //FIFO8,SYNC,!ff,DR
+     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(0xE000); //NOT USED
+     writeCmd(0xC800); //NOT USED
+     writeCmd(0xC040); //1.66MHz,2.2V */
+
+    writeCmd(
+        RFM_CONFIG_EL           |
+        RFM_CONFIG_EF           |
+        RFM_CONFIG_BAND_433     //|
+        //RFM_CONFIG_X_11_0pf // meh, using default
+    );
+
+    // 2. Power Management Command
+    // leave everything switched off for now
+    /*
+    writeCmd(
+        RFM_POWER_MANAGEMENT     // switch all off
+    );
+    */
+
+    // 3. Frequency Setting Command
+    writeCmd(
+        RFM_FREQUENCY            |
+        RFM_FREQ_433Band(435.7)  //I totally made this value up... if someone knows where the sweetspots are in this band, tell me!
+    );
+
+
+    // 4. Data Rate Command
+    writeCmd(RFM_DATA_RATE_9600);
+
+
+    // 5. Receiver Control Command
+    writeCmd(
+        RFM_RX_CONTROL_P20_VDI  |
+        RFM_RX_CONTROL_VDI_FAST |
+        //RFM_RX_CONTROL_BW(RFM_BAUD_RATE) |
+        RFM_RX_CONTROL_BW_134   |     // CHANGE THIS TO 67 TO IMPROVE RANGE! (though the bitrate must then be below 8kbaud, and fsk modulation changed)
+        RFM_RX_CONTROL_GAIN_0   |
+        RFM_RX_CONTROL_RSSI_103      // Might need adjustment. Datasheet says around 10^-5 bit error rate at this level and baudrate.
+    );
+
+    // 6. Data Filter Command
+    writeCmd(
+        RFM_DATA_FILTER_AL      |
+        RFM_DATA_FILTER_ML      |
+        RFM_DATA_FILTER_DIG     //|
+        //RFM_DATA_FILTER_DQD(4)
+    );
+
+    // 7. FIFO and Reset Mode Command
+    writeCmd(
+        RFM_FIFO_IT(8) |
+        RFM_FIFO_DR    |
+        0x8 //turn on 16bit sync word
+    );
+
+    // 8. FIFO Syncword
+    // Leave as default: 0xD4
+
+    // 9. Receiver FIFO Read
+    // when the interupt goes high, (and if we can assume that it was a fifo fill interrupt) we can read a byte using:
+    // result = RFM_READ_FIFO();
+
+    // 10. AFC Command
+    writeCmd(
+        //RFM_AFC_AUTO_VDI        |  //Note this might be changed to improve range. Refer to datasheet.
+        RFM_AFC_AUTO_INDEPENDENT    |
+        RFM_AFC_RANGE_LIMIT_7_8     |
+        RFM_AFC_EN                  |
+        RFM_AFC_OE                  |
+        RFM_AFC_FI
+    );
+
+    // 11. TX Configuration Control Command
+    writeCmd(
+        RFM_TX_CONTROL_MOD_60 |
+        RFM_TX_CONTROL_POW_0
+    );
+
+
+    // 12. PLL Setting Command
+    writeCmd(
+        0xCC77 & ~0x01 // Setting the PLL bandwith, less noise, but max bitrate capped at 86.2
+        // I think this will slow down the plls reaction time. Not sure, check with someone!
+    );
 
     resetRX();
     status();
@@ -122,12 +209,15 @@
 void RF12B::rxISR() {
     unsigned int data = 0, i = 0;
     unsigned char packet_length = 0;
+    unsigned char crc = 0;
+    queue<unsigned char> temp;
 
     /* Grab the packet's length byte */
     data = writeCmd(0x0000);
     if ( (data&0x8000) ) {
         data = writeCmd(0xB000);
         packet_length = (data&0x00FF);
+        crc = crc8(crc, packet_length);
     }
 
     /* Grab the packet's data */
@@ -136,11 +226,27 @@
             data = writeCmd(0x0000);
             if ( (data&0x8000) ) {
                 data = writeCmd(0xB000);
-                fifo.push(data&0x00FF);
+                temp.push(data&0x00FF);
+                crc = crc8(crc, (unsigned char)(data&0x00FF));
                 i++;
             }
         }
     }
+    while (1) {
+        if (!NIRQ_in) {
+            data = writeCmd(0x0000);
+            if ( (data&0x8000) ) {
+                data = writeCmd(0xB000);
+                if ((unsigned char)(data & 0x00FF) == crc) {
+                    while (!temp.empty()) {
+                        fifo.push(temp.front());
+                        temp.pop();
+                    }
+                }
+                break;
+            }
+        }
+    }
     /* Tell RF Module we are finished */
     resetRX();
 }
@@ -153,4 +259,17 @@
 void RF12B::resetRX() {
     writeCmd(0xCA81);
     writeCmd(0xCA83);
-};
\ No newline at end of file
+};
+
+/* Calculate CRC8 */
+unsigned char RF12B::crc8(unsigned char crc, unsigned char data) {
+    crc = crc ^ data;
+    for (int i = 0; i < 8; i++) {
+        if (crc & 0x01) {
+            crc = (crc >> 1) ^ 0x8C;
+        } else {
+            crc >>= 1;
+        }
+    }
+    return crc;
+}
\ No newline at end of file