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 18:07:53 2011 +0000
Revision:
5:a92c3f6d1711
Parent:
4:2a295db9ba1a
Child:
6:98da0571ec31
Fixed some problems in initialization. Pretty much fully working now!

Who changed what in which revision?

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