JunMo Hong / Mbed 2 deprecated cubebite_rnd_SPSGRFC433

Dependencies:   mbed

Fork of HelloWorld_IDS01A4 by ST

Committer:
jmhong
Date:
Wed Jan 17 04:04:16 2018 +0000
Revision:
13:d802c6ed2e75
180117

Who changed what in which revision?

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