Demo of how to use CC1200 radios to send data.

Dependencies:   CC1200

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TestCC1200.cpp Source File

TestCC1200.cpp

00001 //
00002 // Test suite for the CC1200 radio driver.
00003 // Provides a menu to configure radio options, and
00004 // attempts to send and receive a signal using two radios connected
00005 // to the processor.
00006 //
00007 
00008 #include <mbed.h>
00009 #include <SerialStream.h>
00010 
00011 #include <CC1200.h>
00012 #include <cinttypes>
00013 
00014 // Pin definitions
00015 // change these to match your board setup
00016 #define PIN_SPI_MOSI P0_9
00017 #define PIN_SPI_MISO P0_8
00018 #define PIN_SPI_SCLK P0_7
00019 
00020 #define PIN_TX_CS P0_6
00021 #define PIN_TX_RST P0_29
00022 
00023 #define PIN_RX_CS P0_4
00024 #define PIN_RX_RST P0_30
00025 
00026 BufferedSerial serial(USBTX, USBRX, 115200);
00027 SerialStream<BufferedSerial> pc(serial);
00028 
00029 CC1200 txRadio(PIN_SPI_MOSI, PIN_SPI_MISO, PIN_SPI_SCLK, PIN_TX_CS, PIN_TX_RST, &pc);
00030 CC1200 rxRadio(PIN_SPI_MOSI, PIN_SPI_MISO, PIN_SPI_SCLK, PIN_RX_CS, PIN_RX_RST, &pc);
00031 
00032 void checkExistance()
00033 {
00034     pc.printf("Checking TX radio.....\n");
00035     bool txSuccess = txRadio.begin();
00036     pc.printf("TX radio initialized: %s\n", txSuccess ? "true" : "false");
00037 
00038     pc.printf("Checking RX radio.....\n");
00039     bool rxSuccess = rxRadio.begin();
00040     pc.printf("RX radio initialized: %s\n", rxSuccess ? "true" : "false");
00041 }
00042 
00043 void checkSignalTransmit()
00044 {
00045     pc.printf("Initializing CC1200s.....\n");
00046     txRadio.begin();
00047     rxRadio.begin();
00048 
00049     pc.printf("Configuring RF settings.....\n");
00050 
00051     int config=-1;
00052     //MENU. ADD AN OPTION FOR EACH TEST.
00053     pc.printf("Select a config: \n");
00054     // This is similar to the SmartRF "100ksps ARIB Standard" configuration, except it doesn't use zero-if
00055     pc.printf("1.  915MHz 100ksps 2-GFSK DEV=50kHz CHF=208kHz\n");
00056     // This should be identical to the SmartRF "500ksps 4-GFSK Max Throughput ARIB Standard" configuration
00057     pc.printf("2.  915MHz 500ksps 4-GFSK DEV=400kHz CHF=1666kHz Zero-IF\n");
00058     pc.printf("3.  915MHz 38.4ksps 2-GFSK DEV=20kHz CHF=833kHz\n");
00059     pc.printf("4.  915MHz 100ksps 2-GFSK DEV=50kHz CHF=208kHz Fixed Length\n");
00060 
00061 
00062     pc.scanf("%d", &config);
00063     printf("Running test with config %d:\n\n", config);
00064 
00065     CC1200::PacketMode mode = CC1200::PacketMode::VARIABLE_LENGTH;
00066     CC1200::Band band = CC1200::Band::BAND_820_960MHz;
00067     float frequency = 915e6;
00068     const float txPower = 0;
00069     float fskDeviation;
00070     float symbolRate;
00071     float rxFilterBW;
00072     CC1200::ModFormat modFormat;
00073     CC1200::IFCfg ifCfg = CC1200::IFCfg::POSITIVE_DIV_8;
00074     bool imageCompEnabled = true;
00075     bool dcOffsetCorrEnabled = true;
00076     uint8_t agcRefLevel;
00077 
00078     uint8_t dcFiltSettingCfg = 1; // default chip setting
00079     uint8_t dcFiltCutoffCfg = 4; // default chip setting
00080     uint8_t agcSettleWaitCfg = 2;
00081 
00082     CC1200::SyncMode syncMode = CC1200::SyncMode::SYNC_32_BITS;
00083     uint32_t syncWord = 0x930B51DE; // default sync word
00084     uint8_t syncThreshold = 8; // TI seems to recommend this threshold for most configs above 100ksps
00085 
00086     uint8_t preableLengthCfg = 5; // default chip setting
00087     uint8_t preambleFormatCfg = 0; // default chip setting
00088 
00089     if(config == 1)
00090     {
00091         fskDeviation = 49896;
00092         symbolRate = 100000;
00093         rxFilterBW = 208300;
00094         modFormat = CC1200::ModFormat::GFSK_2;
00095         agcRefLevel = 0x2A;
00096     }
00097     else if(config == 2)
00098     {
00099         // SmartRF "500ksps 4-GFSK ARIB standard" config
00100         fskDeviation = 399169;
00101         symbolRate = 500000;
00102         rxFilterBW = 1666700;
00103         ifCfg = CC1200::IFCfg::ZERO;
00104         imageCompEnabled = false;
00105         dcOffsetCorrEnabled = true;
00106         modFormat = CC1200::ModFormat::GFSK_4;
00107         agcRefLevel = 0x2F;
00108     }
00109     else if(config == 3)
00110     {
00111         fskDeviation = 19989;
00112         symbolRate = 38400;
00113         rxFilterBW = 104200;
00114         modFormat = CC1200::ModFormat::GFSK_2;
00115         agcRefLevel = 0x27;
00116         agcSettleWaitCfg = 1;
00117     }
00118     else if(config == 4)
00119     {
00120         fskDeviation = 49896;
00121         symbolRate = 100000;
00122         rxFilterBW = 208300;
00123         modFormat = CC1200::ModFormat::GFSK_2;
00124         agcRefLevel = 0x2A;
00125         mode = CC1200::PacketMode::FIXED_LENGTH;
00126     }
00127     else
00128     {
00129         pc.printf("Invalid config number!");
00130         return;
00131     }
00132 
00133     for(CC1200 & radio : {std::ref(txRadio), std::ref(rxRadio)})
00134     {
00135 
00136         radio.configureFIFOMode();
00137         radio.setPacketMode(mode);
00138         radio.setModulationFormat(modFormat);
00139         radio.setFSKDeviation(fskDeviation);
00140         radio.setSymbolRate(symbolRate);
00141         radio.setOutputPower(txPower);
00142         radio.setRadioFrequency(band, frequency);
00143         radio.setIFCfg(ifCfg, imageCompEnabled);
00144         radio.configureDCFilter(dcOffsetCorrEnabled, dcFiltSettingCfg, dcFiltCutoffCfg);
00145         radio.setRXFilterBandwidth(rxFilterBW);
00146         radio.configureSyncWord(syncWord, syncMode, syncThreshold);
00147         radio.configurePreamble(preableLengthCfg, preambleFormatCfg);
00148 
00149         // AGC configuration (straight from SmartRF)
00150         radio.setAGCReferenceLevel(agcRefLevel);
00151         radio.setAGCSyncBehavior(CC1200::SyncBehavior::FREEZE_NONE);
00152         radio.setAGCSettleWait(agcSettleWaitCfg);
00153         if(ifCfg == CC1200::IFCfg::ZERO)
00154         {
00155             radio.setAGCGainTable(CC1200::GainTable::ZERO_IF, 11, 0);
00156         }
00157         else
00158         {
00159             // enable all AGC steps for NORMAL mode
00160             radio.setAGCGainTable(CC1200::GainTable::NORMAL, 17, 0);
00161         }
00162         radio.setAGCHysteresis(0b10);
00163         radio.setAGCSlewRate(0);
00164     }
00165 
00166     // configure on-transmit actions
00167     txRadio.setOnTransmitState(CC1200::State::TX);
00168     rxRadio.setOnReceiveState(CC1200::State::RX, CC1200::State::RX);
00169 
00170     pc.printf("Starting transmission.....\n");
00171 
00172     txRadio.startTX();
00173     rxRadio.startRX();
00174 
00175     const char message[] = "Hello world!";
00176     char receiveBuffer[sizeof(message)];
00177 
00178     if(mode == CC1200::PacketMode::FIXED_LENGTH)
00179     {
00180         txRadio.setPacketLength(sizeof(message) - 1);
00181         rxRadio.setPacketLength(sizeof(message) - 1);
00182     }
00183 
00184     while(true)
00185     {
00186         ThisThread::sleep_for(1s);
00187 
00188         pc.printf("\n---------------------------------\n");
00189 
00190         pc.printf("<<SENDING: %s\n", message);
00191         txRadio.enqueuePacket(message, sizeof(message) - 1);
00192 
00193 
00194         // update TX radio
00195         pc.printf("TX radio: state = 0x%" PRIx8 ", TX FIFO len = %zu, FS lock = 0x%u\n",
00196                   static_cast<uint8_t>(txRadio.getState()), txRadio.getTXFIFOLen(), txRadio.readRegister(CC1200::ExtRegister::FSCAL_CTRL) & 1);
00197 
00198         // wait a while for the packet to come in.
00199         ThisThread::sleep_for(10ms);
00200 
00201         // wait the time we expect the message to take, with a safety factor of 2
00202         auto timeoutTime = std::chrono::microseconds(static_cast<int64_t>((1/symbolRate) * 1e-6f * sizeof(message) * 2));
00203 
00204         Timer packetReceiveTimeout;
00205         packetReceiveTimeout.start();
00206         bool hasPacket;
00207         do
00208         {
00209             hasPacket = rxRadio.hasReceivedPacket();
00210         }
00211         while(packetReceiveTimeout.elapsed_time() < timeoutTime && !hasPacket);
00212 
00213         pc.printf("RX radio: state = 0x%" PRIx8 ", RX FIFO len = %zu\n",
00214                   static_cast<uint8_t>(rxRadio.getState()), rxRadio.getRXFIFOLen());
00215         if(hasPacket)
00216         {
00217             rxRadio.receivePacket(receiveBuffer, sizeof(message) - 1);
00218             receiveBuffer[sizeof(message)-1] = '\0';
00219             pc.printf(">>RECEIVED: %s\n", receiveBuffer);
00220         }
00221         else
00222         {
00223             pc.printf(">>No packet received!\n");
00224         }
00225     }
00226 }
00227 
00228 
00229 int main()
00230 {
00231     pc.printf("\nCC1200 Radio Test Suite:\n");
00232 
00233     while(1){
00234         int test=-1;
00235         //MENU. ADD AN OPTION FOR EACH TEST.
00236         pc.printf("Select a test: \n");
00237         pc.printf("1.  Exit Test Suite\n");
00238         pc.printf("2.  Check Existence\n");
00239         pc.printf("3.  Check Transmitting Signal\n");
00240 
00241         pc.scanf("%d", &test);
00242         printf("Running test %d:\n\n", test);
00243         //SWITCH. ADD A CASE FOR EACH TEST.
00244         switch(test) {
00245             case 1:         pc.printf("Exiting test suite.\n");    return 0;
00246             case 2:         checkExistance();              break;
00247             case 3:         checkSignalTransmit();              break;
00248             default:        pc.printf("Invalid test number. Please run again.\n"); continue;
00249         }
00250         pc.printf("done.\r\n");
00251     }
00252 
00253     return 0;
00254 
00255 }