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

Committer:
harryeakins
Date:
Thu Mar 10 17:26:42 2011 +0000
Revision:
4:2a295db9ba1a
Parent:
3:e72ad65868ab
Child:
5:a92c3f6d1711
Added variable length packets

Who changed what in which revision?

UserRevisionLine numberNew contents of line
harryeakins 3:e72ad65868ab 1 #include "RF12B.h"
harryeakins 3:e72ad65868ab 2
harryeakins 4:2a295db9ba1a 3 RF12B::RF12B(PinName _SDI,
harryeakins 4:2a295db9ba1a 4 PinName _SDO,
harryeakins 4:2a295db9ba1a 5 PinName _SCK,
harryeakins 4:2a295db9ba1a 6 PinName _NCS,
harryeakins 4:2a295db9ba1a 7 PinName _NIRQ):spi(_SDI, _SDO, _SCK),
harryeakins 4:2a295db9ba1a 8 NCS(_NCS), NIRQ(_NIRQ), NIRQ_in(_NIRQ) {
harryeakins 3:e72ad65868ab 9
harryeakins 4:2a295db9ba1a 10 /* SPI frequency, word lenght, polarity and phase */
harryeakins 4:2a295db9ba1a 11 spi.format(16,0);
harryeakins 4:2a295db9ba1a 12 spi.frequency(2000000);
harryeakins 4:2a295db9ba1a 13
harryeakins 4:2a295db9ba1a 14 /* Set ~CS high */
harryeakins 4:2a295db9ba1a 15 NCS = 1;
harryeakins 3:e72ad65868ab 16
harryeakins 4:2a295db9ba1a 17 /* Initialise RF Module */
harryeakins 3:e72ad65868ab 18 init();
harryeakins 4:2a295db9ba1a 19 resetRX();
harryeakins 4:2a295db9ba1a 20
harryeakins 4:2a295db9ba1a 21 /* Setup interrupt to happen on falling edge of NIRQ */
harryeakins 4:2a295db9ba1a 22 NIRQ.fall(this, &RF12B::rxISR);
harryeakins 3:e72ad65868ab 23 }
harryeakins 3:e72ad65868ab 24
harryeakins 4:2a295db9ba1a 25 /* Returns true if receive buffer contains data */
harryeakins 4:2a295db9ba1a 26 bool RF12B::available() {
harryeakins 4:2a295db9ba1a 27 return !fifo.empty();
harryeakins 4:2a295db9ba1a 28 }
harryeakins 3:e72ad65868ab 29
harryeakins 4:2a295db9ba1a 30 /* Reads a byte of data from the receive buffer */
harryeakins 3:e72ad65868ab 31 unsigned char RF12B::read() {
harryeakins 4:2a295db9ba1a 32 if (available()) {
harryeakins 4:2a295db9ba1a 33 unsigned char data = fifo.front();
harryeakins 4:2a295db9ba1a 34 fifo.pop();
harryeakins 4:2a295db9ba1a 35 return data;
harryeakins 4:2a295db9ba1a 36 } else {
harryeakins 4:2a295db9ba1a 37 return 0xFF; // Error val although could also be data...
harryeakins 3:e72ad65868ab 38 }
harryeakins 3:e72ad65868ab 39 }
harryeakins 3:e72ad65868ab 40
harryeakins 3:e72ad65868ab 41 /* Sends a byte of data to the RF module for transmission */
harryeakins 4:2a295db9ba1a 42 void RF12B::write(unsigned char *data, unsigned char length) {
harryeakins 4:2a295db9ba1a 43 /* Transmitter mode */
harryeakins 4:2a295db9ba1a 44 changeMode(TX);
harryeakins 4:2a295db9ba1a 45
harryeakins 3:e72ad65868ab 46 writeCmd(0x0000);
harryeakins 3:e72ad65868ab 47 send(0xAA); // PREAMBLE
harryeakins 3:e72ad65868ab 48 send(0xAA);
harryeakins 3:e72ad65868ab 49 send(0xAA);
harryeakins 3:e72ad65868ab 50 send(0x2D); // SYNC
harryeakins 3:e72ad65868ab 51 send(0xD4);
harryeakins 4:2a295db9ba1a 52 /* Packet Length */
harryeakins 4:2a295db9ba1a 53 send(length);
harryeakins 4:2a295db9ba1a 54 /* Packet Data */
harryeakins 4:2a295db9ba1a 55 for (unsigned char i=0; i<length; i++) {
harryeakins 3:e72ad65868ab 56 send(data[i]);
harryeakins 3:e72ad65868ab 57 }
harryeakins 3:e72ad65868ab 58 send(0xAA); // DUMMY BYTES
harryeakins 3:e72ad65868ab 59 send(0xAA);
harryeakins 3:e72ad65868ab 60 send(0xAA);
harryeakins 3:e72ad65868ab 61
harryeakins 4:2a295db9ba1a 62 /* Back to receiver mode */
harryeakins 4:2a295db9ba1a 63 changeMode(RX);
harryeakins 3:e72ad65868ab 64 }
harryeakins 3:e72ad65868ab 65
harryeakins 4:2a295db9ba1a 66 /* Transmit a 1-byte data packet */
harryeakins 4:2a295db9ba1a 67 void RF12B::write(unsigned char data) {
harryeakins 4:2a295db9ba1a 68 write(&data, 1);
harryeakins 3:e72ad65868ab 69 }
harryeakins 3:e72ad65868ab 70
harryeakins 4:2a295db9ba1a 71 /**********************************************************************
harryeakins 4:2a295db9ba1a 72 * PRIVATE FUNCTIONS
harryeakins 4:2a295db9ba1a 73 *********************************************************************/
harryeakins 3:e72ad65868ab 74
harryeakins 4:2a295db9ba1a 75 /* Initialises the RF12B module */
harryeakins 3:e72ad65868ab 76 void RF12B::init() {
harryeakins 3:e72ad65868ab 77 writeCmd(0x80E7); //EL,EF,868band,12.0pF
harryeakins 4:2a295db9ba1a 78 changeMode(RX);
harryeakins 3:e72ad65868ab 79 writeCmd(0xA640); //frequency select
harryeakins 3:e72ad65868ab 80 writeCmd(0xC647); //4.8kbps
harryeakins 3:e72ad65868ab 81 writeCmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
harryeakins 3:e72ad65868ab 82 writeCmd(0xC2AC); //AL,!ml,DIG,DQD4
harryeakins 3:e72ad65868ab 83 writeCmd(0xCA81); //FIFO8,SYNC,!ff,DR
harryeakins 3:e72ad65868ab 84 writeCmd(0xCED4); //SYNC=2DD4
harryeakins 3:e72ad65868ab 85 writeCmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
harryeakins 3:e72ad65868ab 86 writeCmd(0x9850); //!mp,90kHz,MAX OUT
harryeakins 4:2a295db9ba1a 87 writeCmd(0xCC17); //OB1, COB0, LPX, Iddy, CDDIT�CBW0
harryeakins 3:e72ad65868ab 88 writeCmd(0xE000); //NOT USED
harryeakins 3:e72ad65868ab 89 writeCmd(0xC800); //NOT USED
harryeakins 3:e72ad65868ab 90 writeCmd(0xC040); //1.66MHz,2.2V
harryeakins 4:2a295db9ba1a 91 }
harryeakins 3:e72ad65868ab 92
harryeakins 4:2a295db9ba1a 93 /* Write a command to the RF Module */
harryeakins 4:2a295db9ba1a 94 unsigned int RF12B::writeCmd(unsigned int cmd) {
harryeakins 4:2a295db9ba1a 95 NCS = 0;
harryeakins 4:2a295db9ba1a 96 unsigned int recv = spi.write(cmd);
harryeakins 4:2a295db9ba1a 97 NCS = 1;
harryeakins 4:2a295db9ba1a 98 return recv;
harryeakins 3:e72ad65868ab 99 }
harryeakins 3:e72ad65868ab 100
harryeakins 4:2a295db9ba1a 101 /* Sends a byte of data across RF */
harryeakins 4:2a295db9ba1a 102 void RF12B::send(unsigned char data) {
harryeakins 4:2a295db9ba1a 103 while (NIRQ);
harryeakins 4:2a295db9ba1a 104 writeCmd(0xB800 + data);
harryeakins 4:2a295db9ba1a 105 }
harryeakins 4:2a295db9ba1a 106
harryeakins 4:2a295db9ba1a 107 /* Change the mode of the RF module to Transmitting or Receiving */
harryeakins 4:2a295db9ba1a 108 void RF12B::changeMode(rfmode_t mode) {
harryeakins 4:2a295db9ba1a 109 if (mode == TX) {
harryeakins 3:e72ad65868ab 110 writeCmd(0x8239); //!er,!ebb,ET,ES,EX,!eb,!ew,DC
harryeakins 4:2a295db9ba1a 111 } else { /* mode == RX */
harryeakins 3:e72ad65868ab 112 writeCmd(0x8299); //er,!ebb,ET,ES,EX,!eb,!ew,DC
harryeakins 3:e72ad65868ab 113 }
harryeakins 3:e72ad65868ab 114 }
harryeakins 3:e72ad65868ab 115
harryeakins 4:2a295db9ba1a 116 /* Interrupt routine for data reception */
harryeakins 4:2a295db9ba1a 117 void RF12B::rxISR() {
harryeakins 4:2a295db9ba1a 118 unsigned int data = 0, i = 0;
harryeakins 4:2a295db9ba1a 119 unsigned char packet_length = 0;
harryeakins 4:2a295db9ba1a 120
harryeakins 4:2a295db9ba1a 121 /* Grab the packet's length byte */
harryeakins 4:2a295db9ba1a 122 data = writeCmd(0x0000);
harryeakins 4:2a295db9ba1a 123 if ( (data&0x8000) ) {
harryeakins 4:2a295db9ba1a 124 data = writeCmd(0xB000);
harryeakins 4:2a295db9ba1a 125 packet_length = (data&0x00FF);
harryeakins 4:2a295db9ba1a 126 }
harryeakins 4:2a295db9ba1a 127
harryeakins 4:2a295db9ba1a 128 /* Grab the packet's data */
harryeakins 4:2a295db9ba1a 129 while ((++i) < packet_length) {
harryeakins 4:2a295db9ba1a 130 data = writeCmd(0x0000);
harryeakins 4:2a295db9ba1a 131 if ( (data&0x8000) ) {
harryeakins 4:2a295db9ba1a 132 data = writeCmd(0xB000);
harryeakins 4:2a295db9ba1a 133 fifo.push(data&0x00FF);
harryeakins 4:2a295db9ba1a 134 }
harryeakins 4:2a295db9ba1a 135 }
harryeakins 4:2a295db9ba1a 136 /* Tell RF Module we are finished */
harryeakins 4:2a295db9ba1a 137 resetRX();
harryeakins 3:e72ad65868ab 138 }
harryeakins 4:2a295db9ba1a 139
harryeakins 4:2a295db9ba1a 140 /* Tell the RF Module this packet is received and wait for the next */
harryeakins 4:2a295db9ba1a 141 void RF12B::resetRX() {
harryeakins 4:2a295db9ba1a 142 writeCmd(0xCA81);
harryeakins 4:2a295db9ba1a 143 writeCmd(0xCA83);
harryeakins 4:2a295db9ba1a 144 };