TI CC1101 Transceiver

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CC1101.cpp Source File

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 ///////////////////////////////////////////////////////////////////////////////////////