Demo of how to use CC1200 radios to send data.

Dependencies:   CC1200

CC1200 Example Project

This project shows how to use my Mbed OS CC1200 driver to send messages over the air. It connects to the radio chips, configures them (using a couple of different configurations converted from SmartRF), and sends a message from a transmitter chip to a receiver.

Hardware Setup

This program assumes that two CC1200s are connected to your processor's SPI bus. The CC1200s' circuit boards must be configured for the 900MHz band. Also, if you are connecting the two radios together directly with a cable, make sure to include an attenuator (-20dB should work) to prevent overloading the radios' RX inputs.

I used a custom circuit board for my testing, but you should also be able to use an Mbed board connected to two CC1200 eval kits to run the program.

Note: License free transmission on the 900MHz band is only legal in Region 2 countries (North and South America). Make sure to follow all local regulations covering radio transmissions!

Committer:
MultipleMonomials
Date:
Fri Aug 28 16:15:10 2020 -0700
Revision:
1:7e7812669c9c
Parent:
0:ea2678a73bde
Child:
2:ff257762763e
Update CC1200 library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MultipleMonomials 0:ea2678a73bde 1 //
MultipleMonomials 0:ea2678a73bde 2 // Test suite for the CC1200 radio driver.
MultipleMonomials 0:ea2678a73bde 3 // Provides a menu to configure radio options, and
MultipleMonomials 0:ea2678a73bde 4 // attempts to send and receive a signal using two radios connected
MultipleMonomials 0:ea2678a73bde 5 // to the processor.
MultipleMonomials 0:ea2678a73bde 6 //
MultipleMonomials 0:ea2678a73bde 7
MultipleMonomials 0:ea2678a73bde 8 #include <mbed.h>
MultipleMonomials 0:ea2678a73bde 9 #include <SerialStream.h>
MultipleMonomials 0:ea2678a73bde 10
MultipleMonomials 0:ea2678a73bde 11 #include <CC1200.h>
MultipleMonomials 0:ea2678a73bde 12 #include <cinttypes>
MultipleMonomials 0:ea2678a73bde 13
MultipleMonomials 0:ea2678a73bde 14 // Pin definitions
MultipleMonomials 0:ea2678a73bde 15 // change these to match your board setup
MultipleMonomials 0:ea2678a73bde 16 #define PIN_SPI_MOSI P0_9
MultipleMonomials 0:ea2678a73bde 17 #define PIN_SPI_MISO P0_8
MultipleMonomials 0:ea2678a73bde 18 #define PIN_SPI_SCLK P0_7
MultipleMonomials 0:ea2678a73bde 19
MultipleMonomials 0:ea2678a73bde 20 #define PIN_TX_CS P0_6
MultipleMonomials 0:ea2678a73bde 21 #define PIN_TX_RST P0_29
MultipleMonomials 0:ea2678a73bde 22
MultipleMonomials 0:ea2678a73bde 23 #define PIN_RX_CS P0_4
MultipleMonomials 0:ea2678a73bde 24 #define PIN_RX_RST P0_30
MultipleMonomials 0:ea2678a73bde 25
MultipleMonomials 0:ea2678a73bde 26 BufferedSerial serial(USBTX, USBRX, 115200);
MultipleMonomials 0:ea2678a73bde 27 SerialStream<BufferedSerial> pc(serial);
MultipleMonomials 0:ea2678a73bde 28
MultipleMonomials 0:ea2678a73bde 29 CC1200 txRadio(PIN_SPI_MOSI, PIN_SPI_MISO, PIN_SPI_SCLK, PIN_TX_CS, PIN_TX_RST, &pc);
MultipleMonomials 0:ea2678a73bde 30 CC1200 rxRadio(PIN_SPI_MOSI, PIN_SPI_MISO, PIN_SPI_SCLK, PIN_RX_CS, PIN_RX_RST, &pc);
MultipleMonomials 0:ea2678a73bde 31
MultipleMonomials 0:ea2678a73bde 32 void checkExistance()
MultipleMonomials 0:ea2678a73bde 33 {
MultipleMonomials 0:ea2678a73bde 34 pc.printf("Checking TX radio.....\n");
MultipleMonomials 0:ea2678a73bde 35 bool txSuccess = txRadio.begin();
MultipleMonomials 0:ea2678a73bde 36 pc.printf("TX radio initialized: %s\n", txSuccess ? "true" : "false");
MultipleMonomials 0:ea2678a73bde 37
MultipleMonomials 0:ea2678a73bde 38 pc.printf("Checking RX radio.....\n");
MultipleMonomials 0:ea2678a73bde 39 bool rxSuccess = rxRadio.begin();
MultipleMonomials 0:ea2678a73bde 40 pc.printf("RX radio initialized: %s\n", rxSuccess ? "true" : "false");
MultipleMonomials 0:ea2678a73bde 41 }
MultipleMonomials 0:ea2678a73bde 42
MultipleMonomials 0:ea2678a73bde 43 void checkSignalTransmit()
MultipleMonomials 0:ea2678a73bde 44 {
MultipleMonomials 0:ea2678a73bde 45 pc.printf("Initializing CC1200s.....\n");
MultipleMonomials 0:ea2678a73bde 46 txRadio.begin();
MultipleMonomials 0:ea2678a73bde 47 rxRadio.begin();
MultipleMonomials 0:ea2678a73bde 48
MultipleMonomials 0:ea2678a73bde 49 pc.printf("Configuring RF settings.....\n");
MultipleMonomials 0:ea2678a73bde 50
MultipleMonomials 0:ea2678a73bde 51 int config=-1;
MultipleMonomials 0:ea2678a73bde 52 //MENU. ADD AN OPTION FOR EACH TEST.
MultipleMonomials 0:ea2678a73bde 53 pc.printf("Select a config: \n");
MultipleMonomials 0:ea2678a73bde 54 // This is similar to the SmartRF "100ksps ARIB Standard" configuration, except it doesn't use zero-if
MultipleMonomials 0:ea2678a73bde 55 pc.printf("1. 915MHz 100ksps 2-GFSK DEV=50kHz CHF=208kHz\n");
MultipleMonomials 0:ea2678a73bde 56 // This should be identical to the SmartRF "500ksps 4-GFSK Max Throughput ARIB Standard" configuration
MultipleMonomials 0:ea2678a73bde 57 pc.printf("2. 915MHz 500ksps 4-GFSK DEV=400kHz CHF=1666kHz Zero-IF\n");
MultipleMonomials 0:ea2678a73bde 58 pc.printf("3. 915MHz 38.4ksps 2-GFSK DEV=20kHz CHF=833kHz\n");
MultipleMonomials 1:7e7812669c9c 59 pc.printf("4. 915MHz 100ksps 2-GFSK DEV=50kHz CHF=208kHz Fixed Length\n");
MultipleMonomials 1:7e7812669c9c 60
MultipleMonomials 0:ea2678a73bde 61
MultipleMonomials 0:ea2678a73bde 62 pc.scanf("%d", &config);
MultipleMonomials 0:ea2678a73bde 63 printf("Running test with config %d:\n\n", config);
MultipleMonomials 0:ea2678a73bde 64
MultipleMonomials 1:7e7812669c9c 65 CC1200::PacketMode mode = CC1200::PacketMode::VARIABLE_LENGTH;
MultipleMonomials 0:ea2678a73bde 66 CC1200::Band band = CC1200::Band::BAND_820_960MHz;
MultipleMonomials 0:ea2678a73bde 67 float frequency = 915e6;
MultipleMonomials 0:ea2678a73bde 68 const float txPower = 0;
MultipleMonomials 0:ea2678a73bde 69 float fskDeviation;
MultipleMonomials 0:ea2678a73bde 70 float symbolRate;
MultipleMonomials 0:ea2678a73bde 71 float rxFilterBW;
MultipleMonomials 0:ea2678a73bde 72 CC1200::ModFormat modFormat;
MultipleMonomials 0:ea2678a73bde 73 uint8_t ifCfg = 0b101; // max IF
MultipleMonomials 0:ea2678a73bde 74 bool imageCompEnabled = true;
MultipleMonomials 0:ea2678a73bde 75 bool dcOffsetCorrEnabled = true;
MultipleMonomials 0:ea2678a73bde 76 uint8_t agcRefLevel;
MultipleMonomials 0:ea2678a73bde 77
MultipleMonomials 0:ea2678a73bde 78 uint8_t dcFiltSettingCfg = 1; // default chip setting
MultipleMonomials 0:ea2678a73bde 79 uint8_t dcFiltCutoffCfg = 4; // default chip setting
MultipleMonomials 0:ea2678a73bde 80
MultipleMonomials 0:ea2678a73bde 81 CC1200::SyncMode syncMode = CC1200::SyncMode::SYNC_32_BITS;
MultipleMonomials 0:ea2678a73bde 82 uint32_t syncWord = 0x930B51DE; // default sync word
MultipleMonomials 0:ea2678a73bde 83 uint8_t syncThreshold = 8; // TI seems to recommend this threshold for most configs above 100ksps
MultipleMonomials 0:ea2678a73bde 84
MultipleMonomials 0:ea2678a73bde 85 uint8_t preableLengthCfg = 5; // default chip setting
MultipleMonomials 0:ea2678a73bde 86 uint8_t preambleFormatCfg = 0; // default chip setting
MultipleMonomials 0:ea2678a73bde 87
MultipleMonomials 0:ea2678a73bde 88 if(config == 1)
MultipleMonomials 0:ea2678a73bde 89 {
MultipleMonomials 0:ea2678a73bde 90 fskDeviation = 49896;
MultipleMonomials 0:ea2678a73bde 91 symbolRate = 100000;
MultipleMonomials 0:ea2678a73bde 92 rxFilterBW = 208300;
MultipleMonomials 0:ea2678a73bde 93 modFormat = CC1200::ModFormat::GFSK_2;
MultipleMonomials 0:ea2678a73bde 94 agcRefLevel = 0x2A;
MultipleMonomials 0:ea2678a73bde 95 }
MultipleMonomials 0:ea2678a73bde 96 else if(config == 2)
MultipleMonomials 0:ea2678a73bde 97 {
MultipleMonomials 0:ea2678a73bde 98 // SmartRF "500ksps 4-GFSK ARIB standard" config
MultipleMonomials 0:ea2678a73bde 99 fskDeviation = 399169;
MultipleMonomials 0:ea2678a73bde 100 symbolRate = 500000;
MultipleMonomials 0:ea2678a73bde 101 rxFilterBW = 1666700;
MultipleMonomials 0:ea2678a73bde 102 ifCfg = 0;
MultipleMonomials 0:ea2678a73bde 103 imageCompEnabled = false;
MultipleMonomials 0:ea2678a73bde 104 dcOffsetCorrEnabled = true;
MultipleMonomials 0:ea2678a73bde 105 modFormat = CC1200::ModFormat::GFSK_4;
MultipleMonomials 0:ea2678a73bde 106 agcRefLevel = 0x2F;
MultipleMonomials 0:ea2678a73bde 107 }
MultipleMonomials 0:ea2678a73bde 108 else if(config == 3)
MultipleMonomials 0:ea2678a73bde 109 {
MultipleMonomials 0:ea2678a73bde 110 fskDeviation = 19989;
MultipleMonomials 0:ea2678a73bde 111 symbolRate = 38400;
MultipleMonomials 0:ea2678a73bde 112 rxFilterBW = 104200;
MultipleMonomials 0:ea2678a73bde 113 modFormat = CC1200::ModFormat::GFSK_2;
MultipleMonomials 0:ea2678a73bde 114 agcRefLevel = 0x27;
MultipleMonomials 0:ea2678a73bde 115 }
MultipleMonomials 1:7e7812669c9c 116 else if(config == 4)
MultipleMonomials 1:7e7812669c9c 117 {
MultipleMonomials 1:7e7812669c9c 118 fskDeviation = 49896;
MultipleMonomials 1:7e7812669c9c 119 symbolRate = 100000;
MultipleMonomials 1:7e7812669c9c 120 rxFilterBW = 208300;
MultipleMonomials 1:7e7812669c9c 121 modFormat = CC1200::ModFormat::GFSK_2;
MultipleMonomials 1:7e7812669c9c 122 agcRefLevel = 0x2A;
MultipleMonomials 1:7e7812669c9c 123 mode = CC1200::PacketMode::FIXED_LENGTH;
MultipleMonomials 1:7e7812669c9c 124 }
MultipleMonomials 0:ea2678a73bde 125 else
MultipleMonomials 0:ea2678a73bde 126 {
MultipleMonomials 0:ea2678a73bde 127 pc.printf("Invalid config number!");
MultipleMonomials 0:ea2678a73bde 128 return;
MultipleMonomials 0:ea2678a73bde 129 }
MultipleMonomials 0:ea2678a73bde 130
MultipleMonomials 0:ea2678a73bde 131 for(CC1200 & radio : {std::ref(txRadio), std::ref(rxRadio)})
MultipleMonomials 0:ea2678a73bde 132 {
MultipleMonomials 0:ea2678a73bde 133
MultipleMonomials 0:ea2678a73bde 134 radio.configureFIFOMode();
MultipleMonomials 1:7e7812669c9c 135 radio.setPacketMode(mode);
MultipleMonomials 0:ea2678a73bde 136 radio.setModulationFormat(modFormat);
MultipleMonomials 0:ea2678a73bde 137 radio.setFSKDeviation(fskDeviation);
MultipleMonomials 0:ea2678a73bde 138 radio.setSymbolRate(symbolRate);
MultipleMonomials 0:ea2678a73bde 139 radio.setOutputPower(txPower);
MultipleMonomials 0:ea2678a73bde 140 radio.setRadioFrequency(band, frequency);
MultipleMonomials 0:ea2678a73bde 141 radio.setIFMixCFG(ifCfg);
MultipleMonomials 0:ea2678a73bde 142 radio.configureDCFilter(dcOffsetCorrEnabled, dcFiltSettingCfg, dcFiltCutoffCfg);
MultipleMonomials 0:ea2678a73bde 143 radio.setIQMismatchCompensationEnabled(imageCompEnabled);
MultipleMonomials 0:ea2678a73bde 144 radio.setRXFilterBandwidth(rxFilterBW);
MultipleMonomials 0:ea2678a73bde 145 radio.configureSyncWord(syncWord, syncMode, syncThreshold);
MultipleMonomials 0:ea2678a73bde 146 radio.configurePreamble(preableLengthCfg, preambleFormatCfg);
MultipleMonomials 0:ea2678a73bde 147
MultipleMonomials 0:ea2678a73bde 148 // AGC configuration (straight from SmartRF)
MultipleMonomials 0:ea2678a73bde 149 radio.setAGCReferenceLevel(agcRefLevel);
MultipleMonomials 0:ea2678a73bde 150 radio.setAGCSyncBehavior(CC1200::SyncBehavior::FREEZE_NONE);
MultipleMonomials 0:ea2678a73bde 151 if(ifCfg == 0)
MultipleMonomials 0:ea2678a73bde 152 {
MultipleMonomials 0:ea2678a73bde 153 radio.setAGCGainTable(CC1200::GainTable::ZERO_IF, 11, 0);
MultipleMonomials 0:ea2678a73bde 154 }
MultipleMonomials 0:ea2678a73bde 155 else
MultipleMonomials 0:ea2678a73bde 156 {
MultipleMonomials 0:ea2678a73bde 157 // enable all AGC steps for NORMAL mode
MultipleMonomials 0:ea2678a73bde 158 radio.setAGCGainTable(CC1200::GainTable::NORMAL, 17, 0);
MultipleMonomials 0:ea2678a73bde 159 }
MultipleMonomials 0:ea2678a73bde 160 radio.setAGCHysteresis(0b10);
MultipleMonomials 0:ea2678a73bde 161 radio.setAGCSlewRate(0);
MultipleMonomials 0:ea2678a73bde 162 }
MultipleMonomials 0:ea2678a73bde 163
MultipleMonomials 0:ea2678a73bde 164 // configure on-transmit actions
MultipleMonomials 0:ea2678a73bde 165 txRadio.setOnTransmitState(CC1200::State::TX);
MultipleMonomials 0:ea2678a73bde 166 rxRadio.setOnReceiveState(CC1200::State::RX, CC1200::State::RX);
MultipleMonomials 0:ea2678a73bde 167
MultipleMonomials 0:ea2678a73bde 168 pc.printf("Starting transmission.....\n");
MultipleMonomials 0:ea2678a73bde 169
MultipleMonomials 0:ea2678a73bde 170 txRadio.startTX();
MultipleMonomials 0:ea2678a73bde 171 rxRadio.startRX();
MultipleMonomials 0:ea2678a73bde 172
MultipleMonomials 0:ea2678a73bde 173 const char message[] = "Hello world!";
MultipleMonomials 1:7e7812669c9c 174 char receiveBuffer[sizeof(message)];
MultipleMonomials 0:ea2678a73bde 175
MultipleMonomials 1:7e7812669c9c 176 if(mode == CC1200::PacketMode::FIXED_LENGTH)
MultipleMonomials 1:7e7812669c9c 177 {
MultipleMonomials 1:7e7812669c9c 178 txRadio.setPacketLength(sizeof(message) - 1);
MultipleMonomials 1:7e7812669c9c 179 rxRadio.setPacketLength(sizeof(message) - 1);
MultipleMonomials 1:7e7812669c9c 180 }
MultipleMonomials 0:ea2678a73bde 181
MultipleMonomials 0:ea2678a73bde 182 while(true)
MultipleMonomials 0:ea2678a73bde 183 {
MultipleMonomials 0:ea2678a73bde 184 ThisThread::sleep_for(1s);
MultipleMonomials 0:ea2678a73bde 185
MultipleMonomials 0:ea2678a73bde 186 pc.printf("\n---------------------------------\n");
MultipleMonomials 0:ea2678a73bde 187
MultipleMonomials 0:ea2678a73bde 188 pc.printf("<<SENDING: %s\n", message);
MultipleMonomials 1:7e7812669c9c 189 txRadio.enqueuePacket(message, sizeof(message) - 1);
MultipleMonomials 0:ea2678a73bde 190
MultipleMonomials 0:ea2678a73bde 191
MultipleMonomials 0:ea2678a73bde 192 // update TX radio
MultipleMonomials 0:ea2678a73bde 193 pc.printf("TX radio: state = 0x%" PRIx8 ", TX FIFO len = %zu, FS lock = 0x%u\n",
MultipleMonomials 0:ea2678a73bde 194 static_cast<uint8_t>(txRadio.getState()), txRadio.getTXFIFOLen(), txRadio.readRegister(CC1200::ExtRegister::FSCAL_CTRL) & 1);
MultipleMonomials 0:ea2678a73bde 195
MultipleMonomials 0:ea2678a73bde 196 // wait a while for the packet to come in.
MultipleMonomials 0:ea2678a73bde 197 ThisThread::sleep_for(10ms);
MultipleMonomials 0:ea2678a73bde 198
MultipleMonomials 0:ea2678a73bde 199 // wait the time we expect the message to take, with a safety factor of 2
MultipleMonomials 0:ea2678a73bde 200 auto timeoutTime = std::chrono::microseconds(static_cast<int64_t>((1/symbolRate) * 1e-6f * sizeof(message) * 2));
MultipleMonomials 0:ea2678a73bde 201
MultipleMonomials 0:ea2678a73bde 202 Timer packetReceiveTimeout;
MultipleMonomials 0:ea2678a73bde 203 packetReceiveTimeout.start();
MultipleMonomials 0:ea2678a73bde 204 bool hasPacket;
MultipleMonomials 0:ea2678a73bde 205 do
MultipleMonomials 0:ea2678a73bde 206 {
MultipleMonomials 0:ea2678a73bde 207 hasPacket = rxRadio.hasReceivedPacket();
MultipleMonomials 0:ea2678a73bde 208 }
MultipleMonomials 0:ea2678a73bde 209 while(packetReceiveTimeout.elapsed_time() < timeoutTime && !hasPacket);
MultipleMonomials 0:ea2678a73bde 210
MultipleMonomials 0:ea2678a73bde 211 pc.printf("RX radio: state = 0x%" PRIx8 ", RX FIFO len = %zu\n",
MultipleMonomials 0:ea2678a73bde 212 static_cast<uint8_t>(rxRadio.getState()), rxRadio.getRXFIFOLen());
MultipleMonomials 0:ea2678a73bde 213 if(hasPacket)
MultipleMonomials 0:ea2678a73bde 214 {
MultipleMonomials 1:7e7812669c9c 215 rxRadio.receivePacket(receiveBuffer, sizeof(message) - 1);
MultipleMonomials 1:7e7812669c9c 216 receiveBuffer[sizeof(message)-1] = '\0';
MultipleMonomials 0:ea2678a73bde 217 pc.printf(">>RECEIVED: %s\n", receiveBuffer);
MultipleMonomials 0:ea2678a73bde 218 }
MultipleMonomials 0:ea2678a73bde 219 else
MultipleMonomials 0:ea2678a73bde 220 {
MultipleMonomials 0:ea2678a73bde 221 pc.printf(">>No packet received!\n");
MultipleMonomials 0:ea2678a73bde 222 }
MultipleMonomials 0:ea2678a73bde 223 }
MultipleMonomials 0:ea2678a73bde 224 }
MultipleMonomials 0:ea2678a73bde 225
MultipleMonomials 0:ea2678a73bde 226
MultipleMonomials 0:ea2678a73bde 227 int main()
MultipleMonomials 0:ea2678a73bde 228 {
MultipleMonomials 0:ea2678a73bde 229 pc.printf("\nCC1200 Radio Test Suite:\n");
MultipleMonomials 0:ea2678a73bde 230
MultipleMonomials 0:ea2678a73bde 231 while(1){
MultipleMonomials 0:ea2678a73bde 232 int test=-1;
MultipleMonomials 0:ea2678a73bde 233 //MENU. ADD AN OPTION FOR EACH TEST.
MultipleMonomials 0:ea2678a73bde 234 pc.printf("Select a test: \n");
MultipleMonomials 0:ea2678a73bde 235 pc.printf("1. Exit Test Suite\n");
MultipleMonomials 0:ea2678a73bde 236 pc.printf("2. Check Existence\n");
MultipleMonomials 0:ea2678a73bde 237 pc.printf("3. Check Transmitting Signal\n");
MultipleMonomials 0:ea2678a73bde 238
MultipleMonomials 0:ea2678a73bde 239 pc.scanf("%d", &test);
MultipleMonomials 0:ea2678a73bde 240 printf("Running test %d:\n\n", test);
MultipleMonomials 0:ea2678a73bde 241 //SWITCH. ADD A CASE FOR EACH TEST.
MultipleMonomials 0:ea2678a73bde 242 switch(test) {
MultipleMonomials 0:ea2678a73bde 243 case 1: pc.printf("Exiting test suite.\n"); return 0;
MultipleMonomials 0:ea2678a73bde 244 case 2: checkExistance(); break;
MultipleMonomials 0:ea2678a73bde 245 case 3: checkSignalTransmit(); break;
MultipleMonomials 0:ea2678a73bde 246 default: pc.printf("Invalid test number. Please run again.\n"); continue;
MultipleMonomials 0:ea2678a73bde 247 }
MultipleMonomials 0:ea2678a73bde 248 pc.printf("done.\r\n");
MultipleMonomials 0:ea2678a73bde 249 }
MultipleMonomials 0:ea2678a73bde 250
MultipleMonomials 0:ea2678a73bde 251 return 0;
MultipleMonomials 0:ea2678a73bde 252
MultipleMonomials 0:ea2678a73bde 253 }