Version of easy-connect with the u-blox cellular platforms C027 and C030 added.

Dependents:   HelloMQTT

Committer:
RobMeades
Date:
Fri Nov 03 13:01:23 2017 +0000
Revision:
6:304d3ba87a01
Parent:
0:19aa55d66228
Add comment concerning N2XX baud rate.

Who changed what in which revision?

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