Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RF12B.cpp Source File

RF12B.cpp

00001 /* RF12B Library. Based on work done by JeeLabs.org ported to mbed by SK Pang.
00002 http://jeelabs.net/projects/cafe/wiki/RF12
00003 
00004 http://opensource.org/licenses/mit-license.php
00005 
00006 Jan 2012 skpang.co.uk
00007 
00008 */
00009 
00010 #include "RF12B.h"
00011 
00012 // RF12 command codes
00013 #define RF_RECEIVER_ON  0x82DD
00014 #define RF_XMITTER_ON   0x823D
00015 #define RF_IDLE_MODE    0x820D
00016 #define RF_SLEEP_MODE   0x8205
00017 #define RF_WAKEUP_MODE  0x8207
00018 #define RF_TXREG_WRITE  0xB800
00019 #define RF_RX_FIFO_READ 0xB000
00020 #define RF_WAKEUP_TIMER 0xE000
00021 
00022 // RF12 status bits
00023 #define RF_LBD_BIT      0x0400
00024 #define RF_RSSI_BIT     0x0100
00025 
00026 // bits in the node id configuration byte
00027 #define NODE_BAND       0xC0        // frequency band
00028 #define NODE_ACKANY     0x20        // ack on broadcast packets if set
00029 #define NODE_ID         0x1F        // id of this node, as A..Z or 1..31
00030 
00031 // transceiver states, these determine what to do with each interrupt
00032 enum {
00033     TXCRC1, TXCRC2, TXTAIL, TXDONE, TXIDLE,
00034     TXRECV,
00035     TXPRE1, TXPRE2, TXPRE3, TXSYN1, TXSYN2,
00036 };
00037 
00038 //DigitalOut rfled(LED3);
00039 
00040 
00041 RF12B::RF12B(PinName _SDI,
00042              PinName _SDO,
00043              PinName _SCK,
00044              PinName _NCS,
00045              PinName _NIRQ):spi(_SDI, _SDO, _SCK),
00046         NCS(_NCS), NIRQ(_NIRQ), NIRQ_in(_NIRQ) {
00047 
00048     /* SPI frequency, word lenght, polarity and phase */
00049     spi.format(8,0);
00050     spi.frequency(2000000);
00051 
00052     /* Set ~CS high */
00053     NCS = 1;
00054 
00055     /* Setup interrupt to happen on falling edge of NIRQ */
00056     NIRQ.fall(this, &RF12B::rxISR);
00057 }
00058 
00059 
00060 /**********************************************************************
00061  *  PRIVATE FUNCTIONS
00062  *********************************************************************/
00063 
00064 /* Initialises the RF12B module */
00065 void RF12B::init(uint8_t id, uint8_t band, uint8_t g) {
00066   
00067     nodeid = id;
00068     group = g;
00069     rf12_grp = g; 
00070     
00071     writeCmd(0x0000); // intitial SPI transfer added to avoid power-up problem
00072     writeCmd(RF_SLEEP_MODE); // DC (disable clk pin), enable lbd
00073     
00074     // wait until RFM12B is out of power-up reset, this takes several *seconds*
00075     writeCmd(RF_TXREG_WRITE); // in case we're still in OOK mode
00076       
00077     while (NIRQ == 0)  writeCmd(0x0000);
00078         
00079     writeCmd(0x80C7 | (2 << 4)); // EL (ena TX), EF (ena RX FIFO), 12.0pF 
00080     writeCmd(0xA640); // 868MHz 
00081     writeCmd(0xC606); // approx 49.2 Kbps, i.e. 10000/29/(1+6) Kbps
00082     writeCmd(0x94A2); // VDI,FAST,134kHz,0dBm,-91dBm 
00083     writeCmd(0xC2AC); // AL,!ml,DIG,DQD4 
00084    
00085     writeCmd(0xCA83); // FIFO8,2-SYNC,!ff,DR 
00086     writeCmd(0xCE00 | group); // SYNC=2DXX&#65307; 
00087     
00088     writeCmd(0xC483); // @PWR,NO RSTRIC,!st,!fi,OE,EN 
00089     writeCmd(0x9850); // !mp,90kHz,MAX OUT 
00090     writeCmd(0xCC77); // OB1&#65292;OB0, LPX,&#65281;ddy&#65292;DDIT&#65292;BW0 
00091     writeCmd(0xE000); // NOT USE 
00092     writeCmd(0xC800); // NOT USE 
00093     writeCmd(0xC049); // 1.66MHz,3.1V 
00094 
00095     rxstate = TXIDLE;
00096        
00097  
00098 }
00099 
00100 /* Write a command to the RF Module */
00101 unsigned int RF12B::writeCmd(unsigned int cmd) {
00102     NCS = 0;
00103     unsigned int recv = spi.write(cmd >>8);
00104     recv = spi.write(cmd);
00105     NCS = 1;
00106     return recv;
00107 }
00108 
00109 /* Sends a byte of data across RF */
00110 void RF12B::send(unsigned char data) {
00111    while (NIRQ);
00112    writeCmd(0xB800 + data);
00113 }
00114 
00115 
00116 /* Interrupt routine for data reception and Txing */
00117 void RF12B::rxISR() {
00118 
00119    // a transfer of 2x 16 bits @ 2 MHz over SPI takes 2x 8 us inside this ISR
00120     writeCmd(0x0000);
00121     
00122     if (rxstate == TXRECV) {
00123         uint8_t in = rf12_xfer(RF_RX_FIFO_READ);
00124 
00125         if (rxfill == 0 && group != 0)
00126             rf12_buf[rxfill++] = group;
00127             
00128         rf12_buf[rxfill++] = in;
00129         rf12_crc = _crc16_update(rf12_crc, in);
00130 
00131         if (rxfill >= rf12_len + 5 || rxfill >= RF_MAX)
00132             rf12_xfer(RF_IDLE_MODE);
00133     } else {
00134         uint8_t out;
00135 
00136         if (rxstate < 0) {
00137             uint8_t pos = 3 + rf12_len + rxstate++;
00138             out = rf12_buf[pos];
00139             rf12_crc = _crc16_update(rf12_crc, out);
00140         } else
00141             switch (rxstate++) {
00142                 case TXSYN1: out = 0x2D; break;
00143                 case TXSYN2: out = rf12_grp; rxstate = - (2 + rf12_len); break;
00144                 case TXCRC1: out = rf12_crc; break;
00145                 case TXCRC2: out = rf12_crc >> 8; break;
00146                 case TXDONE: rf12_xfer(RF_IDLE_MODE); // fall through
00147                 default: out = 0xAA;
00148             }
00149        
00150         rf12_xfer(RF_TXREG_WRITE + out);
00151     }
00152  }
00153 
00154 
00155 void RF12B::rf12_sendStart (uint8_t hdr, const void* ptr, uint8_t len)
00156 {
00157     rf12_len = len;
00158     memcpy((void*) rf12_data, ptr, len);
00159   
00160     rf12_sendStart2(hdr);
00161 
00162 }
00163 void RF12B::rf12_sendStart2 (uint8_t hdr) {
00164     rf12_hdr = hdr & RF12_HDR_DST ? hdr :
00165                 (hdr & ~RF12_HDR_MASK) + (nodeid & NODE_ID);
00166  
00167  /*   if (crypter != 0)
00168         crypter(1);
00169  */   
00170     rf12_crc = ~0;
00171 
00172     rf12_crc = _crc16_update(rf12_crc, rf12_grp);
00173     rxstate = TXPRE1;
00174       
00175     rf12_xfer(RF_XMITTER_ON); // bytes will be fed via interrupts
00176 }
00177 
00178 
00179  uint16_t RF12B::rf12_xfer (uint16_t cmd) {
00180     NCS = 0;
00181     uint16_t reply = rf12_byte(cmd >> 8) << 8;
00182     reply |= rf12_byte(cmd);
00183     NCS = 1;
00184     return reply;
00185 }
00186 
00187  void RF12B::rf12_recvStart (void) {
00188     rxfill = rf12_len = 0;
00189     rf12_crc = ~0;
00190 
00191     if (group != 0)
00192         rf12_crc = _crc16_update(~0, group);
00193 
00194     rxstate = TXRECV;    
00195     rf12_xfer(RF_RECEIVER_ON);
00196 }
00197 uint16_t RF12B::check_crc(void)
00198 {
00199 
00200     return rf12_crc;
00201 }
00202 uint8_t RF12B::length(void)
00203 {
00204 
00205     return rf12_len;
00206 }
00207  uint8_t* RF12B::get_data(void)
00208 {
00209     return  (uint8_t*)rf12_data;
00210 
00211 }
00212  uint8_t RF12B::get_hdr(void)
00213 {
00214     return rf12_hdr;
00215 
00216 }
00217 
00218 
00219 uint8_t  RF12B::rf12_recvDone (void) {
00220     
00221      if (rxstate == TXRECV && (rxfill >= rf12_len + 5 || rxfill >= RF_MAX)) {
00222         rxstate = TXIDLE;
00223  
00224         if (rf12_len > RF12_MAXDATA)
00225             rf12_crc = 1; // force bad crc if packet length is invalid
00226         if (!(rf12_hdr & RF12_HDR_DST) || (nodeid & NODE_ID) == 31 ||
00227                 (rf12_hdr & RF12_HDR_MASK) == (nodeid & NODE_ID)) {
00228                 /*
00229                 for(i=0;i<rf12_len+6;i++)
00230                 {
00231                     printf("%X ",rf12_buf[i]);
00232                 }
00233                 printf(" crc:%x",rf12_crc);
00234                 */
00235            /*     
00236             if (rf12_crc == 0 && crypter != 0)
00237                 crypter(0);
00238             else
00239                 rf12_seq = -1;
00240                  */
00241             return 1; // it's a broadcast packet or it's addressed to this node
00242            
00243         }
00244     }
00245     if (rxstate == TXIDLE)
00246         rf12_recvStart();
00247     return 0;
00248 }
00249 
00250 uint8_t RF12B::rf12_byte(uint8_t out)
00251 {
00252   unsigned char recv = spi.write(out);
00253  
00254     return recv;
00255 }
00256  
00257 uint16_t RF12B::_crc16_update(uint16_t crc, uint8_t data) {
00258     int i;
00259 
00260     crc ^= data;
00261     for (i = 0; i < 8; ++i)
00262     {
00263         if (crc & 1)
00264         crc = (crc >> 1) ^ 0xA001;
00265         else
00266         crc = (crc >> 1);
00267     }
00268 
00269     return crc;
00270 }
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280