Fork of my MQTTGateway

Dependencies:   mbed-http

Committer:
vpcola
Date:
Sat Apr 08 14:45:51 2017 +0000
Revision:
0:f1d3878b8dd9
Initial commit

Who changed what in which revision?

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