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
RF12B.cpp
- Committer:
- harryeakins
- Date:
- 2011-03-10
- Revision:
- 5:a92c3f6d1711
- Parent:
- 4:2a295db9ba1a
- Child:
- 6:98da0571ec31
File content as of revision 5:a92c3f6d1711:
#include "RF12B.h" DigitalOut rfled(LED3); RF12B::RF12B(PinName _SDI, PinName _SDO, PinName _SCK, PinName _NCS, PinName _NIRQ):spi(_SDI, _SDO, _SCK), NCS(_NCS), NIRQ(_NIRQ), NIRQ_in(_NIRQ), rfled(LED3) { /* SPI frequency, word lenght, polarity and phase */ spi.format(16,0); spi.frequency(2000000); /* Set ~CS high */ NCS = 1; /* Initialise RF Module */ init(); /* 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 receive buffer */ unsigned char RF12B::read() { if (available()) { unsigned char data = fifo.front(); fifo.pop(); return data; } else { return 0xFF; // Error val although could also be data... } } /* Sends a packet of data to the RF module for transmission */ 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); /* 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); /* Back to receiver mode */ changeMode(RX); status(); } /* Transmit a 1-byte data packet */ void RF12B::write(unsigned char data) { write(&data, 1); } /********************************************************************** * PRIVATE FUNCTIONS *********************************************************************/ /* 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 resetRX(); status(); } /* 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; } /* 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 { /* mode == RX */ writeCmd(0x8299); //er,!ebb,ET,ES,EX,!eb,!ew,DC } } /* 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) { if (!NIRQ_in) { data = writeCmd(0x0000); if ( (data&0x8000) ) { data = writeCmd(0xB000); fifo.push(data&0x00FF); i++; } } } /* Tell RF Module we are finished */ resetRX(); } unsigned int RF12B::status() { return writeCmd(0x0000); } /* Tell the RF Module this packet is received and wait for the next */ void RF12B::resetRX() { writeCmd(0xCA81); writeCmd(0xCA83); };