Embed:
(wiki syntax)
Show/hide line numbers
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; 00087 00088 writeCmd(0xC483); // @PWR,NO RSTRIC,!st,!fi,OE,EN 00089 writeCmd(0x9850); // !mp,90kHz,MAX OUT 00090 writeCmd(0xCC77); // OB1,OB0, LPX,!ddy,DDIT,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
Generated on Fri Jul 15 2022 11:46:03 by 1.7.2