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 tosetRXFilterBandwidth
- Removed
setIFMixCFG()
(which takes a byte parameter) and replaced it withsetIFCfg()
, 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 tosetIFCfg()
.
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
CC1200.h@5:d22a8885800b, 22 months ago (annotated)
- Committer:
- Jamie Smith
- Date:
- Mon May 03 02:41:34 2021 -0700
- Revision:
- 5:d22a8885800b
- Parent:
- 4:c609cc7c9ea7
Update to v1.2
Who changed what in which revision?
User | Revision | Line number | New 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 |
5:d22a8885800b | 128 | RSSI1 = 0x71, |
Jamie Smith |
5:d22a8885800b | 129 | RSSI0 = 0x72, |
Jamie Smith |
5:d22a8885800b | 130 | MARCSTATE = 0x73, |
Jamie Smith |
5:d22a8885800b | 131 | LQI_VAL = 0x74, |
Jamie Smith |
5:d22a8885800b | 132 | //... |
Jamie Smith |
0:0c3532738887 | 133 | FREQOFF_EST1 = 0x77, |
Jamie Smith |
0:0c3532738887 | 134 | FREQOFF_EST2 = 0x78, |
Jamie Smith |
0:0c3532738887 | 135 | //... |
Jamie Smith |
0:0c3532738887 | 136 | FSCAL_CTRL = 0x8D, |
Jamie Smith |
0:0c3532738887 | 137 | PARTNUMBER = 0x8F, |
Jamie Smith |
0:0c3532738887 | 138 | PARTVERSION = 0x90, |
Jamie Smith |
0:0c3532738887 | 139 | //... |
Jamie Smith |
0:0c3532738887 | 140 | RXFIRST = 0xD2, |
Jamie Smith |
0:0c3532738887 | 141 | TXFIRST = 0xD3, |
Jamie Smith |
0:0c3532738887 | 142 | RXLAST = 0xD4, |
Jamie Smith |
0:0c3532738887 | 143 | TXLAST = 0xD5, |
Jamie Smith |
0:0c3532738887 | 144 | NUM_TXBYTES = 0xD6, |
Jamie Smith |
0:0c3532738887 | 145 | NUM_RXBYTES = 0xD7, |
Jamie Smith |
2:2a447e8e50b8 | 146 | //... |
Jamie Smith |
2:2a447e8e50b8 | 147 | RXFIFO_PRE_BUF = 0xDA |
Jamie Smith |
0:0c3532738887 | 148 | }; |
Jamie Smith |
0:0c3532738887 | 149 | |
Jamie Smith |
0:0c3532738887 | 150 | // Command strobe definitions. See user guide section 3.2.2 |
Jamie Smith |
0:0c3532738887 | 151 | enum class Command : uint8_t |
Jamie Smith |
0:0c3532738887 | 152 | { |
Jamie Smith |
0:0c3532738887 | 153 | SOFT_RESET = 0x30, |
Jamie Smith |
2:2a447e8e50b8 | 154 | FAST_TX_ON = 0x31, |
Jamie Smith |
0:0c3532738887 | 155 | OSC_OFF = 0x32, |
Jamie Smith |
0:0c3532738887 | 156 | CAL_FREQ_SYNTH = 0x33, |
Jamie Smith |
0:0c3532738887 | 157 | RX = 0x34, |
Jamie Smith |
0:0c3532738887 | 158 | TX = 0x35, |
Jamie Smith |
0:0c3532738887 | 159 | IDLE = 0x36, |
Jamie Smith |
0:0c3532738887 | 160 | AUTO_FREQ_COMP = 0x37, |
Jamie Smith |
0:0c3532738887 | 161 | WAKE_ON_RADIO = 0x38, |
Jamie Smith |
0:0c3532738887 | 162 | SLEEP = 0x39, |
Jamie Smith |
0:0c3532738887 | 163 | FLUSH_RX = 0x3A, |
Jamie Smith |
0:0c3532738887 | 164 | FLUSH_TX = 0x3B, |
Jamie Smith |
0:0c3532738887 | 165 | WOR_RESET = 0x3C, |
Jamie Smith |
0:0c3532738887 | 166 | NOP = 0x3D |
Jamie Smith |
0:0c3532738887 | 167 | }; |
Jamie Smith |
0:0c3532738887 | 168 | |
Jamie Smith |
0:0c3532738887 | 169 | // State of the radio chip. See user guide Figure 2. |
Jamie Smith |
0:0c3532738887 | 170 | enum class State : uint8_t |
Jamie Smith |
0:0c3532738887 | 171 | { |
Jamie Smith |
0:0c3532738887 | 172 | IDLE = 0x0, |
Jamie Smith |
0:0c3532738887 | 173 | RX = 0x1, |
Jamie Smith |
0:0c3532738887 | 174 | TX = 0x2, |
Jamie Smith |
0:0c3532738887 | 175 | FAST_ON = 0x3, |
Jamie Smith |
0:0c3532738887 | 176 | CALIBRATE = 0x4, |
Jamie Smith |
0:0c3532738887 | 177 | SETTLING = 0x5, |
Jamie Smith |
0:0c3532738887 | 178 | RX_FIFO_ERROR = 0x6, |
Jamie Smith |
0:0c3532738887 | 179 | TX_FIFO_ERROR = 0x7 |
Jamie Smith |
0:0c3532738887 | 180 | }; |
Jamie Smith |
0:0c3532738887 | 181 | |
Jamie Smith |
0:0c3532738887 | 182 | private: |
Jamie Smith |
0:0c3532738887 | 183 | // chip data variables |
Jamie Smith |
0:0c3532738887 | 184 | bool chipReady = false; |
Jamie Smith |
1:98af824b145e | 185 | State state = State::IDLE; |
Jamie Smith |
0:0c3532738887 | 186 | bool isCC1201; |
Jamie Smith |
0:0c3532738887 | 187 | |
Jamie Smith |
0:0c3532738887 | 188 | // current state variables |
Jamie Smith |
0:0c3532738887 | 189 | |
Jamie Smith |
0:0c3532738887 | 190 | // current symbol rate of the radio |
Jamie Smith |
0:0c3532738887 | 191 | float symbolRateSps = 0; |
Jamie Smith |
0:0c3532738887 | 192 | |
Jamie Smith |
5:d22a8885800b | 193 | // current RX filter params |
Jamie Smith |
0:0c3532738887 | 194 | uint8_t adcCicDecimation = 0; |
Jamie Smith |
5:d22a8885800b | 195 | float currentRXFilterBW = 0; |
Jamie Smith |
5:d22a8885800b | 196 | |
Jamie Smith |
5:d22a8885800b | 197 | // current RF params |
Jamie Smith |
5:d22a8885800b | 198 | float radioFreqHz; |
Jamie Smith |
5:d22a8885800b | 199 | |
Jamie Smith |
0:0c3532738887 | 200 | |
Jamie Smith |
0:0c3532738887 | 201 | public: |
Jamie Smith |
0:0c3532738887 | 202 | |
Jamie Smith |
0:0c3532738887 | 203 | /** |
Jamie Smith |
0:0c3532738887 | 204 | * Construct a CC1200 radio driver from the given set of pins. |
Jamie Smith |
0:0c3532738887 | 205 | * |
Jamie Smith |
0:0c3532738887 | 206 | * @param misoPin |
Jamie Smith |
0:0c3532738887 | 207 | * @param mosiPin |
Jamie Smith |
0:0c3532738887 | 208 | * @param sclkPin |
Jamie Smith |
0:0c3532738887 | 209 | * @param csPin |
Jamie Smith |
0:0c3532738887 | 210 | * @param rstPin |
Jamie Smith |
0:0c3532738887 | 211 | * @param _debugStream Stream to print error/debug information on. |
Jamie Smith |
0:0c3532738887 | 212 | * @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 | 213 | */ |
Jamie Smith |
0:0c3532738887 | 214 | CC1200(PinName mosiPin, PinName misoPin, PinName sclkPin, PinName csPin, PinName rstPin, Stream * _debugStream, bool _isCC1201 = false); |
Jamie Smith |
0:0c3532738887 | 215 | |
Jamie Smith |
0:0c3532738887 | 216 | /** |
Jamie Smith |
0:0c3532738887 | 217 | * Reset the chip and attempt to connect to it. |
Jamie Smith |
0:0c3532738887 | 218 | * Returns whether the chip could be contacted. |
Jamie Smith |
0:0c3532738887 | 219 | * @return |
Jamie Smith |
0:0c3532738887 | 220 | */ |
Jamie Smith |
0:0c3532738887 | 221 | bool begin(); |
Jamie Smith |
0:0c3532738887 | 222 | |
Jamie Smith |
0:0c3532738887 | 223 | /** |
Jamie Smith |
0:0c3532738887 | 224 | * Get the radio's most recently known state. |
Jamie Smith |
0:0c3532738887 | 225 | * State is updated whenever registers are read or commands are sent, or when you call updateState. |
Jamie Smith |
0:0c3532738887 | 226 | * @return |
Jamie Smith |
0:0c3532738887 | 227 | */ |
Jamie Smith |
0:0c3532738887 | 228 | State getState() { return state; } |
Jamie Smith |
0:0c3532738887 | 229 | |
Jamie Smith |
0:0c3532738887 | 230 | // Data tx & rx functions |
Jamie Smith |
0:0c3532738887 | 231 | // ------------------------------------------------------------------------------ |
Jamie Smith |
0:0c3532738887 | 232 | |
Jamie Smith |
0:0c3532738887 | 233 | /** |
Jamie Smith |
0:0c3532738887 | 234 | * Get the number of bytes currently in the TX FIFO |
Jamie Smith |
0:0c3532738887 | 235 | * @return |
Jamie Smith |
0:0c3532738887 | 236 | */ |
Jamie Smith |
0:0c3532738887 | 237 | size_t getTXFIFOLen(); |
Jamie Smith |
0:0c3532738887 | 238 | |
Jamie Smith |
0:0c3532738887 | 239 | /** |
Jamie Smith |
0:0c3532738887 | 240 | * Get the number of bytes currently in the RX FIFO |
Jamie Smith |
0:0c3532738887 | 241 | * @return |
Jamie Smith |
0:0c3532738887 | 242 | */ |
Jamie Smith |
0:0c3532738887 | 243 | size_t getRXFIFOLen(); |
Jamie Smith |
0:0c3532738887 | 244 | |
Jamie Smith |
0:0c3532738887 | 245 | /** |
Jamie Smith |
0:0c3532738887 | 246 | * Enqueue a packet to be sent over the radio. It will be sent the next time the radio is in |
Jamie Smith |
0:0c3532738887 | 247 | * transmit state. |
Jamie Smith |
0:0c3532738887 | 248 | * |
Jamie Smith |
4:c609cc7c9ea7 | 249 | * In variable length mode, the length of a packet is variable, from 1 byte to 127 bytes. |
Jamie Smith |
4:c609cc7c9ea7 | 250 | * The length will be transmitted along with the packet data. |
Jamie Smith |
4:c609cc7c9ea7 | 251 | * |
Jamie Smith |
4:c609cc7c9ea7 | 252 | * In fixed length mode, the length should be the fixed packet length. |
Jamie Smith |
0:0c3532738887 | 253 | * |
Jamie Smith |
5:d22a8885800b | 254 | * The function is not for use with infinite-length mode, use writeStream() instead. |
Jamie Smith |
5:d22a8885800b | 255 | * |
Jamie Smith |
0:0c3532738887 | 256 | * Also reads the radio's state. |
Jamie Smith |
0:0c3532738887 | 257 | * |
Jamie Smith |
0:0c3532738887 | 258 | * @param data |
Jamie Smith |
0:0c3532738887 | 259 | * @param len |
Jamie Smith |
0:0c3532738887 | 260 | * |
Jamie Smith |
0:0c3532738887 | 261 | * @return Whether the packet was enqueued. Could return false if there was not enough FIFO |
Jamie Smith |
0:0c3532738887 | 262 | * space to enqueue the packet, or if the packet is too long. |
Jamie Smith |
0:0c3532738887 | 263 | */ |
Jamie Smith |
0:0c3532738887 | 264 | bool enqueuePacket(char const * data, size_t len); |
Jamie Smith |
0:0c3532738887 | 265 | |
Jamie Smith |
0:0c3532738887 | 266 | /** |
Jamie Smith |
0:0c3532738887 | 267 | * Check whether there is at least one complete packet in the RX FIFO. |
Jamie Smith |
5:d22a8885800b | 268 | * In infinite length mode, this returns true if any data is present at all. |
Jamie Smith |
0:0c3532738887 | 269 | * NOTE: An alternate way to do this using hardware is to configure one |
Jamie Smith |
0:0c3532738887 | 270 | * of the CC1200's GPIOs as PKT_SYNC_RXTX, then set a falling edge interrupt to receive a packet. |
Jamie Smith |
0:0c3532738887 | 271 | * @return |
Jamie Smith |
0:0c3532738887 | 272 | */ |
Jamie Smith |
0:0c3532738887 | 273 | bool hasReceivedPacket(); |
Jamie Smith |
0:0c3532738887 | 274 | |
Jamie Smith |
0:0c3532738887 | 275 | /** |
Jamie Smith |
0:0c3532738887 | 276 | * Receive a packet from the radio. Only packets that pass CRC check are received into the FIFO; |
Jamie Smith |
0:0c3532738887 | 277 | * those which do not pass checksum will be discarded. |
Jamie Smith |
0:0c3532738887 | 278 | * |
Jamie Smith |
0:0c3532738887 | 279 | * This function assumes that there is a packet in the buffer. You should only call it after |
Jamie Smith |
0:0c3532738887 | 280 | * hasReceivedPacket() is true or a PKT_SYNC_RXTX pulse is received. If there is not a packet |
Jamie Smith |
0:0c3532738887 | 281 | * in the FIFO, *undefined behavior* can occur. An arbitrary amount of data will be read from |
Jamie Smith |
0:0c3532738887 | 282 | * the FIFO and garbage may be returned. |
Jamie Smith |
0:0c3532738887 | 283 | * |
Jamie Smith |
5:d22a8885800b | 284 | * The function is not for use with infinite-length mode, use readStream() instead. |
Jamie Smith |
5:d22a8885800b | 285 | * |
Jamie Smith |
0:0c3532738887 | 286 | * NOTE: A null terminator is NOT added unless it was present in the transmitted data. |
Jamie Smith |
0:0c3532738887 | 287 | * Be careful when treating the returned data as a string! |
Jamie Smith |
0:0c3532738887 | 288 | * |
Jamie Smith |
0:0c3532738887 | 289 | * @param buffer Buffer to store received bytes in. |
Jamie Smith |
0:0c3532738887 | 290 | * @param bufferLen Length of the buffer supplied. If the packet is longer than this buffer, then |
Jamie Smith |
0:0c3532738887 | 291 | * the full packet will be read from the FIFO but only a buffer's worth will be stored. |
Jamie Smith |
0:0c3532738887 | 292 | * @return Number of bytes actually received. |
Jamie Smith |
0:0c3532738887 | 293 | */ |
Jamie Smith |
0:0c3532738887 | 294 | size_t receivePacket(char * buffer, size_t bufferLen); |
Jamie Smith |
0:0c3532738887 | 295 | |
Jamie Smith |
5:d22a8885800b | 296 | // Infinite length tx & rx functions |
Jamie Smith |
5:d22a8885800b | 297 | // ------------------------------------------------------------------------------ |
Jamie Smith |
5:d22a8885800b | 298 | |
Jamie Smith |
5:d22a8885800b | 299 | /* |
Jamie Smith |
5:d22a8885800b | 300 | * How to use infinite length from the TX side: |
Jamie Smith |
5:d22a8885800b | 301 | * 1. Place up to 128 bytes of data in the TX FIFO for transmission using writeStream(). |
Jamie Smith |
5:d22a8885800b | 302 | * 2. Enable TX mode using startTX() |
Jamie Smith |
5:d22a8885800b | 303 | * 3. Keep streaming in data using writeStream() writeStreamBlocking() or at least as fast as it is transmitted. |
Jamie Smith |
5:d22a8885800b | 304 | * 4. Disable TX mode when done using idle(). |
Jamie Smith |
5:d22a8885800b | 305 | * |
Jamie Smith |
5:d22a8885800b | 306 | * Take care that the TX fifo never runs completely out of data, or the chip will go into TX FIFO ERROR state. |
Jamie Smith |
5:d22a8885800b | 307 | */ |
Jamie Smith |
5:d22a8885800b | 308 | |
Jamie Smith |
5:d22a8885800b | 309 | /* |
Jamie Smith |
5:d22a8885800b | 310 | * How to use infinite length from the RX side: |
Jamie Smith |
5:d22a8885800b | 311 | * 1. Enable RX mode using startRX(). I'm pretty sure that if sync words are enabled, you must start RX before the transmitter starts transmitting. |
Jamie Smith |
5:d22a8885800b | 312 | * 2. Wait for data to arrive using hasReceivedPacket(). |
Jamie Smith |
5:d22a8885800b | 313 | * 3. Start streaming out data using readStream() or readStreamBlocking(). |
Jamie Smith |
5:d22a8885800b | 314 | * 4. Disable RX mode when done using idle(). |
Jamie Smith |
5:d22a8885800b | 315 | * |
Jamie Smith |
5:d22a8885800b | 316 | * Take care that the RX fifo doesn't become full, or the chip will go into RX FIFO ERROR state. |
Jamie Smith |
5:d22a8885800b | 317 | */ |
Jamie Smith |
5:d22a8885800b | 318 | |
Jamie Smith |
5:d22a8885800b | 319 | /** |
Jamie Smith |
5:d22a8885800b | 320 | * Write a stream of data to the chip. This function is only for use in infinite-length mode. |
Jamie Smith |
5:d22a8885800b | 321 | * As many bytes from the given buffer will be written as can fit in the chip's FIFO. |
Jamie Smith |
5:d22a8885800b | 322 | * If the FIFO is full, this function does nothing. |
Jamie Smith |
5:d22a8885800b | 323 | * |
Jamie Smith |
5:d22a8885800b | 324 | * @param buffer |
Jamie Smith |
5:d22a8885800b | 325 | * @param count |
Jamie Smith |
5:d22a8885800b | 326 | * @return Number of bytes written. |
Jamie Smith |
5:d22a8885800b | 327 | */ |
Jamie Smith |
5:d22a8885800b | 328 | size_t writeStream(const char* buffer, size_t count); |
Jamie Smith |
5:d22a8885800b | 329 | |
Jamie Smith |
5:d22a8885800b | 330 | /** |
Jamie Smith |
5:d22a8885800b | 331 | * Write a stream of data to the chip. This function is only for use in infinite-length mode. |
Jamie Smith |
5:d22a8885800b | 332 | * Will block until all bytes in the given buffer have been written to the TX FIFO, or an error has been |
Jamie Smith |
5:d22a8885800b | 333 | * detected (the radio switches to any state other than TX). |
Jamie Smith |
5:d22a8885800b | 334 | * |
Jamie Smith |
5:d22a8885800b | 335 | * @param buffer |
Jamie Smith |
5:d22a8885800b | 336 | * @param count |
Jamie Smith |
5:d22a8885800b | 337 | * @return True if successful, false if there was an error. |
Jamie Smith |
5:d22a8885800b | 338 | */ |
Jamie Smith |
5:d22a8885800b | 339 | bool writeStreamBlocking(const char* buffer, size_t count); |
Jamie Smith |
5:d22a8885800b | 340 | |
Jamie Smith |
5:d22a8885800b | 341 | /** |
Jamie Smith |
5:d22a8885800b | 342 | * Read up to maxLen bytes into buffer. |
Jamie Smith |
5:d22a8885800b | 343 | * @param buffer |
Jamie Smith |
5:d22a8885800b | 344 | * @param maxLen |
Jamie Smith |
5:d22a8885800b | 345 | * @return How many bytes were actually read. 0 if the RX FIFO was empty. |
Jamie Smith |
5:d22a8885800b | 346 | */ |
Jamie Smith |
5:d22a8885800b | 347 | size_t readStream(char* buffer, size_t maxLen); |
Jamie Smith |
5:d22a8885800b | 348 | |
Jamie Smith |
5:d22a8885800b | 349 | /** |
Jamie Smith |
5:d22a8885800b | 350 | * Read a stream of data from the chip. This function is only for use in infinite-length mode. |
Jamie Smith |
5:d22a8885800b | 351 | * Will block until the buffer was filled, an error has been |
Jamie Smith |
5:d22a8885800b | 352 | * detected (the radio switches to any state other than RX), or the timeout expires. |
Jamie Smith |
5:d22a8885800b | 353 | * |
Jamie Smith |
5:d22a8885800b | 354 | * If false is returned, some data may have been written to the buffer, and the rest will not have been modified. |
Jamie Smith |
5:d22a8885800b | 355 | * |
Jamie Smith |
5:d22a8885800b | 356 | * Note: if using a zero timeout, this function could cause a hang if the transmitter stops transmitting. |
Jamie Smith |
5:d22a8885800b | 357 | * |
Jamie Smith |
5:d22a8885800b | 358 | * @param buffer |
Jamie Smith |
5:d22a8885800b | 359 | * @param count |
Jamie Smith |
5:d22a8885800b | 360 | * @param timeout Timeout, or 0us to disable timeout. |
Jamie Smith |
5:d22a8885800b | 361 | * @return True iff the buffer was completely filled. |
Jamie Smith |
5:d22a8885800b | 362 | */ |
Jamie Smith |
5:d22a8885800b | 363 | bool readStreamBlocking(char* buffer, size_t count, std::chrono::microseconds timeout=0us); |
Jamie Smith |
5:d22a8885800b | 364 | |
Jamie Smith |
5:d22a8885800b | 365 | // State transition configuration |
Jamie Smith |
5:d22a8885800b | 366 | // ------------------------------------------------------------------------------ |
Jamie Smith |
5:d22a8885800b | 367 | |
Jamie Smith |
0:0c3532738887 | 368 | /** |
Jamie Smith |
0:0c3532738887 | 369 | * Set what state the radio will enter when a packet is received. |
Jamie Smith |
0:0c3532738887 | 370 | * @param goodPacket State when a good (CRC pass) packet is received. |
Jamie Smith |
0:0c3532738887 | 371 | * Accepts State::TX, State::IDLE, State::FAST_TX_ON, and State::RX. |
Jamie Smith |
0:0c3532738887 | 372 | * @param badPacket State when a bad (CRC fail) packet is received. |
Jamie Smith |
0:0c3532738887 | 373 | * Accepts State::RX and State::IDLE |
Jamie Smith |
0:0c3532738887 | 374 | */ |
Jamie Smith |
0:0c3532738887 | 375 | void setOnReceiveState(State goodPacket, State badPacket); |
Jamie Smith |
0:0c3532738887 | 376 | |
Jamie Smith |
0:0c3532738887 | 377 | /** |
Jamie Smith |
0:0c3532738887 | 378 | * Set what state the radio will enter when a packet is sent. |
Jamie Smith |
1:98af824b145e | 379 | * @param txState State when a packet is transmitted. |
Jamie Smith |
0:0c3532738887 | 380 | * Accepts State::TX, State::IDLE, State::FAST_TX_ON, and State::RX. |
Jamie Smith |
0:0c3532738887 | 381 | */ |
Jamie Smith |
1:98af824b145e | 382 | void setOnTransmitState(State txState); |
Jamie Smith |
0:0c3532738887 | 383 | |
Jamie Smith |
0:0c3532738887 | 384 | enum class FSCalMode : uint8_t |
Jamie Smith |
0:0c3532738887 | 385 | { |
Jamie Smith |
0:0c3532738887 | 386 | NONE = 0b00, // never calibrate the FS automatically |
Jamie Smith |
0:0c3532738887 | 387 | FROM_IDLE = 0b01, // calibrate the FS when going from idle to TX, RX, or fast TX on |
Jamie Smith |
0:0c3532738887 | 388 | TO_IDLE = 0b10, // calibrate the FS when going from TX, RX, or fast TX on to idle |
Jamie Smith |
0:0c3532738887 | 389 | 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 | 390 | }; |
Jamie Smith |
0:0c3532738887 | 391 | |
Jamie Smith |
0:0c3532738887 | 392 | /** |
Jamie Smith |
0:0c3532738887 | 393 | * Set when the radio calibrates its frequency synthesizer. |
Jamie Smith |
0:0c3532738887 | 394 | * |
Jamie Smith |
0:0c3532738887 | 395 | * Per https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz/f/156/t/375189 |
Jamie Smith |
0:0c3532738887 | 396 | * it looks like the FS can drift with changes in supply voltage and/or temperature, |
Jamie Smith |
0:0c3532738887 | 397 | * so it is good to continually calibrate it in case these change. |
Jamie Smith |
0:0c3532738887 | 398 | */ |
Jamie Smith |
0:0c3532738887 | 399 | void setFSCalMode(FSCalMode mode); |
Jamie Smith |
0:0c3532738887 | 400 | |
Jamie Smith |
0:0c3532738887 | 401 | // GPIO configuration |
Jamie Smith |
0:0c3532738887 | 402 | // ------------------------------------------------------------------------------ |
Jamie Smith |
0:0c3532738887 | 403 | |
Jamie Smith |
0:0c3532738887 | 404 | /** |
Jamie Smith |
0:0c3532738887 | 405 | * Enum for all possible GPIO modes. |
Jamie Smith |
0:0c3532738887 | 406 | * Note: Some modes do different things depending on which GPIOs they're assigned to. |
Jamie Smith |
0:0c3532738887 | 407 | * Duplicate enum values have been intentionally defined for this. |
Jamie Smith |
0:0c3532738887 | 408 | */ |
Jamie Smith |
0:0c3532738887 | 409 | enum class GPIOMode : uint8_t |
Jamie Smith |
0:0c3532738887 | 410 | { |
Jamie Smith |
0:0c3532738887 | 411 | RXFIFO_THR_PKT = 1, |
Jamie Smith |
0:0c3532738887 | 412 | PKT_SYNC_RXTX = 6, |
Jamie Smith |
0:0c3532738887 | 413 | RSSI_UPDATE = 14, // GPIO3 and GPIO2 |
Jamie Smith |
0:0c3532738887 | 414 | AGC_HOLD = 14, // GPIO1 |
Jamie Smith |
0:0c3532738887 | 415 | AGC_UPDATE = 14, // GPIO0 |
Jamie Smith |
0:0c3532738887 | 416 | SYNC_EVENT = 41, // GPIO2 |
Jamie Smith |
0:0c3532738887 | 417 | HIGHZ = 48, |
Jamie Smith |
0:0c3532738887 | 418 | HW0 = 51 |
Jamie Smith |
0:0c3532738887 | 419 | }; |
Jamie Smith |
0:0c3532738887 | 420 | |
Jamie Smith |
0:0c3532738887 | 421 | /** |
Jamie Smith |
0:0c3532738887 | 422 | * Configure a CC1200 GPIO pin. |
Jamie Smith |
0:0c3532738887 | 423 | * @param gpioNumber Pin number, from 0-3. |
Jamie Smith |
0:0c3532738887 | 424 | * @param mode Mode to set the pin to. |
Jamie Smith |
0:0c3532738887 | 425 | * @param outputInvert Whether to invert the output of the pin. |
Jamie Smith |
0:0c3532738887 | 426 | */ |
Jamie Smith |
0:0c3532738887 | 427 | void configureGPIO(uint8_t gpioNumber, GPIOMode mode, bool outputInvert = false); |
Jamie Smith |
0:0c3532738887 | 428 | |
Jamie Smith |
0:0c3532738887 | 429 | // RF configuration |
Jamie Smith |
0:0c3532738887 | 430 | // ------------------------------------------------------------------------------ |
Jamie Smith |
0:0c3532738887 | 431 | |
Jamie Smith |
0:0c3532738887 | 432 | /** |
Jamie Smith |
0:0c3532738887 | 433 | * Set up the radio for FIFO mode. |
Jamie Smith |
0:0c3532738887 | 434 | */ |
Jamie Smith |
0:0c3532738887 | 435 | void configureFIFOMode(); |
Jamie Smith |
0:0c3532738887 | 436 | |
Jamie Smith |
4:c609cc7c9ea7 | 437 | enum class PacketMode : uint8_t |
Jamie Smith |
4:c609cc7c9ea7 | 438 | { |
Jamie Smith |
5:d22a8885800b | 439 | /// Use infinite length transmissions (streaming mode). |
Jamie Smith |
5:d22a8885800b | 440 | INFINITE_LENGTH = 0b10, |
Jamie Smith |
4:c609cc7c9ea7 | 441 | /// Use fixed length packets. |
Jamie Smith |
4:c609cc7c9ea7 | 442 | VARIABLE_LENGTH = 0b1, |
Jamie Smith |
4:c609cc7c9ea7 | 443 | /// Use variable length packets, the length is encoded in the first byte of the packet. |
Jamie Smith |
4:c609cc7c9ea7 | 444 | FIXED_LENGTH = 0b0 |
Jamie Smith |
4:c609cc7c9ea7 | 445 | }; |
Jamie Smith |
4:c609cc7c9ea7 | 446 | |
Jamie Smith |
4:c609cc7c9ea7 | 447 | /** |
Jamie Smith |
5:d22a8885800b | 448 | * Set the packet mode that the system will use. |
Jamie Smith |
4:c609cc7c9ea7 | 449 | * @param mode |
Jamie Smith |
5:d22a8885800b | 450 | * @param appendStatus Have the radio append a status byte to each packet received. This takes up |
Jamie Smith |
5:d22a8885800b | 451 | * 2 bytes per packet in the RX FIFO, but provides status information about each packet. |
Jamie Smith |
4:c609cc7c9ea7 | 452 | */ |
Jamie Smith |
5:d22a8885800b | 453 | void setPacketMode(PacketMode mode, bool appendStatus = false); |
Jamie Smith |
4:c609cc7c9ea7 | 454 | |
Jamie Smith |
4:c609cc7c9ea7 | 455 | /** |
Jamie Smith |
4:c609cc7c9ea7 | 456 | * Set the packet length when in fixed length packet mode. |
Jamie Smith |
4:c609cc7c9ea7 | 457 | * The bit length parameter can be used to send only the x most significant bits of the final byte. |
Jamie Smith |
4:c609cc7c9ea7 | 458 | * For example, if your packets are 20 bits long, you should set length to 2 bytes and bitLength to |
Jamie Smith |
4:c609cc7c9ea7 | 459 | * 4 bytes, so that 2 complete bytes + 4 extra bits are transmitted. Buffers used for sending and receiving packets |
Jamie Smith |
4:c609cc7c9ea7 | 460 | * should then be 3 bytes long. |
Jamie Smith |
5:d22a8885800b | 461 | * |
Jamie Smith |
5:d22a8885800b | 462 | * When appendStatus is disabled, the max length is 256 bytes. When it is enabled, the max length is 254 bytes. |
Jamie Smith |
4:c609cc7c9ea7 | 463 | * @param length |
Jamie Smith |
4:c609cc7c9ea7 | 464 | */ |
Jamie Smith |
5:d22a8885800b | 465 | void setPacketLength(uint16_t length, uint8_t bitLength = 0); |
Jamie Smith |
4:c609cc7c9ea7 | 466 | |
Jamie Smith |
4:c609cc7c9ea7 | 467 | private: |
Jamie Smith |
4:c609cc7c9ea7 | 468 | // current packet mode |
Jamie Smith |
4:c609cc7c9ea7 | 469 | PacketMode _packetMode; |
Jamie Smith |
4:c609cc7c9ea7 | 470 | |
Jamie Smith |
4:c609cc7c9ea7 | 471 | // current packet length when in fixed length packet mode |
Jamie Smith |
5:d22a8885800b | 472 | uint16_t _packetTotalLength = 0; // length in bytes including final partial byte |
Jamie Smith |
5:d22a8885800b | 473 | uint16_t _packetByteLength = 0; // length in whole bytes |
Jamie Smith |
4:c609cc7c9ea7 | 474 | uint8_t _packetBitLength = 0; // extra bit length at end |
Jamie Smith |
4:c609cc7c9ea7 | 475 | |
Jamie Smith |
5:d22a8885800b | 476 | // Whether the two status bytes are included in each received packet |
Jamie Smith |
5:d22a8885800b | 477 | bool appendStatusEnabled = true; |
Jamie Smith |
5:d22a8885800b | 478 | |
Jamie Smith |
4:c609cc7c9ea7 | 479 | public: |
Jamie Smith |
4:c609cc7c9ea7 | 480 | |
Jamie Smith |
4:c609cc7c9ea7 | 481 | /** |
Jamie Smith |
4:c609cc7c9ea7 | 482 | * Set whether the CRC check is enabled. This driver enables it by default. |
Jamie Smith |
4:c609cc7c9ea7 | 483 | * Enabling CRC will cause a 16 bit checksum to be transmitted along with the packet. |
Jamie Smith |
4:c609cc7c9ea7 | 484 | * It will be automatically checked by the receiving CC1200, and the packet will be discarded if the CRC |
Jamie Smith |
4:c609cc7c9ea7 | 485 | * doesn't match. |
Jamie Smith |
4:c609cc7c9ea7 | 486 | * |
Jamie Smith |
4:c609cc7c9ea7 | 487 | * NOTE: it is not recommended to disable the CRC when using variable length mode. |
Jamie Smith |
4:c609cc7c9ea7 | 488 | * If the length byte is corrupted and the CRC doesn't check this, then the driver could read |
Jamie Smith |
4:c609cc7c9ea7 | 489 | * too little or too much from the chip's FIFO and cause the chip to enter the FIFO underflow state. |
Jamie Smith |
4:c609cc7c9ea7 | 490 | * @param enabled |
Jamie Smith |
4:c609cc7c9ea7 | 491 | */ |
Jamie Smith |
4:c609cc7c9ea7 | 492 | void setCRCEnabled(bool enabled); |
Jamie Smith |
4:c609cc7c9ea7 | 493 | |
Jamie Smith |
0:0c3532738887 | 494 | enum class ModFormat : uint8_t |
Jamie Smith |
0:0c3532738887 | 495 | { |
Jamie Smith |
0:0c3532738887 | 496 | FSK_2 = 0x0, |
Jamie Smith |
0:0c3532738887 | 497 | GFSK_2 = 0x1, |
Jamie Smith |
0:0c3532738887 | 498 | ASK = 0x3, |
Jamie Smith |
0:0c3532738887 | 499 | FSK_4 = 0x4, |
Jamie Smith |
0:0c3532738887 | 500 | GFSK_4 = 0x5 |
Jamie Smith |
0:0c3532738887 | 501 | }; |
Jamie Smith |
0:0c3532738887 | 502 | |
Jamie Smith |
0:0c3532738887 | 503 | /** |
Jamie Smith |
0:0c3532738887 | 504 | * Set the modulation format of the radio. |
Jamie Smith |
0:0c3532738887 | 505 | * @param format |
Jamie Smith |
0:0c3532738887 | 506 | */ |
Jamie Smith |
0:0c3532738887 | 507 | void setModulationFormat(ModFormat format); |
Jamie Smith |
0:0c3532738887 | 508 | |
Jamie Smith |
0:0c3532738887 | 509 | /** |
Jamie Smith |
0:0c3532738887 | 510 | * Set the frequency deviation from the center frequency in Hz. |
Jamie Smith |
0:0c3532738887 | 511 | * See user guide section 5.2.1 for details, and cc1200 datasheet section 4.10.2 for example values. |
Jamie Smith |
0:0c3532738887 | 512 | */ |
Jamie Smith |
0:0c3532738887 | 513 | void setFSKDeviation(float deviation); |
Jamie Smith |
0:0c3532738887 | 514 | |
Jamie Smith |
0:0c3532738887 | 515 | /** |
Jamie Smith |
0:0c3532738887 | 516 | * Set the RF symbol rate in Hz. If this radio is to be used in receive mode you must call |
Jamie Smith |
0:0c3532738887 | 517 | * setRXFilterBandwidth() after calling this function. |
Jamie Smith |
0:0c3532738887 | 518 | * @param symbolRateHz |
Jamie Smith |
0:0c3532738887 | 519 | */ |
Jamie Smith |
0:0c3532738887 | 520 | void setSymbolRate(float symbolRateHz); |
Jamie Smith |
0:0c3532738887 | 521 | |
Jamie Smith |
0:0c3532738887 | 522 | /** |
Jamie Smith |
0:0c3532738887 | 523 | * Set the approximate output power in dBm. |
Jamie Smith |
0:0c3532738887 | 524 | * Must be between -16dBm and +14dBm. |
Jamie Smith |
0:0c3532738887 | 525 | * @param outPower |
Jamie Smith |
0:0c3532738887 | 526 | */ |
Jamie Smith |
0:0c3532738887 | 527 | void setOutputPower(float outPower); |
Jamie Smith |
0:0c3532738887 | 528 | |
Jamie Smith |
4:c609cc7c9ea7 | 529 | // min power to use to turn the radio completely off |
Jamie Smith |
4:c609cc7c9ea7 | 530 | const static float ASK_MIN_POWER_OFF; |
Jamie Smith |
4:c609cc7c9ea7 | 531 | |
Jamie Smith |
4:c609cc7c9ea7 | 532 | /** |
Jamie Smith |
4:c609cc7c9ea7 | 533 | * Set the high and low output powers when transmitting in ASK mode. |
Jamie Smith |
4:c609cc7c9ea7 | 534 | * Overrides the setOutputPower() power setting. |
Jamie Smith |
4:c609cc7c9ea7 | 535 | * @param maxPower High output power. Must be between -16dBm and +14dBm. |
Jamie Smith |
4:c609cc7c9ea7 | 536 | * @param minPower Low output power. Must be between maxPower and -17.5dBm. -17.5dBm gives completely off, |
Jamie Smith |
4:c609cc7c9ea7 | 537 | * so OOK modulation instead of ASK. |
Jamie Smith |
4:c609cc7c9ea7 | 538 | */ |
Jamie Smith |
4:c609cc7c9ea7 | 539 | void setASKPowers(float maxPower, float minPower); |
Jamie Smith |
4:c609cc7c9ea7 | 540 | |
Jamie Smith |
0:0c3532738887 | 541 | // Radio band for the chip to operate on. |
Jamie Smith |
0:0c3532738887 | 542 | // See user guide description for FS_CFG register. |
Jamie Smith |
0:0c3532738887 | 543 | enum class Band : uint8_t |
Jamie Smith |
0:0c3532738887 | 544 | { |
Jamie Smith |
0:0c3532738887 | 545 | BAND_820_960MHz = 0x2, |
Jamie Smith |
0:0c3532738887 | 546 | BAND_410_480MHz = 0x4, |
Jamie Smith |
0:0c3532738887 | 547 | BAND_273_320MHz = 0x6, |
Jamie Smith |
0:0c3532738887 | 548 | BAND_205_240MHz = 0x8, |
Jamie Smith |
0:0c3532738887 | 549 | BAND_164_192MHz = 0xA, |
Jamie Smith |
0:0c3532738887 | 550 | BAND_136_160MHz = 0xB |
Jamie Smith |
0:0c3532738887 | 551 | }; |
Jamie Smith |
0:0c3532738887 | 552 | |
Jamie Smith |
0:0c3532738887 | 553 | /** |
Jamie Smith |
0:0c3532738887 | 554 | * Set the radio band and specific frequency. See user guide section 9.12 for details. |
Jamie Smith |
0:0c3532738887 | 555 | * Note: Frequency offsets are not currently implemented, so the frequency can't be |
Jamie Smith |
0:0c3532738887 | 556 | * set at the finest resolution. However, the resolution should be fine for most applications. |
Jamie Smith |
0:0c3532738887 | 557 | * (at 900MHz this function has a resolution of 152.5Hz) |
Jamie Smith |
0:0c3532738887 | 558 | * @param band |
Jamie Smith |
0:0c3532738887 | 559 | * @param frequencyHz |
Jamie Smith |
0:0c3532738887 | 560 | */ |
Jamie Smith |
0:0c3532738887 | 561 | void setRadioFrequency(Band band, float frequencyHz); |
Jamie Smith |
0:0c3532738887 | 562 | |
Jamie Smith |
0:0c3532738887 | 563 | /** |
Jamie Smith |
0:0c3532738887 | 564 | * Set the the RX filter bandwidth. You must call this AFTER setting the symbol rate. |
Jamie Smith |
0:0c3532738887 | 565 | * See user guide section 6.1 for details. |
Jamie Smith |
0:0c3532738887 | 566 | * |
Jamie Smith |
0:0c3532738887 | 567 | * NOTE: The symbol rate and the RX filter bandwidth must be compatible with each other. |
Jamie Smith |
0:0c3532738887 | 568 | * See the user guide for details. |
Jamie Smith |
0:0c3532738887 | 569 | * |
Jamie Smith |
1:98af824b145e | 570 | * A number of different registers must be configured in order to properly configure the radio for a given bandwidth. |
Jamie Smith |
1:98af824b145e | 571 | * This call currently sets the following register fields: |
Jamie Smith |
1:98af824b145e | 572 | * - CHAN_BW.ADC_CIC_DECFACT |
Jamie Smith |
1:98af824b145e | 573 | * - CHAN_BW.BB_CIC_DECFACT |
Jamie Smith |
1:98af824b145e | 574 | * - MDMCFG1.DVGA_GAIN |
Jamie Smith |
1:98af824b145e | 575 | * - MDMCFG0.DATA_FILTER_EN |
Jamie Smith |
1:98af824b145e | 576 | * - SYNC_CFG0.RX_CONFIG_LIMITATION |
Jamie Smith |
1:98af824b145e | 577 | * |
Jamie Smith |
0:0c3532738887 | 578 | * @param bandwidthHz the bandwidth in Hz |
Jamie Smith |
5:d22a8885800b | 579 | * @param preferHigherCICDec If there are multiple register value choices, prefer the one with higher CIC decimation |
Jamie Smith |
5:d22a8885800b | 580 | * and lower BB decimation. This is the recommendation of the datasheet but it actually causes transmission to fail in some cases. |
Jamie Smith |
0:0c3532738887 | 581 | */ |
Jamie Smith |
5:d22a8885800b | 582 | void setRXFilterBandwidth(float bandwidthHz, bool preferHigherCICDec = true); |
Jamie Smith |
0:0c3532738887 | 583 | |
Jamie Smith |
0:0c3532738887 | 584 | /** |
Jamie Smith |
0:0c3532738887 | 585 | * Get the ADC CIC decimation that was calculated by the most recent setRXFilterBandwidth() call. |
Jamie Smith |
0:0c3532738887 | 586 | * This is used for certain other calculations such as the DC offset. |
Jamie Smith |
0:0c3532738887 | 587 | * @return |
Jamie Smith |
0:0c3532738887 | 588 | */ |
Jamie Smith |
0:0c3532738887 | 589 | uint8_t getADCCICDecimation() { return adcCicDecimation; } |
Jamie Smith |
0:0c3532738887 | 590 | |
Jamie Smith |
0:0c3532738887 | 591 | /** |
Jamie Smith |
5:d22a8885800b | 592 | * Configure the radio's automatic DC offset removal algorithm as enabled. |
Jamie Smith |
0:0c3532738887 | 593 | * DC offset correction must be enabled when using zero IF mode, and in my testing |
Jamie Smith |
0:0c3532738887 | 594 | * it seems to be important when staying in TX mode for a long time at |
Jamie Smith |
0:0c3532738887 | 595 | * higher sample rates. |
Jamie Smith |
0:0c3532738887 | 596 | * |
Jamie Smith |
0:0c3532738887 | 597 | * See the datasheet register description for DCFILT_CFG for explanations of what these values do. |
Jamie Smith |
0:0c3532738887 | 598 | * Maybe you'll actually be able to make some sense out of what it says... I sure couldn't. |
Jamie Smith |
0:0c3532738887 | 599 | * |
Jamie Smith |
0:0c3532738887 | 600 | * @param enableAutoFilter Whether automatic filtering is enabled. |
Jamie Smith |
0:0c3532738887 | 601 | * @param settlingCfg Settling time configuration bits. |
Jamie Smith |
0:0c3532738887 | 602 | * @param cutoffCfg Cutoff frequency configuration bits. |
Jamie Smith |
0:0c3532738887 | 603 | */ |
Jamie Smith |
0:0c3532738887 | 604 | void configureDCFilter(bool enableAutoFilter, uint8_t settlingCfg, uint8_t cutoffCfg); |
Jamie Smith |
0:0c3532738887 | 605 | |
Jamie Smith |
0:0c3532738887 | 606 | /** |
Jamie Smith |
5:d22a8885800b | 607 | * Possible intermediate frequency values. |
Jamie Smith |
5:d22a8885800b | 608 | * For right now it seems like you have to get these from SmartRF. |
Jamie Smith |
0:0c3532738887 | 609 | * See the user guide section on IF_MIX_CFG.CMIX_CFG for details. |
Jamie Smith |
0:0c3532738887 | 610 | */ |
Jamie Smith |
5:d22a8885800b | 611 | enum class IFCfg : uint8_t |
Jamie Smith |
5:d22a8885800b | 612 | { |
Jamie Smith |
5:d22a8885800b | 613 | ZERO = 0, // Zero IF. From what I can find, this means samples are taken at the radio frequency. |
Jamie Smith |
5:d22a8885800b | 614 | NEGATIVE_DIV_4 = 0b001, |
Jamie Smith |
5:d22a8885800b | 615 | NEGATIVE_DIV_6 = 0b010, |
Jamie Smith |
5:d22a8885800b | 616 | NEGATIVE_DIV_8 = 0b011, |
Jamie Smith |
5:d22a8885800b | 617 | POSITIVE_DIV_4 = 0b101, |
Jamie Smith |
5:d22a8885800b | 618 | POSITIVE_DIV_6 = 0b110, |
Jamie Smith |
5:d22a8885800b | 619 | POSITIVE_DIV_8 = 0b111 |
Jamie Smith |
5:d22a8885800b | 620 | }; |
Jamie Smith |
0:0c3532738887 | 621 | |
Jamie Smith |
0:0c3532738887 | 622 | /** |
Jamie Smith |
5:d22a8885800b | 623 | * Set the receiver IF mixing configuration. |
Jamie Smith |
5:d22a8885800b | 624 | * See the user guide section on IF_MIX_CFG.CMIX_CFG for details. |
Jamie Smith |
5:d22a8885800b | 625 | * |
Jamie Smith |
5:d22a8885800b | 626 | * You must call *both* setRXFilterBandwidth() and setRadioFrequency() before calling this function. |
Jamie Smith |
5:d22a8885800b | 627 | * |
Jamie Smith |
5:d22a8885800b | 628 | * @param value Divider value to use, or zero-IF |
Jamie Smith |
5:d22a8885800b | 629 | * @param enableIQIC Whether to enable the ImageExtinct IQ mismatch compensation when supported |
Jamie Smith |
5:d22a8885800b | 630 | * (when if IF > RX filter bandwidth). |
Jamie Smith |
0:0c3532738887 | 631 | */ |
Jamie Smith |
5:d22a8885800b | 632 | void setIFCfg(IFCfg value, bool enableIQIC); |
Jamie Smith |
0:0c3532738887 | 633 | |
Jamie Smith |
0:0c3532738887 | 634 | /** |
Jamie Smith |
0:0c3532738887 | 635 | * Mode describing the size and setup of the sync word. |
Jamie Smith |
0:0c3532738887 | 636 | * See user guide register description for SYNC_CFG1 |
Jamie Smith |
0:0c3532738887 | 637 | */ |
Jamie Smith |
0:0c3532738887 | 638 | enum class SyncMode : uint8_t |
Jamie Smith |
0:0c3532738887 | 639 | { |
Jamie Smith |
0:0c3532738887 | 640 | SYNC_NONE = 0, |
Jamie Smith |
0:0c3532738887 | 641 | SYNC_11_BITS = 0b1, |
Jamie Smith |
0:0c3532738887 | 642 | SYNC_16_BITS = 0b10, |
Jamie Smith |
0:0c3532738887 | 643 | SYNC_18_BITS = 0b11, |
Jamie Smith |
0:0c3532738887 | 644 | SYNC_24_BITS = 0b100, |
Jamie Smith |
0:0c3532738887 | 645 | SYNC_32_BITS = 0b101, |
Jamie Smith |
0:0c3532738887 | 646 | SYNC_16_BITS_HIGH_BYTE = 0b110, |
Jamie Smith |
0:0c3532738887 | 647 | SYNC_16_BITS_DUAL = 0b111 |
Jamie Smith |
0:0c3532738887 | 648 | }; |
Jamie Smith |
0:0c3532738887 | 649 | |
Jamie Smith |
0:0c3532738887 | 650 | /** |
Jamie Smith |
0:0c3532738887 | 651 | * Configure the sync word settings of the radio. The sync word is the bit string sent before each packet -- the |
Jamie Smith |
0:0c3532738887 | 652 | * radio knows to switch into receive mode when it detects it. Specific values with low autocorrelation should |
Jamie Smith |
0:0c3532738887 | 653 | * be used for the sync word. |
Jamie Smith |
0:0c3532738887 | 654 | * |
Jamie Smith |
0:0c3532738887 | 655 | * @param syncWord Sync word value. |
Jamie Smith |
0:0c3532738887 | 656 | * @param mode Sync word mode. Configures how many bits of the value are significant. |
Jamie Smith |
0:0c3532738887 | 657 | * @param syncThreshold Correspondance threshold before the radio switches into receive mode. |
Jamie Smith |
0:0c3532738887 | 658 | */ |
Jamie Smith |
0:0c3532738887 | 659 | void configureSyncWord(uint32_t syncWord, SyncMode mode, uint8_t syncThreshold); |
Jamie Smith |
0:0c3532738887 | 660 | |
Jamie Smith |
0:0c3532738887 | 661 | /** |
Jamie Smith |
0:0c3532738887 | 662 | * Check whether the frequency synthesizer is locked on to the correct frequency. |
Jamie Smith |
0:0c3532738887 | 663 | * If not, then the correct RF frequency is not being used. |
Jamie Smith |
0:0c3532738887 | 664 | * If the FS is not locking then check that the correct black box FS registers are applied |
Jamie Smith |
0:0c3532738887 | 665 | * and that the FS has been calibrated. |
Jamie Smith |
0:0c3532738887 | 666 | * @return |
Jamie Smith |
0:0c3532738887 | 667 | */ |
Jamie Smith |
0:0c3532738887 | 668 | bool isFSLocked(); |
Jamie Smith |
0:0c3532738887 | 669 | |
Jamie Smith |
0:0c3532738887 | 670 | /** |
Jamie Smith |
0:0c3532738887 | 671 | * Configure the preamble that the radio is configured to send/receive. The main purpose of the preamble is to |
Jamie Smith |
0:0c3532738887 | 672 | * provide receiving radios with a chance to calibrate their RX gain. However, you can also require that receiving |
Jamie Smith |
0:0c3532738887 | 673 | * radios see a valid preamble before they can detect the sync word (this is not on by default). |
Jamie Smith |
0:0c3532738887 | 674 | * |
Jamie Smith |
0:0c3532738887 | 675 | * @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 | 676 | * @param preambleFormatCfg Bits that determine the format of the preamble. See the PREAMBLE_CFG1 register description for details. |
Jamie Smith |
0:0c3532738887 | 677 | */ |
Jamie Smith |
0:0c3532738887 | 678 | void configurePreamble(uint8_t preambleLengthCfg, uint8_t preambleFormatCfg); |
Jamie Smith |
0:0c3532738887 | 679 | |
Jamie Smith |
1:98af824b145e | 680 | /** |
Jamie Smith |
1:98af824b145e | 681 | * Enum for different PA ramp times. |
Jamie Smith |
1:98af824b145e | 682 | */ |
Jamie Smith |
1:98af824b145e | 683 | enum class RampTime : uint8_t |
Jamie Smith |
1:98af824b145e | 684 | { |
Jamie Smith |
1:98af824b145e | 685 | RAMP_3_8_SYMBOL = 0b0, |
Jamie Smith |
1:98af824b145e | 686 | RAMP_3_2_SYMBOL = 0b1, |
Jamie Smith |
1:98af824b145e | 687 | RAMP_3_SYMBOL = 0b10, |
Jamie Smith |
1:98af824b145e | 688 | RAMP_6_SYMBOL = 0b11 |
Jamie Smith |
1:98af824b145e | 689 | }; |
Jamie Smith |
1:98af824b145e | 690 | |
Jamie Smith |
1:98af824b145e | 691 | /** |
Jamie Smith |
4:c609cc7c9ea7 | 692 | * Enable the the power amplifier ramp-up curve and set its shape and time. |
Jamie Smith |
1:98af824b145e | 693 | * See section 7.1 for details. |
Jamie Smith |
4:c609cc7c9ea7 | 694 | * This is also used to set the ASK ramping between different power levels. |
Jamie Smith |
1:98af824b145e | 695 | * |
Jamie Smith |
1:98af824b145e | 696 | * The PA will gradually ramp from off to full amplitude in rampTime relative to the |
Jamie Smith |
1:98af824b145e | 697 | * symbol rate. At 1/3 of rampTime it will have ramped to (firstRampLevel / 16) * full amplitude, |
Jamie Smith |
1:98af824b145e | 698 | * and at 2/3 of rampTime it will have ramped to ((secondRampLevel + 7) / 16) * full amplitude. |
Jamie Smith |
1:98af824b145e | 699 | */ |
Jamie Smith |
1:98af824b145e | 700 | void setPARampRate(uint8_t firstRampLevel, uint8_t secondRampLevel, RampTime rampTime); |
Jamie Smith |
1:98af824b145e | 701 | |
Jamie Smith |
4:c609cc7c9ea7 | 702 | /** |
Jamie Smith |
4:c609cc7c9ea7 | 703 | * Disable the power amplifier ramp-up curve. |
Jamie Smith |
4:c609cc7c9ea7 | 704 | */ |
Jamie Smith |
4:c609cc7c9ea7 | 705 | void disablePARamping(); |
Jamie Smith |
4:c609cc7c9ea7 | 706 | |
Jamie Smith |
1:98af824b145e | 707 | // Automatic Gain Control (AGC) Config |
Jamie Smith |
1:98af824b145e | 708 | // ------------------------------------------------------------------------------ |
Jamie Smith |
1:98af824b145e | 709 | |
Jamie Smith |
1:98af824b145e | 710 | /** |
Jamie Smith |
1:98af824b145e | 711 | * Set the AGC reference level which is the internal target power level that |
Jamie Smith |
1:98af824b145e | 712 | * the AGC tries to adjust to. |
Jamie Smith |
1:98af824b145e | 713 | * |
Jamie Smith |
1:98af824b145e | 714 | * 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 | 715 | * |
Jamie Smith |
1:98af824b145e | 716 | * @param level Internal power level in dB. |
Jamie Smith |
1:98af824b145e | 717 | */ |
Jamie Smith |
1:98af824b145e | 718 | void setAGCReferenceLevel(uint8_t level); |
Jamie Smith |
1:98af824b145e | 719 | |
Jamie Smith |
1:98af824b145e | 720 | /** |
Jamie Smith |
1:98af824b145e | 721 | * Enum for possible AGC actions after is a sync word detection. |
Jamie Smith |
1:98af824b145e | 722 | * See AGC_CFG3 register description for more info. |
Jamie Smith |
1:98af824b145e | 723 | */ |
Jamie Smith |
1:98af824b145e | 724 | enum class SyncBehavior : uint8_t |
Jamie Smith |
1:98af824b145e | 725 | { |
Jamie Smith |
1:98af824b145e | 726 | FREEZE_NONE = 0b000, |
Jamie Smith |
1:98af824b145e | 727 | FREEZE_GAIN = 0b001, |
Jamie Smith |
1:98af824b145e | 728 | AGC_SLOWMODE = 0b010, |
Jamie Smith |
1:98af824b145e | 729 | FREEZE_BOTH = 0b011 |
Jamie Smith |
1:98af824b145e | 730 | }; |
Jamie Smith |
1:98af824b145e | 731 | |
Jamie Smith |
1:98af824b145e | 732 | /** |
Jamie Smith |
1:98af824b145e | 733 | * Set the AGC behavior after a sync word is detected. |
Jamie Smith |
1:98af824b145e | 734 | * @param behavior |
Jamie Smith |
1:98af824b145e | 735 | */ |
Jamie Smith |
1:98af824b145e | 736 | void setAGCSyncBehavior(SyncBehavior behavior); |
Jamie Smith |
1:98af824b145e | 737 | |
Jamie Smith |
1:98af824b145e | 738 | /** |
Jamie Smith |
1:98af824b145e | 739 | * Enum for possible gain tables to use. |
Jamie Smith |
1:98af824b145e | 740 | * See AGC_CFG2 register description for more info. |
Jamie Smith |
1:98af824b145e | 741 | */ |
Jamie Smith |
1:98af824b145e | 742 | enum class GainTable : uint8_t |
Jamie Smith |
1:98af824b145e | 743 | { |
Jamie Smith |
1:98af824b145e | 744 | OPTIMIZED_LINEARITY = 0b00, |
Jamie Smith |
1:98af824b145e | 745 | NORMAL = 0b01, |
Jamie Smith |
1:98af824b145e | 746 | LOW_POWER = 0b10, |
Jamie Smith |
1:98af824b145e | 747 | ZERO_IF = 0b11 |
Jamie Smith |
1:98af824b145e | 748 | }; |
Jamie Smith |
1:98af824b145e | 749 | |
Jamie Smith |
1:98af824b145e | 750 | /** |
Jamie Smith |
1:98af824b145e | 751 | * Set the gain table and min and max values within that table to use. |
Jamie Smith |
1:98af824b145e | 752 | * Min and max values are indexes into the current selected table. |
Jamie Smith |
1:98af824b145e | 753 | */ |
Jamie Smith |
1:98af824b145e | 754 | void setAGCGainTable(GainTable table, uint8_t minGainIndex, uint8_t maxGainIndex); |
Jamie Smith |
1:98af824b145e | 755 | |
Jamie Smith |
1:98af824b145e | 756 | /** |
Jamie Smith |
1:98af824b145e | 757 | * Configure the change in input signal power that must be sensed before the AGC starts to adjust itself. |
Jamie Smith |
1:98af824b145e | 758 | * See the register description for AGC_CFG0.AGC_HYST_LEVEL |
Jamie Smith |
1:98af824b145e | 759 | * @param hysteresisCfg |
Jamie Smith |
1:98af824b145e | 760 | */ |
Jamie Smith |
1:98af824b145e | 761 | void setAGCHysteresis(uint8_t hysteresisCfg); |
Jamie Smith |
1:98af824b145e | 762 | |
Jamie Smith |
1:98af824b145e | 763 | /** |
Jamie Smith |
1:98af824b145e | 764 | * Configure the rate that the AGC changes the receive gain. |
Jamie Smith |
1:98af824b145e | 765 | * See the register description for AGC_CFG0.AGC_SLEWRATE_LIMIT |
Jamie Smith |
1:98af824b145e | 766 | * @param slewrateCfg |
Jamie Smith |
1:98af824b145e | 767 | */ |
Jamie Smith |
1:98af824b145e | 768 | void setAGCSlewRate(uint8_t slewrateCfg); |
Jamie Smith |
1:98af824b145e | 769 | |
Jamie Smith |
5:d22a8885800b | 770 | /** |
Jamie Smith |
5:d22a8885800b | 771 | * Configure the time that the AGC takes to settle. |
Jamie Smith |
5:d22a8885800b | 772 | * See the register description for AGC_CFG1.AGC_SETTLE_WAIT |
Jamie Smith |
5:d22a8885800b | 773 | * @param settleWaitCfg bytes to write to AGC_CFG1.AGC_SETTLE_WAIT |
Jamie Smith |
5:d22a8885800b | 774 | */ |
Jamie Smith |
5:d22a8885800b | 775 | void setAGCSettleWait(uint8_t settleWaitCfg); |
Jamie Smith |
5:d22a8885800b | 776 | |
Jamie Smith |
5:d22a8885800b | 777 | // Received Signal Strength Indicator (RSSI) and Link Quality Indicator (LQI) functions |
Jamie Smith |
5:d22a8885800b | 778 | // ------------------------------------------------------------------------------ |
Jamie Smith |
5:d22a8885800b | 779 | |
Jamie Smith |
5:d22a8885800b | 780 | private: |
Jamie Smith |
5:d22a8885800b | 781 | // data from packet status bytes |
Jamie Smith |
5:d22a8885800b | 782 | int8_t lastRSSI; |
Jamie Smith |
5:d22a8885800b | 783 | uint8_t lastLQI; |
Jamie Smith |
5:d22a8885800b | 784 | |
Jamie Smith |
5:d22a8885800b | 785 | public: |
Jamie Smith |
5:d22a8885800b | 786 | |
Jamie Smith |
5:d22a8885800b | 787 | /** |
Jamie Smith |
5:d22a8885800b | 788 | * Get the RSSI as of the last packet received. |
Jamie Smith |
5:d22a8885800b | 789 | * Only provides valid data if appendStatus is enabled. |
Jamie Smith |
5:d22a8885800b | 790 | * @return RSSI in dBm, or -128 if no valid RSSI measurement exists. |
Jamie Smith |
5:d22a8885800b | 791 | */ |
Jamie Smith |
5:d22a8885800b | 792 | int8_t getLastRSSI() {return lastRSSI;} |
Jamie Smith |
5:d22a8885800b | 793 | |
Jamie Smith |
5:d22a8885800b | 794 | /** |
Jamie Smith |
5:d22a8885800b | 795 | * Get the current RSSI from the RSSI register. Note: I think |
Jamie Smith |
5:d22a8885800b | 796 | * this might only work while the radio is actively receiving. |
Jamie Smith |
5:d22a8885800b | 797 | * |
Jamie Smith |
5:d22a8885800b | 798 | * @return RSSI in dBm, or NaN if no valid RSSI measurement exists. |
Jamie Smith |
5:d22a8885800b | 799 | */ |
Jamie Smith |
5:d22a8885800b | 800 | float getRSSIRegister(); |
Jamie Smith |
5:d22a8885800b | 801 | |
Jamie Smith |
5:d22a8885800b | 802 | /** |
Jamie Smith |
5:d22a8885800b | 803 | * Set the RSSI gain adjustment. This value is added to the reported RSSI, and also used |
Jamie Smith |
5:d22a8885800b | 804 | * in the calculation of the Carrier Sense (CS) line. |
Jamie Smith |
5:d22a8885800b | 805 | * You have to calibrate this in a lab by feeding in a known amplitude signal, |
Jamie Smith |
5:d22a8885800b | 806 | * see the user manual section 6.9 for details. |
Jamie Smith |
5:d22a8885800b | 807 | */ |
Jamie Smith |
5:d22a8885800b | 808 | void setRSSIOffset(int8_t adjust); |
Jamie Smith |
5:d22a8885800b | 809 | |
Jamie Smith |
5:d22a8885800b | 810 | /** |
Jamie Smith |
5:d22a8885800b | 811 | * Get the LQI from the LQI_VAL register. |
Jamie Smith |
5:d22a8885800b | 812 | * This is a qualitative estimate from 1-128 of how easily a packet can be demodulated. |
Jamie Smith |
5:d22a8885800b | 813 | * Lower is better, but 0 indicates invalid. |
Jamie Smith |
5:d22a8885800b | 814 | * @return |
Jamie Smith |
5:d22a8885800b | 815 | */ |
Jamie Smith |
5:d22a8885800b | 816 | uint8_t getLQIRegister(); |
Jamie Smith |
5:d22a8885800b | 817 | |
Jamie Smith |
5:d22a8885800b | 818 | /** |
Jamie Smith |
5:d22a8885800b | 819 | * Get the LQI as of the last packet received. |
Jamie Smith |
5:d22a8885800b | 820 | * Only provides valid data if appendStatus is enabled. |
Jamie Smith |
5:d22a8885800b | 821 | * This is a qualitative estimate from 1-128 of how easily a packet can be demodulated. |
Jamie Smith |
5:d22a8885800b | 822 | * Lower is better, but 0 indicates invalid. |
Jamie Smith |
5:d22a8885800b | 823 | */ |
Jamie Smith |
5:d22a8885800b | 824 | uint8_t getLastLQI() {return lastLQI;} |
Jamie Smith |
5:d22a8885800b | 825 | |
Jamie Smith |
0:0c3532738887 | 826 | // Register level functions |
Jamie Smith |
0:0c3532738887 | 827 | // ------------------------------------------------------------------------------ |
Jamie Smith |
0:0c3532738887 | 828 | |
Jamie Smith |
0:0c3532738887 | 829 | /** |
Jamie Smith |
0:0c3532738887 | 830 | * Read a register and return the byte value. Also reads the radio's state. |
Jamie Smith |
0:0c3532738887 | 831 | */ |
Jamie Smith |
0:0c3532738887 | 832 | uint8_t readRegister(Register reg); |
Jamie Smith |
0:0c3532738887 | 833 | |
Jamie Smith |
0:0c3532738887 | 834 | /** |
Jamie Smith |
0:0c3532738887 | 835 | * Write a register with a byte value. Also reads the radio's state. |
Jamie Smith |
0:0c3532738887 | 836 | */ |
Jamie Smith |
0:0c3532738887 | 837 | void writeRegister(Register reg, uint8_t value); |
Jamie Smith |
0:0c3532738887 | 838 | |
Jamie Smith |
0:0c3532738887 | 839 | /** |
Jamie Smith |
0:0c3532738887 | 840 | * Write a series of consecutive registers with byte values. Also reads the radio's state. |
Jamie Smith |
0:0c3532738887 | 841 | */ |
Jamie Smith |
0:0c3532738887 | 842 | void writeRegisters(CC1200::Register startReg, uint8_t const *values, size_t numRegisters); |
Jamie Smith |
0:0c3532738887 | 843 | |
Jamie Smith |
0:0c3532738887 | 844 | /** |
Jamie Smith |
0:0c3532738887 | 845 | * Write a series of consecutive registers with byte values. Also reads the radio's state. |
Jamie Smith |
0:0c3532738887 | 846 | * Template version that takes an std::array. |
Jamie Smith |
0:0c3532738887 | 847 | */ |
Jamie Smith |
0:0c3532738887 | 848 | template<size_t numRegisters> |
Jamie Smith |
0:0c3532738887 | 849 | void writeRegisters(CC1200::Register startReg, std::array<uint8_t, numRegisters> const & values) |
Jamie Smith |
0:0c3532738887 | 850 | { |
Jamie Smith |
0:0c3532738887 | 851 | writeRegisters(startReg, values.data(), values.size()); |
Jamie Smith |
0:0c3532738887 | 852 | } |
Jamie Smith |
0:0c3532738887 | 853 | |
Jamie Smith |
0:0c3532738887 | 854 | /** |
Jamie Smith |
0:0c3532738887 | 855 | * Read an extended register and return the byte value. Also reads the radio's state. |
Jamie Smith |
0:0c3532738887 | 856 | */ |
Jamie Smith |
0:0c3532738887 | 857 | uint8_t readRegister(ExtRegister reg); |
Jamie Smith |
0:0c3532738887 | 858 | |
Jamie Smith |
0:0c3532738887 | 859 | /** |
Jamie Smith |
0:0c3532738887 | 860 | * Write an extended register with a byte value. Also reads the radio's state. |
Jamie Smith |
0:0c3532738887 | 861 | */ |
Jamie Smith |
0:0c3532738887 | 862 | void writeRegister(ExtRegister reg, uint8_t value); |
Jamie Smith |
0:0c3532738887 | 863 | |
Jamie Smith |
0:0c3532738887 | 864 | /** |
Jamie Smith |
0:0c3532738887 | 865 | * Write a series of consecutive extended registers with byte values. Also reads the radio's state. |
Jamie Smith |
0:0c3532738887 | 866 | */ |
Jamie Smith |
0:0c3532738887 | 867 | void writeRegisters(CC1200::ExtRegister startReg, uint8_t const *values, size_t numRegisters); |
Jamie Smith |
0:0c3532738887 | 868 | |
Jamie Smith |
0:0c3532738887 | 869 | /** |
Jamie Smith |
0:0c3532738887 | 870 | * Write a series of consecutive registers with byte values. Also reads the radio's state. |
Jamie Smith |
0:0c3532738887 | 871 | * Template version that takes an std::array. |
Jamie Smith |
0:0c3532738887 | 872 | */ |
Jamie Smith |
0:0c3532738887 | 873 | template<size_t numRegisters> |
Jamie Smith |
0:0c3532738887 | 874 | void writeRegisters(CC1200::ExtRegister startReg, std::array<uint8_t, numRegisters> const & values) |
Jamie Smith |
0:0c3532738887 | 875 | { |
Jamie Smith |
0:0c3532738887 | 876 | writeRegisters(startReg, values.data(), values.size()); |
Jamie Smith |
0:0c3532738887 | 877 | } |
Jamie Smith |
0:0c3532738887 | 878 | |
Jamie Smith |
0:0c3532738887 | 879 | |
Jamie Smith |
0:0c3532738887 | 880 | /** |
Jamie Smith |
0:0c3532738887 | 881 | * Send a command. Also reads the radio's state. |
Jamie Smith |
0:0c3532738887 | 882 | * @param command |
Jamie Smith |
0:0c3532738887 | 883 | */ |
Jamie Smith |
0:0c3532738887 | 884 | void sendCommand(Command command); |
Jamie Smith |
0:0c3532738887 | 885 | |
Jamie Smith |
0:0c3532738887 | 886 | /** |
Jamie Smith |
0:0c3532738887 | 887 | * Update the current known state of the radio. |
Jamie Smith |
0:0c3532738887 | 888 | */ |
Jamie Smith |
0:0c3532738887 | 889 | void updateState() { sendCommand(Command::NOP); } |
Jamie Smith |
0:0c3532738887 | 890 | |
Jamie Smith |
0:0c3532738887 | 891 | /** |
Jamie Smith |
0:0c3532738887 | 892 | * Get a byte from the RX FIFO. |
Jamie Smith |
0:0c3532738887 | 893 | * @param address The byte address, from 0-127. |
Jamie Smith |
0:0c3532738887 | 894 | */ |
Jamie Smith |
0:0c3532738887 | 895 | uint8_t readRXFIFOByte(uint8_t address); |
Jamie Smith |
0:0c3532738887 | 896 | |
Jamie Smith |
0:0c3532738887 | 897 | // State change functions |
Jamie Smith |
0:0c3532738887 | 898 | // ------------------------------------------------------------------------------ |
Jamie Smith |
0:0c3532738887 | 899 | |
Jamie Smith |
0:0c3532738887 | 900 | /** |
Jamie Smith |
0:0c3532738887 | 901 | * Send the STX strobe to change the radio into TX state. |
Jamie Smith |
0:0c3532738887 | 902 | * Valid when the radio is in IDLE, FAST_TX_ON, and RX. |
Jamie Smith |
0:0c3532738887 | 903 | * A calibration will be performed if needed. |
Jamie Smith |
0:0c3532738887 | 904 | * |
Jamie Smith |
0:0c3532738887 | 905 | * The radio will stay in TX state until it is commanded to a different state, or a packet is |
Jamie Smith |
0:0c3532738887 | 906 | * transmitted and it is configured to change states when this happens, or a FIFO error occurs (which |
Jamie Smith |
0:0c3532738887 | 907 | * shouldn't be possible with the current configuration). |
Jamie Smith |
0:0c3532738887 | 908 | */ |
Jamie Smith |
0:0c3532738887 | 909 | void startTX() { sendCommand(Command::TX); } |
Jamie Smith |
0:0c3532738887 | 910 | |
Jamie Smith |
0:0c3532738887 | 911 | /** |
Jamie Smith |
0:0c3532738887 | 912 | * Send the SRX strobe to change the radio into TX state. |
Jamie Smith |
0:0c3532738887 | 913 | * Valid when the radio is in IDLE, FAST_TX_ON, and TX. |
Jamie Smith |
0:0c3532738887 | 914 | * A calibration will be performed if needed. |
Jamie Smith |
0:0c3532738887 | 915 | * |
Jamie Smith |
0:0c3532738887 | 916 | * The radio will stay in RX state until it is commanded to a different state, or a packet is |
Jamie Smith |
0:0c3532738887 | 917 | * received and it configured to change states when this happens, or a FIFO overflow occurs |
Jamie Smith |
0:0c3532738887 | 918 | * (because the host is not reading data out fast enough). |
Jamie Smith |
0:0c3532738887 | 919 | */ |
Jamie Smith |
0:0c3532738887 | 920 | void startRX() { sendCommand(Command::RX); } |
Jamie Smith |
0:0c3532738887 | 921 | |
Jamie Smith |
4:c609cc7c9ea7 | 922 | /** |
Jamie Smith |
4:c609cc7c9ea7 | 923 | * Send the radio into idle mode. Stops a currently running tx or rx. |
Jamie Smith |
4:c609cc7c9ea7 | 924 | */ |
Jamie Smith |
4:c609cc7c9ea7 | 925 | void idle() { sendCommand(Command::IDLE); } |
Jamie Smith |
4:c609cc7c9ea7 | 926 | |
Jamie Smith |
0:0c3532738887 | 927 | private: |
Jamie Smith |
0:0c3532738887 | 928 | |
Jamie Smith |
0:0c3532738887 | 929 | /** |
Jamie Smith |
0:0c3532738887 | 930 | * Called whenever we get a status byte from another operation. Saves the info from it to member variables. |
Jamie Smith |
0:0c3532738887 | 931 | * @param status |
Jamie Smith |
0:0c3532738887 | 932 | */ |
Jamie Smith |
0:0c3532738887 | 933 | void loadStatusByte(uint8_t status); |
Jamie Smith |
0:0c3532738887 | 934 | }; |
Jamie Smith |
0:0c3532738887 | 935 | |
Jamie Smith |
0:0c3532738887 | 936 | |
Jamie Smith |
0:0c3532738887 | 937 | #endif //LIGHTSPEEDRANGEFINDER_CC1200_H |