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:
- 4:2a295db9ba1a
- Parent:
- 3:e72ad65868ab
- Child:
- 5:a92c3f6d1711
--- 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, CDDITCBW0 + 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