Fork of my original MQTTGateway

Dependencies:   mbed-http

Committer:
vpcola
Date:
Sat Apr 08 14:43:14 2017 +0000
Revision:
0:a1734fe1ec4b
Initial commit

Who changed what in which revision?

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