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:
Wed Nov 09 14:02:18 2016 +0100
Revision:
23:4192649f35da
Parent:
22:9165bd73c61e
Child:
24:03e351bfc9c9
Enable CSMA/CA

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