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:
7:9f9e2a63a8a2
Parent:
6:98da0571ec31
Child:
8:6fc24b44e027
--- a/RF12B.cpp	Fri Mar 11 15:47:06 2011 +0000
+++ b/RF12B.cpp	Fri Mar 11 19:30:30 2011 +0000
@@ -25,9 +25,23 @@
     NIRQ.fall(this, &RF12B::rxISR);
 }
 
-/* Returns true if receive buffer contains data */
-bool RF12B::available() {
-    return !fifo.empty();
+/* Returns the packet length if data is available in the receive buffer, 0 otherwise*/
+unsigned int RF12B::available() {
+    return fifo.size();
+}
+
+/* Reads a packet of data, with length "size" Returns false if read failed. TODO: make a metafifo to isolate packets*/
+bool RF12B::read(unsigned char* data, unsigned int size) {
+    if (fifo.size() == 0) {
+        return false;
+    } else {
+        unsigned int i = 0;
+        while (fifo.size() > 0 && i < size) {
+            data[i++] = fifo.front();
+            fifo.pop();
+        }
+        return true;
+    }
 }
 
 /* Reads a byte of data from the receive buffer */
@@ -41,7 +55,7 @@
     }
 }
 
-/* Sends a packet of data to the RF module for transmission */
+/* Sends a packet of data to the RF module for transmission TODO: Make asych*/
 void RF12B::write(unsigned char *data, unsigned char length) {
     unsigned char crc = 0;
     /* Transmitter mode */
@@ -56,6 +70,8 @@
     /* Packet Length */
     send(length);
     crc = crc8(crc, length);
+    send(crc);
+    crc = crc8(crc, crc);
     /* Packet Data */
     for (unsigned char i=0; i<length; i++) {
         send(data[i]);
@@ -92,7 +108,7 @@
      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&#65533;CBW0
      writeCmd(0xE000); //NOT USED
      writeCmd(0xC800); //NOT USED
      writeCmd(0xC040); //1.66MHz,2.2V */
@@ -175,7 +191,7 @@
     // 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!
+        // I think this will slow down the pll's reaction time. Not sure, check with someone!
     );
 
     resetRX();
@@ -207,22 +223,56 @@
 
 /* Interrupt routine for data reception */
 void RF12B::rxISR() {
-    unsigned int data = 0, i = 0;
-    unsigned char packet_length = 0;
-    unsigned char crc = 0;
-    queue<unsigned char> temp;
+    unsigned int data = 0;
+    static int i = -2;
+    static unsigned char packet_length = 0;
+    static unsigned char crc = 0;
+    static queue<unsigned char> temp;
+
+    //Loop while interrupt is asserted
+    while (!NIRQ_in) {
+
+        /* Grab the packet's length byte */
+        if (i == -2) {
+            data = writeCmd(0x0000);
+            if ( (data&0x8000) ) {
+                data = writeCmd(0xB000);
+                packet_length = (data&0x00FF);
+                crc = crc8(crc, packet_length);
+                i++;
+            }
+        }
+
+        //If we exhaust the interrupt, exit
+        if (NIRQ_in)
+            break;
 
-    /* Grab the packet's length byte */
-    data = writeCmd(0x0000);
-    if ( (data&0x8000) ) {
-        data = writeCmd(0xB000);
-        packet_length = (data&0x00FF);
-        crc = crc8(crc, packet_length);
-    }
+        // Check that packet length was correct
+        if (i == -1) {
+            data = writeCmd(0x0000);
+            if ( (data&0x8000) ) {
+                data = writeCmd(0xB000);
+                unsigned char crcofsize = (data&0x00FF);
+                if (crcofsize != crc) {
+                    //It was wrong, start over
+                    i = -2;
+                    packet_length = 0;
+                    crc = 0;
+                    temp = queue<unsigned char>();
+                    resetRX();
+                } else {
+                    crc = crc8(crc, crcofsize);
+                    i++;
+                }
+            }
+        }
 
-    /* Grab the packet's data */
-    while (i < packet_length) {
-        if (!NIRQ_in) {
+        //If we exhaust the interrupt, exit
+        if (NIRQ_in)
+            break;
+
+        /* Grab the packet's data */
+        if (i >= 0 && i < packet_length) {
             data = writeCmd(0x0000);
             if ( (data&0x8000) ) {
                 data = writeCmd(0xB000);
@@ -231,24 +281,32 @@
                 i++;
             }
         }
-    }
-    while (1) {
-        if (!NIRQ_in) {
+
+        //If we exhaust the interrupt, exit
+        if (NIRQ_in)
+            break;
+
+        if (i >= packet_length) {
             data = writeCmd(0x0000);
             if ( (data&0x8000) ) {
                 data = writeCmd(0xB000);
                 if ((unsigned char)(data & 0x00FF) == crc) {
+                    //If the checksum is correct, add our data to the end of the output buffer
                     while (!temp.empty()) {
                         fifo.push(temp.front());
                         temp.pop();
                     }
                 }
-                break;
+
+                /* Tell RF Module we are finished, and clean up */
+                i = -2;
+                packet_length = 0;
+                crc = 0;
+                temp = queue<unsigned char>();
+                resetRX();
             }
         }
     }
-    /* Tell RF Module we are finished */
-    resetRX();
 }
 
 unsigned int RF12B::status() {