Prototype RF driver for STM Sub-1 GHz RF expansion board based on the SPSGRF-868 module for STM32 Nucleo.

Prototype RF Driver for STM Sub-1 GHz RF Expansion Boards based on the SPSGRF-868 and SPSGRF-915 Modules for STM32 Nucleo

Currently supported boards:

Note, in order to use expansion board X-NUCLEO-IDS01A4 in mbed you need to perform the following HW modifications on the board:

  • Unmount resistor R4
  • Mount resistor R7

Furthermore, on some Nucleo development boards (e.g. the NUCLEO_F429ZI), in order to be able to use Ethernet together with these Sub-1 GHz RF expansion boards, you need to compile this driver with macro SPIRIT1_SPI_MOSI=PB_5 defined, while the development board typically requires some HW modification as e.g. described here!

This driver can be used together with the 6LoWPAN stack (a.k.a. Nanostack).

Committer:
Wolfgang Betz
Date:
Mon Nov 21 13:26:17 2016 +0100
Revision:
33:c226804be492
Parent:
31:a4d8072139f2
Slightly better send timeout handling

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wolfgang Betz 0:4fb29d9ee571 1 /*** Mbed Includes ***/
Wolfgang Betz 0:4fb29d9ee571 2 #include "SimpleSpirit1.h"
Wolfgang Betz 3:0df38cfb1e53 3 #include "radio_spi.h"
Wolfgang Betz 0:4fb29d9ee571 4
Wolfgang Betz 4:07537ca85c66 5 #define SPIRIT_GPIO_IRQ (SPIRIT_GPIO_3)
Wolfgang Betz 3:0df38cfb1e53 6
Wolfgang Betz 26:45dae8d48029 7 static uint16_t last_state;
Wolfgang Betz 28:6a71e15d5272 8 #define SPIRIT1_STATUS() ((last_state = (uint16_t)refresh_state()) & SPIRIT1_STATE_STATEBITS)
Wolfgang Betz 28:6a71e15d5272 9
Wolfgang Betz 28:6a71e15d5272 10 #define XO_ON (0x1)
Wolfgang Betz 3:0df38cfb1e53 11
Wolfgang Betz 3:0df38cfb1e53 12 #define BUSYWAIT_UNTIL(cond, millisecs) \
Wolfgang Betz 16:25dc4b811ad3 13 do { \
Wolfgang Betz 16:25dc4b811ad3 14 uint32_t start = us_ticker_read(); \
Wolfgang Betz 16:25dc4b811ad3 15 while (!(cond) && ((us_ticker_read() - start) < ((uint32_t)millisecs)*1000U)); \
Wolfgang Betz 16:25dc4b811ad3 16 } while(0)
Wolfgang Betz 3:0df38cfb1e53 17
Wolfgang Betz 4:07537ca85c66 18 #define st_lib_spirit_irqs SpiritIrqs
Wolfgang Betz 4:07537ca85c66 19
Wolfgang Betz 25:2ec45788f28c 20 #define STATE_TIMEOUT (1000)
Wolfgang Betz 0:4fb29d9ee571 21
Wolfgang Betz 31:a4d8072139f2 22 // betzw: switching force & back from standby is on some devices quite unstable
Wolfgang Betz 31:a4d8072139f2 23 #define USE_STANDBY_STATE
Wolfgang Betz 28:6a71e15d5272 24
Wolfgang Betz 0:4fb29d9ee571 25 /*** Class Implementation ***/
Wolfgang Betz 3:0df38cfb1e53 26 /** Static Class Variables **/
Wolfgang Betz 3:0df38cfb1e53 27 SimpleSpirit1 *SimpleSpirit1::_singleton = NULL;
Wolfgang Betz 3:0df38cfb1e53 28
Wolfgang Betz 3:0df38cfb1e53 29 /** Constructor **/
Wolfgang Betz 0:4fb29d9ee571 30 SimpleSpirit1::SimpleSpirit1(PinName mosi, PinName miso, PinName sclk,
Wolfgang Betz 16:25dc4b811ad3 31 PinName irq, PinName cs, PinName sdn,
Wolfgang Betz 16:25dc4b811ad3 32 PinName led) :
Wolfgang Betz 16:25dc4b811ad3 33 _spi(mosi, miso, sclk),
Wolfgang Betz 16:25dc4b811ad3 34 _irq(irq),
Wolfgang Betz 16:25dc4b811ad3 35 _chip_select(cs),
Wolfgang Betz 16:25dc4b811ad3 36 _shut_down(sdn),
Wolfgang Betz 16:25dc4b811ad3 37 _led(led),
Wolfgang Betz 16:25dc4b811ad3 38 _current_irq_callback(),
Wolfgang Betz 16:25dc4b811ad3 39 _rx_receiving_timeout()
Wolfgang Betz 0:4fb29d9ee571 40 {
Wolfgang Betz 9:3db68ab23070 41 }
Wolfgang Betz 9:3db68ab23070 42
Wolfgang Betz 9:3db68ab23070 43 /** Init Function **/
Wolfgang Betz 9:3db68ab23070 44 void SimpleSpirit1::init() {
Wolfgang Betz 16:25dc4b811ad3 45 /* reset irq disable counter and irq callback & disable irq */
Wolfgang Betz 3:0df38cfb1e53 46 _nr_of_irq_disables = 0;
Wolfgang Betz 16:25dc4b811ad3 47 disable_spirit_irq();
Wolfgang Betz 0:4fb29d9ee571 48
Wolfgang Betz 16:25dc4b811ad3 49 /* unselect chip */
Wolfgang Betz 16:25dc4b811ad3 50 chip_unselect();
Wolfgang Betz 0:4fb29d9ee571 51
Wolfgang Betz 16:25dc4b811ad3 52 /* configure spi */
Wolfgang Betz 16:25dc4b811ad3 53 _spi.format(8, 0); /* 8-bit, mode = 0, [order = SPI_MSB] only available in mbed3 */
Wolfgang Betz 27:e68ffb6ac223 54 _spi.frequency(1000000); // 1MHz // betzw - NOTE: higher frequencies lead to instability of Spirit1
Wolfgang Betz 3:0df38cfb1e53 55
Wolfgang Betz 16:25dc4b811ad3 56 /* install irq handler */
Wolfgang Betz 16:25dc4b811ad3 57 _irq.mode(PullUp);
Wolfgang Betz 16:25dc4b811ad3 58 _irq.fall(Callback<void()>(this, &SimpleSpirit1::IrqHandler));
Wolfgang Betz 5:c9c5bc673c64 59
Wolfgang Betz 16:25dc4b811ad3 60 /* init cube vars */
Wolfgang Betz 16:25dc4b811ad3 61 spirit_on = OFF;
Wolfgang Betz 16:25dc4b811ad3 62 last_rssi = 0 ; //MGR
Wolfgang Betz 30:9c6dcfc47619 63 last_sqi = 0 ; //MGR
Wolfgang Betz 0:4fb29d9ee571 64
Wolfgang Betz 16:25dc4b811ad3 65 /* set frequencies */
Wolfgang Betz 16:25dc4b811ad3 66 radio_set_xtal_freq(XTAL_FREQUENCY);
Wolfgang Betz 16:25dc4b811ad3 67 mgmt_set_freq_base((uint32_t)BASE_FREQUENCY);
Wolfgang Betz 0:4fb29d9ee571 68
Wolfgang Betz 16:25dc4b811ad3 69 /* restart board */
Wolfgang Betz 16:25dc4b811ad3 70 enter_shutdown();
Wolfgang Betz 16:25dc4b811ad3 71 exit_shutdown();
Wolfgang Betz 0:4fb29d9ee571 72
Wolfgang Betz 16:25dc4b811ad3 73 /* soft core reset */
Wolfgang Betz 16:25dc4b811ad3 74 cmd_strobe(SPIRIT1_STROBE_SRES);
Wolfgang Betz 15:852b92eed64a 75
Wolfgang Betz 16:25dc4b811ad3 76 /* Configures the SPIRIT1 radio part */
Wolfgang Betz 16:25dc4b811ad3 77 SRadioInit x_radio_init = {
Wolfgang Betz 16:25dc4b811ad3 78 XTAL_OFFSET_PPM,
Wolfgang Betz 16:25dc4b811ad3 79 (uint32_t)BASE_FREQUENCY,
Wolfgang Betz 16:25dc4b811ad3 80 (uint32_t)CHANNEL_SPACE,
Wolfgang Betz 16:25dc4b811ad3 81 CHANNEL_NUMBER,
Wolfgang Betz 16:25dc4b811ad3 82 MODULATION_SELECT,
Wolfgang Betz 16:25dc4b811ad3 83 DATARATE,
Wolfgang Betz 16:25dc4b811ad3 84 (uint32_t)FREQ_DEVIATION,
Wolfgang Betz 16:25dc4b811ad3 85 (uint32_t)BANDWIDTH
Wolfgang Betz 16:25dc4b811ad3 86 };
Wolfgang Betz 16:25dc4b811ad3 87 radio_init(&x_radio_init);
Wolfgang Betz 16:25dc4b811ad3 88 radio_set_pa_level_dbm(0,POWER_DBM);
Wolfgang Betz 16:25dc4b811ad3 89 radio_set_pa_level_max_index(0);
Wolfgang Betz 0:4fb29d9ee571 90
Wolfgang Betz 16:25dc4b811ad3 91 /* Configures the SPIRIT1 packet handler part*/
Wolfgang Betz 16:25dc4b811ad3 92 PktBasicInit x_basic_init = {
Wolfgang Betz 16:25dc4b811ad3 93 PREAMBLE_LENGTH,
Wolfgang Betz 16:25dc4b811ad3 94 SYNC_LENGTH,
Wolfgang Betz 16:25dc4b811ad3 95 SYNC_WORD,
Wolfgang Betz 16:25dc4b811ad3 96 LENGTH_TYPE,
Wolfgang Betz 16:25dc4b811ad3 97 LENGTH_WIDTH,
Wolfgang Betz 16:25dc4b811ad3 98 CRC_MODE,
Wolfgang Betz 16:25dc4b811ad3 99 CONTROL_LENGTH,
Wolfgang Betz 16:25dc4b811ad3 100 EN_ADDRESS,
Wolfgang Betz 16:25dc4b811ad3 101 EN_FEC,
Wolfgang Betz 16:25dc4b811ad3 102 EN_WHITENING
Wolfgang Betz 16:25dc4b811ad3 103 };
Wolfgang Betz 16:25dc4b811ad3 104 pkt_basic_init(&x_basic_init);
Wolfgang Betz 0:4fb29d9ee571 105
Wolfgang Betz 16:25dc4b811ad3 106 /* Enable the following interrupt sources, routed to GPIO */
Wolfgang Betz 16:25dc4b811ad3 107 irq_de_init(NULL);
Wolfgang Betz 16:25dc4b811ad3 108 irq_clear_status();
Wolfgang Betz 16:25dc4b811ad3 109 irq_set_status(TX_DATA_SENT, S_ENABLE);
Wolfgang Betz 16:25dc4b811ad3 110 irq_set_status(RX_DATA_READY,S_ENABLE);
Wolfgang Betz 16:25dc4b811ad3 111 irq_set_status(RX_DATA_DISC, S_ENABLE);
Wolfgang Betz 16:25dc4b811ad3 112 irq_set_status(TX_FIFO_ERROR, S_ENABLE);
Wolfgang Betz 16:25dc4b811ad3 113 irq_set_status(RX_FIFO_ERROR, S_ENABLE);
Wolfgang Betz 16:25dc4b811ad3 114 irq_set_status(RX_FIFO_ALMOST_FULL, S_ENABLE);
Wolfgang Betz 16:25dc4b811ad3 115 irq_set_status(VALID_SYNC, S_ENABLE);
Wolfgang Betz 0:4fb29d9ee571 116
Wolfgang Betz 16:25dc4b811ad3 117 /* Configure Spirit1 */
Wolfgang Betz 28:6a71e15d5272 118 radio_persistent_rx(S_ENABLE);
Wolfgang Betz 16:25dc4b811ad3 119 qi_set_sqi_threshold(SQI_TH_0);
Wolfgang Betz 16:25dc4b811ad3 120 qi_sqi_check(S_ENABLE);
Wolfgang Betz 16:25dc4b811ad3 121 qi_set_rssi_threshold_dbm(CCA_THRESHOLD);
Wolfgang Betz 16:25dc4b811ad3 122 timer_set_rx_timeout_stop_condition(SQI_ABOVE_THRESHOLD);
Wolfgang Betz 16:25dc4b811ad3 123 timer_set_infinite_rx_timeout();
Wolfgang Betz 16:25dc4b811ad3 124 radio_afc_freeze_on_sync(S_ENABLE);
Wolfgang Betz 29:fe1b113f71d0 125 calibration_rco(S_ENABLE);
Wolfgang Betz 0:4fb29d9ee571 126
Wolfgang Betz 16:25dc4b811ad3 127 spirit_on = OFF;
Wolfgang Betz 16:25dc4b811ad3 128 CLEAR_TXBUF();
Wolfgang Betz 16:25dc4b811ad3 129 CLEAR_RXBUF();
Wolfgang Betz 16:25dc4b811ad3 130 _spirit_tx_started = false;
Wolfgang Betz 16:25dc4b811ad3 131 _spirit_rx_err = false;
Wolfgang Betz 16:25dc4b811ad3 132 _is_receiving = false;
Wolfgang Betz 0:4fb29d9ee571 133
Wolfgang Betz 16:25dc4b811ad3 134 /* Configure the radio to route the IRQ signal to its GPIO 3 */
Wolfgang Betz 16:25dc4b811ad3 135 SGpioInit x_gpio_init = {
Wolfgang Betz 16:25dc4b811ad3 136 SPIRIT_GPIO_IRQ,
Wolfgang Betz 16:25dc4b811ad3 137 SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP,
Wolfgang Betz 16:25dc4b811ad3 138 SPIRIT_GPIO_DIG_OUT_IRQ
Wolfgang Betz 16:25dc4b811ad3 139 };
Wolfgang Betz 16:25dc4b811ad3 140 spirit_gpio_init(&x_gpio_init);
Wolfgang Betz 18:d6f789f6f4c9 141
Wolfgang Betz 23:4192649f35da 142 /* Setup CSMA/CA */
Wolfgang Betz 23:4192649f35da 143 CsmaInit x_csma_init = {
Wolfgang Betz 29:fe1b113f71d0 144 S_ENABLE, // enable persistent mode
Wolfgang Betz 23:4192649f35da 145 TBIT_TIME_64, // Tcca time
Wolfgang Betz 23:4192649f35da 146 TCCA_TIME_3, // Lcca length
Wolfgang Betz 23:4192649f35da 147 3, // max nr of backoffs (<8)
Wolfgang Betz 23:4192649f35da 148 1, // BU counter seed
Wolfgang Betz 23:4192649f35da 149 8 // BU prescaler
Wolfgang Betz 23:4192649f35da 150 };
Wolfgang Betz 23:4192649f35da 151 csma_ca_init(&x_csma_init);
Wolfgang Betz 23:4192649f35da 152
Wolfgang Betz 30:9c6dcfc47619 153 #ifdef RX_FIFO_THR_AO_CSMA_WA
Wolfgang Betz 18:d6f789f6f4c9 154 linear_fifo_set_almost_full_thr_rx(SPIRIT_MAX_FIFO_LEN-(MAX_PACKET_LEN+1));
Wolfgang Betz 18:d6f789f6f4c9 155 #endif
Wolfgang Betz 25:2ec45788f28c 156
Wolfgang Betz 28:6a71e15d5272 157 #ifdef USE_STANDBY_STATE
Wolfgang Betz 25:2ec45788f28c 158 /* Puts the SPIRIT1 in STANDBY mode (125us -> rx/tx) */
Wolfgang Betz 25:2ec45788f28c 159 cmd_strobe(SPIRIT1_STROBE_STANDBY);
Wolfgang Betz 28:6a71e15d5272 160 #endif // USE_STANDBY_STATE
Wolfgang Betz 0:4fb29d9ee571 161 }
Wolfgang Betz 3:0df38cfb1e53 162
Wolfgang Betz 6:f5d01793bf86 163 int SimpleSpirit1::send(const void *payload, unsigned int payload_len) {
Wolfgang Betz 5:c9c5bc673c64 164 /* Checks if the payload length is supported */
Wolfgang Betz 5:c9c5bc673c64 165 if(payload_len > MAX_PACKET_LEN) {
Wolfgang Betz 5:c9c5bc673c64 166 return RADIO_TX_ERR;
Wolfgang Betz 5:c9c5bc673c64 167 }
Wolfgang Betz 5:c9c5bc673c64 168
Wolfgang Betz 28:6a71e15d5272 169 disable_spirit_irq();
Wolfgang Betz 28:6a71e15d5272 170
Wolfgang Betz 28:6a71e15d5272 171 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
Wolfgang Betz 25:2ec45788f28c 172 #ifndef NDEBUG
Wolfgang Betz 28:6a71e15d5272 173 if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) {
Wolfgang Betz 27:e68ffb6ac223 174 debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
Wolfgang Betz 26:45dae8d48029 175 }
Wolfgang Betz 25:2ec45788f28c 176 #endif
Wolfgang Betz 25:2ec45788f28c 177
Wolfgang Betz 5:c9c5bc673c64 178 /* Reset State to Ready */
Wolfgang Betz 5:c9c5bc673c64 179 set_ready_state();
Wolfgang Betz 5:c9c5bc673c64 180
Wolfgang Betz 5:c9c5bc673c64 181 cmd_strobe(SPIRIT1_STROBE_FTX); // flush TX FIFO buffer
Wolfgang Betz 25:2ec45788f28c 182
Wolfgang Betz 22:9165bd73c61e 183 #ifndef NDEBUG
Wolfgang Betz 27:e68ffb6ac223 184 debug_if(!(linear_fifo_read_num_elements_tx_fifo() == 0), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
Wolfgang Betz 22:9165bd73c61e 185 #endif
Wolfgang Betz 5:c9c5bc673c64 186
Wolfgang Betz 5:c9c5bc673c64 187 pkt_basic_set_payload_length(payload_len); // set desired payload len
Wolfgang Betz 26:45dae8d48029 188
Wolfgang Betz 30:9c6dcfc47619 189 #ifdef RX_FIFO_THR_AO_CSMA_WA
Wolfgang Betz 30:9c6dcfc47619 190 // betzw - TODO: enabling CSMA/CA seems to be incompatible with TX FIFO usage (to be investigated)
Wolfgang Betz 23:4192649f35da 191 csma_ca_state(S_ENABLE); // enable CSMA/CA
Wolfgang Betz 26:45dae8d48029 192 #endif
Wolfgang Betz 26:45dae8d48029 193
Wolfgang Betz 5:c9c5bc673c64 194 int i = 0;
Wolfgang Betz 5:c9c5bc673c64 195 int remaining = payload_len;
Wolfgang Betz 26:45dae8d48029 196 const uint8_t *buffer = (const uint8_t*)payload;
Wolfgang Betz 28:6a71e15d5272 197 bool tx_triggered = false;
Wolfgang Betz 5:c9c5bc673c64 198 do {
Wolfgang Betz 5:c9c5bc673c64 199 uint8_t fifo_available = SPIRIT_MAX_FIFO_LEN - linear_fifo_read_num_elements_tx_fifo();
Wolfgang Betz 5:c9c5bc673c64 200 uint8_t to_send = (remaining > fifo_available) ? fifo_available : remaining;
Wolfgang Betz 5:c9c5bc673c64 201
Wolfgang Betz 5:c9c5bc673c64 202 /* Fill FIFO Buffer */
Wolfgang Betz 26:45dae8d48029 203 if(to_send > 0) {
Wolfgang Betz 26:45dae8d48029 204 spi_write_linear_fifo(to_send, (uint8_t*)&buffer[i]);
Wolfgang Betz 5:c9c5bc673c64 205 }
Wolfgang Betz 5:c9c5bc673c64 206
Wolfgang Betz 28:6a71e15d5272 207 if(!tx_triggered) {
Wolfgang Betz 28:6a71e15d5272 208 cmd_strobe(SPIRIT1_STROBE_TX);
Wolfgang Betz 28:6a71e15d5272 209 tx_triggered = true;
Wolfgang Betz 28:6a71e15d5272 210 }
Wolfgang Betz 28:6a71e15d5272 211
Wolfgang Betz 5:c9c5bc673c64 212 i += to_send;
Wolfgang Betz 5:c9c5bc673c64 213 remaining -= to_send;
Wolfgang Betz 5:c9c5bc673c64 214 } while(remaining != 0);
Wolfgang Betz 5:c9c5bc673c64 215
Wolfgang Betz 7:e90fa8f6bc6c 216 _spirit_tx_started = true;
Wolfgang Betz 7:e90fa8f6bc6c 217
Wolfgang Betz 7:e90fa8f6bc6c 218 enable_spirit_irq();
Wolfgang Betz 7:e90fa8f6bc6c 219
Wolfgang Betz 28:6a71e15d5272 220 BUSYWAIT_UNTIL(!_spirit_tx_started, STATE_TIMEOUT);
Wolfgang Betz 30:9c6dcfc47619 221 #ifdef HEAVY_DEBUG
Wolfgang Betz 30:9c6dcfc47619 222 debug("\n\r%s (%d): state=%x, _spirit_tx_started=%d\n\r", __func__, __LINE__, SPIRIT1_STATUS()>>1, _spirit_tx_started);
Wolfgang Betz 23:4192649f35da 223 #endif
Wolfgang Betz 5:c9c5bc673c64 224
Wolfgang Betz 33:c226804be492 225 _spirit_tx_started = false; // in case of state timeout
Wolfgang Betz 33:c226804be492 226
Wolfgang Betz 28:6a71e15d5272 227 csma_ca_state(S_DISABLE); // disable CSMA/CA
Wolfgang Betz 28:6a71e15d5272 228 cmd_strobe(SPIRIT1_STROBE_RX); // Return to RX state
Wolfgang Betz 28:6a71e15d5272 229
Wolfgang Betz 5:c9c5bc673c64 230 return RADIO_TX_OK;
Wolfgang Betz 5:c9c5bc673c64 231 }
Wolfgang Betz 5:c9c5bc673c64 232
Wolfgang Betz 3:0df38cfb1e53 233 /** Set Ready State **/
Wolfgang Betz 3:0df38cfb1e53 234 void SimpleSpirit1::set_ready_state(void) {
Wolfgang Betz 25:2ec45788f28c 235 uint16_t state;
Wolfgang Betz 25:2ec45788f28c 236
Wolfgang Betz 16:25dc4b811ad3 237 disable_spirit_irq();
Wolfgang Betz 3:0df38cfb1e53 238
Wolfgang Betz 30:9c6dcfc47619 239 _spirit_tx_started = false;
Wolfgang Betz 16:25dc4b811ad3 240 _is_receiving = false;
Wolfgang Betz 30:9c6dcfc47619 241 _spirit_rx_err = false;
Wolfgang Betz 16:25dc4b811ad3 242 stop_rx_timeout();
Wolfgang Betz 12:b8056eda4028 243
Wolfgang Betz 30:9c6dcfc47619 244 cmd_strobe(SPIRIT1_STROBE_FRX);
Wolfgang Betz 30:9c6dcfc47619 245 CLEAR_RXBUF();
Wolfgang Betz 30:9c6dcfc47619 246 CLEAR_TXBUF();
Wolfgang Betz 30:9c6dcfc47619 247
Wolfgang Betz 25:2ec45788f28c 248 state = SPIRIT1_STATUS();
Wolfgang Betz 25:2ec45788f28c 249 if(state == SPIRIT1_STATE_STANDBY) {
Wolfgang Betz 16:25dc4b811ad3 250 cmd_strobe(SPIRIT1_STROBE_READY);
Wolfgang Betz 25:2ec45788f28c 251 } else if(state == SPIRIT1_STATE_RX) {
Wolfgang Betz 16:25dc4b811ad3 252 cmd_strobe(SPIRIT1_STROBE_SABORT);
Wolfgang Betz 25:2ec45788f28c 253 } else if(state != SPIRIT1_STATE_READY) {
Wolfgang Betz 25:2ec45788f28c 254 #ifndef NDEBUG
Wolfgang Betz 27:e68ffb6ac223 255 debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, state>>1);
Wolfgang Betz 25:2ec45788f28c 256 #endif
Wolfgang Betz 16:25dc4b811ad3 257 }
Wolfgang Betz 25:2ec45788f28c 258
Wolfgang Betz 28:6a71e15d5272 259 BUSYWAIT_UNTIL((SPIRIT1_STATUS() == SPIRIT1_STATE_READY) && ((last_state & XO_ON) == XO_ON), STATE_TIMEOUT);
Wolfgang Betz 28:6a71e15d5272 260 if(last_state != (SPIRIT1_STATE_READY | XO_ON)) {
Wolfgang Betz 28:6a71e15d5272 261 error("\n\rSpirit1: failed to become ready (%x) => pls. reset!\n\r", last_state);
Wolfgang Betz 25:2ec45788f28c 262 enable_spirit_irq();
Wolfgang Betz 25:2ec45788f28c 263 return;
Wolfgang Betz 25:2ec45788f28c 264 }
Wolfgang Betz 25:2ec45788f28c 265
Wolfgang Betz 16:25dc4b811ad3 266 irq_clear_status();
Wolfgang Betz 3:0df38cfb1e53 267
Wolfgang Betz 16:25dc4b811ad3 268 enable_spirit_irq();
Wolfgang Betz 3:0df38cfb1e53 269 }
Wolfgang Betz 3:0df38cfb1e53 270
Wolfgang Betz 4:07537ca85c66 271 int SimpleSpirit1::off(void) {
Wolfgang Betz 16:25dc4b811ad3 272 if(spirit_on == ON) {
Wolfgang Betz 16:25dc4b811ad3 273 /* Disables the mcu to get IRQ from the SPIRIT1 */
Wolfgang Betz 16:25dc4b811ad3 274 disable_spirit_irq();
Wolfgang Betz 3:0df38cfb1e53 275
Wolfgang Betz 16:25dc4b811ad3 276 /* first stop rx/tx */
Wolfgang Betz 25:2ec45788f28c 277 set_ready_state();
Wolfgang Betz 3:0df38cfb1e53 278
Wolfgang Betz 28:6a71e15d5272 279 #ifdef USE_STANDBY_STATE
Wolfgang Betz 16:25dc4b811ad3 280 /* Puts the SPIRIT1 in STANDBY */
Wolfgang Betz 16:25dc4b811ad3 281 cmd_strobe(SPIRIT1_STROBE_STANDBY);
Wolfgang Betz 25:2ec45788f28c 282 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, STATE_TIMEOUT);
Wolfgang Betz 28:6a71e15d5272 283 if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_STANDBY) {
Wolfgang Betz 26:45dae8d48029 284 error("\n\rSpirit1: failed to enter standby (%x)\n\r", last_state>>1);
Wolfgang Betz 16:25dc4b811ad3 285 return 1;
Wolfgang Betz 16:25dc4b811ad3 286 }
Wolfgang Betz 28:6a71e15d5272 287 #endif // USE_STANDBY_STATE
Wolfgang Betz 3:0df38cfb1e53 288
Wolfgang Betz 16:25dc4b811ad3 289 spirit_on = OFF;
Wolfgang Betz 16:25dc4b811ad3 290 _nr_of_irq_disables = 1;
Wolfgang Betz 16:25dc4b811ad3 291 }
Wolfgang Betz 16:25dc4b811ad3 292 return 0;
Wolfgang Betz 3:0df38cfb1e53 293 }
Wolfgang Betz 3:0df38cfb1e53 294
Wolfgang Betz 4:07537ca85c66 295 int SimpleSpirit1::on(void) {
Wolfgang Betz 16:25dc4b811ad3 296 if(spirit_on == OFF) {
Wolfgang Betz 25:2ec45788f28c 297 set_ready_state();
Wolfgang Betz 25:2ec45788f28c 298
Wolfgang Betz 25:2ec45788f28c 299 /* now we go to Rx */
Wolfgang Betz 25:2ec45788f28c 300 cmd_strobe(SPIRIT1_STROBE_RX);
Wolfgang Betz 25:2ec45788f28c 301
Wolfgang Betz 25:2ec45788f28c 302 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
Wolfgang Betz 28:6a71e15d5272 303 if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) {
Wolfgang Betz 26:45dae8d48029 304 error("\n\rSpirit1: failed to enter rx (%x) => retry\n\r", last_state>>1);
Wolfgang Betz 16:25dc4b811ad3 305 }
Wolfgang Betz 3:0df38cfb1e53 306
Wolfgang Betz 16:25dc4b811ad3 307 /* Enables the mcu to get IRQ from the SPIRIT1 */
Wolfgang Betz 16:25dc4b811ad3 308 spirit_on = ON;
Wolfgang Betz 22:9165bd73c61e 309 #ifndef NDEBUG
Wolfgang Betz 27:e68ffb6ac223 310 debug_if(!(_nr_of_irq_disables == 1), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
Wolfgang Betz 22:9165bd73c61e 311 #endif
Wolfgang Betz 16:25dc4b811ad3 312 enable_spirit_irq();
Wolfgang Betz 16:25dc4b811ad3 313 }
Wolfgang Betz 3:0df38cfb1e53 314
Wolfgang Betz 25:2ec45788f28c 315 #ifndef NDEBUG
Wolfgang Betz 26:45dae8d48029 316 if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
Wolfgang Betz 27:e68ffb6ac223 317 debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
Wolfgang Betz 26:45dae8d48029 318 }
Wolfgang Betz 25:2ec45788f28c 319 #endif
Wolfgang Betz 25:2ec45788f28c 320
Wolfgang Betz 16:25dc4b811ad3 321 return 0;
Wolfgang Betz 3:0df38cfb1e53 322 }
Wolfgang Betz 3:0df38cfb1e53 323
Wolfgang Betz 25:2ec45788f28c 324 uint8_t SimpleSpirit1::refresh_state(void) {
Wolfgang Betz 25:2ec45788f28c 325 uint8_t mcstate;
Wolfgang Betz 3:0df38cfb1e53 326
Wolfgang Betz 25:2ec45788f28c 327 SpiritSpiReadRegisters(MC_STATE0_BASE, 1, &mcstate);
Wolfgang Betz 3:0df38cfb1e53 328
Wolfgang Betz 16:25dc4b811ad3 329 return mcstate;
Wolfgang Betz 3:0df38cfb1e53 330 }
Wolfgang Betz 3:0df38cfb1e53 331
Wolfgang Betz 6:f5d01793bf86 332 int SimpleSpirit1::read(void *buf, unsigned int bufsize)
Wolfgang Betz 4:07537ca85c66 333 {
Wolfgang Betz 16:25dc4b811ad3 334 disable_spirit_irq();
Wolfgang Betz 6:f5d01793bf86 335
Wolfgang Betz 16:25dc4b811ad3 336 /* Checks if the RX buffer is empty */
Wolfgang Betz 16:25dc4b811ad3 337 if(IS_RXBUF_EMPTY()) {
Wolfgang Betz 25:2ec45788f28c 338 set_ready_state();
Wolfgang Betz 25:2ec45788f28c 339
Wolfgang Betz 16:25dc4b811ad3 340 cmd_strobe(SPIRIT1_STROBE_RX);
Wolfgang Betz 25:2ec45788f28c 341 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
Wolfgang Betz 16:25dc4b811ad3 342 enable_spirit_irq();
Wolfgang Betz 16:25dc4b811ad3 343 return 0;
Wolfgang Betz 16:25dc4b811ad3 344 }
Wolfgang Betz 4:07537ca85c66 345
Wolfgang Betz 16:25dc4b811ad3 346 if(bufsize < spirit_rx_len) {
Wolfgang Betz 16:25dc4b811ad3 347 enable_spirit_irq();
Wolfgang Betz 6:f5d01793bf86 348
Wolfgang Betz 16:25dc4b811ad3 349 /* If buf has the correct size */
Wolfgang Betz 22:9165bd73c61e 350 #ifndef NDEBUG
Wolfgang Betz 22:9165bd73c61e 351 debug("\n\rTOO SMALL BUF\n\r");
Wolfgang Betz 22:9165bd73c61e 352 #endif
Wolfgang Betz 16:25dc4b811ad3 353 return 0;
Wolfgang Betz 16:25dc4b811ad3 354 } else {
Wolfgang Betz 16:25dc4b811ad3 355 /* Copies the packet received */
Wolfgang Betz 16:25dc4b811ad3 356 memcpy(buf, spirit_rx_buf, spirit_rx_len);
Wolfgang Betz 4:07537ca85c66 357
Wolfgang Betz 16:25dc4b811ad3 358 bufsize = spirit_rx_len;
Wolfgang Betz 16:25dc4b811ad3 359 CLEAR_RXBUF();
Wolfgang Betz 4:07537ca85c66 360
Wolfgang Betz 16:25dc4b811ad3 361 enable_spirit_irq();
Wolfgang Betz 6:f5d01793bf86 362
Wolfgang Betz 16:25dc4b811ad3 363 return bufsize;
Wolfgang Betz 16:25dc4b811ad3 364 }
Wolfgang Betz 4:07537ca85c66 365
Wolfgang Betz 4:07537ca85c66 366 }
Wolfgang Betz 4:07537ca85c66 367
Wolfgang Betz 4:07537ca85c66 368 int SimpleSpirit1::channel_clear(void)
Wolfgang Betz 4:07537ca85c66 369 {
Wolfgang Betz 16:25dc4b811ad3 370 float rssi_value;
Wolfgang Betz 16:25dc4b811ad3 371 /* Local variable used to memorize the SPIRIT1 state */
Wolfgang Betz 16:25dc4b811ad3 372 uint8_t spirit_state = ON;
Wolfgang Betz 4:07537ca85c66 373
Wolfgang Betz 16:25dc4b811ad3 374 if(spirit_on == OFF) {
Wolfgang Betz 16:25dc4b811ad3 375 /* Wakes up the SPIRIT1 */
Wolfgang Betz 16:25dc4b811ad3 376 on();
Wolfgang Betz 16:25dc4b811ad3 377 spirit_state = OFF;
Wolfgang Betz 16:25dc4b811ad3 378 }
Wolfgang Betz 4:07537ca85c66 379
Wolfgang Betz 25:2ec45788f28c 380 #ifndef NDEBUG
Wolfgang Betz 26:45dae8d48029 381 if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
Wolfgang Betz 27:e68ffb6ac223 382 debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
Wolfgang Betz 26:45dae8d48029 383 }
Wolfgang Betz 25:2ec45788f28c 384 #endif
Wolfgang Betz 25:2ec45788f28c 385
Wolfgang Betz 16:25dc4b811ad3 386 disable_spirit_irq();
Wolfgang Betz 7:e90fa8f6bc6c 387
Wolfgang Betz 16:25dc4b811ad3 388 /* Reset State to Ready */
Wolfgang Betz 16:25dc4b811ad3 389 set_ready_state();
Wolfgang Betz 4:07537ca85c66 390
Wolfgang Betz 16:25dc4b811ad3 391 /* Stores the RSSI value */
Wolfgang Betz 16:25dc4b811ad3 392 rssi_value = qi_get_rssi_dbm();
Wolfgang Betz 4:07537ca85c66 393
Wolfgang Betz 16:25dc4b811ad3 394 enable_spirit_irq();
Wolfgang Betz 7:e90fa8f6bc6c 395
Wolfgang Betz 16:25dc4b811ad3 396 /* Puts the SPIRIT1 in its previous state */
Wolfgang Betz 16:25dc4b811ad3 397 if(spirit_state==OFF) {
Wolfgang Betz 16:25dc4b811ad3 398 off();
Wolfgang Betz 25:2ec45788f28c 399 #ifndef NDEBUG
Wolfgang Betz 28:6a71e15d5272 400 #ifdef USE_STANDBY_STATE
Wolfgang Betz 26:45dae8d48029 401 if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) {
Wolfgang Betz 28:6a71e15d5272 402 #else
Wolfgang Betz 28:6a71e15d5272 403 if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
Wolfgang Betz 28:6a71e15d5272 404 #endif
Wolfgang Betz 27:e68ffb6ac223 405 debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
Wolfgang Betz 26:45dae8d48029 406 }
Wolfgang Betz 25:2ec45788f28c 407 #endif
Wolfgang Betz 16:25dc4b811ad3 408 } else {
Wolfgang Betz 16:25dc4b811ad3 409 disable_spirit_irq();
Wolfgang Betz 25:2ec45788f28c 410
Wolfgang Betz 25:2ec45788f28c 411 set_ready_state();
Wolfgang Betz 25:2ec45788f28c 412
Wolfgang Betz 16:25dc4b811ad3 413 cmd_strobe(SPIRIT1_STROBE_RX);
Wolfgang Betz 25:2ec45788f28c 414 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
Wolfgang Betz 28:6a71e15d5272 415 if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) {
Wolfgang Betz 26:45dae8d48029 416 error("\n\rSpirit1: (#2) failed to enter rx (%x) => retry\n\r", last_state>>1);
Wolfgang Betz 25:2ec45788f28c 417 }
Wolfgang Betz 25:2ec45788f28c 418
Wolfgang Betz 16:25dc4b811ad3 419 enable_spirit_irq();
Wolfgang Betz 25:2ec45788f28c 420
Wolfgang Betz 25:2ec45788f28c 421 #ifndef NDEBUG
Wolfgang Betz 26:45dae8d48029 422 if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
Wolfgang Betz 27:e68ffb6ac223 423 debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
Wolfgang Betz 26:45dae8d48029 424 }
Wolfgang Betz 25:2ec45788f28c 425 #endif
Wolfgang Betz 16:25dc4b811ad3 426 }
Wolfgang Betz 4:07537ca85c66 427
Wolfgang Betz 16:25dc4b811ad3 428 /* Checks the RSSI value with the threshold */
Wolfgang Betz 16:25dc4b811ad3 429 if(rssi_value<CCA_THRESHOLD) {
Wolfgang Betz 16:25dc4b811ad3 430 return 0;
Wolfgang Betz 16:25dc4b811ad3 431 } else {
Wolfgang Betz 16:25dc4b811ad3 432 return 1;
Wolfgang Betz 16:25dc4b811ad3 433 }
Wolfgang Betz 4:07537ca85c66 434 }
Wolfgang Betz 4:07537ca85c66 435
Wolfgang Betz 7:e90fa8f6bc6c 436 int SimpleSpirit1::get_pending_packet(void)
Wolfgang Betz 4:07537ca85c66 437 {
Wolfgang Betz 16:25dc4b811ad3 438 return !IS_RXBUF_EMPTY();
Wolfgang Betz 4:07537ca85c66 439 }
Wolfgang Betz 4:07537ca85c66 440
Wolfgang Betz 5:c9c5bc673c64 441 /** Spirit Irq Callback **/
Wolfgang Betz 5:c9c5bc673c64 442 void SimpleSpirit1::IrqHandler() {
Wolfgang Betz 16:25dc4b811ad3 443 st_lib_spirit_irqs x_irq_status;
Wolfgang Betz 4:07537ca85c66 444
Wolfgang Betz 16:25dc4b811ad3 445 /* get interrupt source from radio */
Wolfgang Betz 16:25dc4b811ad3 446 irq_get_status(&x_irq_status);
Wolfgang Betz 4:07537ca85c66 447
Wolfgang Betz 16:25dc4b811ad3 448 /* Reception errors */
Wolfgang Betz 26:45dae8d48029 449 if((x_irq_status.IRQ_RX_FIFO_ERROR) || (x_irq_status.IRQ_RX_DATA_DISC)) {
Wolfgang Betz 28:6a71e15d5272 450 #ifdef DEBUG_IRQ
Wolfgang Betz 28:6a71e15d5272 451 uint32_t *tmp = (uint32_t*)&x_irq_status;
Wolfgang Betz 28:6a71e15d5272 452 debug("\n\r%s (%d): irq=%x", __func__, __LINE__, *tmp);
Wolfgang Betz 23:4192649f35da 453 #endif
Wolfgang Betz 16:25dc4b811ad3 454 _spirit_rx_err = true;
Wolfgang Betz 16:25dc4b811ad3 455 _is_receiving = false;
Wolfgang Betz 16:25dc4b811ad3 456 CLEAR_RXBUF();
Wolfgang Betz 6:f5d01793bf86 457 cmd_strobe(SPIRIT1_STROBE_FRX);
Wolfgang Betz 16:25dc4b811ad3 458 if(_spirit_tx_started) {
Wolfgang Betz 16:25dc4b811ad3 459 _spirit_tx_started = false;
Wolfgang Betz 16:25dc4b811ad3 460 CLEAR_TXBUF();
Wolfgang Betz 16:25dc4b811ad3 461 /* call user callback */
Wolfgang Betz 16:25dc4b811ad3 462 if(_current_irq_callback) {
Wolfgang Betz 16:25dc4b811ad3 463 _current_irq_callback(TX_ERR);
Wolfgang Betz 6:f5d01793bf86 464 }
Wolfgang Betz 6:f5d01793bf86 465 }
Wolfgang Betz 16:25dc4b811ad3 466 }
Wolfgang Betz 16:25dc4b811ad3 467
Wolfgang Betz 16:25dc4b811ad3 468 /* Transmission error */
Wolfgang Betz 16:25dc4b811ad3 469 if(x_irq_status.IRQ_TX_FIFO_ERROR) {
Wolfgang Betz 28:6a71e15d5272 470 #ifdef DEBUG_IRQ
Wolfgang Betz 28:6a71e15d5272 471 uint32_t *tmp = (uint32_t*)&x_irq_status;
Wolfgang Betz 28:6a71e15d5272 472 debug("\n\r%s (%d): irq=%x", __func__, __LINE__, *tmp);
Wolfgang Betz 22:9165bd73c61e 473 #endif
Wolfgang Betz 23:4192649f35da 474 csma_ca_state(S_DISABLE); // disable CSMA/CA
Wolfgang Betz 16:25dc4b811ad3 475 cmd_strobe(SPIRIT1_STROBE_FTX);
Wolfgang Betz 16:25dc4b811ad3 476 if(_spirit_tx_started) {
Wolfgang Betz 16:25dc4b811ad3 477 _spirit_tx_started = false;
Wolfgang Betz 16:25dc4b811ad3 478 CLEAR_TXBUF();
Wolfgang Betz 16:25dc4b811ad3 479 /* call user callback */
Wolfgang Betz 16:25dc4b811ad3 480 if(_current_irq_callback) {
Wolfgang Betz 16:25dc4b811ad3 481 _current_irq_callback(TX_ERR);
Wolfgang Betz 16:25dc4b811ad3 482 }
Wolfgang Betz 16:25dc4b811ad3 483 }
Wolfgang Betz 16:25dc4b811ad3 484 }
Wolfgang Betz 16:25dc4b811ad3 485
Wolfgang Betz 16:25dc4b811ad3 486 /* The IRQ_TX_DATA_SENT notifies the packet received. Puts the SPIRIT1 in RX */
Wolfgang Betz 16:25dc4b811ad3 487 if(x_irq_status.IRQ_TX_DATA_SENT) {
Wolfgang Betz 28:6a71e15d5272 488 #ifdef DEBUG_IRQ
Wolfgang Betz 27:e68ffb6ac223 489 debug_if(!_spirit_tx_started, "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
Wolfgang Betz 22:9165bd73c61e 490 #endif
Wolfgang Betz 5:c9c5bc673c64 491
Wolfgang Betz 28:6a71e15d5272 492 _spirit_rx_err = false;
Wolfgang Betz 28:6a71e15d5272 493 _spirit_tx_started = false;
Wolfgang Betz 16:25dc4b811ad3 494 CLEAR_TXBUF();
Wolfgang Betz 16:25dc4b811ad3 495 CLEAR_RXBUF();
Wolfgang Betz 4:07537ca85c66 496
Wolfgang Betz 6:f5d01793bf86 497 /* call user callback */
Wolfgang Betz 6:f5d01793bf86 498 if(_current_irq_callback) {
Wolfgang Betz 23:4192649f35da 499 _current_irq_callback(TX_DONE);
Wolfgang Betz 6:f5d01793bf86 500 }
Wolfgang Betz 16:25dc4b811ad3 501 }
Wolfgang Betz 15:852b92eed64a 502
Wolfgang Betz 16:25dc4b811ad3 503 /* RX FIFO almost full */
Wolfgang Betz 16:25dc4b811ad3 504 if(x_irq_status.IRQ_RX_FIFO_ALMOST_FULL) {
Wolfgang Betz 16:25dc4b811ad3 505 if(_spirit_rx_err) {
Wolfgang Betz 16:25dc4b811ad3 506 _is_receiving = false;
Wolfgang Betz 16:25dc4b811ad3 507 cmd_strobe(SPIRIT1_STROBE_FRX);
Wolfgang Betz 16:25dc4b811ad3 508 CLEAR_RXBUF();
Wolfgang Betz 16:25dc4b811ad3 509 } else {
Wolfgang Betz 16:25dc4b811ad3 510 uint8_t fifo_available = linear_fifo_read_num_elements_rx_fifo();
Wolfgang Betz 16:25dc4b811ad3 511 unsigned int remaining = MAX_PACKET_LEN - _spirit_rx_pos;
Wolfgang Betz 16:25dc4b811ad3 512 if(fifo_available > remaining) {
Wolfgang Betz 16:25dc4b811ad3 513 _spirit_rx_err = true;
Wolfgang Betz 16:25dc4b811ad3 514 _is_receiving = false;
Wolfgang Betz 16:25dc4b811ad3 515 CLEAR_RXBUF();
Wolfgang Betz 16:25dc4b811ad3 516 cmd_strobe(SPIRIT1_STROBE_FRX);
Wolfgang Betz 16:25dc4b811ad3 517 } else {
Wolfgang Betz 16:25dc4b811ad3 518 spi_read_linear_fifo(fifo_available, &spirit_rx_buf[_spirit_rx_pos]);
Wolfgang Betz 16:25dc4b811ad3 519 _spirit_rx_pos += fifo_available;
Wolfgang Betz 16:25dc4b811ad3 520 if(!_is_receiving) {
Wolfgang Betz 16:25dc4b811ad3 521 _is_receiving = true;
Wolfgang Betz 16:25dc4b811ad3 522 start_rx_timeout();
Wolfgang Betz 16:25dc4b811ad3 523 }
Wolfgang Betz 16:25dc4b811ad3 524 }
Wolfgang Betz 16:25dc4b811ad3 525 }
Wolfgang Betz 16:25dc4b811ad3 526 }
Wolfgang Betz 15:852b92eed64a 527
Wolfgang Betz 16:25dc4b811ad3 528 /* The IRQ_RX_DATA_READY notifies a new packet arrived */
Wolfgang Betz 16:25dc4b811ad3 529 if(x_irq_status.IRQ_RX_DATA_READY) {
Wolfgang Betz 16:25dc4b811ad3 530 _is_receiving = false; // Finished receiving
Wolfgang Betz 16:25dc4b811ad3 531 stop_rx_timeout();
Wolfgang Betz 15:852b92eed64a 532
Wolfgang Betz 16:25dc4b811ad3 533 if(_spirit_rx_err) {
Wolfgang Betz 16:25dc4b811ad3 534 _spirit_rx_err = false;
Wolfgang Betz 16:25dc4b811ad3 535 CLEAR_RXBUF();
Wolfgang Betz 16:25dc4b811ad3 536 cmd_strobe(SPIRIT1_STROBE_FRX);
Wolfgang Betz 16:25dc4b811ad3 537 } else {
Wolfgang Betz 16:25dc4b811ad3 538 spirit_rx_len = pkt_basic_get_received_pkt_length();
Wolfgang Betz 16:25dc4b811ad3 539
Wolfgang Betz 28:6a71e15d5272 540 #ifdef DEBUG_IRQ
Wolfgang Betz 27:e68ffb6ac223 541 debug_if(!(spirit_rx_len <= MAX_PACKET_LEN), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
Wolfgang Betz 22:9165bd73c61e 542 #endif
Wolfgang Betz 16:25dc4b811ad3 543
Wolfgang Betz 16:25dc4b811ad3 544 for(; _spirit_rx_pos < spirit_rx_len;) {
Wolfgang Betz 25:2ec45788f28c 545 uint8_t to_receive = spirit_rx_len - _spirit_rx_pos;
Wolfgang Betz 16:25dc4b811ad3 546 if(to_receive > 0) {
Wolfgang Betz 16:25dc4b811ad3 547 spi_read_linear_fifo(to_receive, &spirit_rx_buf[_spirit_rx_pos]);
Wolfgang Betz 16:25dc4b811ad3 548 _spirit_rx_pos += to_receive;
Wolfgang Betz 16:25dc4b811ad3 549 }
Wolfgang Betz 16:25dc4b811ad3 550 }
Wolfgang Betz 16:25dc4b811ad3 551
Wolfgang Betz 16:25dc4b811ad3 552 cmd_strobe(SPIRIT1_STROBE_FRX);
Wolfgang Betz 16:25dc4b811ad3 553
Wolfgang Betz 16:25dc4b811ad3 554 last_rssi = qi_get_rssi(); //MGR
Wolfgang Betz 30:9c6dcfc47619 555 last_sqi = qi_get_sqi(); //MGR
Wolfgang Betz 16:25dc4b811ad3 556
Wolfgang Betz 16:25dc4b811ad3 557 /* call user callback */
Wolfgang Betz 16:25dc4b811ad3 558 if(_current_irq_callback) {
Wolfgang Betz 23:4192649f35da 559 _current_irq_callback(RX_DONE);
Wolfgang Betz 16:25dc4b811ad3 560 }
Wolfgang Betz 16:25dc4b811ad3 561 }
Wolfgang Betz 16:25dc4b811ad3 562 }
Wolfgang Betz 23:4192649f35da 563
Wolfgang Betz 28:6a71e15d5272 564 /* The IRQ_VALID_SYNC is used to notify a new packet is coming */
Wolfgang Betz 28:6a71e15d5272 565 if(x_irq_status.IRQ_VALID_SYNC) {
Wolfgang Betz 28:6a71e15d5272 566 _is_receiving = true;
Wolfgang Betz 28:6a71e15d5272 567 _spirit_rx_err = false;
Wolfgang Betz 28:6a71e15d5272 568 CLEAR_RXBUF();
Wolfgang Betz 28:6a71e15d5272 569 #ifdef DEBUG_IRQ
Wolfgang Betz 28:6a71e15d5272 570 debug_if(_spirit_tx_started, "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
Wolfgang Betz 28:6a71e15d5272 571 #endif
Wolfgang Betz 28:6a71e15d5272 572 start_rx_timeout();
Wolfgang Betz 23:4192649f35da 573 }
Wolfgang Betz 4:07537ca85c66 574 }