Radio Structures in OOP

Dependencies:   mbed mbed-rtos

Committer:
jjones646
Date:
Sat Jan 03 04:35:32 2015 +0000
Revision:
3:dc7e9c6bc26c
Parent:
2:7d523bdd2f50
Child:
5:146523a0d1f4
updating with threaded tasks for communication classes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jjones646 2:7d523bdd2f50 1 #include "CC1101.h"
jjones646 2:7d523bdd2f50 2
jjones646 2:7d523bdd2f50 3
jjones646 2:7d523bdd2f50 4 // Default constructor
jjones646 2:7d523bdd2f50 5 CC1101::CC1101() :
jjones646 3:dc7e9c6bc26c 6 CommLink()
jjones646 2:7d523bdd2f50 7 {
jjones646 2:7d523bdd2f50 8 }
jjones646 2:7d523bdd2f50 9
jjones646 3:dc7e9c6bc26c 10 // Main constructor
jjones646 3:dc7e9c6bc26c 11 CC1101::CC1101(PinName mosi, PinName miso, PinName sck, PinName cs, PinName int_pin) :
jjones646 3:dc7e9c6bc26c 12 CommLink(mosi, miso, sck, cs, int_pin)
jjones646 3:dc7e9c6bc26c 13 {
jjones646 3:dc7e9c6bc26c 14 // [X] - 1 - Setup the chip
jjones646 3:dc7e9c6bc26c 15 setup();
jjones646 3:dc7e9c6bc26c 16
jjones646 3:dc7e9c6bc26c 17 // [X] - 2 - Call the base class method for beginning full class operation with threads
jjones646 3:dc7e9c6bc26c 18 // =================
jjones646 3:dc7e9c6bc26c 19 CommLink::ready();
jjones646 3:dc7e9c6bc26c 20 }
jjones646 2:7d523bdd2f50 21
jjones646 2:7d523bdd2f50 22 // Deconstructor
jjones646 2:7d523bdd2f50 23 CC1101::~CC1101()
jjones646 2:7d523bdd2f50 24 {
jjones646 3:dc7e9c6bc26c 25 if (_spi)
jjones646 3:dc7e9c6bc26c 26 delete _spi;
jjones646 3:dc7e9c6bc26c 27 if (_cs)
jjones646 3:dc7e9c6bc26c 28 delete _cs;
jjones646 3:dc7e9c6bc26c 29 if (_int_in)
jjones646 3:dc7e9c6bc26c 30 delete _int_in;
jjones646 3:dc7e9c6bc26c 31 }
jjones646 2:7d523bdd2f50 32
jjones646 3:dc7e9c6bc26c 33
jjones646 3:dc7e9c6bc26c 34 void CC1101::setup(void)
jjones646 3:dc7e9c6bc26c 35 {
jjones646 3:dc7e9c6bc26c 36 // [X] - 1 - Initialize the CC1101 radio transceiver for operation
jjones646 3:dc7e9c6bc26c 37 // =================
jjones646 3:dc7e9c6bc26c 38 set_init_vars();
jjones646 3:dc7e9c6bc26c 39 assign_if_freq(CCXXX1_IF_FREQUENCY);
jjones646 3:dc7e9c6bc26c 40 freq(CCXXX1_BASE_FREQUENCY);
jjones646 3:dc7e9c6bc26c 41 assign_channel_spacing(200000); // 200kHz
jjones646 3:dc7e9c6bc26c 42 datarate(250000); // 250 kBaud
jjones646 3:dc7e9c6bc26c 43 set_rf_settings();
jjones646 3:dc7e9c6bc26c 44
jjones646 3:dc7e9c6bc26c 45 // [] - 2 - Test the interrupt pin for proper operation
jjones646 3:dc7e9c6bc26c 46 // =================
jjones646 3:dc7e9c6bc26c 47
jjones646 3:dc7e9c6bc26c 48 // [] - 3 - Check the CC1101's version register to ensure the chip is what we believe it to be
jjones646 3:dc7e9c6bc26c 49 // =================
jjones646 3:dc7e9c6bc26c 50
jjones646 3:dc7e9c6bc26c 51 }
jjones646 3:dc7e9c6bc26c 52
jjones646 3:dc7e9c6bc26c 53
jjones646 3:dc7e9c6bc26c 54 int32_t CC1101::powerUp(void)
jjones646 3:dc7e9c6bc26c 55 {
jjones646 3:dc7e9c6bc26c 56 #if CCXXX1_DEBUG_MODE > 0
jjones646 3:dc7e9c6bc26c 57 std::printf("[CC1101 RADIO TRANSCEIVER INITILIZATION]\r\n");
jjones646 3:dc7e9c6bc26c 58 #endif
jjones646 3:dc7e9c6bc26c 59
jjones646 3:dc7e9c6bc26c 60 // power_on_reset();
jjones646 3:dc7e9c6bc26c 61
jjones646 3:dc7e9c6bc26c 62 // now send the assigned rfSettings struct to the CC1101 for full inililization
jjones646 3:dc7e9c6bc26c 63 // init();
jjones646 3:dc7e9c6bc26c 64
jjones646 3:dc7e9c6bc26c 65 // scan();
jjones646 3:dc7e9c6bc26c 66
jjones646 3:dc7e9c6bc26c 67 return 0;
jjones646 2:7d523bdd2f50 68 }
jjones646 2:7d523bdd2f50 69
jjones646 2:7d523bdd2f50 70
jjones646 2:7d523bdd2f50 71 bool CC1101::isConnected(void)
jjones646 2:7d523bdd2f50 72 {
jjones646 2:7d523bdd2f50 73 // [] - 1 - Perform a check to ensure the CC1101 can provide communication with a secondary base station link
jjones646 3:dc7e9c6bc26c 74 // =================
jjones646 2:7d523bdd2f50 75 // Note: This does not necessarily mean the link must be reliable, this only needs to determine: `Can the perheripial provide communication?`
jjones646 3:dc7e9c6bc26c 76
jjones646 2:7d523bdd2f50 77 // [] - 2 - Return true/false for indicating a connected communication link
jjones646 3:dc7e9c6bc26c 78 // =================
jjones646 3:dc7e9c6bc26c 79
jjones646 2:7d523bdd2f50 80 return true;
jjones646 2:7d523bdd2f50 81 }
jjones646 2:7d523bdd2f50 82
jjones646 2:7d523bdd2f50 83
jjones646 2:7d523bdd2f50 84 uint32_t CC1101::reset(void)
jjones646 2:7d523bdd2f50 85 {
jjones646 3:dc7e9c6bc26c 86 // [X] - 1 - Perform a soft reset for the CC1101 transceiver
jjones646 3:dc7e9c6bc26c 87 // =================
jjones646 3:dc7e9c6bc26c 88 strobe(CCXXX1_SRES);
jjones646 3:dc7e9c6bc26c 89 return 0; // success
jjones646 2:7d523bdd2f50 90 }
jjones646 2:7d523bdd2f50 91
jjones646 2:7d523bdd2f50 92
jjones646 2:7d523bdd2f50 93 uint32_t CC1101::selfTest(void)
jjones646 2:7d523bdd2f50 94 {
jjones646 3:dc7e9c6bc26c 95 // [X] - 1 - Get the chip's version number and fail if different from what was expected.
jjones646 3:dc7e9c6bc26c 96 _chip_version = status(CCXXX1_VERSION);
jjones646 3:dc7e9c6bc26c 97
jjones646 3:dc7e9c6bc26c 98 if (_chip_version != CCXXX1_EXPECTED_VERSION_NUMBER) {
jjones646 3:dc7e9c6bc26c 99
jjones646 3:dc7e9c6bc26c 100 // send message over serial port
jjones646 3:dc7e9c6bc26c 101 std::printf(
jjones646 3:dc7e9c6bc26c 102 "[FATAL ERROR]\r\n"
jjones646 3:dc7e9c6bc26c 103 " Wrong version number returned from chip's 'VERSION' register (Addr: 0x%02X)\r\n"
jjones646 3:dc7e9c6bc26c 104 "\r\n"
jjones646 3:dc7e9c6bc26c 105 " Expected: 0x%02X\r\n"
jjones646 3:dc7e9c6bc26c 106 " Found: 0x%02X\r\n"
jjones646 3:dc7e9c6bc26c 107 "\r\n"
jjones646 3:dc7e9c6bc26c 108 " Troubleshooting Tips:\r\n"
jjones646 3:dc7e9c6bc26c 109 " - Check that the chip is fully connected with no soldering errors\r\n"
jjones646 3:dc7e9c6bc26c 110 " - Determine if chip is newer version & update firmware\r\n"
jjones646 3:dc7e9c6bc26c 111 , CCXXX1_VERSION, CCXXX1_EXPECTED_VERSION_NUMBER, _chip_version);
jjones646 3:dc7e9c6bc26c 112
jjones646 3:dc7e9c6bc26c 113 return 1;
jjones646 3:dc7e9c6bc26c 114 }
jjones646 3:dc7e9c6bc26c 115 return 0; // success
jjones646 3:dc7e9c6bc26c 116 }
jjones646 3:dc7e9c6bc26c 117
jjones646 3:dc7e9c6bc26c 118 void CC1101::set_init_vars(void)
jjones646 3:dc7e9c6bc26c 119 {
jjones646 3:dc7e9c6bc26c 120 // define an initial state of an unselected chip
jjones646 3:dc7e9c6bc26c 121 *_cs = 1;
jjones646 2:7d523bdd2f50 122
jjones646 3:dc7e9c6bc26c 123 _channel = 1;
jjones646 3:dc7e9c6bc26c 124 _address = 0x00;
jjones646 3:dc7e9c6bc26c 125
jjones646 3:dc7e9c6bc26c 126 // frequency that radio links with another CC1101 over the air
jjones646 3:dc7e9c6bc26c 127 _base_freq = CCXXX1_BASE_FREQUENCY;
jjones646 3:dc7e9c6bc26c 128
jjones646 3:dc7e9c6bc26c 129 // turn off address packet filtering and assign 0 (broadcast address) to the address value
jjones646 3:dc7e9c6bc26c 130 _pck_control.addr_check = ADDR_OFF;
jjones646 3:dc7e9c6bc26c 131
jjones646 3:dc7e9c6bc26c 132 // these values determine how the CC1101 will handel a packet
jjones646 3:dc7e9c6bc26c 133 _pck_control.whitening_en = false;
jjones646 3:dc7e9c6bc26c 134
jjones646 3:dc7e9c6bc26c 135 // enable CRC calculation in TX and CRC checking in RX
jjones646 3:dc7e9c6bc26c 136 _pck_control.crc_en = true;
jjones646 3:dc7e9c6bc26c 137
jjones646 3:dc7e9c6bc26c 138 // enable automatically flushing the RX buffer on a bad CRC (only works if 1 packet is in the RX buffer)
jjones646 3:dc7e9c6bc26c 139 _pck_control.autoflush_en = true;
jjones646 3:dc7e9c6bc26c 140
jjones646 3:dc7e9c6bc26c 141 // enable appending 2 status bytes to the end of every packet that includes the CRC and
jjones646 3:dc7e9c6bc26c 142 _pck_control.status_field_en = true;
jjones646 3:dc7e9c6bc26c 143
jjones646 3:dc7e9c6bc26c 144 // normal packet mode uses RX and TX buffers
jjones646 3:dc7e9c6bc26c 145 _pck_control.format_type = FORMAT_DEFAULT;
jjones646 3:dc7e9c6bc26c 146
jjones646 3:dc7e9c6bc26c 147 // setup how the payload of the packet is transmitted - default to a fixed length of 61 bytes
jjones646 3:dc7e9c6bc26c 148 _pck_control.length_type = PACKET_VARIABLE;
jjones646 3:dc7e9c6bc26c 149 //_pck_control.length_type = PACKET_FIXED;
jjones646 3:dc7e9c6bc26c 150 //_pck_control.size = 61;
jjones646 3:dc7e9c6bc26c 151
jjones646 3:dc7e9c6bc26c 152 // this is a preamble threshold for determining when a packet should be accepted
jjones646 3:dc7e9c6bc26c 153 _pck_control.preamble_thresh = 2;
jjones646 3:dc7e9c6bc26c 154
jjones646 3:dc7e9c6bc26c 155 // these values determine how the frequency bands and channels are distributed as well as defining the modulation type
jjones646 3:dc7e9c6bc26c 156 _modem.dc_filter_off_en = false;
jjones646 3:dc7e9c6bc26c 157 _modem.manchester_encode_en = false;
jjones646 3:dc7e9c6bc26c 158 _modem.fec_en = false;
jjones646 3:dc7e9c6bc26c 159
jjones646 3:dc7e9c6bc26c 160 // bandwidth configurations
jjones646 3:dc7e9c6bc26c 161 _modem.channel_bw = 2;
jjones646 3:dc7e9c6bc26c 162 _modem.channel_bw_exp = 0;
jjones646 3:dc7e9c6bc26c 163 _modem.channel_space_exp = 2;
jjones646 3:dc7e9c6bc26c 164 _modem.data_rate_exp = 13;
jjones646 3:dc7e9c6bc26c 165
jjones646 3:dc7e9c6bc26c 166 _modem.mod_type = MOD_GFSK;
jjones646 3:dc7e9c6bc26c 167 _modem.sync_mode = SYNC_HIGH_ALLOW_TWO;
jjones646 3:dc7e9c6bc26c 168 _modem.preamble_bytes = PREAM_FOUR;
jjones646 3:dc7e9c6bc26c 169
jjones646 3:dc7e9c6bc26c 170 // the values assigned here are used for the frequency synthesizer control
jjones646 3:dc7e9c6bc26c 171 // assign_if_freq(CCXXX1_IF_FREQUENCY);
jjones646 3:dc7e9c6bc26c 172
jjones646 3:dc7e9c6bc26c 173 // set all the configuration values into the rfSettings struct
jjones646 3:dc7e9c6bc26c 174 // set_rf_settings();
jjones646 3:dc7e9c6bc26c 175 }
jjones646 3:dc7e9c6bc26c 176
jjones646 3:dc7e9c6bc26c 177
jjones646 3:dc7e9c6bc26c 178 // returns the current mode that the CC1101 is operating in
jjones646 3:dc7e9c6bc26c 179 uint8_t CC1101::mode(void)
jjones646 3:dc7e9c6bc26c 180 {
jjones646 3:dc7e9c6bc26c 181 return status(CCXXX1_MARCSTATE);
jjones646 3:dc7e9c6bc26c 182 }
jjones646 3:dc7e9c6bc26c 183
jjones646 3:dc7e9c6bc26c 184
jjones646 3:dc7e9c6bc26c 185 int32_t CC1101::sendData(uint8_t *buf, uint8_t size)
jjones646 3:dc7e9c6bc26c 186 {
jjones646 3:dc7e9c6bc26c 187 // [X] - 1 - Move all values down by 1 to make room for the packet's size value.
jjones646 3:dc7e9c6bc26c 188 // =================
jjones646 3:dc7e9c6bc26c 189 for (uint8_t i = size; i > 0; i--)
jjones646 3:dc7e9c6bc26c 190 buf[i] = buf[i-1];
jjones646 3:dc7e9c6bc26c 191
jjones646 3:dc7e9c6bc26c 192
jjones646 3:dc7e9c6bc26c 193 // [X] - 2 - Place the packet's size as the array's first value.
jjones646 3:dc7e9c6bc26c 194 // =================
jjones646 3:dc7e9c6bc26c 195 buf[0] = size;
jjones646 3:dc7e9c6bc26c 196
jjones646 3:dc7e9c6bc26c 197
jjones646 3:dc7e9c6bc26c 198 #if CCXXX1_DEBUG_MODE > 0
jjones646 3:dc7e9c6bc26c 199 std::printf("\r\n[PACKET TRANSMITTED]\r\n Bytes: %u\r\n", size);
jjones646 3:dc7e9c6bc26c 200 #endif
jjones646 3:dc7e9c6bc26c 201
jjones646 3:dc7e9c6bc26c 202
jjones646 3:dc7e9c6bc26c 203 // [X] - 3 - Send the data to the CC1101. Increment the size value by 1 before doing so to account for the buffer's inserted value
jjones646 3:dc7e9c6bc26c 204 // =================
jjones646 3:dc7e9c6bc26c 205 write_reg(CCXXX1_TXFIFO, buf, ++size);
jjones646 3:dc7e9c6bc26c 206
jjones646 3:dc7e9c6bc26c 207
jjones646 3:dc7e9c6bc26c 208 #if CCXXX1_DEBUG_MODE > 1
jjones646 3:dc7e9c6bc26c 209 Timer t1;
jjones646 3:dc7e9c6bc26c 210 #endif
jjones646 3:dc7e9c6bc26c 211
jjones646 3:dc7e9c6bc26c 212
jjones646 3:dc7e9c6bc26c 213 // [X] - 4 - Enter the TX state.
jjones646 3:dc7e9c6bc26c 214 // =================
jjones646 3:dc7e9c6bc26c 215 strobe(CCXXX1_STX);
jjones646 3:dc7e9c6bc26c 216
jjones646 3:dc7e9c6bc26c 217
jjones646 3:dc7e9c6bc26c 218 #if CCXXX1_DEBUG_MODE > 1
jjones646 3:dc7e9c6bc26c 219 /* For the debug mode, this will determine how long the CC1101 takes to transmit everything in the TX buffer
jjones646 3:dc7e9c6bc26c 220 and enter or return to the RX state.
jjones646 3:dc7e9c6bc26c 221 */
jjones646 3:dc7e9c6bc26c 222 t1.start();
jjones646 3:dc7e9c6bc26c 223 float ti = t1.read();
jjones646 3:dc7e9c6bc26c 224 #endif
jjones646 3:dc7e9c6bc26c 225
jjones646 3:dc7e9c6bc26c 226
jjones646 3:dc7e9c6bc26c 227 // [X] - 5 - Wait until radio enters back to the RX state.
jjones646 3:dc7e9c6bc26c 228 // =================
jjones646 3:dc7e9c6bc26c 229 // *Note: Takes very few cycles, so might as well wait before returning to elimate querky errors.
jjones646 3:dc7e9c6bc26c 230 while(mode() != 0x0D);
jjones646 3:dc7e9c6bc26c 231
jjones646 3:dc7e9c6bc26c 232 #if CCXXX1_DEBUG_MODE > 1
jjones646 3:dc7e9c6bc26c 233 t1.stop();
jjones646 3:dc7e9c6bc26c 234 std::printf(" Time: %02.4f ms\r\n", (t1.read() - ti)*1000);
jjones646 3:dc7e9c6bc26c 235 #endif
jjones646 3:dc7e9c6bc26c 236
jjones646 3:dc7e9c6bc26c 237 // [] - 6 - Return any error codes if necessary.
jjones646 3:dc7e9c6bc26c 238 // =================
jjones646 3:dc7e9c6bc26c 239
jjones646 3:dc7e9c6bc26c 240 return 0; // success
jjones646 3:dc7e9c6bc26c 241 }
jjones646 3:dc7e9c6bc26c 242
jjones646 3:dc7e9c6bc26c 243
jjones646 3:dc7e9c6bc26c 244 int32_t CC1101::getData(uint8_t *buf, uint8_t *length)
jjones646 3:dc7e9c6bc26c 245 {
jjones646 3:dc7e9c6bc26c 246 // [X] - 1 - Update the frequency offset estimate.
jjones646 3:dc7e9c6bc26c 247 // =================
jjones646 3:dc7e9c6bc26c 248 write_reg(CCXXX1_FSCTRL0, status(CCXXX1_FREQEST));
jjones646 3:dc7e9c6bc26c 249
jjones646 3:dc7e9c6bc26c 250
jjones646 3:dc7e9c6bc26c 251 // [X] - 2 - Get the packet's size.
jjones646 3:dc7e9c6bc26c 252 // =================
jjones646 3:dc7e9c6bc26c 253 uint8_t rx_size;
jjones646 3:dc7e9c6bc26c 254 read_reg(CCXXX1_RXFIFO, &rx_size, 1);
jjones646 3:dc7e9c6bc26c 255
jjones646 3:dc7e9c6bc26c 256
jjones646 3:dc7e9c6bc26c 257 // [X] - 3 - Check if there are indeed bytes to be read.
jjones646 3:dc7e9c6bc26c 258 // =================
jjones646 3:dc7e9c6bc26c 259 if (rx_size & CCXXX1_RXFIFO_MASK) {
jjones646 3:dc7e9c6bc26c 260
jjones646 3:dc7e9c6bc26c 261 // [X] - 3.1 - Check if the received data will fit in the provided buffer - fill the buffer if so.
jjones646 3:dc7e9c6bc26c 262 // =================
jjones646 3:dc7e9c6bc26c 263 if (rx_size <= *length) {
jjones646 3:dc7e9c6bc26c 264
jjones646 3:dc7e9c6bc26c 265 // [X] - 3.1a - Read in received data from the CC1101 and put the contents in the provided buffer.
jjones646 3:dc7e9c6bc26c 266 *length = rx_size; // set the correct length
jjones646 3:dc7e9c6bc26c 267 read_reg(CCXXX1_RXFIFO, buf, *length);
jjones646 3:dc7e9c6bc26c 268
jjones646 3:dc7e9c6bc26c 269 /* The RSSI value takes a bit to be determined by the CC1101, so having 2 separate SPI reads gives
jjones646 3:dc7e9c6bc26c 270 the CC1101 enough time to determine the correct value.
jjones646 3:dc7e9c6bc26c 271 */
jjones646 3:dc7e9c6bc26c 272
jjones646 3:dc7e9c6bc26c 273 // [X] - 3.1b - Read the 2 appended status bytes.
jjones646 3:dc7e9c6bc26c 274 // status[0] = RSSI. status[1] = LQI.
jjones646 3:dc7e9c6bc26c 275 uint8_t status_bytes[2];
jjones646 3:dc7e9c6bc26c 276 read_reg(CCXXX1_RXFIFO, status_bytes, 2);
jjones646 3:dc7e9c6bc26c 277
jjones646 3:dc7e9c6bc26c 278 // Update the RSSI reading.
jjones646 3:dc7e9c6bc26c 279 rssi(status_bytes[0]);
jjones646 3:dc7e9c6bc26c 280 _lqi = status_bytes[1] & CCXXX1_RXFIFO_MASK; // MSB of LQI is the CRC_OK bit - The interrupt is only triggered if CRC is OK, so no need to check again.
jjones646 3:dc7e9c6bc26c 281
jjones646 3:dc7e9c6bc26c 282 #if CCXXX1_DEBUG_MODE > 0
jjones646 3:dc7e9c6bc26c 283 std::printf("\r\n[PACKET RECEIVED]\r\n Bytes: %u\r\n", *length);
jjones646 3:dc7e9c6bc26c 284 std::printf(" RSSI: %ddBm\r\n", _rssi);
jjones646 3:dc7e9c6bc26c 285 std::printf(" LQI: %u\r\n", _lqi);
jjones646 3:dc7e9c6bc26c 286 #endif
jjones646 3:dc7e9c6bc26c 287
jjones646 3:dc7e9c6bc26c 288 // [X] - 3.2c - Go back to the receiving state since CC1101 is configured for transitioning to IDLE on receiving a packet.
jjones646 3:dc7e9c6bc26c 289 rx_mode();
jjones646 3:dc7e9c6bc26c 290 return 0; // success
jjones646 3:dc7e9c6bc26c 291 } else {
jjones646 3:dc7e9c6bc26c 292 *length = rx_size;
jjones646 3:dc7e9c6bc26c 293 flush_rx();
jjones646 3:dc7e9c6bc26c 294 return -2; // passed buffer size is not large enough
jjones646 3:dc7e9c6bc26c 295 }
jjones646 3:dc7e9c6bc26c 296 }
jjones646 3:dc7e9c6bc26c 297
jjones646 3:dc7e9c6bc26c 298 flush_rx();
jjones646 3:dc7e9c6bc26c 299 return -1; // there is no new data to read
jjones646 2:7d523bdd2f50 300 }
jjones646 2:7d523bdd2f50 301
jjones646 2:7d523bdd2f50 302
jjones646 3:dc7e9c6bc26c 303 // Read Register
jjones646 3:dc7e9c6bc26c 304 uint8_t CC1101::read_reg(uint8_t addr)
jjones646 3:dc7e9c6bc26c 305 {
jjones646 3:dc7e9c6bc26c 306 toggle_cs();
jjones646 3:dc7e9c6bc26c 307 _spi->write(addr | CCXXX1_READ_SINGLE);
jjones646 3:dc7e9c6bc26c 308 uint8_t x = _spi->write(0);
jjones646 3:dc7e9c6bc26c 309 toggle_cs();
jjones646 3:dc7e9c6bc26c 310
jjones646 3:dc7e9c6bc26c 311 #if CCXXX1_DEBUG_MODE > 1
jjones646 3:dc7e9c6bc26c 312 std::printf("\r\n== Single Register Read ==\r\n Address: 0x%02X\r\n Value: 0x%02X\r\n", addr, x);
jjones646 3:dc7e9c6bc26c 313 #endif
jjones646 3:dc7e9c6bc26c 314 return x;
jjones646 3:dc7e9c6bc26c 315 } // read_reg
jjones646 3:dc7e9c6bc26c 316 void CC1101::read_reg(uint8_t addr, uint8_t *buffer, uint8_t count)
jjones646 3:dc7e9c6bc26c 317 {
jjones646 3:dc7e9c6bc26c 318 toggle_cs();
jjones646 3:dc7e9c6bc26c 319 _spi->write(addr | CCXXX1_READ_BURST);
jjones646 3:dc7e9c6bc26c 320 tiny_delay();
jjones646 3:dc7e9c6bc26c 321 for (uint8_t i = 0; i < count; i++) {
jjones646 3:dc7e9c6bc26c 322 buffer[i] = _spi->write(0);
jjones646 3:dc7e9c6bc26c 323 tiny_delay();
jjones646 3:dc7e9c6bc26c 324 }
jjones646 3:dc7e9c6bc26c 325 toggle_cs();
jjones646 3:dc7e9c6bc26c 326
jjones646 3:dc7e9c6bc26c 327 #if CCXXX1_DEBUG_MODE > 1
jjones646 3:dc7e9c6bc26c 328 std::printf("\r\n== Burst Register Read ==\r\n Address: 0x%02X\r\n Bytes: %u\r\n", addr, count);
jjones646 3:dc7e9c6bc26c 329 #endif
jjones646 3:dc7e9c6bc26c 330 } // read_reg
jjones646 3:dc7e9c6bc26c 331
jjones646 3:dc7e9c6bc26c 332
jjones646 3:dc7e9c6bc26c 333
jjones646 3:dc7e9c6bc26c 334 // Write Register
jjones646 3:dc7e9c6bc26c 335 void CC1101::write_reg(uint8_t addr, uint8_t value)
jjones646 3:dc7e9c6bc26c 336 {
jjones646 3:dc7e9c6bc26c 337 toggle_cs();
jjones646 3:dc7e9c6bc26c 338 _spi->write(addr);
jjones646 3:dc7e9c6bc26c 339 _spi->write(value);
jjones646 3:dc7e9c6bc26c 340 toggle_cs();
jjones646 3:dc7e9c6bc26c 341
jjones646 3:dc7e9c6bc26c 342 #if CCXXX1_DEBUG_MODE > 1
jjones646 3:dc7e9c6bc26c 343 std::printf("\r\n== Single Register Write ==\r\n Address: 0x%02X\r\n Value: 0x%02X\r\n", addr, value);
jjones646 3:dc7e9c6bc26c 344 #endif
jjones646 3:dc7e9c6bc26c 345 } // write_reg
jjones646 3:dc7e9c6bc26c 346 void CC1101::write_reg(uint8_t addr, uint8_t *buffer, uint8_t count)
jjones646 3:dc7e9c6bc26c 347 {
jjones646 3:dc7e9c6bc26c 348 toggle_cs();
jjones646 3:dc7e9c6bc26c 349 _spi->write(addr | CCXXX1_WRITE_BURST);
jjones646 3:dc7e9c6bc26c 350 tiny_delay();
jjones646 3:dc7e9c6bc26c 351 for (uint8_t i = 0; i < count; i++) {
jjones646 3:dc7e9c6bc26c 352 _spi->write(buffer[i]);
jjones646 3:dc7e9c6bc26c 353 tiny_delay();
jjones646 3:dc7e9c6bc26c 354 }
jjones646 3:dc7e9c6bc26c 355 toggle_cs();
jjones646 3:dc7e9c6bc26c 356
jjones646 3:dc7e9c6bc26c 357 #if CCXXX1_DEBUG_MODE > 1
jjones646 3:dc7e9c6bc26c 358 std::printf("\r\n== Burst Register Write ==\r\n Address: 0x%02X\r\n Bytes: %u\r\n", addr, count);
jjones646 3:dc7e9c6bc26c 359 #endif
jjones646 3:dc7e9c6bc26c 360 } // write_reg
jjones646 3:dc7e9c6bc26c 361
jjones646 3:dc7e9c6bc26c 362
jjones646 3:dc7e9c6bc26c 363 // Strobe
jjones646 3:dc7e9c6bc26c 364 uint8_t CC1101::strobe(uint8_t addr)
jjones646 3:dc7e9c6bc26c 365 {
jjones646 3:dc7e9c6bc26c 366 toggle_cs();
jjones646 3:dc7e9c6bc26c 367 uint8_t x = _spi->write(addr);
jjones646 3:dc7e9c6bc26c 368 toggle_cs();
jjones646 3:dc7e9c6bc26c 369 return x;
jjones646 3:dc7e9c6bc26c 370 } // strobe
jjones646 3:dc7e9c6bc26c 371
jjones646 3:dc7e9c6bc26c 372
jjones646 3:dc7e9c6bc26c 373 // Macro to calibrate the frequency synthesizer
jjones646 3:dc7e9c6bc26c 374 void CC1101::calibrate(void)
jjones646 2:7d523bdd2f50 375 {
jjones646 3:dc7e9c6bc26c 376 // Send the calibration strobe
jjones646 3:dc7e9c6bc26c 377 strobe(CCXXX1_SCAL);
jjones646 3:dc7e9c6bc26c 378
jjones646 3:dc7e9c6bc26c 379 // Wait for the radio to leave the calibration step
jjones646 3:dc7e9c6bc26c 380 while( (mode() == 0x04) | (mode() == 0x05) );
jjones646 3:dc7e9c6bc26c 381
jjones646 3:dc7e9c6bc26c 382 // The radio is now is IDLE mode, so go to RX mode
jjones646 3:dc7e9c6bc26c 383 rx_mode();
jjones646 3:dc7e9c6bc26c 384
jjones646 3:dc7e9c6bc26c 385 // Wait for the radio to enter back into RX mode
jjones646 3:dc7e9c6bc26c 386 while( mode() != 0x0D );
jjones646 3:dc7e9c6bc26c 387 }
jjones646 3:dc7e9c6bc26c 388
jjones646 3:dc7e9c6bc26c 389
jjones646 3:dc7e9c6bc26c 390 void CC1101::tiny_delay(void)
jjones646 3:dc7e9c6bc26c 391 {
jjones646 3:dc7e9c6bc26c 392 int i = 0;
jjones646 3:dc7e9c6bc26c 393 while(i < 5) {
jjones646 3:dc7e9c6bc26c 394 i++;
jjones646 3:dc7e9c6bc26c 395 }
jjones646 3:dc7e9c6bc26c 396 }
jjones646 3:dc7e9c6bc26c 397
jjones646 3:dc7e9c6bc26c 398 void CC1101::address(uint8_t addr)
jjones646 3:dc7e9c6bc26c 399 {
jjones646 3:dc7e9c6bc26c 400 _address = addr;
jjones646 3:dc7e9c6bc26c 401 // NOW, WRITE THE ADDRESS TO THE CC1101
jjones646 3:dc7e9c6bc26c 402 }
jjones646 3:dc7e9c6bc26c 403
jjones646 3:dc7e9c6bc26c 404 uint8_t CC1101::lqi(void)
jjones646 3:dc7e9c6bc26c 405 {
jjones646 3:dc7e9c6bc26c 406 return 0x3F - (_lqi & 0x3F);
jjones646 3:dc7e9c6bc26c 407 }
jjones646 3:dc7e9c6bc26c 408
jjones646 3:dc7e9c6bc26c 409 // returns the CC1101's VERSION register that specifices what exact chip version is being used
jjones646 3:dc7e9c6bc26c 410 uint8_t CC1101::version(void)
jjones646 3:dc7e9c6bc26c 411 {
jjones646 3:dc7e9c6bc26c 412 return _chip_version;
jjones646 3:dc7e9c6bc26c 413 }
jjones646 3:dc7e9c6bc26c 414
jjones646 3:dc7e9c6bc26c 415 void CC1101::channel(uint16_t chan)
jjones646 3:dc7e9c6bc26c 416 {
jjones646 3:dc7e9c6bc26c 417 if ( chan != _channel ) {
jjones646 3:dc7e9c6bc26c 418 _channel = chan;
jjones646 3:dc7e9c6bc26c 419 write_reg(CCXXX1_CHANNR, _channel);
jjones646 3:dc7e9c6bc26c 420 /*
jjones646 3:dc7e9c6bc26c 421 #if CCXXX1_DEBUG_MODE > 0
jjones646 3:dc7e9c6bc26c 422 std::printf("\r\n[CHANNEL UPDATED]\r\n Channel: %02u\r\n Freq: %3.2f MHz\r\n", _channel, static_cast<float>(_final_freq)/1000000);
jjones646 3:dc7e9c6bc26c 423 #endif
jjones646 3:dc7e9c6bc26c 424 */
jjones646 3:dc7e9c6bc26c 425 }
jjones646 3:dc7e9c6bc26c 426 }
jjones646 3:dc7e9c6bc26c 427
jjones646 3:dc7e9c6bc26c 428 // RSSI
jjones646 3:dc7e9c6bc26c 429 int16_t CC1101::rssi(void)
jjones646 3:dc7e9c6bc26c 430 {
jjones646 3:dc7e9c6bc26c 431 return _rssi;
jjones646 3:dc7e9c6bc26c 432 }
jjones646 3:dc7e9c6bc26c 433 void CC1101::rssi(uint8_t rssi_val)
jjones646 3:dc7e9c6bc26c 434 {
jjones646 3:dc7e9c6bc26c 435 int8_t temp;
jjones646 3:dc7e9c6bc26c 436
jjones646 3:dc7e9c6bc26c 437 if (rssi_val & 0x80) {
jjones646 3:dc7e9c6bc26c 438 temp = (rssi_val - 256)>>1;
jjones646 3:dc7e9c6bc26c 439 } else {
jjones646 3:dc7e9c6bc26c 440 temp = rssi_val>>1; // divide by 2
jjones646 3:dc7e9c6bc26c 441 }
jjones646 3:dc7e9c6bc26c 442 _rssi = temp - 74;
jjones646 3:dc7e9c6bc26c 443 } // rssi
jjones646 3:dc7e9c6bc26c 444
jjones646 3:dc7e9c6bc26c 445
jjones646 3:dc7e9c6bc26c 446 void CC1101::flush_rx(void)
jjones646 3:dc7e9c6bc26c 447 {
jjones646 3:dc7e9c6bc26c 448 // Make sure that the radio is in IDLE state before flushing the FIFO
jjones646 3:dc7e9c6bc26c 449 idle();
jjones646 3:dc7e9c6bc26c 450
jjones646 3:dc7e9c6bc26c 451 // Flush RX FIFO
jjones646 3:dc7e9c6bc26c 452 strobe(CCXXX1_SFRX);
jjones646 3:dc7e9c6bc26c 453
jjones646 3:dc7e9c6bc26c 454 // Enter back into a RX state
jjones646 3:dc7e9c6bc26c 455 rx_mode();
jjones646 3:dc7e9c6bc26c 456 }
jjones646 3:dc7e9c6bc26c 457
jjones646 3:dc7e9c6bc26c 458 void CC1101::flush_tx(void)
jjones646 3:dc7e9c6bc26c 459 {
jjones646 3:dc7e9c6bc26c 460 // Make sure that the radio is in IDLE state before flushing the FIFO
jjones646 3:dc7e9c6bc26c 461 idle();
jjones646 3:dc7e9c6bc26c 462
jjones646 3:dc7e9c6bc26c 463 // Flush TX FIFO
jjones646 3:dc7e9c6bc26c 464 strobe(CCXXX1_SFTX);
jjones646 3:dc7e9c6bc26c 465
jjones646 3:dc7e9c6bc26c 466 // Enter back into a RX state
jjones646 3:dc7e9c6bc26c 467 rx_mode();
jjones646 2:7d523bdd2f50 468 }
jjones646 2:7d523bdd2f50 469
jjones646 3:dc7e9c6bc26c 470
jjones646 3:dc7e9c6bc26c 471 void CC1101::rx_mode(void)
jjones646 3:dc7e9c6bc26c 472 {
jjones646 3:dc7e9c6bc26c 473 //strobe(CCXXX1_SIDLE);
jjones646 3:dc7e9c6bc26c 474 strobe(CCXXX1_SRX);
jjones646 3:dc7e9c6bc26c 475 //while(mode() != 0x0D);
jjones646 3:dc7e9c6bc26c 476 }
jjones646 3:dc7e9c6bc26c 477
jjones646 3:dc7e9c6bc26c 478
jjones646 3:dc7e9c6bc26c 479 void CC1101::tx_mode(void)
jjones646 3:dc7e9c6bc26c 480 {
jjones646 3:dc7e9c6bc26c 481 //strobe(CCXXX1_SIDLE);
jjones646 3:dc7e9c6bc26c 482 strobe(CCXXX1_STX);
jjones646 3:dc7e9c6bc26c 483 // while(mode() != 0x13);
jjones646 3:dc7e9c6bc26c 484 }
jjones646 3:dc7e9c6bc26c 485
jjones646 3:dc7e9c6bc26c 486 void CC1101::idle(void)
jjones646 3:dc7e9c6bc26c 487 {
jjones646 3:dc7e9c6bc26c 488 // Send the IDLE strobe
jjones646 3:dc7e9c6bc26c 489 strobe(CCXXX1_SIDLE);
jjones646 3:dc7e9c6bc26c 490 // Wait before returning
jjones646 3:dc7e9c6bc26c 491 // === THIS LIKELY ISN'T NEEDED ===
jjones646 3:dc7e9c6bc26c 492 while( mode() != 0x01);
jjones646 3:dc7e9c6bc26c 493 }
jjones646 3:dc7e9c6bc26c 494
jjones646 3:dc7e9c6bc26c 495
jjones646 3:dc7e9c6bc26c 496 // Status byte & status of a status register
jjones646 3:dc7e9c6bc26c 497 uint8_t CC1101::status(void)
jjones646 3:dc7e9c6bc26c 498 {
jjones646 3:dc7e9c6bc26c 499 return strobe(CCXXX1_SNOP);
jjones646 3:dc7e9c6bc26c 500 }
jjones646 3:dc7e9c6bc26c 501
jjones646 3:dc7e9c6bc26c 502 uint8_t CC1101::status(uint8_t addr)
jjones646 2:7d523bdd2f50 503 {
jjones646 3:dc7e9c6bc26c 504 toggle_cs();
jjones646 3:dc7e9c6bc26c 505 _spi->write(addr | CCXXX1_READ_BURST);
jjones646 3:dc7e9c6bc26c 506 tiny_delay();
jjones646 3:dc7e9c6bc26c 507 uint8_t x = _spi->write(0);
jjones646 3:dc7e9c6bc26c 508 toggle_cs();
jjones646 3:dc7e9c6bc26c 509 return x;
jjones646 3:dc7e9c6bc26c 510 } // status
jjones646 3:dc7e9c6bc26c 511
jjones646 3:dc7e9c6bc26c 512
jjones646 3:dc7e9c6bc26c 513 // SET FREQUENCY
jjones646 3:dc7e9c6bc26c 514 void CC1101::freq(uint32_t freq)
jjones646 3:dc7e9c6bc26c 515 {
jjones646 3:dc7e9c6bc26c 516 /* calculate the value that is written to the register for settings the base frequency
jjones646 3:dc7e9c6bc26c 517 * that the CC1101 should use for sending/receiving over the air. Default value is equivalent
jjones646 3:dc7e9c6bc26c 518 * to 901.83 MHz.
jjones646 3:dc7e9c6bc26c 519 */
jjones646 3:dc7e9c6bc26c 520
jjones646 3:dc7e9c6bc26c 521 // this is split into 3 bytes that are written to 3 different registers on the CC1101
jjones646 3:dc7e9c6bc26c 522 uint32_t reg_freq = _base_freq / (CCXXX1_CRYSTAL_FREQUENCY>>16);
jjones646 3:dc7e9c6bc26c 523
jjones646 3:dc7e9c6bc26c 524 rfSettings.FREQ2 = (reg_freq>>16) & 0xFF; // high byte, bits 7..6 are always 0 for this register
jjones646 3:dc7e9c6bc26c 525 rfSettings.FREQ1 = (reg_freq>>8) & 0xFF; // middle byte
jjones646 3:dc7e9c6bc26c 526 rfSettings.FREQ0 = reg_freq & 0xFF; // low byte
jjones646 3:dc7e9c6bc26c 527 }
jjones646 3:dc7e9c6bc26c 528
jjones646 3:dc7e9c6bc26c 529
jjones646 3:dc7e9c6bc26c 530 void CC1101::datarate(uint32_t rate)
jjones646 3:dc7e9c6bc26c 531 {
jjones646 3:dc7e9c6bc26c 532 // update the baud rate class member
jjones646 3:dc7e9c6bc26c 533 _datarate = rate;
jjones646 3:dc7e9c6bc26c 534
jjones646 3:dc7e9c6bc26c 535 // have to be careful with bit shifting here since it requires a large amount of shifts
jjones646 3:dc7e9c6bc26c 536 uint32_t shift_val = 28 - (_modem.data_rate_exp & 0x0F);
jjones646 3:dc7e9c6bc26c 537
jjones646 3:dc7e9c6bc26c 538 // compute the register value and assign it
jjones646 3:dc7e9c6bc26c 539 rfSettings.MDMCFG3 = ((_datarate)/(CCXXX1_CRYSTAL_FREQUENCY>>shift_val)) - 256;
jjones646 2:7d523bdd2f50 540 }
jjones646 2:7d523bdd2f50 541
jjones646 3:dc7e9c6bc26c 542
jjones646 3:dc7e9c6bc26c 543 // ===============
jjones646 3:dc7e9c6bc26c 544 void CC1101::assign_modem_params()
jjones646 3:dc7e9c6bc26c 545 {
jjones646 3:dc7e9c6bc26c 546 rfSettings.MDMCFG4 = (_modem.channel_bw_exp & 0x03)<<6 | (_modem.channel_bw & 0x03)<<4 | (_modem.data_rate_exp & 0x0F);
jjones646 3:dc7e9c6bc26c 547 rfSettings.MDMCFG2 = _modem.dc_filter_off_en<<7 | (_modem.mod_type & 0x07)<<4 | _modem.manchester_encode_en<<3 | (_modem.sync_mode & 0x07);
jjones646 3:dc7e9c6bc26c 548 rfSettings.MDMCFG1 = _modem.fec_en<<7 | (_modem.preamble_bytes & 0x07)<<4 | (_modem.channel_space_exp & 0x03);
jjones646 3:dc7e9c6bc26c 549 }
jjones646 3:dc7e9c6bc26c 550 // ===============
jjones646 3:dc7e9c6bc26c 551 void CC1101::assign_packet_params()
jjones646 3:dc7e9c6bc26c 552 {
jjones646 3:dc7e9c6bc26c 553 rfSettings.PCKCTRL0 = _pck_control.whitening_en<<6 | (_pck_control.format_type & 0x3)<<4 | _pck_control.crc_en<<2 | (_pck_control.length_type & 0x3);
jjones646 3:dc7e9c6bc26c 554 rfSettings.PCKCTRL1 = (_pck_control.preamble_thresh & 0x07)<<5 | _pck_control.autoflush_en<<3 | _pck_control.status_field_en<<2 | (_pck_control.addr_check & 0x03);
jjones646 3:dc7e9c6bc26c 555 rfSettings.PCKLEN = _pck_control.size;
jjones646 3:dc7e9c6bc26c 556 }
jjones646 3:dc7e9c6bc26c 557 // ===============
jjones646 3:dc7e9c6bc26c 558 void CC1101::assign_if_freq(uint32_t freq)
jjones646 3:dc7e9c6bc26c 559 {
jjones646 3:dc7e9c6bc26c 560 // The desired IF frequency for RX. Subtracted from FS base frequency in RX.
jjones646 3:dc7e9c6bc26c 561 // bits 7..5 are always 0
jjones646 3:dc7e9c6bc26c 562 rfSettings.FSCTRL1 = (freq/(CCXXX1_CRYSTAL_FREQUENCY>>10)) & 0x1F;
jjones646 3:dc7e9c6bc26c 563 rfSettings.FSCTRL0 = 0x00; // set the initial freq calibration to 0
jjones646 3:dc7e9c6bc26c 564 }
jjones646 3:dc7e9c6bc26c 565 // ===============
jjones646 3:dc7e9c6bc26c 566 void CC1101::assign_channel_spacing(uint32_t spacing)
jjones646 3:dc7e9c6bc26c 567 {
jjones646 3:dc7e9c6bc26c 568 // have to be careful with bit shifting here since it requires a large amount of shifts
jjones646 3:dc7e9c6bc26c 569 uint32_t shift_val = 18 - (_modem.channel_space_exp & 0x03);
jjones646 3:dc7e9c6bc26c 570
jjones646 3:dc7e9c6bc26c 571 // compute the register value and assign it
jjones646 3:dc7e9c6bc26c 572 rfSettings.MDMCFG0 = (spacing/(CCXXX1_CRYSTAL_FREQUENCY>>shift_val)) - 256;
jjones646 3:dc7e9c6bc26c 573 }
jjones646 3:dc7e9c6bc26c 574 void CC1101::set_rf_settings(void)
jjones646 3:dc7e9c6bc26c 575 {
jjones646 3:dc7e9c6bc26c 576 // set the fields for packet controls
jjones646 3:dc7e9c6bc26c 577 assign_packet_params();
jjones646 3:dc7e9c6bc26c 578
jjones646 3:dc7e9c6bc26c 579 // set the fields for the frequency limits of the modem
jjones646 3:dc7e9c6bc26c 580 assign_modem_params();
jjones646 3:dc7e9c6bc26c 581
jjones646 3:dc7e9c6bc26c 582 // assign an address to the CC1101. This can be used to filter packets
jjones646 3:dc7e9c6bc26c 583 rfSettings.ADDR = _address;
jjones646 3:dc7e9c6bc26c 584
jjones646 3:dc7e9c6bc26c 585 // there can be 16 different channel numbers. The bandwidth and spacing are defined in other registers
jjones646 3:dc7e9c6bc26c 586 rfSettings.CHANNR = _channel;
jjones646 3:dc7e9c6bc26c 587
jjones646 3:dc7e9c6bc26c 588 // compute the final adjusted frequency so that it will be correct after the constructor
jjones646 3:dc7e9c6bc26c 589 // compute_freq();
jjones646 3:dc7e9c6bc26c 590
jjones646 3:dc7e9c6bc26c 591 // disable GDO0
jjones646 3:dc7e9c6bc26c 592 rfSettings.IOCFG0 = 0x2E;
jjones646 3:dc7e9c6bc26c 593
jjones646 3:dc7e9c6bc26c 594 // setup for SPI
jjones646 3:dc7e9c6bc26c 595 rfSettings.IOCFG1 = 0x0C;
jjones646 3:dc7e9c6bc26c 596
jjones646 3:dc7e9c6bc26c 597 // setup for going HIGH when packet received and CRC is ok
jjones646 3:dc7e9c6bc26c 598 rfSettings.IOCFG2 = 0x07;
jjones646 3:dc7e9c6bc26c 599
jjones646 3:dc7e9c6bc26c 600 rfSettings.DEVIATN = 0x62;
jjones646 3:dc7e9c6bc26c 601
jjones646 3:dc7e9c6bc26c 602 rfSettings.FREND1 = 0xB6;
jjones646 3:dc7e9c6bc26c 603 rfSettings.FREND0 = 0x10;
jjones646 3:dc7e9c6bc26c 604
jjones646 3:dc7e9c6bc26c 605 bool RX_TIME_RSSI = false;
jjones646 3:dc7e9c6bc26c 606 bool RX_TIME_QUAL = false;
jjones646 3:dc7e9c6bc26c 607 uint8_t RX_TIME = 0x07; // no timeout
jjones646 3:dc7e9c6bc26c 608
jjones646 3:dc7e9c6bc26c 609 rfSettings.MCSM2 = (RX_TIME_RSSI<<4) | (RX_TIME_QUAL<<3) | (RX_TIME & 0x07);
jjones646 3:dc7e9c6bc26c 610
jjones646 3:dc7e9c6bc26c 611 uint8_t CCA_MODE = 0x00;
jjones646 3:dc7e9c6bc26c 612 uint8_t RXOFF_MODE = 0x00; // go directly to IDLE when existing RX
jjones646 3:dc7e9c6bc26c 613 //uint8_t RXOFF_MODE = 0x03; // stay in RX when existing RX
jjones646 3:dc7e9c6bc26c 614 uint8_t TXOFF_MODE = 0x03; // go directly to RX when existing TX
jjones646 3:dc7e9c6bc26c 615 // uint8_t TXOFF_MODE = 0x00; // go directly to IDLE when existing TX
jjones646 3:dc7e9c6bc26c 616
jjones646 3:dc7e9c6bc26c 617 rfSettings.MCSM1 = ((CCA_MODE & 0x03)<<4) | ((RXOFF_MODE & 0x03)<<2) | (TXOFF_MODE & 0x03);
jjones646 3:dc7e9c6bc26c 618
jjones646 3:dc7e9c6bc26c 619 uint8_t FS_AUTOCAL = 0x01; // calibrate when going from IDLE to RX or TX
jjones646 3:dc7e9c6bc26c 620 uint8_t PO_TIMEOUT = 0x02;
jjones646 3:dc7e9c6bc26c 621 bool PIN_CTRL_EN = false;
jjones646 3:dc7e9c6bc26c 622 bool XOSC_FORCE_ON = false;
jjones646 3:dc7e9c6bc26c 623
jjones646 3:dc7e9c6bc26c 624 rfSettings.MCSM0 = ((FS_AUTOCAL & 0x03)<<4) | ((PO_TIMEOUT & 0x03)<<2) | (PIN_CTRL_EN<<1) | (XOSC_FORCE_ON);
jjones646 3:dc7e9c6bc26c 625
jjones646 3:dc7e9c6bc26c 626 bool FOC_BS_CS_GATE = false;
jjones646 3:dc7e9c6bc26c 627 uint8_t FOC_PRE_K = 0x03;
jjones646 3:dc7e9c6bc26c 628 bool FOC_POST_K = true;
jjones646 3:dc7e9c6bc26c 629 uint8_t FOC_LIMIT = 0x01;
jjones646 3:dc7e9c6bc26c 630
jjones646 3:dc7e9c6bc26c 631 rfSettings.FOCCFG = 0x40 | (FOC_BS_CS_GATE<<5) | ((FOC_PRE_K & 0x03)<<3) | (FOC_POST_K<<2) | (FOC_LIMIT & 0x03);
jjones646 3:dc7e9c6bc26c 632
jjones646 3:dc7e9c6bc26c 633 rfSettings.BSCFG = 0x1C;
jjones646 3:dc7e9c6bc26c 634
jjones646 3:dc7e9c6bc26c 635 rfSettings.AGCCTRL2 = 0xC7;
jjones646 3:dc7e9c6bc26c 636 rfSettings.AGCCTRL1 = 0x00;
jjones646 3:dc7e9c6bc26c 637 rfSettings.AGCCTRL0 = 0xB0;
jjones646 3:dc7e9c6bc26c 638
jjones646 3:dc7e9c6bc26c 639 // rfSettings.FIFOTHR = 0x0F; // RXFIFO and TXFIFO thresholds.
jjones646 3:dc7e9c6bc26c 640
jjones646 3:dc7e9c6bc26c 641 // 33 byte TX FIFO & 32 byte RX FIFO
jjones646 3:dc7e9c6bc26c 642 rfSettings.FIFOTHR = 0x07; // RXFIFO and TXFIFO thresholds.
jjones646 3:dc7e9c6bc26c 643 }