Jonathan Jones
/
Radios
Radio Structures in OOP
drivers/CC1101/CC1101.cpp@5:146523a0d1f4, 2015-01-14 (annotated)
- Committer:
- jjones646
- Date:
- Wed Jan 14 17:46:44 2015 +0000
- Revision:
- 5:146523a0d1f4
- Parent:
- 3:dc7e9c6bc26c
- Child:
- 6:4a3dbfbc30f1
wrapping up functionality of sockets"
Who changed what in which revision?
User | Revision | Line number | New 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 | 5:146523a0d1f4 | 44 | init(); |
jjones646 | 3:dc7e9c6bc26c | 45 | |
jjones646 | 3:dc7e9c6bc26c | 46 | // [] - 2 - Test the interrupt pin for proper operation |
jjones646 | 3:dc7e9c6bc26c | 47 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 48 | |
jjones646 | 3:dc7e9c6bc26c | 49 | // [] - 3 - Check the CC1101's version register to ensure the chip is what we believe it to be |
jjones646 | 3:dc7e9c6bc26c | 50 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 51 | |
jjones646 | 3:dc7e9c6bc26c | 52 | } |
jjones646 | 3:dc7e9c6bc26c | 53 | |
jjones646 | 3:dc7e9c6bc26c | 54 | |
jjones646 | 3:dc7e9c6bc26c | 55 | int32_t CC1101::powerUp(void) |
jjones646 | 3:dc7e9c6bc26c | 56 | { |
jjones646 | 3:dc7e9c6bc26c | 57 | #if CCXXX1_DEBUG_MODE > 0 |
jjones646 | 3:dc7e9c6bc26c | 58 | std::printf("[CC1101 RADIO TRANSCEIVER INITILIZATION]\r\n"); |
jjones646 | 3:dc7e9c6bc26c | 59 | #endif |
jjones646 | 3:dc7e9c6bc26c | 60 | |
jjones646 | 3:dc7e9c6bc26c | 61 | // power_on_reset(); |
jjones646 | 3:dc7e9c6bc26c | 62 | |
jjones646 | 3:dc7e9c6bc26c | 63 | // now send the assigned rfSettings struct to the CC1101 for full inililization |
jjones646 | 3:dc7e9c6bc26c | 64 | // init(); |
jjones646 | 3:dc7e9c6bc26c | 65 | |
jjones646 | 3:dc7e9c6bc26c | 66 | // scan(); |
jjones646 | 3:dc7e9c6bc26c | 67 | |
jjones646 | 3:dc7e9c6bc26c | 68 | return 0; |
jjones646 | 2:7d523bdd2f50 | 69 | } |
jjones646 | 2:7d523bdd2f50 | 70 | |
jjones646 | 2:7d523bdd2f50 | 71 | |
jjones646 | 2:7d523bdd2f50 | 72 | bool CC1101::isConnected(void) |
jjones646 | 2:7d523bdd2f50 | 73 | { |
jjones646 | 2:7d523bdd2f50 | 74 | // [] - 1 - Perform a check to ensure the CC1101 can provide communication with a secondary base station link |
jjones646 | 3:dc7e9c6bc26c | 75 | // ================= |
jjones646 | 2:7d523bdd2f50 | 76 | // Note: This does not necessarily mean the link must be reliable, this only needs to determine: `Can the perheripial provide communication?` |
jjones646 | 3:dc7e9c6bc26c | 77 | |
jjones646 | 2:7d523bdd2f50 | 78 | // [] - 2 - Return true/false for indicating a connected communication link |
jjones646 | 3:dc7e9c6bc26c | 79 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 80 | |
jjones646 | 2:7d523bdd2f50 | 81 | return true; |
jjones646 | 2:7d523bdd2f50 | 82 | } |
jjones646 | 2:7d523bdd2f50 | 83 | |
jjones646 | 2:7d523bdd2f50 | 84 | |
jjones646 | 2:7d523bdd2f50 | 85 | uint32_t CC1101::reset(void) |
jjones646 | 2:7d523bdd2f50 | 86 | { |
jjones646 | 3:dc7e9c6bc26c | 87 | // [X] - 1 - Perform a soft reset for the CC1101 transceiver |
jjones646 | 3:dc7e9c6bc26c | 88 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 89 | strobe(CCXXX1_SRES); |
jjones646 | 3:dc7e9c6bc26c | 90 | return 0; // success |
jjones646 | 2:7d523bdd2f50 | 91 | } |
jjones646 | 2:7d523bdd2f50 | 92 | |
jjones646 | 2:7d523bdd2f50 | 93 | |
jjones646 | 2:7d523bdd2f50 | 94 | uint32_t CC1101::selfTest(void) |
jjones646 | 2:7d523bdd2f50 | 95 | { |
jjones646 | 3:dc7e9c6bc26c | 96 | // [X] - 1 - Get the chip's version number and fail if different from what was expected. |
jjones646 | 3:dc7e9c6bc26c | 97 | _chip_version = status(CCXXX1_VERSION); |
jjones646 | 3:dc7e9c6bc26c | 98 | |
jjones646 | 3:dc7e9c6bc26c | 99 | if (_chip_version != CCXXX1_EXPECTED_VERSION_NUMBER) { |
jjones646 | 3:dc7e9c6bc26c | 100 | |
jjones646 | 3:dc7e9c6bc26c | 101 | // send message over serial port |
jjones646 | 3:dc7e9c6bc26c | 102 | std::printf( |
jjones646 | 3:dc7e9c6bc26c | 103 | "[FATAL ERROR]\r\n" |
jjones646 | 3:dc7e9c6bc26c | 104 | " Wrong version number returned from chip's 'VERSION' register (Addr: 0x%02X)\r\n" |
jjones646 | 3:dc7e9c6bc26c | 105 | "\r\n" |
jjones646 | 3:dc7e9c6bc26c | 106 | " Expected: 0x%02X\r\n" |
jjones646 | 3:dc7e9c6bc26c | 107 | " Found: 0x%02X\r\n" |
jjones646 | 3:dc7e9c6bc26c | 108 | "\r\n" |
jjones646 | 3:dc7e9c6bc26c | 109 | " Troubleshooting Tips:\r\n" |
jjones646 | 3:dc7e9c6bc26c | 110 | " - Check that the chip is fully connected with no soldering errors\r\n" |
jjones646 | 3:dc7e9c6bc26c | 111 | " - Determine if chip is newer version & update firmware\r\n" |
jjones646 | 3:dc7e9c6bc26c | 112 | , CCXXX1_VERSION, CCXXX1_EXPECTED_VERSION_NUMBER, _chip_version); |
jjones646 | 3:dc7e9c6bc26c | 113 | |
jjones646 | 3:dc7e9c6bc26c | 114 | return 1; |
jjones646 | 3:dc7e9c6bc26c | 115 | } |
jjones646 | 3:dc7e9c6bc26c | 116 | return 0; // success |
jjones646 | 3:dc7e9c6bc26c | 117 | } |
jjones646 | 3:dc7e9c6bc26c | 118 | |
jjones646 | 5:146523a0d1f4 | 119 | |
jjones646 | 3:dc7e9c6bc26c | 120 | void CC1101::set_init_vars(void) |
jjones646 | 3:dc7e9c6bc26c | 121 | { |
jjones646 | 5:146523a0d1f4 | 122 | // define the initial state of an unselected chip |
jjones646 | 3:dc7e9c6bc26c | 123 | *_cs = 1; |
jjones646 | 3:dc7e9c6bc26c | 124 | _channel = 1; |
jjones646 | 3:dc7e9c6bc26c | 125 | _address = 0x00; |
jjones646 | 3:dc7e9c6bc26c | 126 | |
jjones646 | 3:dc7e9c6bc26c | 127 | // frequency that radio links with another CC1101 over the air |
jjones646 | 3:dc7e9c6bc26c | 128 | _base_freq = CCXXX1_BASE_FREQUENCY; |
jjones646 | 3:dc7e9c6bc26c | 129 | |
jjones646 | 3:dc7e9c6bc26c | 130 | // turn off address packet filtering and assign 0 (broadcast address) to the address value |
jjones646 | 3:dc7e9c6bc26c | 131 | _pck_control.addr_check = ADDR_OFF; |
jjones646 | 3:dc7e9c6bc26c | 132 | |
jjones646 | 3:dc7e9c6bc26c | 133 | // these values determine how the CC1101 will handel a packet |
jjones646 | 3:dc7e9c6bc26c | 134 | _pck_control.whitening_en = false; |
jjones646 | 3:dc7e9c6bc26c | 135 | |
jjones646 | 3:dc7e9c6bc26c | 136 | // enable CRC calculation in TX and CRC checking in RX |
jjones646 | 3:dc7e9c6bc26c | 137 | _pck_control.crc_en = true; |
jjones646 | 3:dc7e9c6bc26c | 138 | |
jjones646 | 3:dc7e9c6bc26c | 139 | // enable automatically flushing the RX buffer on a bad CRC (only works if 1 packet is in the RX buffer) |
jjones646 | 3:dc7e9c6bc26c | 140 | _pck_control.autoflush_en = true; |
jjones646 | 3:dc7e9c6bc26c | 141 | |
jjones646 | 3:dc7e9c6bc26c | 142 | // enable appending 2 status bytes to the end of every packet that includes the CRC and |
jjones646 | 3:dc7e9c6bc26c | 143 | _pck_control.status_field_en = true; |
jjones646 | 3:dc7e9c6bc26c | 144 | |
jjones646 | 3:dc7e9c6bc26c | 145 | // normal packet mode uses RX and TX buffers |
jjones646 | 3:dc7e9c6bc26c | 146 | _pck_control.format_type = FORMAT_DEFAULT; |
jjones646 | 3:dc7e9c6bc26c | 147 | |
jjones646 | 3:dc7e9c6bc26c | 148 | // setup how the payload of the packet is transmitted - default to a fixed length of 61 bytes |
jjones646 | 3:dc7e9c6bc26c | 149 | _pck_control.length_type = PACKET_VARIABLE; |
jjones646 | 3:dc7e9c6bc26c | 150 | //_pck_control.length_type = PACKET_FIXED; |
jjones646 | 3:dc7e9c6bc26c | 151 | //_pck_control.size = 61; |
jjones646 | 3:dc7e9c6bc26c | 152 | |
jjones646 | 3:dc7e9c6bc26c | 153 | // this is a preamble threshold for determining when a packet should be accepted |
jjones646 | 3:dc7e9c6bc26c | 154 | _pck_control.preamble_thresh = 2; |
jjones646 | 3:dc7e9c6bc26c | 155 | |
jjones646 | 3:dc7e9c6bc26c | 156 | // these values determine how the frequency bands and channels are distributed as well as defining the modulation type |
jjones646 | 3:dc7e9c6bc26c | 157 | _modem.dc_filter_off_en = false; |
jjones646 | 3:dc7e9c6bc26c | 158 | _modem.manchester_encode_en = false; |
jjones646 | 3:dc7e9c6bc26c | 159 | _modem.fec_en = false; |
jjones646 | 3:dc7e9c6bc26c | 160 | |
jjones646 | 3:dc7e9c6bc26c | 161 | // bandwidth configurations |
jjones646 | 3:dc7e9c6bc26c | 162 | _modem.channel_bw = 2; |
jjones646 | 3:dc7e9c6bc26c | 163 | _modem.channel_bw_exp = 0; |
jjones646 | 3:dc7e9c6bc26c | 164 | _modem.channel_space_exp = 2; |
jjones646 | 3:dc7e9c6bc26c | 165 | _modem.data_rate_exp = 13; |
jjones646 | 3:dc7e9c6bc26c | 166 | |
jjones646 | 3:dc7e9c6bc26c | 167 | _modem.mod_type = MOD_GFSK; |
jjones646 | 3:dc7e9c6bc26c | 168 | _modem.sync_mode = SYNC_HIGH_ALLOW_TWO; |
jjones646 | 3:dc7e9c6bc26c | 169 | _modem.preamble_bytes = PREAM_FOUR; |
jjones646 | 3:dc7e9c6bc26c | 170 | |
jjones646 | 3:dc7e9c6bc26c | 171 | // the values assigned here are used for the frequency synthesizer control |
jjones646 | 3:dc7e9c6bc26c | 172 | // assign_if_freq(CCXXX1_IF_FREQUENCY); |
jjones646 | 3:dc7e9c6bc26c | 173 | |
jjones646 | 3:dc7e9c6bc26c | 174 | // set all the configuration values into the rfSettings struct |
jjones646 | 3:dc7e9c6bc26c | 175 | // set_rf_settings(); |
jjones646 | 3:dc7e9c6bc26c | 176 | } |
jjones646 | 3:dc7e9c6bc26c | 177 | |
jjones646 | 3:dc7e9c6bc26c | 178 | |
jjones646 | 5:146523a0d1f4 | 179 | void CC1101::put_rf_settings() |
jjones646 | 5:146523a0d1f4 | 180 | { |
jjones646 | 5:146523a0d1f4 | 181 | write_reg(CCXXX1_IOCFG2, rfSettings.IOCFG2); |
jjones646 | 5:146523a0d1f4 | 182 | write_reg(CCXXX1_IOCFG1, rfSettings.IOCFG1); |
jjones646 | 5:146523a0d1f4 | 183 | write_reg(CCXXX1_IOCFG0, rfSettings.IOCFG0); |
jjones646 | 5:146523a0d1f4 | 184 | write_reg(CCXXX1_FIFOTHR, rfSettings.FIFOTHR); |
jjones646 | 5:146523a0d1f4 | 185 | // SYNC1 |
jjones646 | 5:146523a0d1f4 | 186 | // SYNC0 |
jjones646 | 5:146523a0d1f4 | 187 | write_reg(CCXXX1_PCKLEN, rfSettings.PCKLEN); |
jjones646 | 5:146523a0d1f4 | 188 | write_reg(CCXXX1_PCKCTRL1, rfSettings.PCKCTRL1); |
jjones646 | 5:146523a0d1f4 | 189 | write_reg(CCXXX1_PCKCTRL0, rfSettings.PCKCTRL0); |
jjones646 | 5:146523a0d1f4 | 190 | write_reg(CCXXX1_ADDR, rfSettings.ADDR); |
jjones646 | 5:146523a0d1f4 | 191 | |
jjones646 | 5:146523a0d1f4 | 192 | write_reg(CCXXX1_CHANNR, rfSettings.CHANNR); |
jjones646 | 5:146523a0d1f4 | 193 | write_reg(CCXXX1_FSCTRL1, rfSettings.FSCTRL1); |
jjones646 | 5:146523a0d1f4 | 194 | write_reg(CCXXX1_FSCTRL0, rfSettings.FSCTRL0); |
jjones646 | 5:146523a0d1f4 | 195 | write_reg(CCXXX1_FREQ2, rfSettings.FREQ2); |
jjones646 | 5:146523a0d1f4 | 196 | |
jjones646 | 5:146523a0d1f4 | 197 | write_reg(CCXXX1_FREQ1, rfSettings.FREQ1); |
jjones646 | 5:146523a0d1f4 | 198 | write_reg(CCXXX1_FREQ0, rfSettings.FREQ0); |
jjones646 | 5:146523a0d1f4 | 199 | write_reg(CCXXX1_MDMCFG4, rfSettings.MDMCFG4); |
jjones646 | 5:146523a0d1f4 | 200 | write_reg(CCXXX1_MDMCFG3, rfSettings.MDMCFG3); |
jjones646 | 5:146523a0d1f4 | 201 | |
jjones646 | 5:146523a0d1f4 | 202 | write_reg(CCXXX1_MDMCFG2, rfSettings.MDMCFG2); |
jjones646 | 5:146523a0d1f4 | 203 | write_reg(CCXXX1_MDMCFG1, rfSettings.MDMCFG1); |
jjones646 | 5:146523a0d1f4 | 204 | write_reg(CCXXX1_MDMCFG0, rfSettings.MDMCFG0); |
jjones646 | 5:146523a0d1f4 | 205 | write_reg(CCXXX1_DEVIATN, rfSettings.DEVIATN); |
jjones646 | 5:146523a0d1f4 | 206 | write_reg(CCXXX1_MCSM2 , rfSettings.MCSM2); |
jjones646 | 5:146523a0d1f4 | 207 | write_reg(CCXXX1_MCSM1 , rfSettings.MCSM1); |
jjones646 | 5:146523a0d1f4 | 208 | write_reg(CCXXX1_MCSM0 , rfSettings.MCSM0 ); |
jjones646 | 5:146523a0d1f4 | 209 | write_reg(CCXXX1_FOCCFG, rfSettings.FOCCFG); |
jjones646 | 5:146523a0d1f4 | 210 | write_reg(CCXXX1_BSCFG, rfSettings.BSCFG); |
jjones646 | 5:146523a0d1f4 | 211 | write_reg(CCXXX1_AGCCTRL2, rfSettings.AGCCTRL2); |
jjones646 | 5:146523a0d1f4 | 212 | write_reg(CCXXX1_AGCCTRL1, rfSettings.AGCCTRL1); |
jjones646 | 5:146523a0d1f4 | 213 | write_reg(CCXXX1_AGCCTRL0, rfSettings.AGCCTRL0); |
jjones646 | 5:146523a0d1f4 | 214 | // WOREVT1 |
jjones646 | 5:146523a0d1f4 | 215 | // WOREVT0 |
jjones646 | 5:146523a0d1f4 | 216 | // WORCTRL |
jjones646 | 5:146523a0d1f4 | 217 | write_reg(CCXXX1_FREND1, rfSettings.FREND1); |
jjones646 | 5:146523a0d1f4 | 218 | write_reg(CCXXX1_FREND0, rfSettings.FREND0); |
jjones646 | 5:146523a0d1f4 | 219 | //write_reg(CCXXX1_FSCAL3, rfSettings.FSCAL3); |
jjones646 | 5:146523a0d1f4 | 220 | //write_reg(CCXXX1_FSCAL2, rfSettings.FSCAL2); |
jjones646 | 5:146523a0d1f4 | 221 | //write_reg(CCXXX1_FSCAL1, rfSettings.FSCAL1); |
jjones646 | 5:146523a0d1f4 | 222 | //write_reg(CCXXX1_FSCAL0, rfSettings.FSCAL0); |
jjones646 | 5:146523a0d1f4 | 223 | // PCCTRL1 |
jjones646 | 5:146523a0d1f4 | 224 | // PCCTRL0 |
jjones646 | 5:146523a0d1f4 | 225 | // FSTEST |
jjones646 | 5:146523a0d1f4 | 226 | // PTEST |
jjones646 | 5:146523a0d1f4 | 227 | // AGCTEST |
jjones646 | 5:146523a0d1f4 | 228 | //write_reg(CCXXX1_TEST2, rfSettings.TEST2); |
jjones646 | 5:146523a0d1f4 | 229 | //write_reg(CCXXX1_TEST1, rfSettings.TEST1); |
jjones646 | 5:146523a0d1f4 | 230 | //write_reg(CCXXX1_TEST0, rfSettings.TEST0); |
jjones646 | 5:146523a0d1f4 | 231 | } // put_rf_settings |
jjones646 | 5:146523a0d1f4 | 232 | |
jjones646 | 5:146523a0d1f4 | 233 | |
jjones646 | 5:146523a0d1f4 | 234 | |
jjones646 | 5:146523a0d1f4 | 235 | void CC1101::power_on_reset(void) |
jjones646 | 5:146523a0d1f4 | 236 | { |
jjones646 | 5:146523a0d1f4 | 237 | #if DEBUG_MODE > 0 |
jjones646 | 5:146523a0d1f4 | 238 | std::printf(" Starting Power-on-Reset procedure..."); |
jjones646 | 5:146523a0d1f4 | 239 | #endif |
jjones646 | 5:146523a0d1f4 | 240 | delete _spi; |
jjones646 | 5:146523a0d1f4 | 241 | |
jjones646 | 5:146523a0d1f4 | 242 | // make sure chip is not selected |
jjones646 | 5:146523a0d1f4 | 243 | toggle_cs(); |
jjones646 | 5:146523a0d1f4 | 244 | |
jjones646 | 5:146523a0d1f4 | 245 | DigitalOut *SI = new DigitalOut(_mosi_pin); |
jjones646 | 5:146523a0d1f4 | 246 | DigitalOut *SCK = new DigitalOut(_sck_pin); |
jjones646 | 5:146523a0d1f4 | 247 | DigitalIn *SO = new DigitalIn(_miso_pin); |
jjones646 | 5:146523a0d1f4 | 248 | |
jjones646 | 5:146523a0d1f4 | 249 | // bring SPI lines to a defined state. Reasons are outlined in CC1101 datasheet - section 11.3 |
jjones646 | 5:146523a0d1f4 | 250 | *SI = 0; |
jjones646 | 5:146523a0d1f4 | 251 | *SCK = 1; |
jjones646 | 5:146523a0d1f4 | 252 | |
jjones646 | 5:146523a0d1f4 | 253 | // toggle chip select and remain in high state afterwards |
jjones646 | 5:146523a0d1f4 | 254 | toggle_cs(); |
jjones646 | 5:146523a0d1f4 | 255 | toggle_cs(); |
jjones646 | 5:146523a0d1f4 | 256 | |
jjones646 | 5:146523a0d1f4 | 257 | // wait at least 40us |
jjones646 | 5:146523a0d1f4 | 258 | wait_us(45); |
jjones646 | 5:146523a0d1f4 | 259 | |
jjones646 | 5:146523a0d1f4 | 260 | // pull CSn low & wait for the serial out line to go low |
jjones646 | 5:146523a0d1f4 | 261 | *_cs = 0; |
jjones646 | 5:146523a0d1f4 | 262 | |
jjones646 | 5:146523a0d1f4 | 263 | while(*SO); |
jjones646 | 5:146523a0d1f4 | 264 | |
jjones646 | 5:146523a0d1f4 | 265 | // cleanup everything before the mbed's SPI library calls take back over |
jjones646 | 5:146523a0d1f4 | 266 | delete SI; |
jjones646 | 5:146523a0d1f4 | 267 | delete SO; |
jjones646 | 5:146523a0d1f4 | 268 | delete SCK; |
jjones646 | 5:146523a0d1f4 | 269 | |
jjones646 | 5:146523a0d1f4 | 270 | // reestablish the SPI bus and call the reset strobe |
jjones646 | 5:146523a0d1f4 | 271 | setup_spi(); |
jjones646 | 5:146523a0d1f4 | 272 | reset(); |
jjones646 | 5:146523a0d1f4 | 273 | |
jjones646 | 5:146523a0d1f4 | 274 | delete _spi; |
jjones646 | 5:146523a0d1f4 | 275 | // wait for the SO line to go low again. Once low, reset is complete and CC1101 is in IDLE state |
jjones646 | 5:146523a0d1f4 | 276 | DigitalIn *SO2 = new DigitalIn(_miso_pin); |
jjones646 | 5:146523a0d1f4 | 277 | while(*SO2); |
jjones646 | 5:146523a0d1f4 | 278 | |
jjones646 | 5:146523a0d1f4 | 279 | // make sure chip is deselected before returning |
jjones646 | 5:146523a0d1f4 | 280 | *_cs = 1; |
jjones646 | 5:146523a0d1f4 | 281 | |
jjones646 | 5:146523a0d1f4 | 282 | // reestablish the SPI bus for the final time after removing the DigitalIn object |
jjones646 | 5:146523a0d1f4 | 283 | delete SO2; |
jjones646 | 5:146523a0d1f4 | 284 | setup_spi(); |
jjones646 | 5:146523a0d1f4 | 285 | |
jjones646 | 5:146523a0d1f4 | 286 | #if DEBUG_MODE > 0 |
jjones646 | 5:146523a0d1f4 | 287 | std::printf("==============done\r\n"); |
jjones646 | 5:146523a0d1f4 | 288 | #endif |
jjones646 | 5:146523a0d1f4 | 289 | } |
jjones646 | 5:146523a0d1f4 | 290 | |
jjones646 | 5:146523a0d1f4 | 291 | // 2nd ighest level of initilization routines behind CC1101::setup(); |
jjones646 | 5:146523a0d1f4 | 292 | void CC1101::init(void) |
jjones646 | 5:146523a0d1f4 | 293 | { |
jjones646 | 5:146523a0d1f4 | 294 | |
jjones646 | 5:146523a0d1f4 | 295 | power_on_reset(); |
jjones646 | 5:146523a0d1f4 | 296 | |
jjones646 | 5:146523a0d1f4 | 297 | // send all configuration values to the CC1101 registers |
jjones646 | 5:146523a0d1f4 | 298 | #if DEBUG_MODE > 0 |
jjones646 | 5:146523a0d1f4 | 299 | std::printf(" Writing configuration registers..."); |
jjones646 | 5:146523a0d1f4 | 300 | #endif |
jjones646 | 5:146523a0d1f4 | 301 | |
jjones646 | 5:146523a0d1f4 | 302 | put_rf_settings(); |
jjones646 | 5:146523a0d1f4 | 303 | |
jjones646 | 5:146523a0d1f4 | 304 | #if DEBUG_MODE > 0 |
jjones646 | 5:146523a0d1f4 | 305 | std::printf("done\r\n"); |
jjones646 | 5:146523a0d1f4 | 306 | #endif |
jjones646 | 5:146523a0d1f4 | 307 | uint8_t paTable[] = {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // 10dB |
jjones646 | 5:146523a0d1f4 | 308 | write_reg(CCXXX1_PATABLE, paTable[0]); |
jjones646 | 5:146523a0d1f4 | 309 | |
jjones646 | 5:146523a0d1f4 | 310 | // flush TX and RX buffers before beginning |
jjones646 | 5:146523a0d1f4 | 311 | #if DEBUG_MODE > 0 |
jjones646 | 5:146523a0d1f4 | 312 | std::printf(" Clearing TX and RX buffers..."); |
jjones646 | 5:146523a0d1f4 | 313 | #endif |
jjones646 | 5:146523a0d1f4 | 314 | |
jjones646 | 5:146523a0d1f4 | 315 | flush_rx(); |
jjones646 | 5:146523a0d1f4 | 316 | flush_tx(); |
jjones646 | 5:146523a0d1f4 | 317 | |
jjones646 | 5:146523a0d1f4 | 318 | #if DEBUG_MODE > 0 |
jjones646 | 5:146523a0d1f4 | 319 | std::printf("done\r\n"); |
jjones646 | 5:146523a0d1f4 | 320 | #endif |
jjones646 | 5:146523a0d1f4 | 321 | |
jjones646 | 5:146523a0d1f4 | 322 | #if DEBUG_MODE > 0 |
jjones646 | 5:146523a0d1f4 | 323 | std::printf(" Configuring frequency offset estimate..."); |
jjones646 | 5:146523a0d1f4 | 324 | #endif |
jjones646 | 5:146523a0d1f4 | 325 | |
jjones646 | 5:146523a0d1f4 | 326 | //write_reg(CCXXX1_FSCTRL0, status(CCXXX1_FREQEST)); |
jjones646 | 5:146523a0d1f4 | 327 | |
jjones646 | 5:146523a0d1f4 | 328 | #if DEBUG_MODE > 0 |
jjones646 | 5:146523a0d1f4 | 329 | std::printf("done\r\n"); |
jjones646 | 5:146523a0d1f4 | 330 | #endif |
jjones646 | 5:146523a0d1f4 | 331 | |
jjones646 | 5:146523a0d1f4 | 332 | // Enter RX mode |
jjones646 | 5:146523a0d1f4 | 333 | #if DEBUG_MODE > 0 |
jjones646 | 5:146523a0d1f4 | 334 | std::printf(" Entering RX mode..."); |
jjones646 | 5:146523a0d1f4 | 335 | #endif |
jjones646 | 5:146523a0d1f4 | 336 | rx_mode(); |
jjones646 | 5:146523a0d1f4 | 337 | #if DEBUG_MODE > 0 |
jjones646 | 5:146523a0d1f4 | 338 | std::printf("done\r\n"); |
jjones646 | 5:146523a0d1f4 | 339 | #endif |
jjones646 | 5:146523a0d1f4 | 340 | } |
jjones646 | 5:146523a0d1f4 | 341 | |
jjones646 | 3:dc7e9c6bc26c | 342 | // returns the current mode that the CC1101 is operating in |
jjones646 | 3:dc7e9c6bc26c | 343 | uint8_t CC1101::mode(void) |
jjones646 | 3:dc7e9c6bc26c | 344 | { |
jjones646 | 3:dc7e9c6bc26c | 345 | return status(CCXXX1_MARCSTATE); |
jjones646 | 3:dc7e9c6bc26c | 346 | } |
jjones646 | 3:dc7e9c6bc26c | 347 | |
jjones646 | 3:dc7e9c6bc26c | 348 | |
jjones646 | 3:dc7e9c6bc26c | 349 | int32_t CC1101::sendData(uint8_t *buf, uint8_t size) |
jjones646 | 5:146523a0d1f4 | 350 | { |
jjones646 | 3:dc7e9c6bc26c | 351 | // [X] - 1 - Move all values down by 1 to make room for the packet's size value. |
jjones646 | 3:dc7e9c6bc26c | 352 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 353 | for (uint8_t i = size; i > 0; i--) |
jjones646 | 3:dc7e9c6bc26c | 354 | buf[i] = buf[i-1]; |
jjones646 | 3:dc7e9c6bc26c | 355 | |
jjones646 | 3:dc7e9c6bc26c | 356 | |
jjones646 | 3:dc7e9c6bc26c | 357 | // [X] - 2 - Place the packet's size as the array's first value. |
jjones646 | 3:dc7e9c6bc26c | 358 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 359 | buf[0] = size; |
jjones646 | 3:dc7e9c6bc26c | 360 | |
jjones646 | 3:dc7e9c6bc26c | 361 | |
jjones646 | 3:dc7e9c6bc26c | 362 | #if CCXXX1_DEBUG_MODE > 0 |
jjones646 | 3:dc7e9c6bc26c | 363 | std::printf("\r\n[PACKET TRANSMITTED]\r\n Bytes: %u\r\n", size); |
jjones646 | 3:dc7e9c6bc26c | 364 | #endif |
jjones646 | 3:dc7e9c6bc26c | 365 | |
jjones646 | 3:dc7e9c6bc26c | 366 | |
jjones646 | 3:dc7e9c6bc26c | 367 | // [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 | 368 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 369 | write_reg(CCXXX1_TXFIFO, buf, ++size); |
jjones646 | 3:dc7e9c6bc26c | 370 | |
jjones646 | 3:dc7e9c6bc26c | 371 | |
jjones646 | 3:dc7e9c6bc26c | 372 | #if CCXXX1_DEBUG_MODE > 1 |
jjones646 | 3:dc7e9c6bc26c | 373 | Timer t1; |
jjones646 | 3:dc7e9c6bc26c | 374 | #endif |
jjones646 | 3:dc7e9c6bc26c | 375 | |
jjones646 | 3:dc7e9c6bc26c | 376 | |
jjones646 | 3:dc7e9c6bc26c | 377 | // [X] - 4 - Enter the TX state. |
jjones646 | 3:dc7e9c6bc26c | 378 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 379 | strobe(CCXXX1_STX); |
jjones646 | 3:dc7e9c6bc26c | 380 | |
jjones646 | 3:dc7e9c6bc26c | 381 | |
jjones646 | 3:dc7e9c6bc26c | 382 | #if CCXXX1_DEBUG_MODE > 1 |
jjones646 | 3:dc7e9c6bc26c | 383 | /* For the debug mode, this will determine how long the CC1101 takes to transmit everything in the TX buffer |
jjones646 | 3:dc7e9c6bc26c | 384 | and enter or return to the RX state. |
jjones646 | 3:dc7e9c6bc26c | 385 | */ |
jjones646 | 3:dc7e9c6bc26c | 386 | t1.start(); |
jjones646 | 3:dc7e9c6bc26c | 387 | float ti = t1.read(); |
jjones646 | 3:dc7e9c6bc26c | 388 | #endif |
jjones646 | 3:dc7e9c6bc26c | 389 | |
jjones646 | 3:dc7e9c6bc26c | 390 | |
jjones646 | 3:dc7e9c6bc26c | 391 | // [X] - 5 - Wait until radio enters back to the RX state. |
jjones646 | 3:dc7e9c6bc26c | 392 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 393 | // *Note: Takes very few cycles, so might as well wait before returning to elimate querky errors. |
jjones646 | 3:dc7e9c6bc26c | 394 | while(mode() != 0x0D); |
jjones646 | 3:dc7e9c6bc26c | 395 | |
jjones646 | 3:dc7e9c6bc26c | 396 | #if CCXXX1_DEBUG_MODE > 1 |
jjones646 | 3:dc7e9c6bc26c | 397 | t1.stop(); |
jjones646 | 3:dc7e9c6bc26c | 398 | std::printf(" Time: %02.4f ms\r\n", (t1.read() - ti)*1000); |
jjones646 | 3:dc7e9c6bc26c | 399 | #endif |
jjones646 | 3:dc7e9c6bc26c | 400 | |
jjones646 | 3:dc7e9c6bc26c | 401 | // [] - 6 - Return any error codes if necessary. |
jjones646 | 3:dc7e9c6bc26c | 402 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 403 | |
jjones646 | 3:dc7e9c6bc26c | 404 | return 0; // success |
jjones646 | 3:dc7e9c6bc26c | 405 | } |
jjones646 | 3:dc7e9c6bc26c | 406 | |
jjones646 | 3:dc7e9c6bc26c | 407 | |
jjones646 | 3:dc7e9c6bc26c | 408 | int32_t CC1101::getData(uint8_t *buf, uint8_t *length) |
jjones646 | 3:dc7e9c6bc26c | 409 | { |
jjones646 | 3:dc7e9c6bc26c | 410 | // [X] - 1 - Update the frequency offset estimate. |
jjones646 | 3:dc7e9c6bc26c | 411 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 412 | write_reg(CCXXX1_FSCTRL0, status(CCXXX1_FREQEST)); |
jjones646 | 3:dc7e9c6bc26c | 413 | |
jjones646 | 3:dc7e9c6bc26c | 414 | |
jjones646 | 3:dc7e9c6bc26c | 415 | // [X] - 2 - Get the packet's size. |
jjones646 | 3:dc7e9c6bc26c | 416 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 417 | uint8_t rx_size; |
jjones646 | 3:dc7e9c6bc26c | 418 | read_reg(CCXXX1_RXFIFO, &rx_size, 1); |
jjones646 | 3:dc7e9c6bc26c | 419 | |
jjones646 | 3:dc7e9c6bc26c | 420 | |
jjones646 | 3:dc7e9c6bc26c | 421 | // [X] - 3 - Check if there are indeed bytes to be read. |
jjones646 | 3:dc7e9c6bc26c | 422 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 423 | if (rx_size & CCXXX1_RXFIFO_MASK) { |
jjones646 | 3:dc7e9c6bc26c | 424 | |
jjones646 | 3:dc7e9c6bc26c | 425 | // [X] - 3.1 - Check if the received data will fit in the provided buffer - fill the buffer if so. |
jjones646 | 3:dc7e9c6bc26c | 426 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 427 | if (rx_size <= *length) { |
jjones646 | 3:dc7e9c6bc26c | 428 | |
jjones646 | 3:dc7e9c6bc26c | 429 | // [X] - 3.1a - Read in received data from the CC1101 and put the contents in the provided buffer. |
jjones646 | 3:dc7e9c6bc26c | 430 | *length = rx_size; // set the correct length |
jjones646 | 3:dc7e9c6bc26c | 431 | read_reg(CCXXX1_RXFIFO, buf, *length); |
jjones646 | 3:dc7e9c6bc26c | 432 | |
jjones646 | 3:dc7e9c6bc26c | 433 | /* The RSSI value takes a bit to be determined by the CC1101, so having 2 separate SPI reads gives |
jjones646 | 3:dc7e9c6bc26c | 434 | the CC1101 enough time to determine the correct value. |
jjones646 | 3:dc7e9c6bc26c | 435 | */ |
jjones646 | 3:dc7e9c6bc26c | 436 | |
jjones646 | 3:dc7e9c6bc26c | 437 | // [X] - 3.1b - Read the 2 appended status bytes. |
jjones646 | 3:dc7e9c6bc26c | 438 | // status[0] = RSSI. status[1] = LQI. |
jjones646 | 3:dc7e9c6bc26c | 439 | uint8_t status_bytes[2]; |
jjones646 | 3:dc7e9c6bc26c | 440 | read_reg(CCXXX1_RXFIFO, status_bytes, 2); |
jjones646 | 3:dc7e9c6bc26c | 441 | |
jjones646 | 3:dc7e9c6bc26c | 442 | // Update the RSSI reading. |
jjones646 | 3:dc7e9c6bc26c | 443 | rssi(status_bytes[0]); |
jjones646 | 3:dc7e9c6bc26c | 444 | _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 | 445 | |
jjones646 | 3:dc7e9c6bc26c | 446 | #if CCXXX1_DEBUG_MODE > 0 |
jjones646 | 3:dc7e9c6bc26c | 447 | std::printf("\r\n[PACKET RECEIVED]\r\n Bytes: %u\r\n", *length); |
jjones646 | 3:dc7e9c6bc26c | 448 | std::printf(" RSSI: %ddBm\r\n", _rssi); |
jjones646 | 3:dc7e9c6bc26c | 449 | std::printf(" LQI: %u\r\n", _lqi); |
jjones646 | 3:dc7e9c6bc26c | 450 | #endif |
jjones646 | 3:dc7e9c6bc26c | 451 | |
jjones646 | 3:dc7e9c6bc26c | 452 | // [X] - 3.2c - Go back to the receiving state since CC1101 is configured for transitioning to IDLE on receiving a packet. |
jjones646 | 3:dc7e9c6bc26c | 453 | rx_mode(); |
jjones646 | 3:dc7e9c6bc26c | 454 | return 0; // success |
jjones646 | 3:dc7e9c6bc26c | 455 | } else { |
jjones646 | 3:dc7e9c6bc26c | 456 | *length = rx_size; |
jjones646 | 3:dc7e9c6bc26c | 457 | flush_rx(); |
jjones646 | 3:dc7e9c6bc26c | 458 | return -2; // passed buffer size is not large enough |
jjones646 | 3:dc7e9c6bc26c | 459 | } |
jjones646 | 3:dc7e9c6bc26c | 460 | } |
jjones646 | 3:dc7e9c6bc26c | 461 | |
jjones646 | 3:dc7e9c6bc26c | 462 | flush_rx(); |
jjones646 | 3:dc7e9c6bc26c | 463 | return -1; // there is no new data to read |
jjones646 | 2:7d523bdd2f50 | 464 | } |
jjones646 | 2:7d523bdd2f50 | 465 | |
jjones646 | 2:7d523bdd2f50 | 466 | |
jjones646 | 3:dc7e9c6bc26c | 467 | // Read Register |
jjones646 | 3:dc7e9c6bc26c | 468 | uint8_t CC1101::read_reg(uint8_t addr) |
jjones646 | 3:dc7e9c6bc26c | 469 | { |
jjones646 | 5:146523a0d1f4 | 470 | _spi->frequency(8000000); |
jjones646 | 3:dc7e9c6bc26c | 471 | toggle_cs(); |
jjones646 | 3:dc7e9c6bc26c | 472 | _spi->write(addr | CCXXX1_READ_SINGLE); |
jjones646 | 5:146523a0d1f4 | 473 | //tiny_delay(); |
jjones646 | 3:dc7e9c6bc26c | 474 | uint8_t x = _spi->write(0); |
jjones646 | 3:dc7e9c6bc26c | 475 | toggle_cs(); |
jjones646 | 3:dc7e9c6bc26c | 476 | |
jjones646 | 3:dc7e9c6bc26c | 477 | #if CCXXX1_DEBUG_MODE > 1 |
jjones646 | 3:dc7e9c6bc26c | 478 | std::printf("\r\n== Single Register Read ==\r\n Address: 0x%02X\r\n Value: 0x%02X\r\n", addr, x); |
jjones646 | 3:dc7e9c6bc26c | 479 | #endif |
jjones646 | 3:dc7e9c6bc26c | 480 | return x; |
jjones646 | 3:dc7e9c6bc26c | 481 | } // read_reg |
jjones646 | 3:dc7e9c6bc26c | 482 | void CC1101::read_reg(uint8_t addr, uint8_t *buffer, uint8_t count) |
jjones646 | 3:dc7e9c6bc26c | 483 | { |
jjones646 | 5:146523a0d1f4 | 484 | _spi->frequency(4500000); |
jjones646 | 3:dc7e9c6bc26c | 485 | toggle_cs(); |
jjones646 | 3:dc7e9c6bc26c | 486 | _spi->write(addr | CCXXX1_READ_BURST); |
jjones646 | 5:146523a0d1f4 | 487 | //tiny_delay(); |
jjones646 | 3:dc7e9c6bc26c | 488 | for (uint8_t i = 0; i < count; i++) { |
jjones646 | 3:dc7e9c6bc26c | 489 | buffer[i] = _spi->write(0); |
jjones646 | 5:146523a0d1f4 | 490 | //tiny_delay(); |
jjones646 | 3:dc7e9c6bc26c | 491 | } |
jjones646 | 3:dc7e9c6bc26c | 492 | toggle_cs(); |
jjones646 | 3:dc7e9c6bc26c | 493 | |
jjones646 | 3:dc7e9c6bc26c | 494 | #if CCXXX1_DEBUG_MODE > 1 |
jjones646 | 3:dc7e9c6bc26c | 495 | std::printf("\r\n== Burst Register Read ==\r\n Address: 0x%02X\r\n Bytes: %u\r\n", addr, count); |
jjones646 | 3:dc7e9c6bc26c | 496 | #endif |
jjones646 | 3:dc7e9c6bc26c | 497 | } // read_reg |
jjones646 | 3:dc7e9c6bc26c | 498 | |
jjones646 | 3:dc7e9c6bc26c | 499 | |
jjones646 | 3:dc7e9c6bc26c | 500 | |
jjones646 | 3:dc7e9c6bc26c | 501 | // Write Register |
jjones646 | 3:dc7e9c6bc26c | 502 | void CC1101::write_reg(uint8_t addr, uint8_t value) |
jjones646 | 3:dc7e9c6bc26c | 503 | { |
jjones646 | 5:146523a0d1f4 | 504 | _spi->frequency(8000000); |
jjones646 | 3:dc7e9c6bc26c | 505 | toggle_cs(); |
jjones646 | 3:dc7e9c6bc26c | 506 | _spi->write(addr); |
jjones646 | 5:146523a0d1f4 | 507 | //tiny_delay(); |
jjones646 | 3:dc7e9c6bc26c | 508 | _spi->write(value); |
jjones646 | 3:dc7e9c6bc26c | 509 | toggle_cs(); |
jjones646 | 3:dc7e9c6bc26c | 510 | |
jjones646 | 3:dc7e9c6bc26c | 511 | #if CCXXX1_DEBUG_MODE > 1 |
jjones646 | 3:dc7e9c6bc26c | 512 | std::printf("\r\n== Single Register Write ==\r\n Address: 0x%02X\r\n Value: 0x%02X\r\n", addr, value); |
jjones646 | 3:dc7e9c6bc26c | 513 | #endif |
jjones646 | 3:dc7e9c6bc26c | 514 | } // write_reg |
jjones646 | 3:dc7e9c6bc26c | 515 | void CC1101::write_reg(uint8_t addr, uint8_t *buffer, uint8_t count) |
jjones646 | 3:dc7e9c6bc26c | 516 | { |
jjones646 | 5:146523a0d1f4 | 517 | _spi->frequency(4500000); |
jjones646 | 3:dc7e9c6bc26c | 518 | toggle_cs(); |
jjones646 | 3:dc7e9c6bc26c | 519 | _spi->write(addr | CCXXX1_WRITE_BURST); |
jjones646 | 3:dc7e9c6bc26c | 520 | for (uint8_t i = 0; i < count; i++) { |
jjones646 | 3:dc7e9c6bc26c | 521 | _spi->write(buffer[i]); |
jjones646 | 3:dc7e9c6bc26c | 522 | } |
jjones646 | 3:dc7e9c6bc26c | 523 | toggle_cs(); |
jjones646 | 3:dc7e9c6bc26c | 524 | |
jjones646 | 3:dc7e9c6bc26c | 525 | #if CCXXX1_DEBUG_MODE > 1 |
jjones646 | 3:dc7e9c6bc26c | 526 | std::printf("\r\n== Burst Register Write ==\r\n Address: 0x%02X\r\n Bytes: %u\r\n", addr, count); |
jjones646 | 3:dc7e9c6bc26c | 527 | #endif |
jjones646 | 3:dc7e9c6bc26c | 528 | } // write_reg |
jjones646 | 3:dc7e9c6bc26c | 529 | |
jjones646 | 3:dc7e9c6bc26c | 530 | |
jjones646 | 3:dc7e9c6bc26c | 531 | // Strobe |
jjones646 | 3:dc7e9c6bc26c | 532 | uint8_t CC1101::strobe(uint8_t addr) |
jjones646 | 3:dc7e9c6bc26c | 533 | { |
jjones646 | 5:146523a0d1f4 | 534 | _spi->frequency(4500000); |
jjones646 | 3:dc7e9c6bc26c | 535 | toggle_cs(); |
jjones646 | 3:dc7e9c6bc26c | 536 | uint8_t x = _spi->write(addr); |
jjones646 | 3:dc7e9c6bc26c | 537 | toggle_cs(); |
jjones646 | 3:dc7e9c6bc26c | 538 | return x; |
jjones646 | 3:dc7e9c6bc26c | 539 | } // strobe |
jjones646 | 3:dc7e9c6bc26c | 540 | |
jjones646 | 3:dc7e9c6bc26c | 541 | |
jjones646 | 3:dc7e9c6bc26c | 542 | // Macro to calibrate the frequency synthesizer |
jjones646 | 3:dc7e9c6bc26c | 543 | void CC1101::calibrate(void) |
jjones646 | 2:7d523bdd2f50 | 544 | { |
jjones646 | 3:dc7e9c6bc26c | 545 | // Send the calibration strobe |
jjones646 | 3:dc7e9c6bc26c | 546 | strobe(CCXXX1_SCAL); |
jjones646 | 3:dc7e9c6bc26c | 547 | |
jjones646 | 3:dc7e9c6bc26c | 548 | // Wait for the radio to leave the calibration step |
jjones646 | 5:146523a0d1f4 | 549 | // while( (mode() == 0x04) | (mode() == 0x05) ); |
jjones646 | 3:dc7e9c6bc26c | 550 | |
jjones646 | 3:dc7e9c6bc26c | 551 | // The radio is now is IDLE mode, so go to RX mode |
jjones646 | 3:dc7e9c6bc26c | 552 | rx_mode(); |
jjones646 | 3:dc7e9c6bc26c | 553 | |
jjones646 | 3:dc7e9c6bc26c | 554 | // Wait for the radio to enter back into RX mode |
jjones646 | 5:146523a0d1f4 | 555 | //while( mode() != 0x0D ); |
jjones646 | 3:dc7e9c6bc26c | 556 | } |
jjones646 | 3:dc7e9c6bc26c | 557 | |
jjones646 | 3:dc7e9c6bc26c | 558 | |
jjones646 | 3:dc7e9c6bc26c | 559 | void CC1101::tiny_delay(void) |
jjones646 | 3:dc7e9c6bc26c | 560 | { |
jjones646 | 3:dc7e9c6bc26c | 561 | int i = 0; |
jjones646 | 5:146523a0d1f4 | 562 | while(i < 4) { |
jjones646 | 3:dc7e9c6bc26c | 563 | i++; |
jjones646 | 3:dc7e9c6bc26c | 564 | } |
jjones646 | 3:dc7e9c6bc26c | 565 | } |
jjones646 | 3:dc7e9c6bc26c | 566 | |
jjones646 | 3:dc7e9c6bc26c | 567 | void CC1101::address(uint8_t addr) |
jjones646 | 3:dc7e9c6bc26c | 568 | { |
jjones646 | 3:dc7e9c6bc26c | 569 | _address = addr; |
jjones646 | 3:dc7e9c6bc26c | 570 | // NOW, WRITE THE ADDRESS TO THE CC1101 |
jjones646 | 3:dc7e9c6bc26c | 571 | } |
jjones646 | 3:dc7e9c6bc26c | 572 | |
jjones646 | 3:dc7e9c6bc26c | 573 | uint8_t CC1101::lqi(void) |
jjones646 | 3:dc7e9c6bc26c | 574 | { |
jjones646 | 3:dc7e9c6bc26c | 575 | return 0x3F - (_lqi & 0x3F); |
jjones646 | 3:dc7e9c6bc26c | 576 | } |
jjones646 | 3:dc7e9c6bc26c | 577 | |
jjones646 | 3:dc7e9c6bc26c | 578 | // returns the CC1101's VERSION register that specifices what exact chip version is being used |
jjones646 | 3:dc7e9c6bc26c | 579 | uint8_t CC1101::version(void) |
jjones646 | 3:dc7e9c6bc26c | 580 | { |
jjones646 | 3:dc7e9c6bc26c | 581 | return _chip_version; |
jjones646 | 3:dc7e9c6bc26c | 582 | } |
jjones646 | 3:dc7e9c6bc26c | 583 | |
jjones646 | 3:dc7e9c6bc26c | 584 | void CC1101::channel(uint16_t chan) |
jjones646 | 3:dc7e9c6bc26c | 585 | { |
jjones646 | 3:dc7e9c6bc26c | 586 | if ( chan != _channel ) { |
jjones646 | 3:dc7e9c6bc26c | 587 | _channel = chan; |
jjones646 | 3:dc7e9c6bc26c | 588 | write_reg(CCXXX1_CHANNR, _channel); |
jjones646 | 3:dc7e9c6bc26c | 589 | /* |
jjones646 | 3:dc7e9c6bc26c | 590 | #if CCXXX1_DEBUG_MODE > 0 |
jjones646 | 3:dc7e9c6bc26c | 591 | 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 | 592 | #endif |
jjones646 | 3:dc7e9c6bc26c | 593 | */ |
jjones646 | 3:dc7e9c6bc26c | 594 | } |
jjones646 | 3:dc7e9c6bc26c | 595 | } |
jjones646 | 3:dc7e9c6bc26c | 596 | |
jjones646 | 3:dc7e9c6bc26c | 597 | // RSSI |
jjones646 | 3:dc7e9c6bc26c | 598 | int16_t CC1101::rssi(void) |
jjones646 | 3:dc7e9c6bc26c | 599 | { |
jjones646 | 3:dc7e9c6bc26c | 600 | return _rssi; |
jjones646 | 3:dc7e9c6bc26c | 601 | } |
jjones646 | 3:dc7e9c6bc26c | 602 | void CC1101::rssi(uint8_t rssi_val) |
jjones646 | 3:dc7e9c6bc26c | 603 | { |
jjones646 | 3:dc7e9c6bc26c | 604 | int8_t temp; |
jjones646 | 3:dc7e9c6bc26c | 605 | |
jjones646 | 3:dc7e9c6bc26c | 606 | if (rssi_val & 0x80) { |
jjones646 | 3:dc7e9c6bc26c | 607 | temp = (rssi_val - 256)>>1; |
jjones646 | 3:dc7e9c6bc26c | 608 | } else { |
jjones646 | 3:dc7e9c6bc26c | 609 | temp = rssi_val>>1; // divide by 2 |
jjones646 | 3:dc7e9c6bc26c | 610 | } |
jjones646 | 3:dc7e9c6bc26c | 611 | _rssi = temp - 74; |
jjones646 | 3:dc7e9c6bc26c | 612 | } // rssi |
jjones646 | 3:dc7e9c6bc26c | 613 | |
jjones646 | 3:dc7e9c6bc26c | 614 | |
jjones646 | 3:dc7e9c6bc26c | 615 | void CC1101::flush_rx(void) |
jjones646 | 3:dc7e9c6bc26c | 616 | { |
jjones646 | 3:dc7e9c6bc26c | 617 | // Make sure that the radio is in IDLE state before flushing the FIFO |
jjones646 | 3:dc7e9c6bc26c | 618 | idle(); |
jjones646 | 3:dc7e9c6bc26c | 619 | |
jjones646 | 3:dc7e9c6bc26c | 620 | // Flush RX FIFO |
jjones646 | 3:dc7e9c6bc26c | 621 | strobe(CCXXX1_SFRX); |
jjones646 | 3:dc7e9c6bc26c | 622 | |
jjones646 | 3:dc7e9c6bc26c | 623 | // Enter back into a RX state |
jjones646 | 3:dc7e9c6bc26c | 624 | rx_mode(); |
jjones646 | 3:dc7e9c6bc26c | 625 | } |
jjones646 | 3:dc7e9c6bc26c | 626 | |
jjones646 | 3:dc7e9c6bc26c | 627 | void CC1101::flush_tx(void) |
jjones646 | 3:dc7e9c6bc26c | 628 | { |
jjones646 | 3:dc7e9c6bc26c | 629 | // Make sure that the radio is in IDLE state before flushing the FIFO |
jjones646 | 3:dc7e9c6bc26c | 630 | idle(); |
jjones646 | 3:dc7e9c6bc26c | 631 | |
jjones646 | 3:dc7e9c6bc26c | 632 | // Flush TX FIFO |
jjones646 | 3:dc7e9c6bc26c | 633 | strobe(CCXXX1_SFTX); |
jjones646 | 3:dc7e9c6bc26c | 634 | |
jjones646 | 3:dc7e9c6bc26c | 635 | // Enter back into a RX state |
jjones646 | 3:dc7e9c6bc26c | 636 | rx_mode(); |
jjones646 | 2:7d523bdd2f50 | 637 | } |
jjones646 | 2:7d523bdd2f50 | 638 | |
jjones646 | 3:dc7e9c6bc26c | 639 | |
jjones646 | 3:dc7e9c6bc26c | 640 | void CC1101::rx_mode(void) |
jjones646 | 3:dc7e9c6bc26c | 641 | { |
jjones646 | 3:dc7e9c6bc26c | 642 | //strobe(CCXXX1_SIDLE); |
jjones646 | 3:dc7e9c6bc26c | 643 | strobe(CCXXX1_SRX); |
jjones646 | 3:dc7e9c6bc26c | 644 | //while(mode() != 0x0D); |
jjones646 | 3:dc7e9c6bc26c | 645 | } |
jjones646 | 3:dc7e9c6bc26c | 646 | |
jjones646 | 3:dc7e9c6bc26c | 647 | |
jjones646 | 3:dc7e9c6bc26c | 648 | void CC1101::tx_mode(void) |
jjones646 | 3:dc7e9c6bc26c | 649 | { |
jjones646 | 3:dc7e9c6bc26c | 650 | //strobe(CCXXX1_SIDLE); |
jjones646 | 3:dc7e9c6bc26c | 651 | strobe(CCXXX1_STX); |
jjones646 | 3:dc7e9c6bc26c | 652 | // while(mode() != 0x13); |
jjones646 | 3:dc7e9c6bc26c | 653 | } |
jjones646 | 3:dc7e9c6bc26c | 654 | |
jjones646 | 3:dc7e9c6bc26c | 655 | void CC1101::idle(void) |
jjones646 | 3:dc7e9c6bc26c | 656 | { |
jjones646 | 3:dc7e9c6bc26c | 657 | // Send the IDLE strobe |
jjones646 | 3:dc7e9c6bc26c | 658 | strobe(CCXXX1_SIDLE); |
jjones646 | 3:dc7e9c6bc26c | 659 | // Wait before returning |
jjones646 | 5:146523a0d1f4 | 660 | //while( mode() != 0x01); |
jjones646 | 3:dc7e9c6bc26c | 661 | } |
jjones646 | 3:dc7e9c6bc26c | 662 | |
jjones646 | 3:dc7e9c6bc26c | 663 | |
jjones646 | 3:dc7e9c6bc26c | 664 | // Status byte & status of a status register |
jjones646 | 3:dc7e9c6bc26c | 665 | uint8_t CC1101::status(void) |
jjones646 | 3:dc7e9c6bc26c | 666 | { |
jjones646 | 3:dc7e9c6bc26c | 667 | return strobe(CCXXX1_SNOP); |
jjones646 | 3:dc7e9c6bc26c | 668 | } |
jjones646 | 3:dc7e9c6bc26c | 669 | |
jjones646 | 3:dc7e9c6bc26c | 670 | uint8_t CC1101::status(uint8_t addr) |
jjones646 | 2:7d523bdd2f50 | 671 | { |
jjones646 | 5:146523a0d1f4 | 672 | _spi->frequency(800000); |
jjones646 | 3:dc7e9c6bc26c | 673 | toggle_cs(); |
jjones646 | 3:dc7e9c6bc26c | 674 | _spi->write(addr | CCXXX1_READ_BURST); |
jjones646 | 3:dc7e9c6bc26c | 675 | tiny_delay(); |
jjones646 | 3:dc7e9c6bc26c | 676 | uint8_t x = _spi->write(0); |
jjones646 | 3:dc7e9c6bc26c | 677 | toggle_cs(); |
jjones646 | 3:dc7e9c6bc26c | 678 | return x; |
jjones646 | 3:dc7e9c6bc26c | 679 | } // status |
jjones646 | 3:dc7e9c6bc26c | 680 | |
jjones646 | 3:dc7e9c6bc26c | 681 | |
jjones646 | 3:dc7e9c6bc26c | 682 | // SET FREQUENCY |
jjones646 | 3:dc7e9c6bc26c | 683 | void CC1101::freq(uint32_t freq) |
jjones646 | 3:dc7e9c6bc26c | 684 | { |
jjones646 | 3:dc7e9c6bc26c | 685 | /* calculate the value that is written to the register for settings the base frequency |
jjones646 | 3:dc7e9c6bc26c | 686 | * that the CC1101 should use for sending/receiving over the air. Default value is equivalent |
jjones646 | 3:dc7e9c6bc26c | 687 | * to 901.83 MHz. |
jjones646 | 3:dc7e9c6bc26c | 688 | */ |
jjones646 | 3:dc7e9c6bc26c | 689 | |
jjones646 | 3:dc7e9c6bc26c | 690 | // this is split into 3 bytes that are written to 3 different registers on the CC1101 |
jjones646 | 3:dc7e9c6bc26c | 691 | uint32_t reg_freq = _base_freq / (CCXXX1_CRYSTAL_FREQUENCY>>16); |
jjones646 | 3:dc7e9c6bc26c | 692 | |
jjones646 | 3:dc7e9c6bc26c | 693 | rfSettings.FREQ2 = (reg_freq>>16) & 0xFF; // high byte, bits 7..6 are always 0 for this register |
jjones646 | 3:dc7e9c6bc26c | 694 | rfSettings.FREQ1 = (reg_freq>>8) & 0xFF; // middle byte |
jjones646 | 3:dc7e9c6bc26c | 695 | rfSettings.FREQ0 = reg_freq & 0xFF; // low byte |
jjones646 | 3:dc7e9c6bc26c | 696 | } |
jjones646 | 3:dc7e9c6bc26c | 697 | |
jjones646 | 3:dc7e9c6bc26c | 698 | |
jjones646 | 3:dc7e9c6bc26c | 699 | void CC1101::datarate(uint32_t rate) |
jjones646 | 3:dc7e9c6bc26c | 700 | { |
jjones646 | 3:dc7e9c6bc26c | 701 | // update the baud rate class member |
jjones646 | 3:dc7e9c6bc26c | 702 | _datarate = rate; |
jjones646 | 3:dc7e9c6bc26c | 703 | |
jjones646 | 3:dc7e9c6bc26c | 704 | // have to be careful with bit shifting here since it requires a large amount of shifts |
jjones646 | 3:dc7e9c6bc26c | 705 | uint32_t shift_val = 28 - (_modem.data_rate_exp & 0x0F); |
jjones646 | 3:dc7e9c6bc26c | 706 | |
jjones646 | 3:dc7e9c6bc26c | 707 | // compute the register value and assign it |
jjones646 | 3:dc7e9c6bc26c | 708 | rfSettings.MDMCFG3 = ((_datarate)/(CCXXX1_CRYSTAL_FREQUENCY>>shift_val)) - 256; |
jjones646 | 2:7d523bdd2f50 | 709 | } |
jjones646 | 2:7d523bdd2f50 | 710 | |
jjones646 | 3:dc7e9c6bc26c | 711 | |
jjones646 | 3:dc7e9c6bc26c | 712 | // =============== |
jjones646 | 3:dc7e9c6bc26c | 713 | void CC1101::assign_modem_params() |
jjones646 | 3:dc7e9c6bc26c | 714 | { |
jjones646 | 3:dc7e9c6bc26c | 715 | rfSettings.MDMCFG4 = (_modem.channel_bw_exp & 0x03)<<6 | (_modem.channel_bw & 0x03)<<4 | (_modem.data_rate_exp & 0x0F); |
jjones646 | 3:dc7e9c6bc26c | 716 | 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 | 717 | rfSettings.MDMCFG1 = _modem.fec_en<<7 | (_modem.preamble_bytes & 0x07)<<4 | (_modem.channel_space_exp & 0x03); |
jjones646 | 3:dc7e9c6bc26c | 718 | } |
jjones646 | 3:dc7e9c6bc26c | 719 | // =============== |
jjones646 | 3:dc7e9c6bc26c | 720 | void CC1101::assign_packet_params() |
jjones646 | 3:dc7e9c6bc26c | 721 | { |
jjones646 | 3:dc7e9c6bc26c | 722 | 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 | 723 | 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 | 724 | rfSettings.PCKLEN = _pck_control.size; |
jjones646 | 3:dc7e9c6bc26c | 725 | } |
jjones646 | 3:dc7e9c6bc26c | 726 | // =============== |
jjones646 | 3:dc7e9c6bc26c | 727 | void CC1101::assign_if_freq(uint32_t freq) |
jjones646 | 3:dc7e9c6bc26c | 728 | { |
jjones646 | 3:dc7e9c6bc26c | 729 | // The desired IF frequency for RX. Subtracted from FS base frequency in RX. |
jjones646 | 3:dc7e9c6bc26c | 730 | // bits 7..5 are always 0 |
jjones646 | 3:dc7e9c6bc26c | 731 | rfSettings.FSCTRL1 = (freq/(CCXXX1_CRYSTAL_FREQUENCY>>10)) & 0x1F; |
jjones646 | 3:dc7e9c6bc26c | 732 | rfSettings.FSCTRL0 = 0x00; // set the initial freq calibration to 0 |
jjones646 | 3:dc7e9c6bc26c | 733 | } |
jjones646 | 3:dc7e9c6bc26c | 734 | // =============== |
jjones646 | 3:dc7e9c6bc26c | 735 | void CC1101::assign_channel_spacing(uint32_t spacing) |
jjones646 | 3:dc7e9c6bc26c | 736 | { |
jjones646 | 3:dc7e9c6bc26c | 737 | // have to be careful with bit shifting here since it requires a large amount of shifts |
jjones646 | 3:dc7e9c6bc26c | 738 | uint32_t shift_val = 18 - (_modem.channel_space_exp & 0x03); |
jjones646 | 3:dc7e9c6bc26c | 739 | |
jjones646 | 3:dc7e9c6bc26c | 740 | // compute the register value and assign it |
jjones646 | 3:dc7e9c6bc26c | 741 | rfSettings.MDMCFG0 = (spacing/(CCXXX1_CRYSTAL_FREQUENCY>>shift_val)) - 256; |
jjones646 | 3:dc7e9c6bc26c | 742 | } |
jjones646 | 3:dc7e9c6bc26c | 743 | void CC1101::set_rf_settings(void) |
jjones646 | 3:dc7e9c6bc26c | 744 | { |
jjones646 | 3:dc7e9c6bc26c | 745 | // set the fields for packet controls |
jjones646 | 3:dc7e9c6bc26c | 746 | assign_packet_params(); |
jjones646 | 3:dc7e9c6bc26c | 747 | |
jjones646 | 3:dc7e9c6bc26c | 748 | // set the fields for the frequency limits of the modem |
jjones646 | 3:dc7e9c6bc26c | 749 | assign_modem_params(); |
jjones646 | 3:dc7e9c6bc26c | 750 | |
jjones646 | 3:dc7e9c6bc26c | 751 | // assign an address to the CC1101. This can be used to filter packets |
jjones646 | 3:dc7e9c6bc26c | 752 | rfSettings.ADDR = _address; |
jjones646 | 3:dc7e9c6bc26c | 753 | |
jjones646 | 3:dc7e9c6bc26c | 754 | // there can be 16 different channel numbers. The bandwidth and spacing are defined in other registers |
jjones646 | 3:dc7e9c6bc26c | 755 | rfSettings.CHANNR = _channel; |
jjones646 | 3:dc7e9c6bc26c | 756 | |
jjones646 | 3:dc7e9c6bc26c | 757 | // compute the final adjusted frequency so that it will be correct after the constructor |
jjones646 | 3:dc7e9c6bc26c | 758 | // compute_freq(); |
jjones646 | 3:dc7e9c6bc26c | 759 | |
jjones646 | 3:dc7e9c6bc26c | 760 | // disable GDO0 |
jjones646 | 3:dc7e9c6bc26c | 761 | rfSettings.IOCFG0 = 0x2E; |
jjones646 | 3:dc7e9c6bc26c | 762 | |
jjones646 | 3:dc7e9c6bc26c | 763 | // setup for SPI |
jjones646 | 3:dc7e9c6bc26c | 764 | rfSettings.IOCFG1 = 0x0C; |
jjones646 | 3:dc7e9c6bc26c | 765 | |
jjones646 | 3:dc7e9c6bc26c | 766 | // setup for going HIGH when packet received and CRC is ok |
jjones646 | 3:dc7e9c6bc26c | 767 | rfSettings.IOCFG2 = 0x07; |
jjones646 | 3:dc7e9c6bc26c | 768 | |
jjones646 | 3:dc7e9c6bc26c | 769 | rfSettings.DEVIATN = 0x62; |
jjones646 | 3:dc7e9c6bc26c | 770 | |
jjones646 | 3:dc7e9c6bc26c | 771 | rfSettings.FREND1 = 0xB6; |
jjones646 | 3:dc7e9c6bc26c | 772 | rfSettings.FREND0 = 0x10; |
jjones646 | 3:dc7e9c6bc26c | 773 | |
jjones646 | 3:dc7e9c6bc26c | 774 | bool RX_TIME_RSSI = false; |
jjones646 | 3:dc7e9c6bc26c | 775 | bool RX_TIME_QUAL = false; |
jjones646 | 3:dc7e9c6bc26c | 776 | uint8_t RX_TIME = 0x07; // no timeout |
jjones646 | 3:dc7e9c6bc26c | 777 | |
jjones646 | 3:dc7e9c6bc26c | 778 | rfSettings.MCSM2 = (RX_TIME_RSSI<<4) | (RX_TIME_QUAL<<3) | (RX_TIME & 0x07); |
jjones646 | 3:dc7e9c6bc26c | 779 | |
jjones646 | 3:dc7e9c6bc26c | 780 | uint8_t CCA_MODE = 0x00; |
jjones646 | 3:dc7e9c6bc26c | 781 | uint8_t RXOFF_MODE = 0x00; // go directly to IDLE when existing RX |
jjones646 | 3:dc7e9c6bc26c | 782 | //uint8_t RXOFF_MODE = 0x03; // stay in RX when existing RX |
jjones646 | 3:dc7e9c6bc26c | 783 | uint8_t TXOFF_MODE = 0x03; // go directly to RX when existing TX |
jjones646 | 3:dc7e9c6bc26c | 784 | // uint8_t TXOFF_MODE = 0x00; // go directly to IDLE when existing TX |
jjones646 | 3:dc7e9c6bc26c | 785 | |
jjones646 | 3:dc7e9c6bc26c | 786 | rfSettings.MCSM1 = ((CCA_MODE & 0x03)<<4) | ((RXOFF_MODE & 0x03)<<2) | (TXOFF_MODE & 0x03); |
jjones646 | 3:dc7e9c6bc26c | 787 | |
jjones646 | 3:dc7e9c6bc26c | 788 | uint8_t FS_AUTOCAL = 0x01; // calibrate when going from IDLE to RX or TX |
jjones646 | 3:dc7e9c6bc26c | 789 | uint8_t PO_TIMEOUT = 0x02; |
jjones646 | 3:dc7e9c6bc26c | 790 | bool PIN_CTRL_EN = false; |
jjones646 | 3:dc7e9c6bc26c | 791 | bool XOSC_FORCE_ON = false; |
jjones646 | 3:dc7e9c6bc26c | 792 | |
jjones646 | 3:dc7e9c6bc26c | 793 | rfSettings.MCSM0 = ((FS_AUTOCAL & 0x03)<<4) | ((PO_TIMEOUT & 0x03)<<2) | (PIN_CTRL_EN<<1) | (XOSC_FORCE_ON); |
jjones646 | 3:dc7e9c6bc26c | 794 | |
jjones646 | 3:dc7e9c6bc26c | 795 | bool FOC_BS_CS_GATE = false; |
jjones646 | 3:dc7e9c6bc26c | 796 | uint8_t FOC_PRE_K = 0x03; |
jjones646 | 3:dc7e9c6bc26c | 797 | bool FOC_POST_K = true; |
jjones646 | 3:dc7e9c6bc26c | 798 | uint8_t FOC_LIMIT = 0x01; |
jjones646 | 3:dc7e9c6bc26c | 799 | |
jjones646 | 3:dc7e9c6bc26c | 800 | rfSettings.FOCCFG = 0x40 | (FOC_BS_CS_GATE<<5) | ((FOC_PRE_K & 0x03)<<3) | (FOC_POST_K<<2) | (FOC_LIMIT & 0x03); |
jjones646 | 3:dc7e9c6bc26c | 801 | |
jjones646 | 3:dc7e9c6bc26c | 802 | rfSettings.BSCFG = 0x1C; |
jjones646 | 3:dc7e9c6bc26c | 803 | |
jjones646 | 3:dc7e9c6bc26c | 804 | rfSettings.AGCCTRL2 = 0xC7; |
jjones646 | 3:dc7e9c6bc26c | 805 | rfSettings.AGCCTRL1 = 0x00; |
jjones646 | 3:dc7e9c6bc26c | 806 | rfSettings.AGCCTRL0 = 0xB0; |
jjones646 | 3:dc7e9c6bc26c | 807 | |
jjones646 | 3:dc7e9c6bc26c | 808 | // rfSettings.FIFOTHR = 0x0F; // RXFIFO and TXFIFO thresholds. |
jjones646 | 3:dc7e9c6bc26c | 809 | |
jjones646 | 3:dc7e9c6bc26c | 810 | // 33 byte TX FIFO & 32 byte RX FIFO |
jjones646 | 3:dc7e9c6bc26c | 811 | rfSettings.FIFOTHR = 0x07; // RXFIFO and TXFIFO thresholds. |
jjones646 | 3:dc7e9c6bc26c | 812 | } |