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
Diff: RF12B.cpp
- 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�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() {