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:
Fri Aug 28 15:39:31 2020 -0700
Revision:
4:c609cc7c9ea7
Parent:
2:2a447e8e50b8
Child:
5:d22a8885800b
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.

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