Driver for TI's CC1200 radio ICs. Forget hardcoded register settings -- this driver calculates everything from scratch!

Dependents:   CC1200-MorseEncoder CC1200-Examples

CC1200 Driver

by Jamie Smith / USC Rocket Propulsion Lab

After months of work, we are proud to present our driver for Texas Instruments' CC1200 digital radio IC! This driver has been written from scratch to be an easy and flexible way of using this radio transceiver. For our application, we needed to be able to tune each and every setting of the radio to try and eke that last bit of performance of our system - so using premade configurations alone wasn't going to cut it! Instead, this driver calculates each parameter of the radio using the equations and instructions given in the datasheet. So, you can tweak parameters to your heart's content, and you shouldn't have to do any math yourself!

Features

  • Automatic calculation of correct register values for:
    • RF frequency
    • FSK deviation
    • Symbol rate
    • Output power
    • RX filter bandwidth (this one's harder than it looks!)
  • Easy handling of data packets
  • GPIO configuration
  • Preamble and sync word configuration
  • RTOS compatible (always locks SPI bus during transactions)
  • Two debug levels available
  • RSSI and LQI support

Not Supported

  • Transparent mode
  • FM mode
  • ASK parameter configuration
  • Frequency offsets

Examples

  • See the example project here for an example of how to use the driver.
  • Another example (using a more exotic configuration) is the CC1200-MorseEncoder.

Changelog

Version 1.2 May 3 2021

  • Added unfinished infinite length packet support via the readStream() and writeStream() functions. The API is complete and basic usage works but there's still a bug I haven't been able to track down yet where incorrect data is transmitted at the end of a stream. Use with caution!
  • Added preferHigherCICDec parameter to setRXFilterBandwidth
  • Removed setIFMixCFG() (which takes a byte parameter) and replaced it with setIFCfg(), which takes documented enum class values.
  • Added setAGCSettleWait(), which per my testing is needed for correct 430MHz operation.
  • Added support for reading RSSI and LQI values, both from packet appended status bytes and from the registers.
  • Update 430MHz black box registers based on SmartRF values
  • Removed setIQMismatchCompensationEnabled(). This call has been replaced by the new 2nd parameter to setIFCfg().

Version 1.1 Aug 28 2020

  • Add fixed length packet support and other features needed for Morse support.
  • Fix bug causing weird behavior with low sample rates (<1ksps).

NOTE: you must now call setPacketMode() when configuring the radio.

Version 1.0 Aug 10 2020

Initial Release

Committer:
Jamie Smith
Date:
Sun Aug 09 23:39:21 2020 -0700
Revision:
1:98af824b145e
Parent:
0:0c3532738887
Child:
2:2a447e8e50b8
Add a few new features, fix issue with reading from wrong FIFO

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jamie Smith 0:0c3532738887 1 //
Jamie Smith 0:0c3532738887 2 // Created by jamie on 3/27/2020.
Jamie Smith 0:0c3532738887 3 //
Jamie Smith 0:0c3532738887 4
Jamie Smith 0:0c3532738887 5 #ifndef LIGHTSPEEDRANGEFINDER_CC1200_H
Jamie Smith 0:0c3532738887 6 #define LIGHTSPEEDRANGEFINDER_CC1200_H
Jamie Smith 0:0c3532738887 7
Jamie Smith 0:0c3532738887 8 #include <mbed.h>
Jamie Smith 0:0c3532738887 9
Jamie Smith 0:0c3532738887 10 #include <cstdint>
Jamie Smith 0:0c3532738887 11
Jamie Smith 0:0c3532738887 12 /**
Jamie Smith 0:0c3532738887 13 * Base driver for the CC1200 radio communications IC.
Jamie Smith 0:0c3532738887 14 * This class provides basic functions and register level IO with the chip.
Jamie Smith 0:0c3532738887 15 */
Jamie Smith 0:0c3532738887 16 class CC1200
Jamie Smith 0:0c3532738887 17 {
Jamie Smith 0:0c3532738887 18 // connections to chip
Jamie Smith 0:0c3532738887 19 SPI spi;
Jamie Smith 0:0c3532738887 20 DigitalOut rst;
Jamie Smith 0:0c3532738887 21
Jamie Smith 0:0c3532738887 22 // Output to print debug messages to
Jamie Smith 0:0c3532738887 23 Stream * debugStream;
Jamie Smith 0:0c3532738887 24
Jamie Smith 0:0c3532738887 25 public:
Jamie Smith 0:0c3532738887 26
Jamie Smith 0:0c3532738887 27 // register definitions
Jamie Smith 0:0c3532738887 28 enum class Register : uint8_t
Jamie Smith 0:0c3532738887 29 {
Jamie Smith 0:0c3532738887 30 IOCFG3 = 0x00,
Jamie Smith 0:0c3532738887 31 IOCFG2 = 0x01,
Jamie Smith 0:0c3532738887 32 IOCFG1 = 0x02,
Jamie Smith 0:0c3532738887 33 IOCFG0 = 0x03,
Jamie Smith 0:0c3532738887 34 SYNC3 = 0x4,
Jamie Smith 0:0c3532738887 35 SYNC2 = 0x5,
Jamie Smith 0:0c3532738887 36 SYNC1 = 0x6,
Jamie Smith 0:0c3532738887 37 SYNC0 = 0x7,
Jamie Smith 0:0c3532738887 38 SYNC_CFG1 = 0x8,
Jamie Smith 0:0c3532738887 39 SYNC_CFG0 = 0x9,
Jamie Smith 0:0c3532738887 40 DEVIATION_M = 0xA,
Jamie Smith 0:0c3532738887 41 MODCFG_DEV_E = 0xB,
Jamie Smith 0:0c3532738887 42 DCFILT_CFG = 0xC,
Jamie Smith 0:0c3532738887 43 PREAMBLE_CFG1 = 0xD,
Jamie Smith 0:0c3532738887 44 PREAMBLE_CFG0 = 0xE,
Jamie Smith 0:0c3532738887 45 IQIC = 0xF,
Jamie Smith 0:0c3532738887 46 CHAN_BW = 0x10,
Jamie Smith 0:0c3532738887 47 MDMCFG1 = 0x11,
Jamie Smith 0:0c3532738887 48 MDMCFG0 = 0x12,
Jamie Smith 0:0c3532738887 49 SYMBOL_RATE2 = 0x13,
Jamie Smith 0:0c3532738887 50 SYMBOL_RATE1 = 0x14,
Jamie Smith 0:0c3532738887 51 SYMBOL_RATE0 = 0x15,
Jamie Smith 0:0c3532738887 52 AGC_REF = 0x16,
Jamie Smith 0:0c3532738887 53 AGC_CS_THR = 0x17,
Jamie Smith 0:0c3532738887 54 AGC_GAIN_ADJUST = 0x18,
Jamie Smith 0:0c3532738887 55 AGC_CFG3 = 0x19,
Jamie Smith 0:0c3532738887 56 AGC_CFG2 = 0x1A,
Jamie Smith 0:0c3532738887 57 AGC_CFG1 = 0x1B,
Jamie Smith 0:0c3532738887 58 AGC_CFG0 = 0x1C,
Jamie Smith 0:0c3532738887 59 FIFO_CFG = 0x1D,
Jamie Smith 0:0c3532738887 60 DEV_ADDR = 0x1E,
Jamie Smith 0:0c3532738887 61 SETTLING_CFG = 0x1F,
Jamie Smith 0:0c3532738887 62 FS_CFG = 0x20,
Jamie Smith 0:0c3532738887 63 WOR_CFG1 = 0x21,
Jamie Smith 0:0c3532738887 64 WOR_CFG0 = 0x22,
Jamie Smith 0:0c3532738887 65 WOR_EVENT0_MSB = 0x23,
Jamie Smith 0:0c3532738887 66 WOR_EVENT0_LSB = 0x24,
Jamie Smith 0:0c3532738887 67 RXDCM_TIME = 0x25,
Jamie Smith 0:0c3532738887 68 PKT_CFG2 = 0x26,
Jamie Smith 0:0c3532738887 69 PKT_CFG1 = 0x27,
Jamie Smith 0:0c3532738887 70 PKT_CFG0 = 0x28,
Jamie Smith 0:0c3532738887 71 RFEND_CFG1 = 0x29,
Jamie Smith 0:0c3532738887 72 RFEND_CFG0 = 0x2A,
Jamie Smith 0:0c3532738887 73 PA_CFG1 = 0x2B,
Jamie Smith 0:0c3532738887 74 PA_CFG0 = 0x2C,
Jamie Smith 0:0c3532738887 75 ASK_CFG = 0x2D,
Jamie Smith 0:0c3532738887 76 PKT_LEN = 0x2E
Jamie Smith 0:0c3532738887 77 };
Jamie Smith 0:0c3532738887 78
Jamie Smith 0:0c3532738887 79 // extended register definitions
Jamie Smith 0:0c3532738887 80 enum class ExtRegister : uint8_t
Jamie Smith 0:0c3532738887 81 {
Jamie Smith 0:0c3532738887 82 IF_MIX_CFG = 0x0,
Jamie Smith 0:0c3532738887 83 FREQOFF_CFG = 0x1,
Jamie Smith 0:0c3532738887 84 TOC_CFG = 0x2,
Jamie Smith 0:0c3532738887 85 //...
Jamie Smith 0:0c3532738887 86 MDMCFG2 = 0x5,
Jamie Smith 0:0c3532738887 87 //...
Jamie Smith 0:0c3532738887 88 FREQOFF1 = 0xA,
Jamie Smith 0:0c3532738887 89 FREQOFF2 = 0xB,
Jamie Smith 0:0c3532738887 90 FREQ2 = 0xC,
Jamie Smith 0:0c3532738887 91 FREQ1 = 0xD,
Jamie Smith 0:0c3532738887 92 FREQ0 = 0xE,
Jamie Smith 0:0c3532738887 93 IF_ADC2 = 0xF,
Jamie Smith 0:0c3532738887 94 IF_ADC1 = 0x10,
Jamie Smith 0:0c3532738887 95 IF_ADC0 = 0x11,
Jamie Smith 0:0c3532738887 96 FS_DIG1 = 0x12,
Jamie Smith 0:0c3532738887 97 FS_DIG0 = 0x13,
Jamie Smith 0:0c3532738887 98 //...
Jamie Smith 0:0c3532738887 99 FS_CAL1 = 0x16,
Jamie Smith 0:0c3532738887 100 FS_CAL0 = 0x17,
Jamie Smith 0:0c3532738887 101 FS_CHP = 0x18,
Jamie Smith 0:0c3532738887 102 FS_DIVTWO = 0x19,
Jamie Smith 0:0c3532738887 103 FS_DSM1 = 0x1A,
Jamie Smith 0:0c3532738887 104 FS_DSM0 = 0x1B,
Jamie Smith 0:0c3532738887 105 FS_DVC1 = 0x1C,
Jamie Smith 0:0c3532738887 106 FS_DVC0 = 0x1D,
Jamie Smith 0:0c3532738887 107 FS_LBI = 0x1E,
Jamie Smith 0:0c3532738887 108 FS_PFD = 0x1F,
Jamie Smith 0:0c3532738887 109 FS_PRE = 0x20,
Jamie Smith 0:0c3532738887 110 FS_REG_DIV_CML = 0x21,
Jamie Smith 0:0c3532738887 111 FS_SPARE = 0x22,
Jamie Smith 0:0c3532738887 112 FS_VCO4 = 0x23,
Jamie Smith 0:0c3532738887 113 FS_VCO3 = 0x24,
Jamie Smith 0:0c3532738887 114 FS_VCO2 = 0x25,
Jamie Smith 0:0c3532738887 115 FS_VCO1 = 0x26,
Jamie Smith 0:0c3532738887 116 FS_VCO0 = 0x27,
Jamie Smith 0:0c3532738887 117 //...
Jamie Smith 0:0c3532738887 118 IFAMP = 0x2F,
Jamie Smith 0:0c3532738887 119 //..
Jamie Smith 0:0c3532738887 120 XOSC5 = 0x32,
Jamie Smith 0:0c3532738887 121 XOSC4 = 0x33,
Jamie Smith 0:0c3532738887 122 XOSC3 = 0x34,
Jamie Smith 0:0c3532738887 123 XOSC2 = 0x35,
Jamie Smith 0:0c3532738887 124 XOSC1 = 0x36,
Jamie Smith 0:0c3532738887 125 XOSC0 = 0x37,
Jamie Smith 0:0c3532738887 126 //...
Jamie Smith 0:0c3532738887 127 FREQOFF_EST1 = 0x77,
Jamie Smith 0:0c3532738887 128 FREQOFF_EST2 = 0x78,
Jamie Smith 0:0c3532738887 129 //...
Jamie Smith 0:0c3532738887 130 FSCAL_CTRL = 0x8D,
Jamie Smith 0:0c3532738887 131 PARTNUMBER = 0x8F,
Jamie Smith 0:0c3532738887 132 PARTVERSION = 0x90,
Jamie Smith 0:0c3532738887 133 //...
Jamie Smith 0:0c3532738887 134 RXFIRST = 0xD2,
Jamie Smith 0:0c3532738887 135 TXFIRST = 0xD3,
Jamie Smith 0:0c3532738887 136 RXLAST = 0xD4,
Jamie Smith 0:0c3532738887 137 TXLAST = 0xD5,
Jamie Smith 0:0c3532738887 138 NUM_TXBYTES = 0xD6,
Jamie Smith 0:0c3532738887 139 NUM_RXBYTES = 0xD7,
Jamie Smith 0:0c3532738887 140 };
Jamie Smith 0:0c3532738887 141
Jamie Smith 0:0c3532738887 142 // Command strobe definitions. See user guide section 3.2.2
Jamie Smith 0:0c3532738887 143 enum class Command : uint8_t
Jamie Smith 0:0c3532738887 144 {
Jamie Smith 0:0c3532738887 145 SOFT_RESET = 0x30,
Jamie Smith 0:0c3532738887 146 ENABLE_FREQ_SYNTH = 0x31,
Jamie Smith 0:0c3532738887 147 OSC_OFF = 0x32,
Jamie Smith 0:0c3532738887 148 CAL_FREQ_SYNTH = 0x33,
Jamie Smith 0:0c3532738887 149 RX = 0x34,
Jamie Smith 0:0c3532738887 150 TX = 0x35,
Jamie Smith 0:0c3532738887 151 IDLE = 0x36,
Jamie Smith 0:0c3532738887 152 AUTO_FREQ_COMP = 0x37,
Jamie Smith 0:0c3532738887 153 WAKE_ON_RADIO = 0x38,
Jamie Smith 0:0c3532738887 154 SLEEP = 0x39,
Jamie Smith 0:0c3532738887 155 FLUSH_RX = 0x3A,
Jamie Smith 0:0c3532738887 156 FLUSH_TX = 0x3B,
Jamie Smith 0:0c3532738887 157 WOR_RESET = 0x3C,
Jamie Smith 0:0c3532738887 158 NOP = 0x3D
Jamie Smith 0:0c3532738887 159 };
Jamie Smith 0:0c3532738887 160
Jamie Smith 0:0c3532738887 161 // State of the radio chip. See user guide Figure 2.
Jamie Smith 0:0c3532738887 162 enum class State : uint8_t
Jamie Smith 0:0c3532738887 163 {
Jamie Smith 0:0c3532738887 164 IDLE = 0x0,
Jamie Smith 0:0c3532738887 165 RX = 0x1,
Jamie Smith 0:0c3532738887 166 TX = 0x2,
Jamie Smith 0:0c3532738887 167 FAST_ON = 0x3,
Jamie Smith 0:0c3532738887 168 CALIBRATE = 0x4,
Jamie Smith 0:0c3532738887 169 SETTLING = 0x5,
Jamie Smith 0:0c3532738887 170 RX_FIFO_ERROR = 0x6,
Jamie Smith 0:0c3532738887 171 TX_FIFO_ERROR = 0x7
Jamie Smith 0:0c3532738887 172 };
Jamie Smith 0:0c3532738887 173
Jamie Smith 0:0c3532738887 174 private:
Jamie Smith 0:0c3532738887 175 // chip data variables
Jamie Smith 0:0c3532738887 176 bool chipReady = false;
Jamie Smith 1:98af824b145e 177 State state = State::IDLE;
Jamie Smith 0:0c3532738887 178 bool isCC1201;
Jamie Smith 0:0c3532738887 179
Jamie Smith 0:0c3532738887 180 // current state variables
Jamie Smith 0:0c3532738887 181
Jamie Smith 0:0c3532738887 182 // current symbol rate of the radio
Jamie Smith 0:0c3532738887 183 float symbolRateSps = 0;
Jamie Smith 0:0c3532738887 184
Jamie Smith 0:0c3532738887 185 // current ADC CIC decimation of the radio
Jamie Smith 0:0c3532738887 186 uint8_t adcCicDecimation = 0;
Jamie Smith 0:0c3532738887 187
Jamie Smith 0:0c3532738887 188 public:
Jamie Smith 0:0c3532738887 189
Jamie Smith 0:0c3532738887 190 /**
Jamie Smith 0:0c3532738887 191 * Construct a CC1200 radio driver from the given set of pins.
Jamie Smith 0:0c3532738887 192 *
Jamie Smith 0:0c3532738887 193 * @param misoPin
Jamie Smith 0:0c3532738887 194 * @param mosiPin
Jamie Smith 0:0c3532738887 195 * @param sclkPin
Jamie Smith 0:0c3532738887 196 * @param csPin
Jamie Smith 0:0c3532738887 197 * @param rstPin
Jamie Smith 0:0c3532738887 198 * @param _debugStream Stream to print error/debug information on.
Jamie Smith 0:0c3532738887 199 * @param isCC1201 True if the chip is a CC1201, false if it is a CC1200. The CC1201 is a cheaper option that lacks low bandwidth settings but is otherwise identical.
Jamie Smith 0:0c3532738887 200 */
Jamie Smith 0:0c3532738887 201 CC1200(PinName mosiPin, PinName misoPin, PinName sclkPin, PinName csPin, PinName rstPin, Stream * _debugStream, bool _isCC1201 = false);
Jamie Smith 0:0c3532738887 202
Jamie Smith 0:0c3532738887 203 /**
Jamie Smith 0:0c3532738887 204 * Reset the chip and attempt to connect to it.
Jamie Smith 0:0c3532738887 205 * Returns whether the chip could be contacted.
Jamie Smith 0:0c3532738887 206 * @return
Jamie Smith 0:0c3532738887 207 */
Jamie Smith 0:0c3532738887 208 bool begin();
Jamie Smith 0:0c3532738887 209
Jamie Smith 0:0c3532738887 210 /**
Jamie Smith 0:0c3532738887 211 * Get the radio's most recently known state.
Jamie Smith 0:0c3532738887 212 * State is updated whenever registers are read or commands are sent, or when you call updateState.
Jamie Smith 0:0c3532738887 213 * @return
Jamie Smith 0:0c3532738887 214 */
Jamie Smith 0:0c3532738887 215 State getState() { return state; }
Jamie Smith 0:0c3532738887 216
Jamie Smith 0:0c3532738887 217 // Data tx & rx functions
Jamie Smith 0:0c3532738887 218 // ------------------------------------------------------------------------------
Jamie Smith 0:0c3532738887 219
Jamie Smith 0:0c3532738887 220 /**
Jamie Smith 0:0c3532738887 221 * Get the number of bytes currently in the TX FIFO
Jamie Smith 0:0c3532738887 222 * @return
Jamie Smith 0:0c3532738887 223 */
Jamie Smith 0:0c3532738887 224 size_t getTXFIFOLen();
Jamie Smith 0:0c3532738887 225
Jamie Smith 0:0c3532738887 226 /**
Jamie Smith 0:0c3532738887 227 * Get the number of bytes currently in the RX FIFO
Jamie Smith 0:0c3532738887 228 * @return
Jamie Smith 0:0c3532738887 229 */
Jamie Smith 0:0c3532738887 230 size_t getRXFIFOLen();
Jamie Smith 0:0c3532738887 231
Jamie Smith 0:0c3532738887 232 /**
Jamie Smith 0:0c3532738887 233 * Enqueue a packet to be sent over the radio. It will be sent the next time the radio is in
Jamie Smith 0:0c3532738887 234 * transmit state.
Jamie Smith 0:0c3532738887 235 *
Jamie Smith 0:0c3532738887 236 * The length of a packet is variable, from 1 byte to 127 bytes. The length will be transmitted
Jamie Smith 0:0c3532738887 237 * along with the packet data.
Jamie Smith 0:0c3532738887 238 *
Jamie Smith 0:0c3532738887 239 * Also reads the radio's state.
Jamie Smith 0:0c3532738887 240 *
Jamie Smith 0:0c3532738887 241 * @param data
Jamie Smith 0:0c3532738887 242 * @param len
Jamie Smith 0:0c3532738887 243 *
Jamie Smith 0:0c3532738887 244 * @return Whether the packet was enqueued. Could return false if there was not enough FIFO
Jamie Smith 0:0c3532738887 245 * space to enqueue the packet, or if the packet is too long.
Jamie Smith 0:0c3532738887 246 */
Jamie Smith 0:0c3532738887 247 bool enqueuePacket(char const * data, size_t len);
Jamie Smith 0:0c3532738887 248
Jamie Smith 0:0c3532738887 249 /**
Jamie Smith 0:0c3532738887 250 * Check whether there is at least one complete packet in the RX FIFO.
Jamie Smith 0:0c3532738887 251 * NOTE: An alternate way to do this using hardware is to configure one
Jamie Smith 0:0c3532738887 252 * of the CC1200's GPIOs as PKT_SYNC_RXTX, then set a falling edge interrupt to receive a packet.
Jamie Smith 0:0c3532738887 253 * @return
Jamie Smith 0:0c3532738887 254 */
Jamie Smith 0:0c3532738887 255 bool hasReceivedPacket();
Jamie Smith 0:0c3532738887 256
Jamie Smith 0:0c3532738887 257 /**
Jamie Smith 0:0c3532738887 258 * Receive a packet from the radio. Only packets that pass CRC check are received into the FIFO;
Jamie Smith 0:0c3532738887 259 * those which do not pass checksum will be discarded.
Jamie Smith 0:0c3532738887 260 *
Jamie Smith 0:0c3532738887 261 * This function assumes that there is a packet in the buffer. You should only call it after
Jamie Smith 0:0c3532738887 262 * hasReceivedPacket() is true or a PKT_SYNC_RXTX pulse is received. If there is not a packet
Jamie Smith 0:0c3532738887 263 * in the FIFO, *undefined behavior* can occur. An arbitrary amount of data will be read from
Jamie Smith 0:0c3532738887 264 * the FIFO and garbage may be returned.
Jamie Smith 0:0c3532738887 265 *
Jamie Smith 0:0c3532738887 266 * NOTE: A null terminator is NOT added unless it was present in the transmitted data.
Jamie Smith 0:0c3532738887 267 * Be careful when treating the returned data as a string!
Jamie Smith 0:0c3532738887 268 *
Jamie Smith 0:0c3532738887 269 * @param buffer Buffer to store received bytes in.
Jamie Smith 0:0c3532738887 270 * @param bufferLen Length of the buffer supplied. If the packet is longer than this buffer, then
Jamie Smith 0:0c3532738887 271 * the full packet will be read from the FIFO but only a buffer's worth will be stored.
Jamie Smith 0:0c3532738887 272 * @return Number of bytes actually received.
Jamie Smith 0:0c3532738887 273 */
Jamie Smith 0:0c3532738887 274 size_t receivePacket(char * buffer, size_t bufferLen);
Jamie Smith 0:0c3532738887 275
Jamie Smith 0:0c3532738887 276 /**
Jamie Smith 0:0c3532738887 277 * Set what state the radio will enter when a packet is received.
Jamie Smith 0:0c3532738887 278 * @param goodPacket State when a good (CRC pass) packet is received.
Jamie Smith 0:0c3532738887 279 * Accepts State::TX, State::IDLE, State::FAST_TX_ON, and State::RX.
Jamie Smith 0:0c3532738887 280 * @param badPacket State when a bad (CRC fail) packet is received.
Jamie Smith 0:0c3532738887 281 * Accepts State::RX and State::IDLE
Jamie Smith 0:0c3532738887 282 */
Jamie Smith 0:0c3532738887 283 void setOnReceiveState(State goodPacket, State badPacket);
Jamie Smith 0:0c3532738887 284
Jamie Smith 0:0c3532738887 285 /**
Jamie Smith 0:0c3532738887 286 * Set what state the radio will enter when a packet is sent.
Jamie Smith 1:98af824b145e 287 * @param txState State when a packet is transmitted.
Jamie Smith 0:0c3532738887 288 * Accepts State::TX, State::IDLE, State::FAST_TX_ON, and State::RX.
Jamie Smith 0:0c3532738887 289 */
Jamie Smith 1:98af824b145e 290 void setOnTransmitState(State txState);
Jamie Smith 0:0c3532738887 291
Jamie Smith 0:0c3532738887 292 enum class FSCalMode : uint8_t
Jamie Smith 0:0c3532738887 293 {
Jamie Smith 0:0c3532738887 294 NONE = 0b00, // never calibrate the FS automatically
Jamie Smith 0:0c3532738887 295 FROM_IDLE = 0b01, // calibrate the FS when going from idle to TX, RX, or fast TX on
Jamie Smith 0:0c3532738887 296 TO_IDLE = 0b10, // calibrate the FS when going from TX, RX, or fast TX on to idle
Jamie Smith 0:0c3532738887 297 TO_IDLE_1_4 = 0b11 // calibrate the FS 1/4 of the time when going from TX, RX, or fast TX on to idle
Jamie Smith 0:0c3532738887 298 };
Jamie Smith 0:0c3532738887 299
Jamie Smith 0:0c3532738887 300 /**
Jamie Smith 0:0c3532738887 301 * Set when the radio calibrates its frequency synthesizer.
Jamie Smith 0:0c3532738887 302 *
Jamie Smith 0:0c3532738887 303 * Per https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz/f/156/t/375189
Jamie Smith 0:0c3532738887 304 * it looks like the FS can drift with changes in supply voltage and/or temperature,
Jamie Smith 0:0c3532738887 305 * so it is good to continually calibrate it in case these change.
Jamie Smith 0:0c3532738887 306 */
Jamie Smith 0:0c3532738887 307 void setFSCalMode(FSCalMode mode);
Jamie Smith 0:0c3532738887 308
Jamie Smith 0:0c3532738887 309 // GPIO configuration
Jamie Smith 0:0c3532738887 310 // ------------------------------------------------------------------------------
Jamie Smith 0:0c3532738887 311
Jamie Smith 0:0c3532738887 312 /**
Jamie Smith 0:0c3532738887 313 * Enum for all possible GPIO modes.
Jamie Smith 0:0c3532738887 314 * Note: Some modes do different things depending on which GPIOs they're assigned to.
Jamie Smith 0:0c3532738887 315 * Duplicate enum values have been intentionally defined for this.
Jamie Smith 0:0c3532738887 316 */
Jamie Smith 0:0c3532738887 317 enum class GPIOMode : uint8_t
Jamie Smith 0:0c3532738887 318 {
Jamie Smith 0:0c3532738887 319 RXFIFO_THR_PKT = 1,
Jamie Smith 0:0c3532738887 320 PKT_SYNC_RXTX = 6,
Jamie Smith 0:0c3532738887 321 RSSI_UPDATE = 14, // GPIO3 and GPIO2
Jamie Smith 0:0c3532738887 322 AGC_HOLD = 14, // GPIO1
Jamie Smith 0:0c3532738887 323 AGC_UPDATE = 14, // GPIO0
Jamie Smith 0:0c3532738887 324 SYNC_EVENT = 41, // GPIO2
Jamie Smith 0:0c3532738887 325 HIGHZ = 48,
Jamie Smith 0:0c3532738887 326 HW0 = 51
Jamie Smith 0:0c3532738887 327 };
Jamie Smith 0:0c3532738887 328
Jamie Smith 0:0c3532738887 329 /**
Jamie Smith 0:0c3532738887 330 * Configure a CC1200 GPIO pin.
Jamie Smith 0:0c3532738887 331 * @param gpioNumber Pin number, from 0-3.
Jamie Smith 0:0c3532738887 332 * @param mode Mode to set the pin to.
Jamie Smith 0:0c3532738887 333 * @param outputInvert Whether to invert the output of the pin.
Jamie Smith 0:0c3532738887 334 */
Jamie Smith 0:0c3532738887 335 void configureGPIO(uint8_t gpioNumber, GPIOMode mode, bool outputInvert = false);
Jamie Smith 0:0c3532738887 336
Jamie Smith 0:0c3532738887 337 // RF configuration
Jamie Smith 0:0c3532738887 338 // ------------------------------------------------------------------------------
Jamie Smith 0:0c3532738887 339
Jamie Smith 0:0c3532738887 340 /**
Jamie Smith 0:0c3532738887 341 * Set up the radio for FIFO mode.
Jamie Smith 0:0c3532738887 342 */
Jamie Smith 0:0c3532738887 343 void configureFIFOMode();
Jamie Smith 0:0c3532738887 344
Jamie Smith 0:0c3532738887 345 enum class ModFormat : uint8_t
Jamie Smith 0:0c3532738887 346 {
Jamie Smith 0:0c3532738887 347 FSK_2 = 0x0,
Jamie Smith 0:0c3532738887 348 GFSK_2 = 0x1,
Jamie Smith 0:0c3532738887 349 ASK = 0x3,
Jamie Smith 0:0c3532738887 350 FSK_4 = 0x4,
Jamie Smith 0:0c3532738887 351 GFSK_4 = 0x5
Jamie Smith 0:0c3532738887 352 };
Jamie Smith 0:0c3532738887 353
Jamie Smith 0:0c3532738887 354 /**
Jamie Smith 0:0c3532738887 355 * Set the modulation format of the radio.
Jamie Smith 0:0c3532738887 356 * @param format
Jamie Smith 0:0c3532738887 357 */
Jamie Smith 0:0c3532738887 358 void setModulationFormat(ModFormat format);
Jamie Smith 0:0c3532738887 359
Jamie Smith 0:0c3532738887 360 /**
Jamie Smith 0:0c3532738887 361 * Set the frequency deviation from the center frequency in Hz.
Jamie Smith 0:0c3532738887 362 * See user guide section 5.2.1 for details, and cc1200 datasheet section 4.10.2 for example values.
Jamie Smith 0:0c3532738887 363 */
Jamie Smith 0:0c3532738887 364 void setFSKDeviation(float deviation);
Jamie Smith 0:0c3532738887 365
Jamie Smith 0:0c3532738887 366 /**
Jamie Smith 0:0c3532738887 367 * Set the RF symbol rate in Hz. If this radio is to be used in receive mode you must call
Jamie Smith 0:0c3532738887 368 * setRXFilterBandwidth() after calling this function.
Jamie Smith 0:0c3532738887 369 * @param symbolRateHz
Jamie Smith 0:0c3532738887 370 */
Jamie Smith 0:0c3532738887 371 void setSymbolRate(float symbolRateHz);
Jamie Smith 0:0c3532738887 372
Jamie Smith 0:0c3532738887 373 /**
Jamie Smith 0:0c3532738887 374 * Set the approximate output power in dBm.
Jamie Smith 0:0c3532738887 375 * Must be between -16dBm and +14dBm.
Jamie Smith 0:0c3532738887 376 * @param outPower
Jamie Smith 0:0c3532738887 377 */
Jamie Smith 0:0c3532738887 378 void setOutputPower(float outPower);
Jamie Smith 0:0c3532738887 379
Jamie Smith 0:0c3532738887 380 // Radio band for the chip to operate on.
Jamie Smith 0:0c3532738887 381 // See user guide description for FS_CFG register.
Jamie Smith 0:0c3532738887 382 enum class Band : uint8_t
Jamie Smith 0:0c3532738887 383 {
Jamie Smith 0:0c3532738887 384 BAND_820_960MHz = 0x2,
Jamie Smith 0:0c3532738887 385 BAND_410_480MHz = 0x4,
Jamie Smith 0:0c3532738887 386 BAND_273_320MHz = 0x6,
Jamie Smith 0:0c3532738887 387 BAND_205_240MHz = 0x8,
Jamie Smith 0:0c3532738887 388 BAND_164_192MHz = 0xA,
Jamie Smith 0:0c3532738887 389 BAND_136_160MHz = 0xB
Jamie Smith 0:0c3532738887 390 };
Jamie Smith 0:0c3532738887 391
Jamie Smith 0:0c3532738887 392 /**
Jamie Smith 0:0c3532738887 393 * Set the radio band and specific frequency. See user guide section 9.12 for details.
Jamie Smith 0:0c3532738887 394 * Note: Frequency offsets are not currently implemented, so the frequency can't be
Jamie Smith 0:0c3532738887 395 * set at the finest resolution. However, the resolution should be fine for most applications.
Jamie Smith 0:0c3532738887 396 * (at 900MHz this function has a resolution of 152.5Hz)
Jamie Smith 0:0c3532738887 397 * @param band
Jamie Smith 0:0c3532738887 398 * @param frequencyHz
Jamie Smith 0:0c3532738887 399 */
Jamie Smith 0:0c3532738887 400 void setRadioFrequency(Band band, float frequencyHz);
Jamie Smith 0:0c3532738887 401
Jamie Smith 0:0c3532738887 402 /**
Jamie Smith 0:0c3532738887 403 * Set the the RX filter bandwidth. You must call this AFTER setting the symbol rate.
Jamie Smith 0:0c3532738887 404 * See user guide section 6.1 for details.
Jamie Smith 0:0c3532738887 405 *
Jamie Smith 0:0c3532738887 406 * NOTE: The symbol rate and the RX filter bandwidth must be compatible with each other.
Jamie Smith 0:0c3532738887 407 * See the user guide for details.
Jamie Smith 0:0c3532738887 408 *
Jamie Smith 1:98af824b145e 409 * A number of different registers must be configured in order to properly configure the radio for a given bandwidth.
Jamie Smith 1:98af824b145e 410 * This call currently sets the following register fields:
Jamie Smith 1:98af824b145e 411 * - CHAN_BW.ADC_CIC_DECFACT
Jamie Smith 1:98af824b145e 412 * - CHAN_BW.BB_CIC_DECFACT
Jamie Smith 1:98af824b145e 413 * - MDMCFG1.DVGA_GAIN
Jamie Smith 1:98af824b145e 414 * - MDMCFG0.DATA_FILTER_EN
Jamie Smith 1:98af824b145e 415 * - SYNC_CFG0.RX_CONFIG_LIMITATION
Jamie Smith 1:98af824b145e 416 *
Jamie Smith 0:0c3532738887 417 * @param bandwidthHz the bandwidth in Hz
Jamie Smith 0:0c3532738887 418 */
Jamie Smith 1:98af824b145e 419 void setRXFilterBandwidth(float bandwidthHz);
Jamie Smith 0:0c3532738887 420
Jamie Smith 0:0c3532738887 421 /**
Jamie Smith 0:0c3532738887 422 * Get the ADC CIC decimation that was calculated by the most recent setRXFilterBandwidth() call.
Jamie Smith 0:0c3532738887 423 * This is used for certain other calculations such as the DC offset.
Jamie Smith 0:0c3532738887 424 * @return
Jamie Smith 0:0c3532738887 425 */
Jamie Smith 0:0c3532738887 426 uint8_t getADCCICDecimation() { return adcCicDecimation; }
Jamie Smith 0:0c3532738887 427
Jamie Smith 0:0c3532738887 428 /**
Jamie Smith 0:0c3532738887 429 * Configure the radio's automatic DC offset removal algorithm is enabled.
Jamie Smith 0:0c3532738887 430 * DC offset correction must be enabled when using zero IF mode, and in my testing
Jamie Smith 0:0c3532738887 431 * it seems to be important when staying in TX mode for a long time at
Jamie Smith 0:0c3532738887 432 * higher sample rates.
Jamie Smith 0:0c3532738887 433 *
Jamie Smith 0:0c3532738887 434 * See the datasheet register description for DCFILT_CFG for explanations of what these values do.
Jamie Smith 0:0c3532738887 435 * Maybe you'll actually be able to make some sense out of what it says... I sure couldn't.
Jamie Smith 0:0c3532738887 436 *
Jamie Smith 0:0c3532738887 437 * @param enableAutoFilter Whether automatic filtering is enabled.
Jamie Smith 0:0c3532738887 438 * @param settlingCfg Settling time configuration bits.
Jamie Smith 0:0c3532738887 439 * @param cutoffCfg Cutoff frequency configuration bits.
Jamie Smith 0:0c3532738887 440 */
Jamie Smith 0:0c3532738887 441 void configureDCFilter(bool enableAutoFilter, uint8_t settlingCfg, uint8_t cutoffCfg);
Jamie Smith 0:0c3532738887 442
Jamie Smith 0:0c3532738887 443 /**
Jamie Smith 0:0c3532738887 444 * Set the IF mixing configuration.
Jamie Smith 0:0c3532738887 445 * See the user guide section on IF_MIX_CFG.CMIX_CFG for details.
Jamie Smith 0:0c3532738887 446 */
Jamie Smith 0:0c3532738887 447 void setIFMixCFG(uint8_t value);
Jamie Smith 0:0c3532738887 448
Jamie Smith 0:0c3532738887 449 /**
Jamie Smith 0:0c3532738887 450 * Set whether the ImageExtinct IQ mismatch compensation logic is enabled.
Jamie Smith 0:0c3532738887 451 * This should be disabled if IF < RX filter bandwidth
Jamie Smith 0:0c3532738887 452 * @param enabled
Jamie Smith 0:0c3532738887 453 */
Jamie Smith 0:0c3532738887 454 void setIQMismatchCompensationEnabled(bool enabled);
Jamie Smith 0:0c3532738887 455
Jamie Smith 0:0c3532738887 456 /**
Jamie Smith 0:0c3532738887 457 * Mode describing the size and setup of the sync word.
Jamie Smith 0:0c3532738887 458 * See user guide register description for SYNC_CFG1
Jamie Smith 0:0c3532738887 459 */
Jamie Smith 0:0c3532738887 460 enum class SyncMode : uint8_t
Jamie Smith 0:0c3532738887 461 {
Jamie Smith 0:0c3532738887 462 SYNC_NONE = 0,
Jamie Smith 0:0c3532738887 463 SYNC_11_BITS = 0b1,
Jamie Smith 0:0c3532738887 464 SYNC_16_BITS = 0b10,
Jamie Smith 0:0c3532738887 465 SYNC_18_BITS = 0b11,
Jamie Smith 0:0c3532738887 466 SYNC_24_BITS = 0b100,
Jamie Smith 0:0c3532738887 467 SYNC_32_BITS = 0b101,
Jamie Smith 0:0c3532738887 468 SYNC_16_BITS_HIGH_BYTE = 0b110,
Jamie Smith 0:0c3532738887 469 SYNC_16_BITS_DUAL = 0b111
Jamie Smith 0:0c3532738887 470 };
Jamie Smith 0:0c3532738887 471
Jamie Smith 0:0c3532738887 472 /**
Jamie Smith 0:0c3532738887 473 * Configure the sync word settings of the radio. The sync word is the bit string sent before each packet -- the
Jamie Smith 0:0c3532738887 474 * radio knows to switch into receive mode when it detects it. Specific values with low autocorrelation should
Jamie Smith 0:0c3532738887 475 * be used for the sync word.
Jamie Smith 0:0c3532738887 476 *
Jamie Smith 0:0c3532738887 477 * @param syncWord Sync word value.
Jamie Smith 0:0c3532738887 478 * @param mode Sync word mode. Configures how many bits of the value are significant.
Jamie Smith 0:0c3532738887 479 * @param syncThreshold Correspondance threshold before the radio switches into receive mode.
Jamie Smith 0:0c3532738887 480 */
Jamie Smith 0:0c3532738887 481 void configureSyncWord(uint32_t syncWord, SyncMode mode, uint8_t syncThreshold);
Jamie Smith 0:0c3532738887 482
Jamie Smith 0:0c3532738887 483 /**
Jamie Smith 0:0c3532738887 484 * Check whether the frequency synthesizer is locked on to the correct frequency.
Jamie Smith 0:0c3532738887 485 * If not, then the correct RF frequency is not being used.
Jamie Smith 0:0c3532738887 486 * If the FS is not locking then check that the correct black box FS registers are applied
Jamie Smith 0:0c3532738887 487 * and that the FS has been calibrated.
Jamie Smith 0:0c3532738887 488 * @return
Jamie Smith 0:0c3532738887 489 */
Jamie Smith 0:0c3532738887 490 bool isFSLocked();
Jamie Smith 0:0c3532738887 491
Jamie Smith 0:0c3532738887 492 /**
Jamie Smith 0:0c3532738887 493 * Configure the preamble that the radio is configured to send/receive. The main purpose of the preamble is to
Jamie Smith 0:0c3532738887 494 * provide receiving radios with a chance to calibrate their RX gain. However, you can also require that receiving
Jamie Smith 0:0c3532738887 495 * radios see a valid preamble before they can detect the sync word (this is not on by default).
Jamie Smith 0:0c3532738887 496 *
Jamie Smith 0:0c3532738887 497 * @param preambleLengthCfg Bits that determine the length of the preamble. See the PREAMBLE_CFG1 register description for details. Set to 0 disable transmitting a preamble.
Jamie Smith 0:0c3532738887 498 * @param preambleFormatCfg Bits that determine the format of the preamble. See the PREAMBLE_CFG1 register description for details.
Jamie Smith 0:0c3532738887 499 */
Jamie Smith 0:0c3532738887 500 void configurePreamble(uint8_t preambleLengthCfg, uint8_t preambleFormatCfg);
Jamie Smith 0:0c3532738887 501
Jamie Smith 1:98af824b145e 502 /**
Jamie Smith 1:98af824b145e 503 * Enum for different PA ramp times.
Jamie Smith 1:98af824b145e 504 */
Jamie Smith 1:98af824b145e 505 enum class RampTime : uint8_t
Jamie Smith 1:98af824b145e 506 {
Jamie Smith 1:98af824b145e 507 RAMP_3_8_SYMBOL = 0b0,
Jamie Smith 1:98af824b145e 508 RAMP_3_2_SYMBOL = 0b1,
Jamie Smith 1:98af824b145e 509 RAMP_3_SYMBOL = 0b10,
Jamie Smith 1:98af824b145e 510 RAMP_6_SYMBOL = 0b11
Jamie Smith 1:98af824b145e 511 };
Jamie Smith 1:98af824b145e 512
Jamie Smith 1:98af824b145e 513 /**
Jamie Smith 1:98af824b145e 514 * Set the length and shape of the power amplifier ramp-up curve.
Jamie Smith 1:98af824b145e 515 * See section 7.1 for details.
Jamie Smith 1:98af824b145e 516 *
Jamie Smith 1:98af824b145e 517 * The PA will gradually ramp from off to full amplitude in rampTime relative to the
Jamie Smith 1:98af824b145e 518 * symbol rate. At 1/3 of rampTime it will have ramped to (firstRampLevel / 16) * full amplitude,
Jamie Smith 1:98af824b145e 519 * and at 2/3 of rampTime it will have ramped to ((secondRampLevel + 7) / 16) * full amplitude.
Jamie Smith 1:98af824b145e 520 */
Jamie Smith 1:98af824b145e 521 void setPARampRate(uint8_t firstRampLevel, uint8_t secondRampLevel, RampTime rampTime);
Jamie Smith 1:98af824b145e 522
Jamie Smith 1:98af824b145e 523 // Automatic Gain Control (AGC) Config
Jamie Smith 1:98af824b145e 524 // ------------------------------------------------------------------------------
Jamie Smith 1:98af824b145e 525
Jamie Smith 1:98af824b145e 526 /**
Jamie Smith 1:98af824b145e 527 * Set the AGC reference level which is the internal target power level that
Jamie Smith 1:98af824b145e 528 * the AGC tries to adjust to.
Jamie Smith 1:98af824b145e 529 *
Jamie Smith 1:98af824b145e 530 * The user manual section 6.4 gives a rough formula to calculate this, but I've just used the SmartRF values.
Jamie Smith 1:98af824b145e 531 *
Jamie Smith 1:98af824b145e 532 * @param level Internal power level in dB.
Jamie Smith 1:98af824b145e 533 */
Jamie Smith 1:98af824b145e 534 void setAGCReferenceLevel(uint8_t level);
Jamie Smith 1:98af824b145e 535
Jamie Smith 1:98af824b145e 536 /**
Jamie Smith 1:98af824b145e 537 * Enum for possible AGC actions after is a sync word detection.
Jamie Smith 1:98af824b145e 538 * See AGC_CFG3 register description for more info.
Jamie Smith 1:98af824b145e 539 */
Jamie Smith 1:98af824b145e 540 enum class SyncBehavior : uint8_t
Jamie Smith 1:98af824b145e 541 {
Jamie Smith 1:98af824b145e 542 FREEZE_NONE = 0b000,
Jamie Smith 1:98af824b145e 543 FREEZE_GAIN = 0b001,
Jamie Smith 1:98af824b145e 544 AGC_SLOWMODE = 0b010,
Jamie Smith 1:98af824b145e 545 FREEZE_BOTH = 0b011
Jamie Smith 1:98af824b145e 546 };
Jamie Smith 1:98af824b145e 547
Jamie Smith 1:98af824b145e 548 /**
Jamie Smith 1:98af824b145e 549 * Set the AGC behavior after a sync word is detected.
Jamie Smith 1:98af824b145e 550 * @param behavior
Jamie Smith 1:98af824b145e 551 */
Jamie Smith 1:98af824b145e 552 void setAGCSyncBehavior(SyncBehavior behavior);
Jamie Smith 1:98af824b145e 553
Jamie Smith 1:98af824b145e 554 /**
Jamie Smith 1:98af824b145e 555 * Enum for possible gain tables to use.
Jamie Smith 1:98af824b145e 556 * See AGC_CFG2 register description for more info.
Jamie Smith 1:98af824b145e 557 */
Jamie Smith 1:98af824b145e 558 enum class GainTable : uint8_t
Jamie Smith 1:98af824b145e 559 {
Jamie Smith 1:98af824b145e 560 OPTIMIZED_LINEARITY = 0b00,
Jamie Smith 1:98af824b145e 561 NORMAL = 0b01,
Jamie Smith 1:98af824b145e 562 LOW_POWER = 0b10,
Jamie Smith 1:98af824b145e 563 ZERO_IF = 0b11
Jamie Smith 1:98af824b145e 564 };
Jamie Smith 1:98af824b145e 565
Jamie Smith 1:98af824b145e 566 /**
Jamie Smith 1:98af824b145e 567 * Set the gain table and min and max values within that table to use.
Jamie Smith 1:98af824b145e 568 * Min and max values are indexes into the current selected table.
Jamie Smith 1:98af824b145e 569 */
Jamie Smith 1:98af824b145e 570 void setAGCGainTable(GainTable table, uint8_t minGainIndex, uint8_t maxGainIndex);
Jamie Smith 1:98af824b145e 571
Jamie Smith 1:98af824b145e 572 /**
Jamie Smith 1:98af824b145e 573 * Configure the change in input signal power that must be sensed before the AGC starts to adjust itself.
Jamie Smith 1:98af824b145e 574 * See the register description for AGC_CFG0.AGC_HYST_LEVEL
Jamie Smith 1:98af824b145e 575 * @param hysteresisCfg
Jamie Smith 1:98af824b145e 576 */
Jamie Smith 1:98af824b145e 577 void setAGCHysteresis(uint8_t hysteresisCfg);
Jamie Smith 1:98af824b145e 578
Jamie Smith 1:98af824b145e 579 /**
Jamie Smith 1:98af824b145e 580 * Configure the rate that the AGC changes the receive gain.
Jamie Smith 1:98af824b145e 581 * See the register description for AGC_CFG0.AGC_SLEWRATE_LIMIT
Jamie Smith 1:98af824b145e 582 * @param slewrateCfg
Jamie Smith 1:98af824b145e 583 */
Jamie Smith 1:98af824b145e 584 void setAGCSlewRate(uint8_t slewrateCfg);
Jamie Smith 1:98af824b145e 585
Jamie Smith 0:0c3532738887 586 // Register level functions
Jamie Smith 0:0c3532738887 587 // ------------------------------------------------------------------------------
Jamie Smith 0:0c3532738887 588
Jamie Smith 0:0c3532738887 589 /**
Jamie Smith 0:0c3532738887 590 * Read a register and return the byte value. Also reads the radio's state.
Jamie Smith 0:0c3532738887 591 */
Jamie Smith 0:0c3532738887 592 uint8_t readRegister(Register reg);
Jamie Smith 0:0c3532738887 593
Jamie Smith 0:0c3532738887 594 /**
Jamie Smith 0:0c3532738887 595 * Write a register with a byte value. Also reads the radio's state.
Jamie Smith 0:0c3532738887 596 */
Jamie Smith 0:0c3532738887 597 void writeRegister(Register reg, uint8_t value);
Jamie Smith 0:0c3532738887 598
Jamie Smith 0:0c3532738887 599 /**
Jamie Smith 0:0c3532738887 600 * Write a series of consecutive registers with byte values. Also reads the radio's state.
Jamie Smith 0:0c3532738887 601 */
Jamie Smith 0:0c3532738887 602 void writeRegisters(CC1200::Register startReg, uint8_t const *values, size_t numRegisters);
Jamie Smith 0:0c3532738887 603
Jamie Smith 0:0c3532738887 604 /**
Jamie Smith 0:0c3532738887 605 * Write a series of consecutive registers with byte values. Also reads the radio's state.
Jamie Smith 0:0c3532738887 606 * Template version that takes an std::array.
Jamie Smith 0:0c3532738887 607 */
Jamie Smith 0:0c3532738887 608 template<size_t numRegisters>
Jamie Smith 0:0c3532738887 609 void writeRegisters(CC1200::Register startReg, std::array<uint8_t, numRegisters> const & values)
Jamie Smith 0:0c3532738887 610 {
Jamie Smith 0:0c3532738887 611 writeRegisters(startReg, values.data(), values.size());
Jamie Smith 0:0c3532738887 612 }
Jamie Smith 0:0c3532738887 613
Jamie Smith 0:0c3532738887 614 /**
Jamie Smith 0:0c3532738887 615 * Read an extended register and return the byte value. Also reads the radio's state.
Jamie Smith 0:0c3532738887 616 */
Jamie Smith 0:0c3532738887 617 uint8_t readRegister(ExtRegister reg);
Jamie Smith 0:0c3532738887 618
Jamie Smith 0:0c3532738887 619 /**
Jamie Smith 0:0c3532738887 620 * Write an extended register with a byte value. Also reads the radio's state.
Jamie Smith 0:0c3532738887 621 */
Jamie Smith 0:0c3532738887 622 void writeRegister(ExtRegister reg, uint8_t value);
Jamie Smith 0:0c3532738887 623
Jamie Smith 0:0c3532738887 624 /**
Jamie Smith 0:0c3532738887 625 * Write a series of consecutive extended registers with byte values. Also reads the radio's state.
Jamie Smith 0:0c3532738887 626 */
Jamie Smith 0:0c3532738887 627 void writeRegisters(CC1200::ExtRegister startReg, uint8_t const *values, size_t numRegisters);
Jamie Smith 0:0c3532738887 628
Jamie Smith 0:0c3532738887 629 /**
Jamie Smith 0:0c3532738887 630 * Write a series of consecutive registers with byte values. Also reads the radio's state.
Jamie Smith 0:0c3532738887 631 * Template version that takes an std::array.
Jamie Smith 0:0c3532738887 632 */
Jamie Smith 0:0c3532738887 633 template<size_t numRegisters>
Jamie Smith 0:0c3532738887 634 void writeRegisters(CC1200::ExtRegister startReg, std::array<uint8_t, numRegisters> const & values)
Jamie Smith 0:0c3532738887 635 {
Jamie Smith 0:0c3532738887 636 writeRegisters(startReg, values.data(), values.size());
Jamie Smith 0:0c3532738887 637 }
Jamie Smith 0:0c3532738887 638
Jamie Smith 0:0c3532738887 639
Jamie Smith 0:0c3532738887 640 /**
Jamie Smith 0:0c3532738887 641 * Send a command. Also reads the radio's state.
Jamie Smith 0:0c3532738887 642 * @param command
Jamie Smith 0:0c3532738887 643 */
Jamie Smith 0:0c3532738887 644 void sendCommand(Command command);
Jamie Smith 0:0c3532738887 645
Jamie Smith 0:0c3532738887 646 /**
Jamie Smith 0:0c3532738887 647 * Update the current known state of the radio.
Jamie Smith 0:0c3532738887 648 */
Jamie Smith 0:0c3532738887 649 void updateState() { sendCommand(Command::NOP); }
Jamie Smith 0:0c3532738887 650
Jamie Smith 0:0c3532738887 651 /**
Jamie Smith 0:0c3532738887 652 * Get a byte from the RX FIFO.
Jamie Smith 0:0c3532738887 653 * @param address The byte address, from 0-127.
Jamie Smith 0:0c3532738887 654 */
Jamie Smith 0:0c3532738887 655 uint8_t readRXFIFOByte(uint8_t address);
Jamie Smith 0:0c3532738887 656
Jamie Smith 0:0c3532738887 657 // State change functions
Jamie Smith 0:0c3532738887 658 // ------------------------------------------------------------------------------
Jamie Smith 0:0c3532738887 659
Jamie Smith 0:0c3532738887 660 /**
Jamie Smith 0:0c3532738887 661 * Send the STX strobe to change the radio into TX state.
Jamie Smith 0:0c3532738887 662 * Valid when the radio is in IDLE, FAST_TX_ON, and RX.
Jamie Smith 0:0c3532738887 663 * A calibration will be performed if needed.
Jamie Smith 0:0c3532738887 664 *
Jamie Smith 0:0c3532738887 665 * The radio will stay in TX state until it is commanded to a different state, or a packet is
Jamie Smith 0:0c3532738887 666 * transmitted and it is configured to change states when this happens, or a FIFO error occurs (which
Jamie Smith 0:0c3532738887 667 * shouldn't be possible with the current configuration).
Jamie Smith 0:0c3532738887 668 */
Jamie Smith 0:0c3532738887 669 void startTX() { sendCommand(Command::TX); }
Jamie Smith 0:0c3532738887 670
Jamie Smith 0:0c3532738887 671 /**
Jamie Smith 0:0c3532738887 672 * Send the SRX strobe to change the radio into TX state.
Jamie Smith 0:0c3532738887 673 * Valid when the radio is in IDLE, FAST_TX_ON, and TX.
Jamie Smith 0:0c3532738887 674 * A calibration will be performed if needed.
Jamie Smith 0:0c3532738887 675 *
Jamie Smith 0:0c3532738887 676 * The radio will stay in RX state until it is commanded to a different state, or a packet is
Jamie Smith 0:0c3532738887 677 * received and it configured to change states when this happens, or a FIFO overflow occurs
Jamie Smith 0:0c3532738887 678 * (because the host is not reading data out fast enough).
Jamie Smith 0:0c3532738887 679 */
Jamie Smith 0:0c3532738887 680 void startRX() { sendCommand(Command::RX); }
Jamie Smith 0:0c3532738887 681
Jamie Smith 0:0c3532738887 682 private:
Jamie Smith 0:0c3532738887 683
Jamie Smith 0:0c3532738887 684 /**
Jamie Smith 0:0c3532738887 685 * Called whenever we get a status byte from another operation. Saves the info from it to member variables.
Jamie Smith 0:0c3532738887 686 * @param status
Jamie Smith 0:0c3532738887 687 */
Jamie Smith 0:0c3532738887 688 void loadStatusByte(uint8_t status);
Jamie Smith 0:0c3532738887 689 };
Jamie Smith 0:0c3532738887 690
Jamie Smith 0:0c3532738887 691
Jamie Smith 0:0c3532738887 692 #endif //LIGHTSPEEDRANGEFINDER_CC1200_H