Committer:
narshu
Date:
Thu Apr 26 17:50:00 2012 +0000
Revision:
1:0370ea94b64a
Parent:
0:7583de124698

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
narshu 0:7583de124698 1 #include "RF12B.h"
narshu 0:7583de124698 2
narshu 0:7583de124698 3 #include "RF_defs.h"
narshu 0:7583de124698 4 #include <algorithm>
narshu 1:0370ea94b64a 5 #include "system.h"
narshu 1:0370ea94b64a 6 #include "globals.h"
narshu 0:7583de124698 7
narshu 0:7583de124698 8
narshu 0:7583de124698 9 RF12B::RF12B(PinName _SDI,
narshu 0:7583de124698 10 PinName _SDO,
narshu 0:7583de124698 11 PinName _SCK,
narshu 0:7583de124698 12 PinName _NCS,
narshu 0:7583de124698 13 PinName _NIRQ):spi(_SDI, _SDO, _SCK),
narshu 1:0370ea94b64a 14 NCS(_NCS), NIRQ(_NIRQ), NIRQ_in(_NIRQ) {// rfled(LED3) {
narshu 0:7583de124698 15
narshu 1:0370ea94b64a 16 // SPI frequency, word lenght, polarity and phase */
narshu 0:7583de124698 17 spi.format(16,0);
narshu 0:7583de124698 18 spi.frequency(2000000);
narshu 0:7583de124698 19
narshu 1:0370ea94b64a 20 // Set ~CS high
narshu 0:7583de124698 21 NCS = 1;
narshu 0:7583de124698 22
narshu 1:0370ea94b64a 23 // Initialise RF Module
narshu 0:7583de124698 24 init();
narshu 0:7583de124698 25
narshu 1:0370ea94b64a 26 // Setup interrupt to happen on falling edge of NIRQ
narshu 0:7583de124698 27 NIRQ.fall(this, &RF12B::rxISR);
narshu 0:7583de124698 28 }
narshu 0:7583de124698 29
narshu 1:0370ea94b64a 30 // Returns the packet length if data is available in the receive buffer, 0 otherwise
narshu 1:0370ea94b64a 31 //unsigned int RF12B::available() {
narshu 1:0370ea94b64a 32 // return fifo.size();
narshu 1:0370ea94b64a 33 //}
narshu 0:7583de124698 34
narshu 1:0370ea94b64a 35 // Reads a packet of data, with length "size" Returns false if read failed. TODO: make a metafifo to isolate packets
narshu 1:0370ea94b64a 36 /*bool RF12B::read(unsigned char* data, unsigned int size) {
narshu 0:7583de124698 37 if (fifo.size() == 0) {
narshu 0:7583de124698 38 return false;
narshu 0:7583de124698 39 } else {
narshu 0:7583de124698 40 unsigned int i = 0;
narshu 0:7583de124698 41 while (fifo.size() > 0 && i < size) {
narshu 0:7583de124698 42 data[i++] = fifo.front();
narshu 0:7583de124698 43 fifo.pop();
narshu 0:7583de124698 44 }
narshu 0:7583de124698 45 return true;
narshu 0:7583de124698 46 }
narshu 0:7583de124698 47 }
narshu 1:0370ea94b64a 48 */
narshu 0:7583de124698 49
narshu 1:0370ea94b64a 50 // Reads a byte of data from the receive buffer
narshu 1:0370ea94b64a 51 /*
narshu 0:7583de124698 52 unsigned char RF12B::read() {
narshu 0:7583de124698 53 if (available()) {
narshu 0:7583de124698 54 unsigned char data = fifo.front();
narshu 0:7583de124698 55 fifo.pop();
narshu 0:7583de124698 56 return data;
narshu 0:7583de124698 57 } else {
narshu 0:7583de124698 58 return 0xFF; // Error val although could also be data...
narshu 0:7583de124698 59 }
narshu 0:7583de124698 60 }
narshu 1:0370ea94b64a 61 */
narshu 0:7583de124698 62
narshu 1:0370ea94b64a 63 // Sends a packet of data to the RF module for transmission TODO: Make asych
narshu 0:7583de124698 64 void RF12B::write(unsigned char *data, unsigned char length) {
narshu 0:7583de124698 65 unsigned char crc = 0;
narshu 1:0370ea94b64a 66
narshu 1:0370ea94b64a 67 // Transmitter mode
narshu 0:7583de124698 68 changeMode(TX);
narshu 0:7583de124698 69
narshu 0:7583de124698 70 writeCmd(0x0000);
narshu 0:7583de124698 71 send(0xAA); // PREAMBLE
narshu 0:7583de124698 72 send(0xAA);
narshu 0:7583de124698 73 send(0xAA);
narshu 0:7583de124698 74 send(0x2D); // SYNC
narshu 0:7583de124698 75 send(0xD4);
narshu 1:0370ea94b64a 76 // Packet Length
narshu 0:7583de124698 77 send(length);
narshu 0:7583de124698 78 crc = crc8(crc, length);
narshu 0:7583de124698 79 send(crc);
narshu 0:7583de124698 80 crc = crc8(crc, crc);
narshu 1:0370ea94b64a 81 // Packet Data
narshu 0:7583de124698 82 for (unsigned char i=0; i<length; i++) {
narshu 0:7583de124698 83 send(data[i]);
narshu 0:7583de124698 84 crc = crc8(crc, data[i]);
narshu 0:7583de124698 85 }
narshu 0:7583de124698 86 send(crc);
narshu 0:7583de124698 87 send(0xAA); // DUMMY BYTES
narshu 0:7583de124698 88 send(0xAA);
narshu 0:7583de124698 89 send(0xAA);
narshu 0:7583de124698 90
narshu 1:0370ea94b64a 91 // Back to receiver mode
narshu 0:7583de124698 92 changeMode(RX);
narshu 0:7583de124698 93 status();
narshu 1:0370ea94b64a 94
narshu 0:7583de124698 95
narshu 0:7583de124698 96 }
narshu 0:7583de124698 97
narshu 1:0370ea94b64a 98 // Transmit a 1-byte data packet
narshu 0:7583de124698 99 void RF12B::write(unsigned char data) {
narshu 0:7583de124698 100 write(&data, 1);
narshu 0:7583de124698 101 }
narshu 1:0370ea94b64a 102 /*
narshu 0:7583de124698 103 void RF12B::write(queue<char> &data, int length) {
narshu 0:7583de124698 104 char crc = 0;
narshu 0:7583de124698 105 char length_byte = 0;
narshu 1:0370ea94b64a 106
narshu 1:0370ea94b64a 107 // -1 means try to transmit everything in the queue
narshu 1:0370ea94b64a 108 if (length == -1) {
narshu 0:7583de124698 109 length = data.size();
narshu 0:7583de124698 110 }
narshu 1:0370ea94b64a 111
narshu 1:0370ea94b64a 112 // max length of packet is 255
narshu 0:7583de124698 113 length_byte = min(length, 255);
narshu 1:0370ea94b64a 114
narshu 1:0370ea94b64a 115 // Transmitter mode
narshu 0:7583de124698 116 changeMode(TX);
narshu 0:7583de124698 117
narshu 0:7583de124698 118 writeCmd(0x0000);
narshu 0:7583de124698 119 send(0xAA); // PREAMBLE
narshu 0:7583de124698 120 send(0xAA);
narshu 0:7583de124698 121 send(0xAA);
narshu 0:7583de124698 122 send(0x2D); // SYNC
narshu 0:7583de124698 123 send(0xD4);
narshu 1:0370ea94b64a 124 // Packet Length
narshu 0:7583de124698 125 send(length_byte);
narshu 0:7583de124698 126 crc = crc8(crc, length_byte);
narshu 0:7583de124698 127 send(crc);
narshu 0:7583de124698 128 crc = crc8(crc, crc);
narshu 1:0370ea94b64a 129 // Packet Data
narshu 0:7583de124698 130 for (char i=0; i<length_byte; i++) {
narshu 0:7583de124698 131 send(data.front());
narshu 0:7583de124698 132 crc = crc8(crc, data.front());
narshu 0:7583de124698 133 data.pop();
narshu 0:7583de124698 134 }
narshu 0:7583de124698 135 send(crc);
narshu 0:7583de124698 136 send(0xAA); // DUMMY BYTES
narshu 0:7583de124698 137 send(0xAA);
narshu 0:7583de124698 138 send(0xAA);
narshu 0:7583de124698 139
narshu 1:0370ea94b64a 140 // Back to receiver mode
narshu 0:7583de124698 141 changeMode(RX);
narshu 0:7583de124698 142 status();
narshu 0:7583de124698 143 }
narshu 1:0370ea94b64a 144 */
narshu 0:7583de124698 145 /**********************************************************************
narshu 0:7583de124698 146 * PRIVATE FUNCTIONS
narshu 0:7583de124698 147 *********************************************************************/
narshu 0:7583de124698 148
narshu 1:0370ea94b64a 149 // Initialises the RF12B module
narshu 0:7583de124698 150 void RF12B::init() {
narshu 1:0370ea94b64a 151 // writeCmd(0x80E7); //EL,EF,868band,12.0pF
narshu 0:7583de124698 152 changeMode(RX);
narshu 0:7583de124698 153 writeCmd(0xA640); //frequency select
narshu 0:7583de124698 154 writeCmd(0xC647); //4.8kbps
narshu 0:7583de124698 155 writeCmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
narshu 0:7583de124698 156 writeCmd(0xC2AC); //AL,!ml,DIG,DQD4
narshu 0:7583de124698 157 writeCmd(0xCA81); //FIFO8,SYNC,!ff,DR
narshu 0:7583de124698 158 writeCmd(0xCED4); //SYNC=2DD4
narshu 0:7583de124698 159 writeCmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
narshu 0:7583de124698 160 writeCmd(0x9850); //!mp,90kHz,MAX OUT
narshu 0:7583de124698 161 writeCmd(0xCC17); //OB1, COB0, LPX, Iddy, CDDIT&#65533;CBW0
narshu 0:7583de124698 162 writeCmd(0xE000); //NOT USED
narshu 0:7583de124698 163 writeCmd(0xC800); //NOT USED
narshu 1:0370ea94b64a 164 writeCmd(0xC040); //1.66MHz,2.2V
narshu 0:7583de124698 165
narshu 0:7583de124698 166 writeCmd(
narshu 0:7583de124698 167 RFM_CONFIG_EL |
narshu 0:7583de124698 168 RFM_CONFIG_EF |
narshu 0:7583de124698 169 RFM_CONFIG_BAND_433 //|
narshu 0:7583de124698 170 //RFM_CONFIG_X_11_0pf // meh, using default
narshu 0:7583de124698 171 );
narshu 0:7583de124698 172
narshu 0:7583de124698 173 // 2. Power Management Command
narshu 0:7583de124698 174 // leave everything switched off for now
narshu 0:7583de124698 175 /*
narshu 0:7583de124698 176 writeCmd(
narshu 0:7583de124698 177 RFM_POWER_MANAGEMENT // switch all off
narshu 0:7583de124698 178 );
narshu 0:7583de124698 179 */
narshu 0:7583de124698 180
narshu 0:7583de124698 181 // 3. Frequency Setting Command
narshu 0:7583de124698 182 writeCmd(
narshu 0:7583de124698 183 RFM_FREQUENCY |
narshu 0:7583de124698 184 RFM_FREQ_433Band(435.7) //I totally made this value up... if someone knows where the sweetspots are in this band, tell me!
narshu 0:7583de124698 185 );
narshu 0:7583de124698 186
narshu 0:7583de124698 187
narshu 0:7583de124698 188 // 4. Data Rate Command
narshu 0:7583de124698 189 writeCmd(RFM_DATA_RATE_9600);
narshu 0:7583de124698 190
narshu 0:7583de124698 191
narshu 0:7583de124698 192 // 5. Receiver Control Command
narshu 0:7583de124698 193 writeCmd(
narshu 0:7583de124698 194 RFM_RX_CONTROL_P20_VDI |
narshu 0:7583de124698 195 RFM_RX_CONTROL_VDI_FAST |
narshu 0:7583de124698 196 //RFM_RX_CONTROL_BW(RFM_BAUD_RATE) |
narshu 0:7583de124698 197 RFM_RX_CONTROL_BW_134 | // CHANGE THIS TO 67 TO IMPROVE RANGE! (though the bitrate must then be below 8kbaud, and fsk modulation changed)
narshu 0:7583de124698 198 RFM_RX_CONTROL_GAIN_0 |
narshu 0:7583de124698 199 RFM_RX_CONTROL_RSSI_103 // Might need adjustment. Datasheet says around 10^-5 bit error rate at this level and baudrate.
narshu 0:7583de124698 200 );
narshu 0:7583de124698 201
narshu 0:7583de124698 202 // 6. Data Filter Command
narshu 0:7583de124698 203 writeCmd(
narshu 0:7583de124698 204 RFM_DATA_FILTER_AL |
narshu 0:7583de124698 205 RFM_DATA_FILTER_ML |
narshu 0:7583de124698 206 RFM_DATA_FILTER_DIG //|
narshu 0:7583de124698 207 //RFM_DATA_FILTER_DQD(4)
narshu 0:7583de124698 208 );
narshu 0:7583de124698 209
narshu 0:7583de124698 210 // 7. FIFO and Reset Mode Command
narshu 0:7583de124698 211 writeCmd(
narshu 0:7583de124698 212 RFM_FIFO_IT(8) |
narshu 0:7583de124698 213 RFM_FIFO_DR |
narshu 0:7583de124698 214 0x8 //turn on 16bit sync word
narshu 0:7583de124698 215 );
narshu 0:7583de124698 216
narshu 0:7583de124698 217 // 8. FIFO Syncword
narshu 0:7583de124698 218 // Leave as default: 0xD4
narshu 0:7583de124698 219
narshu 0:7583de124698 220 // 9. Receiver FIFO Read
narshu 0:7583de124698 221 // when the interupt goes high, (and if we can assume that it was a fifo fill interrupt) we can read a byte using:
narshu 0:7583de124698 222 // result = RFM_READ_FIFO();
narshu 0:7583de124698 223
narshu 0:7583de124698 224 // 10. AFC Command
narshu 0:7583de124698 225 writeCmd(
narshu 0:7583de124698 226 //RFM_AFC_AUTO_VDI | //Note this might be changed to improve range. Refer to datasheet.
narshu 0:7583de124698 227 RFM_AFC_AUTO_INDEPENDENT |
narshu 0:7583de124698 228 RFM_AFC_RANGE_LIMIT_7_8 |
narshu 0:7583de124698 229 RFM_AFC_EN |
narshu 0:7583de124698 230 RFM_AFC_OE |
narshu 0:7583de124698 231 RFM_AFC_FI
narshu 0:7583de124698 232 );
narshu 0:7583de124698 233
narshu 0:7583de124698 234 // 11. TX Configuration Control Command
narshu 0:7583de124698 235 writeCmd(
narshu 0:7583de124698 236 RFM_TX_CONTROL_MOD_60 |
narshu 0:7583de124698 237 RFM_TX_CONTROL_POW_0
narshu 0:7583de124698 238 );
narshu 0:7583de124698 239
narshu 0:7583de124698 240
narshu 0:7583de124698 241 // 12. PLL Setting Command
narshu 0:7583de124698 242 writeCmd(
narshu 0:7583de124698 243 0xCC77 & ~0x01 // Setting the PLL bandwith, less noise, but max bitrate capped at 86.2
narshu 0:7583de124698 244 // I think this will slow down the pll's reaction time. Not sure, check with someone!
narshu 0:7583de124698 245 );
narshu 0:7583de124698 246
narshu 0:7583de124698 247 changeMode(RX);
narshu 0:7583de124698 248 resetRX();
narshu 0:7583de124698 249 status();
narshu 0:7583de124698 250 }
narshu 0:7583de124698 251
narshu 0:7583de124698 252 /* Write a command to the RF Module */
narshu 0:7583de124698 253 unsigned int RF12B::writeCmd(unsigned int cmd) {
narshu 0:7583de124698 254 NCS = 0;
narshu 0:7583de124698 255 unsigned int recv = spi.write(cmd);
narshu 0:7583de124698 256 NCS = 1;
narshu 0:7583de124698 257 return recv;
narshu 0:7583de124698 258 }
narshu 0:7583de124698 259
narshu 0:7583de124698 260 /* Sends a byte of data across RF */
narshu 0:7583de124698 261 void RF12B::send(unsigned char data) {
narshu 0:7583de124698 262 while (NIRQ);
narshu 0:7583de124698 263 writeCmd(0xB800 + data);
narshu 0:7583de124698 264 }
narshu 0:7583de124698 265
narshu 0:7583de124698 266 /* Change the mode of the RF module to Transmitting or Receiving */
narshu 0:7583de124698 267 void RF12B::changeMode(rfmode_t _mode) {
narshu 0:7583de124698 268 mode = _mode;
narshu 0:7583de124698 269 if (_mode == TX) {
narshu 0:7583de124698 270 writeCmd(0x8239); //!er,!ebb,ET,ES,EX,!eb,!ew,DC
narshu 0:7583de124698 271 } else { /* mode == RX */
narshu 0:7583de124698 272 writeCmd(0x8299); //er,!ebb,ET,ES,EX,!eb,!ew,DC
narshu 0:7583de124698 273 }
narshu 0:7583de124698 274 }
narshu 0:7583de124698 275
narshu 1:0370ea94b64a 276 // Interrupt routine for data reception */
narshu 0:7583de124698 277 void RF12B::rxISR() {
narshu 0:7583de124698 278
narshu 0:7583de124698 279 unsigned int data = 0;
narshu 0:7583de124698 280 static int i = -2;
narshu 0:7583de124698 281 static unsigned char packet_length = 0;
narshu 0:7583de124698 282 static unsigned char crc = 0;
narshu 1:0370ea94b64a 283 static unsigned char temp;
narshu 0:7583de124698 284
narshu 0:7583de124698 285 //Loop while interrupt is asserted
narshu 0:7583de124698 286 while (!NIRQ_in && mode == RX) {
narshu 1:0370ea94b64a 287
narshu 0:7583de124698 288 // Grab the packet's length byte
narshu 0:7583de124698 289 if (i == -2) {
narshu 0:7583de124698 290 data = writeCmd(0x0000);
narshu 0:7583de124698 291 if ( (data&0x8000) ) {
narshu 0:7583de124698 292 data = writeCmd(0xB000);
narshu 0:7583de124698 293 packet_length = (data&0x00FF);
narshu 0:7583de124698 294 crc = crc8(crc, packet_length);
narshu 0:7583de124698 295 i++;
narshu 0:7583de124698 296 }
narshu 0:7583de124698 297 }
narshu 0:7583de124698 298
narshu 0:7583de124698 299 //If we exhaust the interrupt, exit
narshu 0:7583de124698 300 if (NIRQ_in)
narshu 0:7583de124698 301 break;
narshu 0:7583de124698 302
narshu 0:7583de124698 303 // Check that packet length was correct
narshu 0:7583de124698 304 if (i == -1) {
narshu 0:7583de124698 305 data = writeCmd(0x0000);
narshu 0:7583de124698 306 if ( (data&0x8000) ) {
narshu 0:7583de124698 307 data = writeCmd(0xB000);
narshu 0:7583de124698 308 unsigned char crcofsize = (data&0x00FF);
narshu 0:7583de124698 309 if (crcofsize != crc) {
narshu 0:7583de124698 310 //It was wrong, start over
narshu 0:7583de124698 311 i = -2;
narshu 0:7583de124698 312 packet_length = 0;
narshu 0:7583de124698 313 crc = 0;
narshu 0:7583de124698 314 //temp = queue<unsigned char>();
narshu 0:7583de124698 315 resetRX();
narshu 0:7583de124698 316 } else {
narshu 0:7583de124698 317 crc = crc8(crc, crcofsize);
narshu 0:7583de124698 318 i++;
narshu 0:7583de124698 319 }
narshu 0:7583de124698 320 }
narshu 0:7583de124698 321 }
narshu 0:7583de124698 322
narshu 0:7583de124698 323 //If we exhaust the interrupt, exit
narshu 0:7583de124698 324 if (NIRQ_in)
narshu 0:7583de124698 325 break;
narshu 0:7583de124698 326
narshu 1:0370ea94b64a 327 // Grab the packet's data
narshu 0:7583de124698 328 if (i >= 0 && i < packet_length) {
narshu 0:7583de124698 329 data = writeCmd(0x0000);
narshu 0:7583de124698 330 if ( (data&0x8000) ) {
narshu 0:7583de124698 331 data = writeCmd(0xB000);
narshu 1:0370ea94b64a 332 temp = data&0x00FF;
narshu 0:7583de124698 333 //temp.push(data&0x00FF);
narshu 0:7583de124698 334 crc = crc8(crc, (unsigned char)(data&0x00FF));
narshu 0:7583de124698 335 i++;
narshu 0:7583de124698 336 }
narshu 0:7583de124698 337 }
narshu 0:7583de124698 338
narshu 0:7583de124698 339 //If we exhaust the interrupt, exit
narshu 0:7583de124698 340 if (NIRQ_in)
narshu 0:7583de124698 341 break;
narshu 0:7583de124698 342
narshu 0:7583de124698 343 if (i >= packet_length) {
narshu 0:7583de124698 344 data = writeCmd(0x0000);
narshu 0:7583de124698 345 if ( (data&0x8000) ) {
narshu 0:7583de124698 346 data = writeCmd(0xB000);
narshu 0:7583de124698 347 if ((unsigned char)(data & 0x00FF) == crc) {
narshu 0:7583de124698 348 //If the checksum is correct, add our data to the end of the output buffer
narshu 0:7583de124698 349 //while (!temp.empty()) {
narshu 1:0370ea94b64a 350 //fifo.push(temp);
narshu 1:0370ea94b64a 351 // temp.pop();
narshu 1:0370ea94b64a 352 #ifdef ROBOT_SECONDARY
narshu 1:0370ea94b64a 353 if (callbackfunc)
narshu 1:0370ea94b64a 354 (*callbackfunc)(temp);
narshu 1:0370ea94b64a 355
narshu 1:0370ea94b64a 356 if (callbackobj && mcallbackfunc)
narshu 1:0370ea94b64a 357 (callbackobj->*mcallbackfunc)(temp);
narshu 1:0370ea94b64a 358 #endif
narshu 1:0370ea94b64a 359 // }
narshu 0:7583de124698 360 }
narshu 0:7583de124698 361
narshu 0:7583de124698 362 // Tell RF Module we are finished, and clean up
narshu 0:7583de124698 363 i = -2;
narshu 0:7583de124698 364 packet_length = 0;
narshu 0:7583de124698 365 crc = 0;
narshu 0:7583de124698 366 //temp = queue<unsigned char>();
narshu 0:7583de124698 367 resetRX();
narshu 0:7583de124698 368 }
narshu 0:7583de124698 369 }
narshu 0:7583de124698 370 }
narshu 1:0370ea94b64a 371
narshu 0:7583de124698 372 }
narshu 0:7583de124698 373
narshu 0:7583de124698 374 unsigned int RF12B::status() {
narshu 0:7583de124698 375 return writeCmd(0x0000);
narshu 0:7583de124698 376 }
narshu 0:7583de124698 377
narshu 1:0370ea94b64a 378 // Tell the RF Module this packet is received and wait for the next */
narshu 0:7583de124698 379 void RF12B::resetRX() {
narshu 0:7583de124698 380 writeCmd(0xCA81);
narshu 0:7583de124698 381 writeCmd(0xCA83);
narshu 0:7583de124698 382 };
narshu 0:7583de124698 383
narshu 1:0370ea94b64a 384 // Calculate CRC8 */
narshu 0:7583de124698 385 unsigned char RF12B::crc8(unsigned char crc, unsigned char data) {
narshu 0:7583de124698 386 crc = crc ^ data;
narshu 0:7583de124698 387 for (int i = 0; i < 8; i++) {
narshu 0:7583de124698 388 if (crc & 0x01) {
narshu 0:7583de124698 389 crc = (crc >> 1) ^ 0x8C;
narshu 0:7583de124698 390 } else {
narshu 0:7583de124698 391 crc >>= 1;
narshu 0:7583de124698 392 }
narshu 0:7583de124698 393 }
narshu 0:7583de124698 394 return crc;
narshu 0:7583de124698 395 }