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:
Mon May 03 02:47:04 2021 -0700
Revision:
3:2d1f7e1cd3d4
Parent:
2:ff257762763e
Update CC1200 driver version

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 2:ff257762763e 73 CC1200::IFCfg ifCfg = CC1200::IFCfg::POSITIVE_DIV_8;
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 2:ff257762763e 80 uint8_t agcSettleWaitCfg = 2;
MultipleMonomials 0:ea2678a73bde 81
MultipleMonomials 0:ea2678a73bde 82 CC1200::SyncMode syncMode = CC1200::SyncMode::SYNC_32_BITS;
MultipleMonomials 0:ea2678a73bde 83 uint32_t syncWord = 0x930B51DE; // default sync word
MultipleMonomials 0:ea2678a73bde 84 uint8_t syncThreshold = 8; // TI seems to recommend this threshold for most configs above 100ksps
MultipleMonomials 0:ea2678a73bde 85
MultipleMonomials 0:ea2678a73bde 86 uint8_t preableLengthCfg = 5; // default chip setting
MultipleMonomials 0:ea2678a73bde 87 uint8_t preambleFormatCfg = 0; // default chip setting
MultipleMonomials 0:ea2678a73bde 88
MultipleMonomials 0:ea2678a73bde 89 if(config == 1)
MultipleMonomials 0:ea2678a73bde 90 {
MultipleMonomials 0:ea2678a73bde 91 fskDeviation = 49896;
MultipleMonomials 0:ea2678a73bde 92 symbolRate = 100000;
MultipleMonomials 0:ea2678a73bde 93 rxFilterBW = 208300;
MultipleMonomials 0:ea2678a73bde 94 modFormat = CC1200::ModFormat::GFSK_2;
MultipleMonomials 0:ea2678a73bde 95 agcRefLevel = 0x2A;
MultipleMonomials 0:ea2678a73bde 96 }
MultipleMonomials 0:ea2678a73bde 97 else if(config == 2)
MultipleMonomials 0:ea2678a73bde 98 {
MultipleMonomials 0:ea2678a73bde 99 // SmartRF "500ksps 4-GFSK ARIB standard" config
MultipleMonomials 0:ea2678a73bde 100 fskDeviation = 399169;
MultipleMonomials 0:ea2678a73bde 101 symbolRate = 500000;
MultipleMonomials 0:ea2678a73bde 102 rxFilterBW = 1666700;
MultipleMonomials 2:ff257762763e 103 ifCfg = CC1200::IFCfg::ZERO;
MultipleMonomials 0:ea2678a73bde 104 imageCompEnabled = false;
MultipleMonomials 0:ea2678a73bde 105 dcOffsetCorrEnabled = true;
MultipleMonomials 0:ea2678a73bde 106 modFormat = CC1200::ModFormat::GFSK_4;
MultipleMonomials 0:ea2678a73bde 107 agcRefLevel = 0x2F;
MultipleMonomials 0:ea2678a73bde 108 }
MultipleMonomials 0:ea2678a73bde 109 else if(config == 3)
MultipleMonomials 0:ea2678a73bde 110 {
MultipleMonomials 0:ea2678a73bde 111 fskDeviation = 19989;
MultipleMonomials 0:ea2678a73bde 112 symbolRate = 38400;
MultipleMonomials 0:ea2678a73bde 113 rxFilterBW = 104200;
MultipleMonomials 0:ea2678a73bde 114 modFormat = CC1200::ModFormat::GFSK_2;
MultipleMonomials 0:ea2678a73bde 115 agcRefLevel = 0x27;
MultipleMonomials 2:ff257762763e 116 agcSettleWaitCfg = 1;
MultipleMonomials 0:ea2678a73bde 117 }
MultipleMonomials 1:7e7812669c9c 118 else if(config == 4)
MultipleMonomials 1:7e7812669c9c 119 {
MultipleMonomials 1:7e7812669c9c 120 fskDeviation = 49896;
MultipleMonomials 1:7e7812669c9c 121 symbolRate = 100000;
MultipleMonomials 1:7e7812669c9c 122 rxFilterBW = 208300;
MultipleMonomials 1:7e7812669c9c 123 modFormat = CC1200::ModFormat::GFSK_2;
MultipleMonomials 1:7e7812669c9c 124 agcRefLevel = 0x2A;
MultipleMonomials 1:7e7812669c9c 125 mode = CC1200::PacketMode::FIXED_LENGTH;
MultipleMonomials 1:7e7812669c9c 126 }
MultipleMonomials 0:ea2678a73bde 127 else
MultipleMonomials 0:ea2678a73bde 128 {
MultipleMonomials 0:ea2678a73bde 129 pc.printf("Invalid config number!");
MultipleMonomials 0:ea2678a73bde 130 return;
MultipleMonomials 0:ea2678a73bde 131 }
MultipleMonomials 0:ea2678a73bde 132
MultipleMonomials 0:ea2678a73bde 133 for(CC1200 & radio : {std::ref(txRadio), std::ref(rxRadio)})
MultipleMonomials 0:ea2678a73bde 134 {
MultipleMonomials 0:ea2678a73bde 135
MultipleMonomials 0:ea2678a73bde 136 radio.configureFIFOMode();
MultipleMonomials 1:7e7812669c9c 137 radio.setPacketMode(mode);
MultipleMonomials 0:ea2678a73bde 138 radio.setModulationFormat(modFormat);
MultipleMonomials 0:ea2678a73bde 139 radio.setFSKDeviation(fskDeviation);
MultipleMonomials 0:ea2678a73bde 140 radio.setSymbolRate(symbolRate);
MultipleMonomials 0:ea2678a73bde 141 radio.setOutputPower(txPower);
MultipleMonomials 0:ea2678a73bde 142 radio.setRadioFrequency(band, frequency);
MultipleMonomials 2:ff257762763e 143 radio.setIFCfg(ifCfg, imageCompEnabled);
MultipleMonomials 0:ea2678a73bde 144 radio.configureDCFilter(dcOffsetCorrEnabled, dcFiltSettingCfg, dcFiltCutoffCfg);
MultipleMonomials 0:ea2678a73bde 145 radio.setRXFilterBandwidth(rxFilterBW);
MultipleMonomials 0:ea2678a73bde 146 radio.configureSyncWord(syncWord, syncMode, syncThreshold);
MultipleMonomials 0:ea2678a73bde 147 radio.configurePreamble(preableLengthCfg, preambleFormatCfg);
MultipleMonomials 0:ea2678a73bde 148
MultipleMonomials 0:ea2678a73bde 149 // AGC configuration (straight from SmartRF)
MultipleMonomials 0:ea2678a73bde 150 radio.setAGCReferenceLevel(agcRefLevel);
MultipleMonomials 0:ea2678a73bde 151 radio.setAGCSyncBehavior(CC1200::SyncBehavior::FREEZE_NONE);
MultipleMonomials 2:ff257762763e 152 radio.setAGCSettleWait(agcSettleWaitCfg);
MultipleMonomials 2:ff257762763e 153 if(ifCfg == CC1200::IFCfg::ZERO)
MultipleMonomials 0:ea2678a73bde 154 {
MultipleMonomials 0:ea2678a73bde 155 radio.setAGCGainTable(CC1200::GainTable::ZERO_IF, 11, 0);
MultipleMonomials 0:ea2678a73bde 156 }
MultipleMonomials 0:ea2678a73bde 157 else
MultipleMonomials 0:ea2678a73bde 158 {
MultipleMonomials 0:ea2678a73bde 159 // enable all AGC steps for NORMAL mode
MultipleMonomials 0:ea2678a73bde 160 radio.setAGCGainTable(CC1200::GainTable::NORMAL, 17, 0);
MultipleMonomials 0:ea2678a73bde 161 }
MultipleMonomials 0:ea2678a73bde 162 radio.setAGCHysteresis(0b10);
MultipleMonomials 0:ea2678a73bde 163 radio.setAGCSlewRate(0);
MultipleMonomials 0:ea2678a73bde 164 }
MultipleMonomials 0:ea2678a73bde 165
MultipleMonomials 0:ea2678a73bde 166 // configure on-transmit actions
MultipleMonomials 0:ea2678a73bde 167 txRadio.setOnTransmitState(CC1200::State::TX);
MultipleMonomials 0:ea2678a73bde 168 rxRadio.setOnReceiveState(CC1200::State::RX, CC1200::State::RX);
MultipleMonomials 0:ea2678a73bde 169
MultipleMonomials 0:ea2678a73bde 170 pc.printf("Starting transmission.....\n");
MultipleMonomials 0:ea2678a73bde 171
MultipleMonomials 0:ea2678a73bde 172 txRadio.startTX();
MultipleMonomials 0:ea2678a73bde 173 rxRadio.startRX();
MultipleMonomials 0:ea2678a73bde 174
MultipleMonomials 0:ea2678a73bde 175 const char message[] = "Hello world!";
MultipleMonomials 1:7e7812669c9c 176 char receiveBuffer[sizeof(message)];
MultipleMonomials 0:ea2678a73bde 177
MultipleMonomials 1:7e7812669c9c 178 if(mode == CC1200::PacketMode::FIXED_LENGTH)
MultipleMonomials 1:7e7812669c9c 179 {
MultipleMonomials 1:7e7812669c9c 180 txRadio.setPacketLength(sizeof(message) - 1);
MultipleMonomials 1:7e7812669c9c 181 rxRadio.setPacketLength(sizeof(message) - 1);
MultipleMonomials 1:7e7812669c9c 182 }
MultipleMonomials 0:ea2678a73bde 183
MultipleMonomials 0:ea2678a73bde 184 while(true)
MultipleMonomials 0:ea2678a73bde 185 {
MultipleMonomials 0:ea2678a73bde 186 ThisThread::sleep_for(1s);
MultipleMonomials 0:ea2678a73bde 187
MultipleMonomials 0:ea2678a73bde 188 pc.printf("\n---------------------------------\n");
MultipleMonomials 0:ea2678a73bde 189
MultipleMonomials 0:ea2678a73bde 190 pc.printf("<<SENDING: %s\n", message);
MultipleMonomials 1:7e7812669c9c 191 txRadio.enqueuePacket(message, sizeof(message) - 1);
MultipleMonomials 0:ea2678a73bde 192
MultipleMonomials 0:ea2678a73bde 193
MultipleMonomials 0:ea2678a73bde 194 // update TX radio
MultipleMonomials 0:ea2678a73bde 195 pc.printf("TX radio: state = 0x%" PRIx8 ", TX FIFO len = %zu, FS lock = 0x%u\n",
MultipleMonomials 0:ea2678a73bde 196 static_cast<uint8_t>(txRadio.getState()), txRadio.getTXFIFOLen(), txRadio.readRegister(CC1200::ExtRegister::FSCAL_CTRL) & 1);
MultipleMonomials 0:ea2678a73bde 197
MultipleMonomials 0:ea2678a73bde 198 // wait a while for the packet to come in.
MultipleMonomials 0:ea2678a73bde 199 ThisThread::sleep_for(10ms);
MultipleMonomials 0:ea2678a73bde 200
MultipleMonomials 0:ea2678a73bde 201 // wait the time we expect the message to take, with a safety factor of 2
MultipleMonomials 0:ea2678a73bde 202 auto timeoutTime = std::chrono::microseconds(static_cast<int64_t>((1/symbolRate) * 1e-6f * sizeof(message) * 2));
MultipleMonomials 0:ea2678a73bde 203
MultipleMonomials 0:ea2678a73bde 204 Timer packetReceiveTimeout;
MultipleMonomials 0:ea2678a73bde 205 packetReceiveTimeout.start();
MultipleMonomials 0:ea2678a73bde 206 bool hasPacket;
MultipleMonomials 0:ea2678a73bde 207 do
MultipleMonomials 0:ea2678a73bde 208 {
MultipleMonomials 0:ea2678a73bde 209 hasPacket = rxRadio.hasReceivedPacket();
MultipleMonomials 0:ea2678a73bde 210 }
MultipleMonomials 0:ea2678a73bde 211 while(packetReceiveTimeout.elapsed_time() < timeoutTime && !hasPacket);
MultipleMonomials 0:ea2678a73bde 212
MultipleMonomials 0:ea2678a73bde 213 pc.printf("RX radio: state = 0x%" PRIx8 ", RX FIFO len = %zu\n",
MultipleMonomials 0:ea2678a73bde 214 static_cast<uint8_t>(rxRadio.getState()), rxRadio.getRXFIFOLen());
MultipleMonomials 0:ea2678a73bde 215 if(hasPacket)
MultipleMonomials 0:ea2678a73bde 216 {
MultipleMonomials 1:7e7812669c9c 217 rxRadio.receivePacket(receiveBuffer, sizeof(message) - 1);
MultipleMonomials 1:7e7812669c9c 218 receiveBuffer[sizeof(message)-1] = '\0';
MultipleMonomials 0:ea2678a73bde 219 pc.printf(">>RECEIVED: %s\n", receiveBuffer);
MultipleMonomials 0:ea2678a73bde 220 }
MultipleMonomials 0:ea2678a73bde 221 else
MultipleMonomials 0:ea2678a73bde 222 {
MultipleMonomials 0:ea2678a73bde 223 pc.printf(">>No packet received!\n");
MultipleMonomials 0:ea2678a73bde 224 }
MultipleMonomials 0:ea2678a73bde 225 }
MultipleMonomials 0:ea2678a73bde 226 }
MultipleMonomials 0:ea2678a73bde 227
MultipleMonomials 0:ea2678a73bde 228
MultipleMonomials 0:ea2678a73bde 229 int main()
MultipleMonomials 0:ea2678a73bde 230 {
MultipleMonomials 0:ea2678a73bde 231 pc.printf("\nCC1200 Radio Test Suite:\n");
MultipleMonomials 0:ea2678a73bde 232
MultipleMonomials 0:ea2678a73bde 233 while(1){
MultipleMonomials 0:ea2678a73bde 234 int test=-1;
MultipleMonomials 0:ea2678a73bde 235 //MENU. ADD AN OPTION FOR EACH TEST.
MultipleMonomials 0:ea2678a73bde 236 pc.printf("Select a test: \n");
MultipleMonomials 0:ea2678a73bde 237 pc.printf("1. Exit Test Suite\n");
MultipleMonomials 0:ea2678a73bde 238 pc.printf("2. Check Existence\n");
MultipleMonomials 0:ea2678a73bde 239 pc.printf("3. Check Transmitting Signal\n");
MultipleMonomials 0:ea2678a73bde 240
MultipleMonomials 0:ea2678a73bde 241 pc.scanf("%d", &test);
MultipleMonomials 0:ea2678a73bde 242 printf("Running test %d:\n\n", test);
MultipleMonomials 0:ea2678a73bde 243 //SWITCH. ADD A CASE FOR EACH TEST.
MultipleMonomials 0:ea2678a73bde 244 switch(test) {
MultipleMonomials 0:ea2678a73bde 245 case 1: pc.printf("Exiting test suite.\n"); return 0;
MultipleMonomials 0:ea2678a73bde 246 case 2: checkExistance(); break;
MultipleMonomials 0:ea2678a73bde 247 case 3: checkSignalTransmit(); break;
MultipleMonomials 0:ea2678a73bde 248 default: pc.printf("Invalid test number. Please run again.\n"); continue;
MultipleMonomials 0:ea2678a73bde 249 }
MultipleMonomials 0:ea2678a73bde 250 pc.printf("done.\r\n");
MultipleMonomials 0:ea2678a73bde 251 }
MultipleMonomials 0:ea2678a73bde 252
MultipleMonomials 0:ea2678a73bde 253 return 0;
MultipleMonomials 0:ea2678a73bde 254
MultipleMonomials 0:ea2678a73bde 255 }