Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of CC1101_Transceiver by
CC1101.cpp
00001 00002 #include "CC1101.h" 00003 00004 #define RF_0db 00005 //#define RF_10db 00006 /////////////////////////////////////////////////////////////////////////////////////// 00007 CC1101::CC1101(PinName mosi, PinName miso, PinName clk, PinName csn, PinName RDmiso): 00008 _spi(mosi, miso, clk), _csn(csn), _RDmiso(RDmiso) 00009 { 00010 _csn = 1; 00011 00012 // Setup the spi for 8 bit data, high steady state clock, 00013 // second edge capture, with a 1MHz clock rate 00014 _spi.format(8,0); 00015 _spi.frequency(1000000); 00016 00017 POWER_UP_RESET_CCxxx0(); 00018 Strobe(CCxxx0_SRX); 00019 } 00020 /////////////////////////////////////////////////////////////////////////////////////// 00021 RF_SETTINGS rfSettings = // 433Mhz, 9600Bauds 00022 { 00023 0x06, // FSCTRL1 Frequency Synthesizer Control - IF:152.343Khz 00024 0x07, // IOCFG0 GDO0 Output Pin Configuration - Packet received and CRC OK 00025 0x00, // FSCTRL0 Frequency Synthesizer Control - Freq offset 00026 0x10, // FREQ2 Frequency Control Word, High Byte - 433.999 Mhz 00027 0xB1, // FREQ1 Frequency Control Word, Middle Byte 00028 0x3B, // FREQ0 Frequency Control Word, Low Byte 00029 0xF8, // MDMCFG4 Modem Configuration - BW: 58.035Khz 00030 0x83, // MDMCFG3 Modem Configuration - 9595 Baud 00031 0x13, // MDMCFG2 Modem Configuration - 30/32 sync word bits - Manchester disable - GFSK - Digital DC filter enable 00032 0x22, // MDMCFG1 Modem Configuration - num of preamble bytes:4 - FEC disable 00033 0xF8, // MDMCFG0 Modem Configuration - Channel spacing: 199.951Khz 00034 0x00, // CHANNR Channel Number 00035 0x15, // DEVIATN Modem Deviation Setting - 5.157Khz 00036 0x56, // FREND1 Front End RX Configuration 00037 0x10, // FREND0 Front End TX Configuration 00038 0x18, // MCSM0 Main Radio Control State Machine Configuration - PO timeout: 64(149-155us) - Auto calibrate from idle to rx/tx 00039 0x16, // FOCCFG Frequency Offset Compensation Configuration 00040 0x6C, // BSCFG Bit Synchronization Configuration 00041 0x03, // AGCCTRL2 AGC Control - target amplitude: 33dB - Maximum possible LNA + LNA 2 gain - All gain settings can be used 00042 0x40, // AGCCTRL1 AGC Control - LNA gain decreased first 00043 0x91, // AGCCTRL0 AGC Control - Medium hysterisis - Filter Samples: 16 - Normal AGC operation 00044 0xE9, // FSCAL3 Frequency Synthesizer Calibration 00045 0x2A, // FSCAL2 Frequency Synthesizer Calibration 00046 0x00, // FSCAL1 Frequency Synthesizer Calibration 00047 0x1F, // FSCAL0 Frequency Synthesizer Calibration 00048 0x59, // FSTEST Frequency Synthesizer Calibration Control 00049 0x88, // TEST2 Various Test Settings 00050 0x31, // TEST1 Various Test Settings 00051 0x09, // TEST0 Various Test Settings 00052 0x07, // FIFOTHR RX FIFO and TX FIFO Thresholds - Bytes in TX FIFO:33 - Bytes in RX FIFO:32 00053 0x06, // IOCFG2 GDO2 Output Pin Configuration - Sync word received/sent - end of packet 00054 0x04, // PKTCTRL1 Packet Automation Control - No address check - Automatic flush of RX FIFO is disable - sync word is always accepted 00055 0x05, // PKTCTRL0 Packet Automation Control - whitening is off - RX/TX data normal mode - CRC calculation in TX and CRC check in RX - Variable packet length 00056 0x00, // ADDR Device Address 00057 0xFF, // PKTLEN Packet Length 00058 0x3F, // MCSM1 Main Radio Control State Machine Configuration 00059 }; 00060 #ifdef RF_0db 00061 // PATABLE (0 dBm output power) 00062 char paTable[] = {0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 00063 #endif 00064 #ifdef RF_10db 00065 // PATABLE (10 dBm output power) 00066 char paTable[] = {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 00067 #endif 00068 /////////////////////////////////////////////////////////////////////////////////////// 00069 /////////////////////////////////////////////////////////////////////////////////////// 00070 // Macro to reset the CCxxx0 and wait for it to be ready 00071 void CC1101::RESET_CCxxx0(void) 00072 { 00073 // while (_RDmiso); 00074 _csn = 0; 00075 wait(0.000002); 00076 while (_RDmiso); 00077 _spi.write(CCxxx0_SRES); 00078 wait(0.000002); 00079 _csn = 1; 00080 } 00081 /////////////////////////////////////////////////////////////////////////////////////// 00082 // Macro to reset the CCxxx0 after power_on and wait for it to be ready 00083 // IMPORTANT NOTICE: 00084 // The file Wait.c must be included if this macro shall be used 00085 // The file is located under: ..\Lib\Chipcon\Hal\CCxx00 00086 // 00087 // min 40 us 00088 // <-----------------------> 00089 // CSn |--| |--------------------| |----------- 00090 // | | | | | 00091 // -- ---------- 00092 // 00093 // MISO |--------------- 00094 // - - - - - - - - - - - - - - - -| | 00095 // -- 00096 // Unknown / don't care 00097 // 00098 // MOSI - - - - - - - - - - - - - - - ---------- - - - - - 00099 // | SRES | 00100 // - - - - - - - - - - - - - - - ---------- - - - - - 00101 // 00102 void CC1101::POWER_UP_RESET_CCxxx0(void) 00103 { 00104 _csn = 1; 00105 wait(1e-6); 00106 _csn = 0; 00107 wait(1e-6); 00108 _csn = 1; 00109 wait(41e-6); 00110 RESET_CCxxx0(); 00111 } 00112 /////////////////////////////////////////////////////////////////////////////////////// 00113 // void Strobe(unsigned char strobe) 00114 // 00115 // DESCRIPTION: 00116 // Function for writing a strobe command to the CCxxx0 00117 // 00118 // ARGUMENTS: 00119 // unsigned char strobe 00120 // Strobe command 00121 /////////////////////////////////////////////////////////////////////////////////////// 00122 unsigned char CC1101::Strobe(unsigned char strobe) 00123 { 00124 unsigned char x; 00125 wait(0.000005); 00126 _csn = 0; 00127 wait(0.000002); 00128 while (_RDmiso); 00129 x = _spi.write(strobe); 00130 wait(0.000002); 00131 _csn = 1; 00132 return x; 00133 }// Strobe 00134 /////////////////////////////////////////////////////////////////////////////////////// 00135 // unsigned char ReadStatus(unsigned char addr) 00136 // 00137 // DESCRIPTION: 00138 // This function reads a CCxxx0 status register. 00139 // 00140 // ARGUMENTS: 00141 // unsigned char addr 00142 // Address of the CCxxx0 status register to be accessed. 00143 // 00144 // RETURN VALUE: 00145 // unsigned char 00146 // Value of the accessed CCxxx0 status register. 00147 /////////////////////////////////////////////////////////////////////////////////////// 00148 unsigned char CC1101::ReadStatus(unsigned char addr) 00149 { 00150 unsigned char x; 00151 wait(0.000005); 00152 _csn = 0; 00153 wait(0.000002); 00154 while (_RDmiso); 00155 _spi.write(addr | READ_BURST); 00156 x = _spi.write(0); 00157 wait(0.000002); 00158 _csn = 1; 00159 return x; 00160 }// ReadStatus 00161 /////////////////////////////////////////////////////////////////////////////////////// 00162 // void WriteRfSettings(RF_SETTINGS *pRfSettings) 00163 // 00164 // DESCRIPTION: 00165 // This function is used to configure the CCxxx0 based on a given rf setting 00166 // 00167 // ARGUMENTS: 00168 // RF_SETTINGS *pRfSettings 00169 // Pointer to a struct containing rf register settings 00170 /////////////////////////////////////////////////////////////////////////////////////// 00171 void CC1101::WriteRfSettings(RF_SETTINGS *pRfSettings) 00172 { 00173 // Write register settings 00174 WriteReg(CCxxx0_FSCTRL1, pRfSettings->FSCTRL1); 00175 WriteReg(CCxxx0_FSCTRL0, pRfSettings->FSCTRL0); 00176 WriteReg(CCxxx0_FREQ2, pRfSettings->FREQ2); 00177 WriteReg(CCxxx0_FREQ1, pRfSettings->FREQ1); 00178 WriteReg(CCxxx0_FREQ0, pRfSettings->FREQ0); 00179 WriteReg(CCxxx0_MDMCFG4, pRfSettings->MDMCFG4); 00180 WriteReg(CCxxx0_MDMCFG3, pRfSettings->MDMCFG3); 00181 WriteReg(CCxxx0_MDMCFG2, pRfSettings->MDMCFG2); 00182 WriteReg(CCxxx0_MDMCFG1, pRfSettings->MDMCFG1); 00183 WriteReg(CCxxx0_MDMCFG0, pRfSettings->MDMCFG0); 00184 WriteReg(CCxxx0_CHANNR, pRfSettings->CHANNR); 00185 WriteReg(CCxxx0_DEVIATN, pRfSettings->DEVIATN); 00186 WriteReg(CCxxx0_FREND1, pRfSettings->FREND1); 00187 WriteReg(CCxxx0_FREND0, pRfSettings->FREND0); 00188 WriteReg(CCxxx0_MCSM0 , pRfSettings->MCSM0 ); 00189 WriteReg(CCxxx0_FOCCFG, pRfSettings->FOCCFG); 00190 WriteReg(CCxxx0_BSCFG, pRfSettings->BSCFG); 00191 WriteReg(CCxxx0_AGCCTRL2, pRfSettings->AGCCTRL2); 00192 WriteReg(CCxxx0_AGCCTRL1, pRfSettings->AGCCTRL1); 00193 WriteReg(CCxxx0_AGCCTRL0, pRfSettings->AGCCTRL0); 00194 WriteReg(CCxxx0_FSCAL3, pRfSettings->FSCAL3); 00195 WriteReg(CCxxx0_FSCAL2, pRfSettings->FSCAL2); 00196 WriteReg(CCxxx0_FSCAL1, pRfSettings->FSCAL1); 00197 WriteReg(CCxxx0_FSCAL0, pRfSettings->FSCAL0); 00198 WriteReg(CCxxx0_FSTEST, pRfSettings->FSTEST); 00199 WriteReg(CCxxx0_TEST2, pRfSettings->TEST2); 00200 WriteReg(CCxxx0_TEST1, pRfSettings->TEST1); 00201 WriteReg(CCxxx0_TEST0, pRfSettings->TEST0); 00202 WriteReg(CCxxx0_FIFOTHR, pRfSettings->FIFOTHR); 00203 WriteReg(CCxxx0_IOCFG2, pRfSettings->IOCFG2); 00204 WriteReg(CCxxx0_IOCFG0, pRfSettings->IOCFG0); 00205 WriteReg(CCxxx0_PKTCTRL1, pRfSettings->PKTCTRL1); 00206 WriteReg(CCxxx0_PKTCTRL0, pRfSettings->PKTCTRL0); 00207 WriteReg(CCxxx0_ADDR, pRfSettings->ADDR); 00208 WriteReg(CCxxx0_PKTLEN, pRfSettings->PKTLEN); 00209 WriteReg(CCxxx0_MCSM1 , pRfSettings->MCSM1 ); 00210 RXMode(); 00211 00212 }// WriteRfSettings 00213 /////////////////////////////////////////////////////////////////////////////////////// 00214 void CC1101::init(void) 00215 { 00216 WriteRfSettings(&rfSettings); 00217 WriteReg(CCxxx0_PATABLE, paTable[0]); 00218 } 00219 /////////////////////////////////////////////////////////////////////////////////////// 00220 // unsigned char ReadReg(unsigned char addr) 00221 // 00222 // DESCRIPTION: 00223 // This function gets the value of a single specified CCxxx0 register. 00224 // 00225 // ARGUMENTS: 00226 // unsigned char addr 00227 // Address of the CCxxx0 register to be accessed. 00228 // 00229 // RETURN VALUE: 00230 // unsigned char 00231 // Value of the accessed CCxxx0 register. 00232 /////////////////////////////////////////////////////////////////////////////////////// 00233 unsigned char CC1101::ReadReg(unsigned char addr) 00234 { 00235 unsigned char x; 00236 wait(0.000005); 00237 _csn = 0; 00238 wait(0.000002); 00239 while (_RDmiso); 00240 _spi.write(addr | READ_SINGLE); 00241 x = _spi.write(0); 00242 wait(0.000002); 00243 _csn = 1; 00244 return x; 00245 }// ReadReg 00246 /////////////////////////////////////////////////////////////////////////////////////// 00247 // void ReadBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count) 00248 // 00249 // DESCRIPTION: 00250 // This function reads multiple CCxxx0 register, using SPI burst access. 00251 // 00252 // ARGUMENTS: 00253 // unsigned char addr 00254 // Address of the first CCxxx0 register to be accessed. 00255 // unsigned char *buffer 00256 // Pointer to a byte array which stores the values read from a 00257 // corresponding range of CCxxx0 registers. 00258 // unsigned char count 00259 // Number of bytes to be read from the subsequent CCxxx0 registers. 00260 /////////////////////////////////////////////////////////////////////////////////////// 00261 void CC1101::ReadBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count) 00262 { 00263 unsigned char i; 00264 wait(0.000005); 00265 _csn = 0; 00266 wait(0.000002); 00267 while (_RDmiso); 00268 _spi.write(addr | READ_BURST); 00269 for (i = 0; i < count; i++) 00270 { 00271 buffer[i] = _spi.write(0); 00272 } 00273 wait(0.000002); 00274 _csn = 1; 00275 }// ReadBurstReg 00276 /////////////////////////////////////////////////////////////////////////////////////// 00277 // void WriteReg(unsigned char addr, unsigned char value) 00278 // 00279 // DESCRIPTION: 00280 // Function for writing to a single CCxxx0 register 00281 // 00282 // ARGUMENTS: 00283 // unsigned char addr 00284 // Address of a specific CCxxx0 register to accessed. 00285 // unsigned char value 00286 // Value to be written to the specified CCxxx0 register. 00287 /////////////////////////////////////////////////////////////////////////////////////// 00288 void CC1101::WriteReg(unsigned char addr, unsigned char value) 00289 { 00290 wait(0.000005); 00291 _csn = 0; 00292 wait(0.000002); 00293 while (_RDmiso); 00294 _spi.write(addr); 00295 _spi.write(value); 00296 wait(0.000002); 00297 _csn = 1; 00298 }// WriteReg 00299 /////////////////////////////////////////////////////////////////////////////////////// 00300 // void WriteBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count) 00301 // 00302 // DESCRIPTION: 00303 // This function writes to multiple CCxxx0 register, using SPI burst access. 00304 // 00305 // ARGUMENTS: 00306 // unsigned char addr 00307 // Address of the first CCxxx0 register to be accessed. 00308 // unsigned char *buffer 00309 // Array of bytes to be written into a corresponding range of 00310 // CCxx00 registers, starting by the address specified in _addr_. 00311 // unsigned char count 00312 // Number of bytes to be written to the subsequent CCxxx0 registers. 00313 /////////////////////////////////////////////////////////////////////////////////////// 00314 void CC1101::WriteBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count) 00315 { 00316 unsigned char i; 00317 wait(0.000005); 00318 _csn = 0; 00319 wait(0.000002); 00320 while (_RDmiso); 00321 _spi.write(addr | WRITE_BURST); 00322 for (i = 0; i < count; i++) 00323 { 00324 _spi.write(buffer[i]); 00325 } 00326 wait(0.000002); 00327 _csn = 1; 00328 }// WriteBurstReg 00329 /////////////////////////////////////////////////////////////////////////////////////// 00330 unsigned char CC1101::RdRSSI(void) 00331 { 00332 unsigned char crssi; 00333 00334 00335 if (rssi >= 128) 00336 { 00337 crssi = 255 - rssi; 00338 crssi /= 2; 00339 crssi += 74; 00340 } 00341 else 00342 { 00343 crssi = rssi/2; 00344 crssi += 74; 00345 } 00346 return crssi; 00347 } 00348 /////////////////////////////////////////////////////////////////////////////////////// 00349 unsigned char CC1101::RdLQI(void) 00350 { 00351 unsigned char clqi; 00352 clqi = 0x3F - (lqi & 0x3F); 00353 00354 return clqi; 00355 } 00356 /////////////////////////////////////////////////////////////////////////////////////// 00357 unsigned char CC1101::RxFifoEmpty(void) 00358 { 00359 unsigned char RxFifoStatus; 00360 00361 Strobe(CCxxx0_SRX); 00362 RxFifoStatus = ReadStatus(CCxxx0_RXBYTES); 00363 00364 if (RxFifoStatus & 0x80) // check for RXFIFO overflow 00365 { 00366 // Make sure that the radio is in IDLE state before flushing the FIFO 00367 // (Unless RXOFF_MODE has been changed, the radio should be in IDLE state at this point) 00368 Strobe(CCxxx0_SIDLE); 00369 00370 // Flush RX FIFO 00371 Strobe(CCxxx0_SFRX); 00372 } 00373 if (RxFifoStatus & ~0x80) 00374 { 00375 return 0; 00376 } 00377 else 00378 return 1; 00379 } 00380 /////////////////////////////////////////////////////////////////////////////////////// 00381 //------------------------------------------------------------------------------------------------------- 00382 // BOOL ReceivePacket(unsigned char *rxBuffer, unsigned char *length) 00383 // 00384 // DESCRIPTION: 00385 // This function can be used to receive a packet of variable packet length (first byte in the packet 00386 // must be the length byte). The packet length should not exceed the RX FIFO size. 00387 // 00388 // ARGUMENTS: 00389 // unsigned char *rxBuffer 00390 // Pointer to the buffer where the incoming data should be stored 00391 // unsigned char *length 00392 // Pointer to a variable containing the size of the buffer where the incoming data should be 00393 // stored. After this function returns, that variable holds the packet length. 00394 // 00395 // RETURN VALUE: 00396 // BOOL 00397 // 1: CRC OK 00398 // 0: CRC NOT OK (or no packet was put in the RX FIFO due to filtering) 00399 /////////////////////////////////////////////////////////////////////////////////////// 00400 00401 int CC1101::ReceivePacket(unsigned char *rxBuffer, unsigned char *length) 00402 { 00403 unsigned char status[2]; 00404 unsigned char packetLength; 00405 00406 packetLength = ReadStatus(CCxxx0_RXBYTES); 00407 if (packetLength & BYTES_IN_RXFIFO) 00408 { 00409 // Read length byte 00410 packetLength = ReadReg(CCxxx0_RXFIFO); 00411 00412 // Read data from RX FIFO and store in rxBuffer 00413 if (packetLength <= *length) 00414 { 00415 ReadBurstReg(CCxxx0_RXFIFO, rxBuffer, packetLength); 00416 *length = packetLength; 00417 00418 // Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI) 00419 ReadBurstReg(CCxxx0_RXFIFO, status, 2); 00420 00421 rssi = status[RSSI]; 00422 lqi = status[LQI]; 00423 // MSB of LQI is the CRC_OK bit 00424 // return (status[LQI] & CRC_OK); 00425 if(status[LQI] & CRC_OK) 00426 { 00427 return 1; 00428 } 00429 } 00430 else 00431 { 00432 *length = packetLength; 00433 00434 // Make sure that the radio is in IDLE state before flushing the FIFO 00435 // (Unless RXOFF_MODE has been changed, the radio should be in IDLE state at this point) 00436 Strobe(CCxxx0_SIDLE); 00437 00438 // Flush RX FIFO 00439 Strobe(CCxxx0_SFRX); 00440 return 0; 00441 } 00442 } else 00443 return 0; 00444 return 0; 00445 }// halRfReceivePacket 00446 /////////////////////////////////////////////////////////////////////////////////////// 00447 unsigned char CC1101::TxFifoEmpty(void) 00448 { 00449 unsigned char TxFifoStatus; 00450 00451 Strobe(CCxxx0_STX); 00452 TxFifoStatus = ReadStatus(CCxxx0_TXBYTES); 00453 00454 if (TxFifoStatus & 0x80) // check for TXFIFO underflow 00455 { 00456 // Make sure that the radio is in IDLE state before flushing the FIFO 00457 Strobe(CCxxx0_SIDLE); 00458 00459 // Flush TX FIFO 00460 Strobe(CCxxx0_SFTX); 00461 } 00462 if (TxFifoStatus & ~0x80) 00463 { 00464 return 0; 00465 } 00466 else 00467 return 1; 00468 } 00469 /////////////////////////////////////////////////////////////////////////////////////// 00470 // void halRfSendPacket(unsigned char *txBuffer, unsigned char size) 00471 // 00472 // DESCRIPTION: 00473 // This function can be used to transmit a packet with packet length up to 63 bytes. 00474 // 00475 // ARGUMENTS: 00476 // unsigned char *txBuffer 00477 // Pointer to a buffer containing the data that are going to be transmitted 00478 // 00479 // unsigned char size 00480 // The size of the txBuffer 00481 /////////////////////////////////////////////////////////////////////////////////////// 00482 void CC1101::SendPacket(unsigned char *txBuffer, unsigned char size) 00483 { 00484 unsigned char i; 00485 00486 for (i = size; i > 0; i--) 00487 txBuffer[i] = txBuffer[i-1]; 00488 txBuffer[0] = size; 00489 00490 WriteBurstReg(CCxxx0_TXFIFO, txBuffer, size+1); 00491 Strobe(CCxxx0_SIDLE); 00492 Strobe(CCxxx0_STX); 00493 }// halRfSendPacket 00494 /////////////////////////////////////////////////////////////////////////////////////// 00495 unsigned char CC1101::ReadChipStatusTX(void) 00496 { 00497 unsigned char x; 00498 00499 x = Strobe(CCxxx0_SNOP); 00500 return x; 00501 } 00502 /////////////////////////////////////////////////////////////////////////////////////// 00503 unsigned char CC1101::ReadChipStatusRX(void) 00504 { 00505 unsigned char x; 00506 wait(0.000005); 00507 _csn = 0; 00508 wait(0.000002); 00509 while (_RDmiso); 00510 x = _spi.write(CCxxx0_PARTNUM | READ_BURST); 00511 wait(0.000002); 00512 _csn = 1; 00513 return x; 00514 } 00515 /////////////////////////////////////////////////////////////////////////////////////// 00516 void CC1101::FlushRX(void) 00517 { 00518 // Make sure that the radio is in IDLE state before flushing the FIFO 00519 Strobe(CCxxx0_SIDLE); 00520 00521 // Flush RX FIFO 00522 Strobe(CCxxx0_SFRX); 00523 } 00524 /////////////////////////////////////////////////////////////////////////////////////// 00525 void CC1101::FlushTX(void) 00526 { 00527 // Make sure that the radio is in IDLE state before flushing the FIFO 00528 Strobe(CCxxx0_SIDLE); 00529 00530 // Flush TX FIFO 00531 Strobe(CCxxx0_SFTX); 00532 } 00533 /////////////////////////////////////////////////////////////////////////////////////// 00534 void CC1101::RXMode(void) 00535 { 00536 Strobe(CCxxx0_SIDLE); 00537 Strobe(CCxxx0_SRX); 00538 } 00539 ///////////////////////////////////////////////////////////////////////////////////////
Generated on Sun Jul 17 2022 23:15:06 by
1.7.2
