Codebase from CC1101_Transceiver, ported to LPC1114 Cortex-M0, will be merged with panStamp project to replace AVR/MSP MCU
Fork of CC1101_Transceiver by
Revision 0:9df942ea84f4, committed 2010-11-21
- Comitter:
- tmav123
- Date:
- Sun Nov 21 11:37:56 2010 +0000
- Child:
- 1:b8285d79c9a1
- Commit message:
- initial revision
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC1101.cpp Sun Nov 21 11:37:56 2010 +0000
@@ -0,0 +1,539 @@
+
+#include "CC1101.h"
+
+#define RF_0db
+//#define RF_10db
+///////////////////////////////////////////////////////////////////////////////////////
+CC1101::CC1101(PinName mosi, PinName miso, PinName clk, PinName csn, PinName RDmiso):
+ _spi(mosi, miso, clk), _csn(csn), _RDmiso(RDmiso)
+{
+ _csn = 1;
+
+ // Setup the spi for 8 bit data, high steady state clock,
+ // second edge capture, with a 1MHz clock rate
+ _spi.format(8,0);
+ _spi.frequency(1000000);
+
+ POWER_UP_RESET_CCxxx0();
+ Strobe(CCxxx0_SRX);
+}
+///////////////////////////////////////////////////////////////////////////////////////
+RF_SETTINGS rfSettings = // 433Mhz, 9600Bauds
+{
+ 0x06, // FSCTRL1 Frequency Synthesizer Control - IF:152.343Khz
+ 0x07, // IOCFG0 GDO0 Output Pin Configuration - Packet received and CRC OK
+ 0x00, // FSCTRL0 Frequency Synthesizer Control - Freq offset
+ 0x10, // FREQ2 Frequency Control Word, High Byte - 433.999 Mhz
+ 0xB1, // FREQ1 Frequency Control Word, Middle Byte
+ 0x3B, // FREQ0 Frequency Control Word, Low Byte
+ 0xF8, // MDMCFG4 Modem Configuration - BW: 58.035Khz
+ 0x83, // MDMCFG3 Modem Configuration - 9595 Baud
+ 0x13, // MDMCFG2 Modem Configuration - 30/32 sync word bits - Manchester disable - GFSK - Digital DC filter enable
+ 0x22, // MDMCFG1 Modem Configuration - num of preamble bytes:4 - FEC disable
+ 0xF8, // MDMCFG0 Modem Configuration - Channel spacing: 199.951Khz
+ 0x00, // CHANNR Channel Number
+ 0x15, // DEVIATN Modem Deviation Setting - 5.157Khz
+ 0x56, // FREND1 Front End RX Configuration
+ 0x10, // FREND0 Front End TX Configuration
+ 0x18, // MCSM0 Main Radio Control State Machine Configuration - PO timeout: 64(149-155us) - Auto calibrate from idle to rx/tx
+ 0x16, // FOCCFG Frequency Offset Compensation Configuration
+ 0x6C, // BSCFG Bit Synchronization Configuration
+ 0x03, // AGCCTRL2 AGC Control - target amplitude: 33dB - Maximum possible LNA + LNA 2 gain - All gain settings can be used
+ 0x40, // AGCCTRL1 AGC Control - LNA gain decreased first
+ 0x91, // AGCCTRL0 AGC Control - Medium hysterisis - Filter Samples: 16 - Normal AGC operation
+ 0xE9, // FSCAL3 Frequency Synthesizer Calibration
+ 0x2A, // FSCAL2 Frequency Synthesizer Calibration
+ 0x00, // FSCAL1 Frequency Synthesizer Calibration
+ 0x1F, // FSCAL0 Frequency Synthesizer Calibration
+ 0x59, // FSTEST Frequency Synthesizer Calibration Control
+ 0x88, // TEST2 Various Test Settings
+ 0x31, // TEST1 Various Test Settings
+ 0x09, // TEST0 Various Test Settings
+ 0x07, // FIFOTHR RX FIFO and TX FIFO Thresholds - Bytes in TX FIFO:33 - Bytes in RX FIFO:32
+ 0x06, // IOCFG2 GDO2 Output Pin Configuration - Sync word received/sent - end of packet
+ 0x04, // PKTCTRL1 Packet Automation Control - No address check - Automatic flush of RX FIFO is disable - sync word is always accepted
+ 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
+ 0x00, // ADDR Device Address
+ 0xFF, // PKTLEN Packet Length
+ 0x3F, // MCSM1 Main Radio Control State Machine Configuration
+};
+#ifdef RF_0db
+// PATABLE (0 dBm output power)
+char paTable[] = {0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+#endif
+#ifdef RF_10db
+// PATABLE (10 dBm output power)
+char paTable[] = {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+#endif
+///////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////
+// Macro to reset the CCxxx0 and wait for it to be ready
+void CC1101::RESET_CCxxx0(void)
+{
+// while (_RDmiso);
+ _csn = 0;
+ wait(0.000002);
+ while (_RDmiso);
+ _spi.write(CCxxx0_SRES);
+ wait(0.000002);
+ _csn = 1;
+}
+///////////////////////////////////////////////////////////////////////////////////////
+// Macro to reset the CCxxx0 after power_on and wait for it to be ready
+// IMPORTANT NOTICE:
+// The file Wait.c must be included if this macro shall be used
+// The file is located under: ..\Lib\Chipcon\Hal\CCxx00
+//
+// min 40 us
+// <----------------------->
+// CSn |--| |--------------------| |-----------
+// | | | | |
+// -- ----------
+//
+// MISO |---------------
+// - - - - - - - - - - - - - - - -| |
+// --
+// Unknown / don't care
+//
+// MOSI - - - - - - - - - - - - - - - ---------- - - - - -
+// | SRES |
+// - - - - - - - - - - - - - - - ---------- - - - - -
+//
+void CC1101::POWER_UP_RESET_CCxxx0(void)
+{
+ _csn = 1;
+ wait(1e-6);
+ _csn = 0;
+ wait(1e-6);
+ _csn = 1;
+ wait(41e-6);
+ RESET_CCxxx0();
+}
+///////////////////////////////////////////////////////////////////////////////////////
+// void Strobe(unsigned char strobe)
+//
+// DESCRIPTION:
+// Function for writing a strobe command to the CCxxx0
+//
+// ARGUMENTS:
+// unsigned char strobe
+// Strobe command
+///////////////////////////////////////////////////////////////////////////////////////
+unsigned char CC1101::Strobe(unsigned char strobe)
+{
+ unsigned char x;
+ wait(0.000005);
+ _csn = 0;
+ wait(0.000002);
+ while (_RDmiso);
+ x = _spi.write(strobe);
+ wait(0.000002);
+ _csn = 1;
+ return x;
+}// Strobe
+///////////////////////////////////////////////////////////////////////////////////////
+// unsigned char ReadStatus(unsigned char addr)
+//
+// DESCRIPTION:
+// This function reads a CCxxx0 status register.
+//
+// ARGUMENTS:
+// unsigned char addr
+// Address of the CCxxx0 status register to be accessed.
+//
+// RETURN VALUE:
+// unsigned char
+// Value of the accessed CCxxx0 status register.
+///////////////////////////////////////////////////////////////////////////////////////
+unsigned char CC1101::ReadStatus(unsigned char addr)
+{
+ unsigned char x;
+ wait(0.000005);
+ _csn = 0;
+ wait(0.000002);
+ while (_RDmiso);
+ _spi.write(addr | READ_BURST);
+ x = _spi.write(0);
+ wait(0.000002);
+ _csn = 1;
+ return x;
+}// ReadStatus
+///////////////////////////////////////////////////////////////////////////////////////
+// void WriteRfSettings(RF_SETTINGS *pRfSettings)
+//
+// DESCRIPTION:
+// This function is used to configure the CCxxx0 based on a given rf setting
+//
+// ARGUMENTS:
+// RF_SETTINGS *pRfSettings
+// Pointer to a struct containing rf register settings
+///////////////////////////////////////////////////////////////////////////////////////
+void CC1101::WriteRfSettings(RF_SETTINGS *pRfSettings)
+{
+ // Write register settings
+ WriteReg(CCxxx0_FSCTRL1, pRfSettings->FSCTRL1);
+ WriteReg(CCxxx0_FSCTRL0, pRfSettings->FSCTRL0);
+ WriteReg(CCxxx0_FREQ2, pRfSettings->FREQ2);
+ WriteReg(CCxxx0_FREQ1, pRfSettings->FREQ1);
+ WriteReg(CCxxx0_FREQ0, pRfSettings->FREQ0);
+ WriteReg(CCxxx0_MDMCFG4, pRfSettings->MDMCFG4);
+ WriteReg(CCxxx0_MDMCFG3, pRfSettings->MDMCFG3);
+ WriteReg(CCxxx0_MDMCFG2, pRfSettings->MDMCFG2);
+ WriteReg(CCxxx0_MDMCFG1, pRfSettings->MDMCFG1);
+ WriteReg(CCxxx0_MDMCFG0, pRfSettings->MDMCFG0);
+ WriteReg(CCxxx0_CHANNR, pRfSettings->CHANNR);
+ WriteReg(CCxxx0_DEVIATN, pRfSettings->DEVIATN);
+ WriteReg(CCxxx0_FREND1, pRfSettings->FREND1);
+ WriteReg(CCxxx0_FREND0, pRfSettings->FREND0);
+ WriteReg(CCxxx0_MCSM0 , pRfSettings->MCSM0 );
+ WriteReg(CCxxx0_FOCCFG, pRfSettings->FOCCFG);
+ WriteReg(CCxxx0_BSCFG, pRfSettings->BSCFG);
+ WriteReg(CCxxx0_AGCCTRL2, pRfSettings->AGCCTRL2);
+ WriteReg(CCxxx0_AGCCTRL1, pRfSettings->AGCCTRL1);
+ WriteReg(CCxxx0_AGCCTRL0, pRfSettings->AGCCTRL0);
+ WriteReg(CCxxx0_FSCAL3, pRfSettings->FSCAL3);
+ WriteReg(CCxxx0_FSCAL2, pRfSettings->FSCAL2);
+ WriteReg(CCxxx0_FSCAL1, pRfSettings->FSCAL1);
+ WriteReg(CCxxx0_FSCAL0, pRfSettings->FSCAL0);
+ WriteReg(CCxxx0_FSTEST, pRfSettings->FSTEST);
+ WriteReg(CCxxx0_TEST2, pRfSettings->TEST2);
+ WriteReg(CCxxx0_TEST1, pRfSettings->TEST1);
+ WriteReg(CCxxx0_TEST0, pRfSettings->TEST0);
+ WriteReg(CCxxx0_FIFOTHR, pRfSettings->FIFOTHR);
+ WriteReg(CCxxx0_IOCFG2, pRfSettings->IOCFG2);
+ WriteReg(CCxxx0_IOCFG0, pRfSettings->IOCFG0);
+ WriteReg(CCxxx0_PKTCTRL1, pRfSettings->PKTCTRL1);
+ WriteReg(CCxxx0_PKTCTRL0, pRfSettings->PKTCTRL0);
+ WriteReg(CCxxx0_ADDR, pRfSettings->ADDR);
+ WriteReg(CCxxx0_PKTLEN, pRfSettings->PKTLEN);
+ WriteReg(CCxxx0_MCSM1 , pRfSettings->MCSM1 );
+ RXMode();
+
+}// WriteRfSettings
+///////////////////////////////////////////////////////////////////////////////////////
+void CC1101::init(void)
+{
+ WriteRfSettings(&rfSettings);
+ WriteReg(CCxxx0_PATABLE, paTable[0]);
+}
+///////////////////////////////////////////////////////////////////////////////////////
+// unsigned char ReadReg(unsigned char addr)
+//
+// DESCRIPTION:
+// This function gets the value of a single specified CCxxx0 register.
+//
+// ARGUMENTS:
+// unsigned char addr
+// Address of the CCxxx0 register to be accessed.
+//
+// RETURN VALUE:
+// unsigned char
+// Value of the accessed CCxxx0 register.
+///////////////////////////////////////////////////////////////////////////////////////
+unsigned char CC1101::ReadReg(unsigned char addr)
+{
+ unsigned char x;
+ wait(0.000005);
+ _csn = 0;
+ wait(0.000002);
+ while (_RDmiso);
+ _spi.write(addr | READ_SINGLE);
+ x = _spi.write(0);
+ wait(0.000002);
+ _csn = 1;
+ return x;
+}// ReadReg
+///////////////////////////////////////////////////////////////////////////////////////
+// void ReadBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count)
+//
+// DESCRIPTION:
+// This function reads multiple CCxxx0 register, using SPI burst access.
+//
+// ARGUMENTS:
+// unsigned char addr
+// Address of the first CCxxx0 register to be accessed.
+// unsigned char *buffer
+// Pointer to a byte array which stores the values read from a
+// corresponding range of CCxxx0 registers.
+// unsigned char count
+// Number of bytes to be read from the subsequent CCxxx0 registers.
+///////////////////////////////////////////////////////////////////////////////////////
+void CC1101::ReadBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count)
+{
+ unsigned char i;
+ wait(0.000005);
+ _csn = 0;
+ wait(0.000002);
+ while (_RDmiso);
+ _spi.write(addr | READ_BURST);
+ for (i = 0; i < count; i++)
+ {
+ buffer[i] = _spi.write(0);
+ }
+ wait(0.000002);
+ _csn = 1;
+}// ReadBurstReg
+///////////////////////////////////////////////////////////////////////////////////////
+// void WriteReg(unsigned char addr, unsigned char value)
+//
+// DESCRIPTION:
+// Function for writing to a single CCxxx0 register
+//
+// ARGUMENTS:
+// unsigned char addr
+// Address of a specific CCxxx0 register to accessed.
+// unsigned char value
+// Value to be written to the specified CCxxx0 register.
+///////////////////////////////////////////////////////////////////////////////////////
+void CC1101::WriteReg(unsigned char addr, unsigned char value)
+{
+ wait(0.000005);
+ _csn = 0;
+ wait(0.000002);
+ while (_RDmiso);
+ _spi.write(addr);
+ _spi.write(value);
+ wait(0.000002);
+ _csn = 1;
+}// WriteReg
+///////////////////////////////////////////////////////////////////////////////////////
+// void WriteBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count)
+//
+// DESCRIPTION:
+// This function writes to multiple CCxxx0 register, using SPI burst access.
+//
+// ARGUMENTS:
+// unsigned char addr
+// Address of the first CCxxx0 register to be accessed.
+// unsigned char *buffer
+// Array of bytes to be written into a corresponding range of
+// CCxx00 registers, starting by the address specified in _addr_.
+// unsigned char count
+// Number of bytes to be written to the subsequent CCxxx0 registers.
+///////////////////////////////////////////////////////////////////////////////////////
+void CC1101::WriteBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count)
+{
+ unsigned char i;
+ wait(0.000005);
+ _csn = 0;
+ wait(0.000002);
+ while (_RDmiso);
+ _spi.write(addr | WRITE_BURST);
+ for (i = 0; i < count; i++)
+ {
+ _spi.write(buffer[i]);
+ }
+ wait(0.000002);
+ _csn = 1;
+}// WriteBurstReg
+///////////////////////////////////////////////////////////////////////////////////////
+unsigned char CC1101::RdRSSI(void)
+{
+ unsigned char crssi;
+
+
+ if (rssi >= 128)
+ {
+ crssi = 255 - rssi;
+ crssi /= 2;
+ crssi += 74;
+ }
+ else
+ {
+ crssi = rssi/2;
+ crssi += 74;
+ }
+ return crssi;
+}
+///////////////////////////////////////////////////////////////////////////////////////
+unsigned char CC1101::RdLQI(void)
+{
+ unsigned char clqi;
+ clqi = 0x3F - (lqi & 0x3F);
+
+ return clqi;
+}
+///////////////////////////////////////////////////////////////////////////////////////
+unsigned char CC1101::RxFifoEmpty(void)
+{
+ unsigned char RxFifoStatus;
+
+ Strobe(CCxxx0_SRX);
+ RxFifoStatus = ReadStatus(CCxxx0_RXBYTES);
+
+ if (RxFifoStatus & 0x80) // check for RXFIFO overflow
+ {
+ // Make sure that the radio is in IDLE state before flushing the FIFO
+ // (Unless RXOFF_MODE has been changed, the radio should be in IDLE state at this point)
+ Strobe(CCxxx0_SIDLE);
+
+ // Flush RX FIFO
+ Strobe(CCxxx0_SFRX);
+ }
+ if (RxFifoStatus & ~0x80)
+ {
+ return 0;
+ }
+ else
+ return 1;
+}
+///////////////////////////////////////////////////////////////////////////////////////
+//-------------------------------------------------------------------------------------------------------
+// BOOL ReceivePacket(unsigned char *rxBuffer, unsigned char *length)
+//
+// DESCRIPTION:
+// This function can be used to receive a packet of variable packet length (first byte in the packet
+// must be the length byte). The packet length should not exceed the RX FIFO size.
+//
+// ARGUMENTS:
+// unsigned char *rxBuffer
+// Pointer to the buffer where the incoming data should be stored
+// unsigned char *length
+// Pointer to a variable containing the size of the buffer where the incoming data should be
+// stored. After this function returns, that variable holds the packet length.
+//
+// RETURN VALUE:
+// BOOL
+// 1: CRC OK
+// 0: CRC NOT OK (or no packet was put in the RX FIFO due to filtering)
+///////////////////////////////////////////////////////////////////////////////////////
+
+int CC1101::ReceivePacket(unsigned char *rxBuffer, unsigned char *length)
+{
+ unsigned char status[2];
+ unsigned char packetLength;
+
+ packetLength = ReadStatus(CCxxx0_RXBYTES);
+ if (packetLength & BYTES_IN_RXFIFO)
+ {
+ // Read length byte
+ packetLength = ReadReg(CCxxx0_RXFIFO);
+
+ // Read data from RX FIFO and store in rxBuffer
+ if (packetLength <= *length)
+ {
+ ReadBurstReg(CCxxx0_RXFIFO, rxBuffer, packetLength);
+ *length = packetLength;
+
+ // Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI)
+ ReadBurstReg(CCxxx0_RXFIFO, status, 2);
+
+ rssi = status[RSSI];
+ lqi = status[LQI];
+ // MSB of LQI is the CRC_OK bit
+// return (status[LQI] & CRC_OK);
+ if(status[LQI] & CRC_OK)
+ {
+ return 1;
+ }
+ }
+ else
+ {
+ *length = packetLength;
+
+ // Make sure that the radio is in IDLE state before flushing the FIFO
+ // (Unless RXOFF_MODE has been changed, the radio should be in IDLE state at this point)
+ Strobe(CCxxx0_SIDLE);
+
+ // Flush RX FIFO
+ Strobe(CCxxx0_SFRX);
+ return 0;
+ }
+ } else
+ return 0;
+ return 0;
+}// halRfReceivePacket
+///////////////////////////////////////////////////////////////////////////////////////
+unsigned char CC1101::TxFifoEmpty(void)
+{
+ unsigned char TxFifoStatus;
+
+ Strobe(CCxxx0_STX);
+ TxFifoStatus = ReadStatus(CCxxx0_TXBYTES);
+
+ if (TxFifoStatus & 0x80) // check for TXFIFO underflow
+ {
+ // Make sure that the radio is in IDLE state before flushing the FIFO
+ Strobe(CCxxx0_SIDLE);
+
+ // Flush TX FIFO
+ Strobe(CCxxx0_SFTX);
+ }
+ if (TxFifoStatus & ~0x80)
+ {
+ return 0;
+ }
+ else
+ return 1;
+}
+///////////////////////////////////////////////////////////////////////////////////////
+// void halRfSendPacket(unsigned char *txBuffer, unsigned char size)
+//
+// DESCRIPTION:
+// This function can be used to transmit a packet with packet length up to 63 bytes.
+//
+// ARGUMENTS:
+// unsigned char *txBuffer
+// Pointer to a buffer containing the data that are going to be transmitted
+//
+// unsigned char size
+// The size of the txBuffer
+///////////////////////////////////////////////////////////////////////////////////////
+void CC1101::SendPacket(unsigned char *txBuffer, unsigned char size)
+{
+ unsigned char i;
+
+ for (i = size; i > 0; i--)
+ txBuffer[i] = txBuffer[i-1];
+ txBuffer[0] = size;
+
+ WriteBurstReg(CCxxx0_TXFIFO, txBuffer, size+1);
+ Strobe(CCxxx0_SIDLE);
+ Strobe(CCxxx0_STX);
+}// halRfSendPacket
+///////////////////////////////////////////////////////////////////////////////////////
+unsigned char CC1101::ReadChipStatusTX(void)
+{
+ unsigned char x;
+
+ x = Strobe(CCxxx0_SNOP);
+ return x;
+}
+///////////////////////////////////////////////////////////////////////////////////////
+unsigned char CC1101::ReadChipStatusRX(void)
+{
+ unsigned char x;
+ wait(0.000005);
+ _csn = 0;
+ wait(0.000002);
+ while (_RDmiso);
+ x = _spi.write(CCxxx0_PARTNUM | READ_BURST);
+ wait(0.000002);
+ _csn = 1;
+ return x;
+}
+///////////////////////////////////////////////////////////////////////////////////////
+void CC1101::FlushRX(void)
+{
+ // Make sure that the radio is in IDLE state before flushing the FIFO
+ Strobe(CCxxx0_SIDLE);
+
+ // Flush RX FIFO
+ Strobe(CCxxx0_SFRX);
+}
+///////////////////////////////////////////////////////////////////////////////////////
+void CC1101::FlushTX(void)
+{
+ // Make sure that the radio is in IDLE state before flushing the FIFO
+ Strobe(CCxxx0_SIDLE);
+
+ // Flush TX FIFO
+ Strobe(CCxxx0_SFTX);
+}
+///////////////////////////////////////////////////////////////////////////////////////
+void CC1101::RXMode(void)
+{
+ Strobe(CCxxx0_SIDLE);
+ Strobe(CCxxx0_SRX);
+}
+///////////////////////////////////////////////////////////////////////////////////////
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC1101.h Sun Nov 21 11:37:56 2010 +0000
@@ -0,0 +1,356 @@
+/**
+ * @author Athanassios Mavrogeorgiadis
+ * @author TI CC1101 library developed by Athanassios Mavrogeorgiadis (tmav Electronics) as template based on TI C8051 SOURCE CODE swrc021f
+ * @section LICENSE
+ *
+ * Copyright (c) 2010 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @section DESCRIPTION
+ *
+ * CC1101 Low-Power Sub-1 GHz RF Transceiver CC1101.
+ *
+ * Datasheet:
+ *
+ * http://focus.ti.com/lit/ds/swrs061f/swrs061f.pdf
+ */
+
+#ifndef MBED_CC1101_H
+#define MBED_CC1101_H
+
+/**
+ * Includes
+ */
+#include "mbed.h"
+
+/**
+ * Defines
+ */
+///////////////////////////////////////////////////////////////////////////////////////
+//------------------------------------------------------------------------------------------------------
+// CC2500/CC1100 STROBE, CONTROL AND STATUS REGSITER
+#define CCxxx0_IOCFG2 0x00 // GDO2 output pin configuration
+#define CCxxx0_IOCFG1 0x01 // GDO1 output pin configuration
+#define CCxxx0_FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds
+#define CCxxx0_SYNC1 0x04 // Sync word, high byte
+#define CCxxx0_SYNC0 0x05 // Sync word, low byte
+#define CCxxx0_IOCFG0 0x02 // GDO0 output pin configuration
+#define CCxxx0_FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds
+#define CCxxx0_SYNC1 0x04 // Sync word, high byte
+#define CCxxx0_SYNC0 0x05 // Sync word, low byte
+#define CCxxx0_PKTLEN 0x06 // Packet length
+#define CCxxx0_PKTCTRL1 0x07 // Packet automation control
+#define CCxxx0_PKTCTRL0 0x08 // Packet automation control
+#define CCxxx0_ADDR 0x09 // Device address
+#define CCxxx0_CHANNR 0x0A // Channel number
+#define CCxxx0_FSCTRL1 0x0B // Frequency synthesizer control
+#define CCxxx0_FSCTRL0 0x0C // Frequency synthesizer control
+#define CCxxx0_FREQ2 0x0D // Frequency control word, high byte
+#define CCxxx0_FREQ1 0x0E // Frequency control word, middle byte
+#define CCxxx0_FREQ0 0x0F // Frequency control word, low byte
+#define CCxxx0_MDMCFG4 0x10 // Modem configuration
+#define CCxxx0_MDMCFG3 0x11 // Modem configuration
+#define CCxxx0_MDMCFG2 0x12 // Modem configuration
+#define CCxxx0_MDMCFG1 0x13 // Modem configuration
+#define CCxxx0_MDMCFG0 0x14 // Modem configuration
+#define CCxxx0_DEVIATN 0x15 // Modem deviation setting
+#define CCxxx0_MCSM2 0x16 // Main Radio Control State Machine configuration
+#define CCxxx0_MCSM1 0x17 // Main Radio Control State Machine configuration
+#define CCxxx0_MCSM0 0x18 // Main Radio Control State Machine configuration
+#define CCxxx0_FOCCFG 0x19 // Frequency Offset Compensation configuration
+#define CCxxx0_BSCFG 0x1A // Bit Synchronization configuration
+#define CCxxx0_AGCCTRL2 0x1B // AGC control
+#define CCxxx0_AGCCTRL1 0x1C // AGC control
+#define CCxxx0_AGCCTRL0 0x1D // AGC control
+#define CCxxx0_WOREVT1 0x1E // High byte Event 0 timeout
+#define CCxxx0_WOREVT0 0x1F // Low byte Event 0 timeout
+#define CCxxx0_WORCTRL 0x20 // Wake On Radio control
+#define CCxxx0_FREND1 0x21 // Front end RX configuration
+#define CCxxx0_FREND0 0x22 // Front end TX configuration
+#define CCxxx0_FSCAL3 0x23 // Frequency synthesizer calibration
+#define CCxxx0_FSCAL2 0x24 // Frequency synthesizer calibration
+#define CCxxx0_FSCAL1 0x25 // Frequency synthesizer calibration
+#define CCxxx0_FSCAL0 0x26 // Frequency synthesizer calibration
+#define CCxxx0_RCCTRL1 0x27 // RC oscillator configuration
+#define CCxxx0_RCCTRL0 0x28 // RC oscillator configuration
+#define CCxxx0_FSTEST 0x29 // Frequency synthesizer calibration control
+#define CCxxx0_PTEST 0x2A // Production test
+#define CCxxx0_AGCTEST 0x2B // AGC test
+#define CCxxx0_TEST2 0x2C // Various test settings
+#define CCxxx0_TEST1 0x2D // Various test settings
+#define CCxxx0_TEST0 0x2E // Various test settings
+
+// Strobe commands
+#define CCxxx0_SRES 0x30 // Reset chip.
+#define CCxxx0_SFSTXON 0x31 // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1).
+ // If in RX/TX: Go to a wait state where only the synthesizer is
+ // running (for quick RX / TX turnaround).
+#define CCxxx0_SXOFF 0x32 // Turn off crystal oscillator.
+#define CCxxx0_SCAL 0x33 // Calibrate frequency synthesizer and turn it off
+ // (enables quick start).
+#define CCxxx0_SRX 0x34 // Enable RX. Perform calibration first if coming from IDLE and
+ // MCSM0.FS_AUTOCAL=1.
+#define CCxxx0_STX 0x35 // In IDLE state: Enable TX. Perform calibration first if
+ // MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled:
+ // Only go to TX if channel is clear.
+#define CCxxx0_SIDLE 0x36 // Exit RX / TX, turn off frequency synthesizer and exit
+ // Wake-On-Radio mode if applicable.
+#define CCxxx0_SAFC 0x37 // Perform AFC adjustment of the frequency synthesizer
+#define CCxxx0_SWOR 0x38 // Start automatic RX polling sequence (Wake-on-Radio)
+#define CCxxx0_SPWD 0x39 // Enter power down mode when CSn goes high.
+#define CCxxx0_SFRX 0x3A // Flush the RX FIFO buffer.
+#define CCxxx0_SFTX 0x3B // Flush the TX FIFO buffer.
+#define CCxxx0_SWORRST 0x3C // Reset real time clock.
+#define CCxxx0_SNOP 0x3D // No operation. May be used to pad strobe commands to two
+ // bytes for simpler software.
+
+#define CCxxx0_PARTNUM 0x30
+#define CCxxx0_VERSION 0x31
+#define CCxxx0_FREQEST 0x32
+#define CCxxx0_LQI 0x33
+#define CCxxx0_RSSI 0x34
+#define CCxxx0_MARCSTATE 0x35
+#define CCxxx0_WORTIME1 0x36
+#define CCxxx0_WORTIME0 0x37
+#define CCxxx0_PKTSTATUS 0x38
+#define CCxxx0_VCO_VC_DAC 0x39
+#define CCxxx0_TXBYTES 0x3A
+#define CCxxx0_RXBYTES 0x3B
+#define CCxxx0_RCCTRL1_STATUS 0x3C
+#define CCxxx0_RCCTRL0_STATUS 0x3D
+
+#define CCxxx0_PATABLE 0x3E
+#define CCxxx0_TXFIFO 0x3F
+#define CCxxx0_RXFIFO 0x3F
+///////////////////////////////////////////////////////////////////////////////////////
+// RF_SETTINGS is a data structure which contains all relevant CCxxx0 registers
+typedef struct S_RF_SETTINGS
+{
+ unsigned char FSCTRL1; // Frequency synthesizer control.
+ unsigned char IOCFG0; // GDO0 output pin configuration
+ unsigned char FSCTRL0; // Frequency synthesizer control.
+ unsigned char FREQ2; // Frequency control word, high byte.
+ unsigned char FREQ1; // Frequency control word, middle byte.
+ unsigned char FREQ0; // Frequency control word, low byte.
+ unsigned char MDMCFG4; // Modem configuration.
+ unsigned char MDMCFG3; // Modem configuration.
+ unsigned char MDMCFG2; // Modem configuration.
+ unsigned char MDMCFG1; // Modem configuration.
+ unsigned char MDMCFG0; // Modem configuration.
+ unsigned char CHANNR; // Channel number.
+ unsigned char DEVIATN; // Modem deviation setting (when FSK modulation is enabled).
+ unsigned char FREND1; // Front end RX configuration.
+ unsigned char FREND0; // Front end RX configuration.
+ unsigned char MCSM0; // Main Radio Control State Machine configuration.
+ unsigned char FOCCFG; // Frequency Offset Compensation Configuration.
+ unsigned char BSCFG; // Bit synchronization Configuration.
+ unsigned char AGCCTRL2; // AGC control.
+ unsigned char AGCCTRL1; // AGC control.
+ unsigned char AGCCTRL0; // AGC control.
+ unsigned char FSCAL3; // Frequency synthesizer calibration.
+ unsigned char FSCAL2; // Frequency synthesizer calibration.
+ unsigned char FSCAL1; // Frequency synthesizer calibration.
+ unsigned char FSCAL0; // Frequency synthesizer calibration.
+ unsigned char FSTEST; // Frequency synthesizer calibration control
+ unsigned char TEST2; // Various test settings.
+ unsigned char TEST1; // Various test settings.
+ unsigned char TEST0; // Various test settings.
+ unsigned char FIFOTHR; // RXFIFO and TXFIFO thresholds.
+ unsigned char IOCFG2; // GDO2 output pin configuration
+ unsigned char PKTCTRL1; // Packet automation control.
+ unsigned char PKTCTRL0; // Packet automation control.
+ unsigned char ADDR; // Device address.
+ unsigned char PKTLEN; // Packet length.
+ unsigned char MCSM1; // Main Radio Control State Machine configuration.
+} RF_SETTINGS;
+///////////////////////////////////////////////////////////////////////////////////////
+// Definitions to support burst/single access:
+#define WRITE_BURST 0x40
+#define READ_SINGLE 0x80
+#define READ_BURST 0xC0
+///////////////////////////////////////////////////////////////////////////////////////
+#define CRC_OK 0x80
+#define RSSI 0
+#define LQI 1
+#define BYTES_IN_RXFIFO 0x7F
+///////////////////////////////////////////////////////////////////////////////////////
+// Definitions for chip status
+#define CHIP_RDY 0x80
+#define CHIP_STATE_MASK 0x70
+#define CHIP_STATE_IDLE 0x00
+#define CHIP_STATE_RX 0x10
+#define CHIP_STATE_TX 0x20
+#define CHIP_STATE_FSTON 0x30
+#define CHIP_STATE_CALIBRATE 0x40
+#define CHIP_STATE_SETTLING 0x50
+#define CHIP_STATE_RXFIFO_OVERFLOW 0x60
+#define CHIP_STATE_TXFIFO_UNDERFLOW 0x70
+#define FIFO_BYTES_MASK 0x0F
+///////////////////////////////////////////////////////////////////////////////////////
+/**
+ * CC1101 Low-Power Sub-1 GHz RF Transceiver .
+ */
+
+class CC1101
+{
+public:
+ /**
+ * Constructor.
+ *
+ * @param mosi mbed pin to use for MOSI line of SPI interface.
+ * @param miso mbed pin to use for MISO line of SPI interface.
+ * @param clk mbed pin to use for SCK line of SPI interface.
+ * @param csn mbed pin to use for not chip select line of SPI interface.
+ * @param RDmiso mbed pin connected to SPI MISO pin for CC1101 RDY read.
+ */
+ CC1101(PinName mosi, PinName miso, PinName clk, PinName csn, PinName RDmiso);
+
+ /**
+ * Initialize CC1101 parameters.
+ */
+ void init(void);
+
+ /**
+ * This function gets the value of a single specified CCxxx0 register.
+ *
+ * @param addr Value of the accessed CCxxx0 register
+ * @return Value of the accessed CCxxx0 register
+ */
+ unsigned char ReadReg(unsigned char addr);
+
+ /**
+ * This function reads multiple CCxxx0 register, using SPI burst access.
+ *
+ * @param addr Value of the accessed CCxxx0 register
+ * @param *buffer Pointer to a byte array which stores the values read from a
+ * corresponding range of CCxxx0 registers.
+ * @param count Number of bytes to be read from the subsequent CCxxx0 registers.
+ */
+ void ReadBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count);
+
+ /**
+ * Function for writing to a single CCxxx0 register
+ *
+ * @param addr Address of the first CCxxx0 register to be accessed.
+ * @param value Value to be written to the specified CCxxx0 register.
+ */
+ void WriteReg(unsigned char addr, unsigned char value);
+
+ /**
+ * This function writes to multiple CCxxx0 register, using SPI burst access.
+ *
+ * @param addr Address of the first CCxxx0 register to be accessed.
+ * @param *buffer Array of bytes to be written into a corresponding range of
+ * CCxx00 registers, starting by the address specified in _addr_.
+ * @param count Number of bytes to be written to the subsequent CCxxx0 registers.
+ */
+ void WriteBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count);
+
+ /**
+ * This function can be used to transmit a packet with packet length up to 63 bytes.
+ *
+ * @param *txBuffer Pointer to a buffer containing the data that are going to be transmitted
+ * @param size The size of the txBuffer
+ */
+ void SendPacket(unsigned char *txBuffer, unsigned char size);
+
+ /**
+ * This function check if the TX FIFO is empty
+ *
+ * @return Return value is 1 if the TX FIFO buffer is empty or else 0
+ */
+ unsigned char TxFifoEmpty(void);
+
+ /**
+ * This function can be used to receive a packet of variable packet length (first byte in the packet
+ * must be the length byte). The packet length should not exceed the RX FIFO size.
+ *
+ * @param *rxBuffer Pointer to the buffer where the incoming data should be stored
+ * @param *length Pointer to a variable containing the size of the buffer where the incoming data should be
+ * stored. After this function returns, that variable holds the packet length.
+ * @return Return value is 1 if CRC OK or else 0 if CRC NOT OK (or no packet was put in the RX FIFO due to filtering)
+ */
+ int ReceivePacket(unsigned char *rxBuffer, unsigned char *length);
+
+ /**
+ * This function check if the RX FIFO is empty
+ *
+ * @return Return value is 1 if the RX FIFO buffer is empty or else 0
+ */
+ unsigned char RxFifoEmpty(void);
+
+ /**
+ * This function returns the Chip Status RX register
+ *
+ * @return Return the Chip Status RX register
+ */
+ unsigned char ReadChipStatusRX(void);
+
+ /**
+ * This function returns the Chip Status TX register
+ *
+ * @return Return the Chip Status TX register
+ */
+ unsigned char ReadChipStatusTX(void);
+
+ /**
+ * This function returns the RSSI value based from the last packet received
+ *
+ * @return Return the RSSI value.
+ */
+ unsigned char RdRSSI(void);
+
+ /**
+ * This function returns the LQI value based from the last packet received
+ *
+ * @return Return the LQI value.
+ */
+ unsigned char RdLQI(void);
+
+ /**
+ * This function flushes the RX FIFO buffer.
+ */
+ void FlushRX(void);
+
+ /**
+ * This function flushes the TX FIFO buffer.
+ */
+ void FlushTX(void);
+
+ /**
+ * This function change the state of CC1101 to RX mode.
+ */
+ void RXMode(void);
+
+protected:
+ void RESET_CCxxx0(void);
+ void POWER_UP_RESET_CCxxx0(void);
+ unsigned char ReadStatus(unsigned char addr);
+ unsigned char Strobe(unsigned char strobe);
+ void WriteRfSettings(RF_SETTINGS *pRfSettings);
+
+ SPI _spi;
+ DigitalOut _csn;
+ DigitalIn _RDmiso;
+ unsigned char rssi;
+ unsigned char lqi;
+};
+///////////////////////////////////////////////////////////////////////////////////////
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/RingBuffer.cpp Sun Nov 21 11:37:56 2010 +0000
@@ -0,0 +1,86 @@
+/*
+ * mbed library for RingBuffer
+ * Copyright (c) 2010 Hiroshi Suga
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+
+#include "RingBuffer.h"
+
+RingBuffer::RingBuffer (int p_size) {
+ size = p_size + 1;
+ buf = new char[size];
+ addr_w = 0;
+ addr_r = 0;
+}
+/*
+RingBuffer::~RingBuffer () {
+ delete [] buf;
+}
+*/
+int RingBuffer::_putc (int dat) {
+ int next;
+
+ next = (addr_w + 1) % size;
+ if (next == addr_r) {
+ return -1;
+ }
+ buf[addr_w] = dat;
+ addr_w = next;
+ return dat;
+}
+
+int RingBuffer::put (char *dat, int len) {
+ int next, i;
+
+
+ for (i = 0; i < len; i ++) {
+ next = (addr_w + 1) % size;
+ if (next == addr_r) {
+ break;
+ }
+ buf[addr_w] = dat[i];
+ addr_w = next;
+ }
+ return i;
+}
+
+int RingBuffer::_getc (void)
+{
+ char dat;
+ if (addr_r == addr_w) {
+ return 0;
+ }
+ dat = buf[addr_r];
+ addr_r = (addr_r + 1) % size;
+ return dat;
+}
+
+int RingBuffer::get (char *dat, int len) {
+ int i;
+
+ for (i = 0; i < len; i ++) {
+ if (addr_r == addr_w) {
+ break;
+ }
+ dat[i] = buf[addr_r];
+ addr_r = (addr_r + 1) % size;
+ }
+ return i;
+}
+
+int RingBuffer::available () {
+ if (addr_w < addr_r) {
+ return addr_r - addr_w - 1;
+ } else {
+ return (size - addr_w) + addr_r - 1;
+ }
+}
+
+int RingBuffer::use () {
+ return size - available() - 1;
+}
+
+void RingBuffer::clear () {
+ addr_w = 0;
+ addr_r = 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/RingBuffer.h Sun Nov 21 11:37:56 2010 +0000
@@ -0,0 +1,39 @@
+/*
+ * mbed library for RingBuffer
+ * Copyright (c) 2010 Hiroshi Suga
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+
+#ifndef RingBuffer_H
+#define RingBuffer_H
+
+#include "mbed.h"
+
+class RingBuffer : public Stream {
+public:
+ RingBuffer (int p_size);
+// ~RingBuffer ();
+
+#if DOXYGEN_ONLY
+ int putc(int c);
+ int printf(const char* format, ...);
+#endif
+// int putc (char);
+ int put (char *, int);
+ char get ();
+ int get (char *, int);
+ void clear ();
+ int available ();
+ int use ();
+
+private:
+ // Stream implementation functions
+ virtual int _putc(int value);
+ virtual int _getc();
+
+ char *buf;
+ int size;
+ int addr_w, addr_r;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Sun Nov 21 11:37:56 2010 +0000
@@ -0,0 +1,98 @@
+#include "mbed.h"
+#include "CC1101.h"
+#include "RingBuffer.h"
+
+///////////////////////////////////////////////////
+Ticker timer;
+CC1101 cc1101(p5, p6, p7, p8, p10);
+DigitalIn gdo0(p9); // pin connected to gdo0 pin of CC1101 for checking that received a new packet
+
+DigitalOut led1(LED1); // timer blink led
+DigitalOut led2(LED2); // RX led
+DigitalOut led3(LED3); // TX led
+Serial pc(USBTX, USBRX); // tx, rx
+RingBuffer pcRX(512); // ring buffer for the pc RX data
+RingBuffer pcTX(512); // ring buffer for the pc TX data
+Timeout pcRXtimeout;
+Timeout led2timeout;
+Timeout led3timeout;
+unsigned char buffer[128];
+///////////////////////////////////////////////////
+void led2timeout_func()
+{
+ led2 = 0;
+ led2timeout.detach();
+}
+///////////////////////////////////////////////////
+void led3timeout_func()
+{
+ led3 = 0;
+ led3timeout.detach();
+}
+///////////////////////////////////////////////////
+void pcRXtimeout_func() // function for transmiting the RF packets - empty the pcRX ring buffer
+{
+ unsigned char txlength;
+
+ txlength = 0;
+ while(pcRX.use() > 0)
+ {
+ led2 = 1;
+ buffer[txlength] = pcRX.getc();
+ txlength++;
+ led2timeout.attach(&led2timeout_func, 0.050); // for switch off the led
+ }
+ if (txlength)
+ cc1101.SendPacket(buffer, txlength); // tx packet
+
+ pcRXtimeout.detach();
+}
+///////////////////////////////////////////////////
+void timer_func() // check the status of the CC1101 every 100ms
+{
+ unsigned char chip_status_rx, chip_status_tx;
+
+ led1 = !led1;
+ chip_status_rx = cc1101.ReadChipStatusRX(); // check the rx status
+ if ((chip_status_rx & CHIP_STATE_MASK) == CHIP_STATE_RXFIFO_OVERFLOW) // if rx overflow flush the rx fifo
+ cc1101.FlushRX();
+ if ((chip_status_rx & CHIP_STATE_MASK) == CHIP_STATE_IDLE) // if state is idle go to rx state again
+ cc1101.RXMode();
+ chip_status_tx = cc1101.ReadChipStatusTX(); // check the tx sttus
+ if ((chip_status_tx & CHIP_STATE_MASK) == CHIP_STATE_TXFIFO_UNDERFLOW) // if tx underflow flush the tx fifo
+ cc1101.FlushTX();
+}
+///////////////////////////////////////////////////
+int main()
+{
+ unsigned char rxlength, i;
+
+ pcRX.clear();
+ pcTX.clear();
+ cc1101.init();
+ timer.attach(&timer_func, 0.1);
+ while(1)
+ {
+ if(gdo0) // rx finished and CRC OK read the new packet
+ {
+ rxlength = sizeof(buffer);
+ if (cc1101.ReceivePacket(buffer, &rxlength) == 1) // read the rx packet
+ {
+ led3 = 1;
+ for (i = 0; i < rxlength; i++)
+ pcTX.putc(buffer[i]); // store the packet to the pcTX ring buffer
+ led3timeout.attach(&led3timeout_func, 0.050); // for switch off the led
+ }
+ }
+ if (pcTX.use() > 0) // check if we have data to transmit to pc
+ pc.putc(pcTX.getc()); // get the data from the ring buffer and transmit it to the pc
+ if (pc.readable()) // check if we received new data from the pc
+ {
+ pcRX.putc(pc.getc()); // put the data to the pcRX buffer and wait until 20ms passed till the last byte before tx the packet in RF
+ pcRXtimeout.attach(&pcRXtimeout_func, 0.020);
+ }
+ if (pcRX.use() > 20) // if more than 20 bytes received then tx the packet in RF
+ pcRXtimeout_func();
+ }
+}
+///////////////////////////////////////////////////
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sun Nov 21 11:37:56 2010 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/e2ac27c8e93e
