180718 HJM : 8 Count sensing data RF send, certTest, temp(cold)Test
Fork of EV-COG-AD3029LZ by
Diff: source/SimpleSpirit1.cpp
- Revision:
- 69:22e9b407effa
- Parent:
- 68:247fd6e0ab66
- Child:
- 70:19b5f9b9ba80
--- a/source/SimpleSpirit1.cpp Thu Jul 06 14:15:57 2017 +0200 +++ b/source/SimpleSpirit1.cpp Mon Jul 10 13:54:43 2017 +0200 @@ -10,10 +10,10 @@ #define XO_ON (0x1) #define BUSYWAIT_UNTIL(cond, millisecs) \ - do { \ - uint32_t start = us_ticker_read(); \ - while (!(cond) && ((us_ticker_read() - start) < ((uint32_t)millisecs)*1000U)); \ - } while(0) + do { \ + uint32_t start = us_ticker_read(); \ + while (!(cond) && ((us_ticker_read() - start) < ((uint32_t)millisecs)*1000U)); \ + } while(0) #define st_lib_spirit_irqs SpiritIrqs @@ -28,599 +28,603 @@ /** Constructor **/ SimpleSpirit1::SimpleSpirit1(PinName mosi, PinName miso, PinName sclk, - PinName irq, PinName cs, PinName sdn, - PinName led) : - _spi(mosi, miso, sclk), - _irq(irq), - _chip_select(cs), - _shut_down(sdn), - _led(led), - _current_irq_callback(), - _rx_receiving_timeout() + PinName irq, PinName cs, PinName sdn, + PinName led) : + _spi(mosi, miso, sclk), + _irq(irq), + _chip_select(cs), + _shut_down(sdn), + _led(led), + _current_irq_callback(), + _rx_receiving_timeout() { } /** Init Function **/ void SimpleSpirit1::init() { - /* reset irq disable counter and irq callback & disable irq */ - _nr_of_irq_disables = 0; - disable_spirit_irq(); + /* reset irq disable counter and irq callback & disable irq */ + _nr_of_irq_disables = 0; + disable_spirit_irq(); - /* unselect chip */ - chip_unselect(); + /* unselect chip */ + chip_unselect(); - /* configure spi */ - _spi.format(8, 0); /* 8-bit, mode = 0, [order = SPI_MSB] only available in mbed3 */ - _spi.frequency(10000000); // 10MHz (i.e. max speed allowed for Spirit1) + /* configure spi */ + _spi.format(8, 0); /* 8-bit, mode = 0, [order = SPI_MSB] only available in mbed3 */ + _spi.frequency(10000000); // 10MHz (i.e. max speed allowed for Spirit1) - /* install irq handler */ - _irq.mode(PullUp); - _irq.fall(Callback<void()>(this, &SimpleSpirit1::IrqHandler)); + /* install irq handler */ + _irq.mode(PullUp); + _irq.fall(Callback<void()>(this, &SimpleSpirit1::IrqHandler)); - /* init cube vars */ - spirit_on = OFF; - last_rssi = 0 ; //MGR - last_sqi = 0 ; //MGR + /* init cube vars */ + spirit_on = OFF; + last_rssi = 0 ; //MGR + last_sqi = 0 ; //MGR - /* set frequencies */ - radio_set_xtal_freq(XTAL_FREQUENCY); - mgmt_set_freq_base((uint32_t)BASE_FREQUENCY); + /* set frequencies */ + radio_set_xtal_freq(XTAL_FREQUENCY); + mgmt_set_freq_base((uint32_t)BASE_FREQUENCY); - /* restart board */ - enter_shutdown(); - exit_shutdown(); + /* restart board */ + enter_shutdown(); + exit_shutdown(); - /* soft core reset */ - cmd_strobe(SPIRIT1_STROBE_SRES); + /* soft core reset */ + cmd_strobe(SPIRIT1_STROBE_SRES); - /* Configures the SPIRIT1 radio part */ - SRadioInit x_radio_init = { - XTAL_OFFSET_PPM, - (uint32_t)BASE_FREQUENCY, - (uint32_t)CHANNEL_SPACE, - CHANNEL_NUMBER, - MODULATION_SELECT, - DATARATE, - (uint32_t)FREQ_DEVIATION, - (uint32_t)BANDWIDTH - }; - radio_init(&x_radio_init); - radio_set_pa_level_dbm(0,POWER_DBM); - radio_set_pa_level_max_index(0); + /* Configures the SPIRIT1 radio part */ + SRadioInit x_radio_init = { + XTAL_OFFSET_PPM, + (uint32_t)BASE_FREQUENCY, + (uint32_t)CHANNEL_SPACE, + CHANNEL_NUMBER, + MODULATION_SELECT, + DATARATE, + (uint32_t)FREQ_DEVIATION, + (uint32_t)BANDWIDTH + }; + radio_init(&x_radio_init); + radio_set_pa_level_dbm(0,POWER_DBM); + radio_set_pa_level_max_index(0); - /* Configures the SPIRIT1 packet handler part*/ - PktBasicInit x_basic_init = { - PREAMBLE_LENGTH, - SYNC_LENGTH, - SYNC_WORD, - LENGTH_TYPE, - LENGTH_WIDTH, - CRC_MODE, - CONTROL_LENGTH, - EN_ADDRESS, - EN_FEC, - EN_WHITENING - }; - pkt_basic_init(&x_basic_init); + /* Configures the SPIRIT1 packet handler part*/ + PktBasicInit x_basic_init = { + PREAMBLE_LENGTH, + SYNC_LENGTH, + SYNC_WORD, + LENGTH_TYPE, + LENGTH_WIDTH, + CRC_MODE, + CONTROL_LENGTH, + EN_ADDRESS, + EN_FEC, + EN_WHITENING + }; + pkt_basic_init(&x_basic_init); - /* Enable the following interrupt sources, routed to GPIO */ - irq_de_init(NULL); - irq_clear_status(); - irq_set_status(TX_DATA_SENT, S_ENABLE); - irq_set_status(RX_DATA_READY,S_ENABLE); - irq_set_status(RX_DATA_DISC, S_ENABLE); - irq_set_status(VALID_SYNC, S_ENABLE); - irq_set_status(TX_FIFO_ERROR, S_ENABLE); - irq_set_status(RX_FIFO_ERROR, S_ENABLE); + /* Enable the following interrupt sources, routed to GPIO */ + irq_de_init(NULL); + irq_clear_status(); + irq_set_status(TX_DATA_SENT, S_ENABLE); + irq_set_status(RX_DATA_READY,S_ENABLE); + irq_set_status(RX_DATA_DISC, S_ENABLE); + irq_set_status(VALID_SYNC, S_ENABLE); + irq_set_status(TX_FIFO_ERROR, S_ENABLE); + irq_set_status(RX_FIFO_ERROR, S_ENABLE); #ifndef RX_FIFO_THR_WA - irq_set_status(TX_FIFO_ALMOST_EMPTY, S_ENABLE); - irq_set_status(RX_FIFO_ALMOST_FULL, S_ENABLE); + irq_set_status(TX_FIFO_ALMOST_EMPTY, S_ENABLE); + irq_set_status(RX_FIFO_ALMOST_FULL, S_ENABLE); #endif // !RX_FIFO_THR_WA - /* Configure Spirit1 */ - radio_persistent_rx(S_ENABLE); - qi_set_sqi_threshold(SQI_TH_0); - qi_sqi_check(S_ENABLE); - qi_set_rssi_threshold_dbm(CCA_THRESHOLD); - timer_set_rx_timeout_stop_condition(SQI_ABOVE_THRESHOLD); - timer_set_infinite_rx_timeout(); - radio_afc_freeze_on_sync(S_ENABLE); - calibration_rco(S_ENABLE); + /* Configure Spirit1 */ + radio_persistent_rx(S_ENABLE); + qi_set_sqi_threshold(SQI_TH_0); + qi_sqi_check(S_ENABLE); + qi_set_rssi_threshold_dbm(CCA_THRESHOLD); + timer_set_rx_timeout_stop_condition(SQI_ABOVE_THRESHOLD); + timer_set_infinite_rx_timeout(); + radio_afc_freeze_on_sync(S_ENABLE); + calibration_rco(S_ENABLE); - spirit_on = OFF; - CLEAR_TXBUF(); - CLEAR_RXBUF(); - _spirit_tx_started = false; - _is_receiving = false; + spirit_on = OFF; + CLEAR_TXBUF(); + CLEAR_RXBUF(); + _spirit_tx_started = false; + _is_receiving = false; - /* Configure the radio to route the IRQ signal to its GPIO 3 */ - SGpioInit x_gpio_init = { - SPIRIT_GPIO_IRQ, - SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP, - SPIRIT_GPIO_DIG_OUT_IRQ - }; - spirit_gpio_init(&x_gpio_init); + /* Configure the radio to route the IRQ signal to its GPIO 3 */ + SGpioInit x_gpio_init = { + SPIRIT_GPIO_IRQ, + SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP, + SPIRIT_GPIO_DIG_OUT_IRQ + }; + spirit_gpio_init(&x_gpio_init); - /* Setup CSMA/CA */ - CsmaInit x_csma_init = { - S_ENABLE, // enable persistent mode - TBIT_TIME_64, // Tcca time - TCCA_TIME_3, // Lcca length - 5, // max nr of backoffs (<8) - 1, // BU counter seed - 8 // BU prescaler - }; - csma_ca_init(&x_csma_init); + /* Setup CSMA/CA */ + CsmaInit x_csma_init = { + S_ENABLE, // enable persistent mode + TBIT_TIME_64, // Tcca time + TCCA_TIME_3, // Lcca length + 5, // max nr of backoffs (<8) + 1, // BU counter seed + 8 // BU prescaler + }; + csma_ca_init(&x_csma_init); #ifdef USE_STANDBY_STATE - /* Puts the SPIRIT1 in STANDBY mode (125us -> rx/tx) */ - cmd_strobe(SPIRIT1_STROBE_STANDBY); + /* Puts the SPIRIT1 in STANDBY mode (125us -> rx/tx) */ + cmd_strobe(SPIRIT1_STROBE_STANDBY); #endif // USE_STANDBY_STATE } -static volatile int tx_fifo_remaining = 0; // to be used in irq handler -static volatile int tx_buffer_pos = 0; // to be used in irq handler -const volatile uint8_t *tx_fifo_buffer = NULL; // to be used in irq handler +static volatile int tx_fifo_remaining = 0; // to be used in irq handler +static volatile int tx_buffer_pos = 0; // to be used in irq handler +static const volatile uint8_t *tx_fifo_buffer = NULL; // to be used in irq handler int SimpleSpirit1::send(const void *payload, unsigned int payload_len, bool use_csma_ca) { - /* Checks if the payload length is supported */ - if(payload_len > MAX_PACKET_LEN) { - return RADIO_TX_ERR; - } + /* Checks if the payload length is supported */ + if(payload_len > MAX_PACKET_LEN) { + return RADIO_TX_ERR; + } - disable_spirit_irq(); + disable_spirit_irq(); - BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT); + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT); #ifndef NDEBUG - if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) { - debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1); - } + if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) { + debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1); + } #endif - /* Reset State to Ready */ - set_ready_state(); + /* Reset State to Ready */ + set_ready_state(); - cmd_strobe(SPIRIT1_STROBE_FTX); // flush TX FIFO buffer + cmd_strobe(SPIRIT1_STROBE_FTX); // flush TX FIFO buffer #ifndef NDEBUG - debug_if(!(linear_fifo_read_num_elements_tx_fifo() == 0), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); + debug_if(!(linear_fifo_read_num_elements_tx_fifo() == 0), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); #endif - pkt_basic_set_payload_length(payload_len); // set desired payload len + pkt_basic_set_payload_length(payload_len); // set desired payload len - if(use_csma_ca) { - csma_ca_state(S_ENABLE); // enable CSMA/CA - } + if(use_csma_ca) { + csma_ca_state(S_ENABLE); // enable CSMA/CA + } - /* Init buffer & number of bytes to be send */ - tx_fifo_remaining = payload_len; - tx_fifo_buffer = (const uint8_t*)payload; + /* Init buffer & number of bytes to be send */ + tx_fifo_remaining = payload_len; + tx_fifo_buffer = (const uint8_t*)payload; - int8_t fifo_available = SPIRIT_MAX_FIFO_LEN; // fill-up whole fifo - int8_t to_send = (tx_fifo_remaining > fifo_available) ? fifo_available : tx_fifo_remaining; + int8_t fifo_available = SPIRIT_MAX_FIFO_LEN; // fill-up whole fifo + int8_t to_send = (tx_fifo_remaining > fifo_available) ? fifo_available : tx_fifo_remaining; - tx_fifo_remaining -= to_send; + tx_fifo_remaining -= to_send; - /* Fill FIFO Buffer */ - if(to_send > 0) { - spi_write_linear_fifo(to_send, (uint8_t*)&tx_fifo_buffer[0]); - } + /* Fill FIFO Buffer */ + if(to_send > 0) { + spi_write_linear_fifo(to_send, (uint8_t*)&tx_fifo_buffer[0]); + } - tx_buffer_pos = to_send; - _spirit_tx_started = true; + tx_buffer_pos = to_send; + _spirit_tx_started = true; - enable_spirit_irq(); + enable_spirit_irq(); - /* Start transmitting */ - cmd_strobe(SPIRIT1_STROBE_TX); + /* Start transmitting */ + cmd_strobe(SPIRIT1_STROBE_TX); - while(tx_fifo_remaining != 0); // wait until not everything is yet send (evtl. by irq handler) + while(tx_fifo_remaining != 0); // wait until not everything is yet send (evtl. by irq handler) - BUSYWAIT_UNTIL(!_spirit_tx_started, STATE_TIMEOUT); + BUSYWAIT_UNTIL(!_spirit_tx_started, STATE_TIMEOUT); #ifdef HEAVY_DEBUG - debug("\r\n%s (%d): state=%x, _spirit_tx_started=%d\r\n", __func__, __LINE__, SPIRIT1_STATUS()>>1, _spirit_tx_started); + debug("\r\n%s (%d): state=%x, _spirit_tx_started=%d\r\n", __func__, __LINE__, SPIRIT1_STATUS()>>1, _spirit_tx_started); #endif if(use_csma_ca) { csma_ca_state(S_DISABLE); // disable CSMA/CA } - cmd_strobe(SPIRIT1_STROBE_RX); // Return to RX state + cmd_strobe(SPIRIT1_STROBE_RX); // Return to RX state - if(_spirit_tx_started) { // in case of state timeout - _spirit_tx_started = false; - return RADIO_TX_ERR; - } else { - return RADIO_TX_OK; - } + disable_spirit_irq(); + if(_spirit_tx_started) { // in case of state timeout + _spirit_tx_started = false; + enable_spirit_irq(); + return RADIO_TX_ERR; + } else { + enable_spirit_irq(); + return RADIO_TX_OK; + } } /** Set Ready State **/ void SimpleSpirit1::set_ready_state(void) { - uint16_t state; + uint16_t state; - disable_spirit_irq(); + disable_spirit_irq(); - _spirit_tx_started = false; - _is_receiving = false; - stop_rx_timeout(); + _spirit_tx_started = false; + _is_receiving = false; + stop_rx_timeout(); - cmd_strobe(SPIRIT1_STROBE_FRX); - CLEAR_RXBUF(); - CLEAR_TXBUF(); + cmd_strobe(SPIRIT1_STROBE_FRX); + CLEAR_RXBUF(); + CLEAR_TXBUF(); - state = SPIRIT1_STATUS(); - if(state == SPIRIT1_STATE_STANDBY) { - cmd_strobe(SPIRIT1_STROBE_READY); - } else if(state == SPIRIT1_STATE_RX) { - cmd_strobe(SPIRIT1_STROBE_SABORT); - } else if(state != SPIRIT1_STATE_READY) { + state = SPIRIT1_STATUS(); + if(state == SPIRIT1_STATE_STANDBY) { + cmd_strobe(SPIRIT1_STROBE_READY); + } else if(state == SPIRIT1_STATE_RX) { + cmd_strobe(SPIRIT1_STROBE_SABORT); + } else if(state != SPIRIT1_STATE_READY) { #ifndef NDEBUG - debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, state>>1); + debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, state>>1); #endif - } + } - BUSYWAIT_UNTIL((SPIRIT1_STATUS() == SPIRIT1_STATE_READY) && ((last_state & XO_ON) == XO_ON), STATE_TIMEOUT); - if(last_state != (SPIRIT1_STATE_READY | XO_ON)) { - error("\r\nSpirit1: failed to become ready (%x) => pls. reset!\r\n", last_state); - enable_spirit_irq(); - return; - } + BUSYWAIT_UNTIL((SPIRIT1_STATUS() == SPIRIT1_STATE_READY) && ((last_state & XO_ON) == XO_ON), STATE_TIMEOUT); + if(last_state != (SPIRIT1_STATE_READY | XO_ON)) { + error("\r\nSpirit1: failed to become ready (%x) => pls. reset!\r\n", last_state); + enable_spirit_irq(); + return; + } - irq_clear_status(); + irq_clear_status(); - enable_spirit_irq(); + enable_spirit_irq(); } int SimpleSpirit1::off(void) { - if(spirit_on == ON) { - /* Disables the mcu to get IRQ from the SPIRIT1 */ - disable_spirit_irq(); + if(spirit_on == ON) { + /* Disables the mcu to get IRQ from the SPIRIT1 */ + disable_spirit_irq(); - /* first stop rx/tx */ - set_ready_state(); + /* first stop rx/tx */ + set_ready_state(); #ifdef USE_STANDBY_STATE - /* Puts the SPIRIT1 in STANDBY */ - cmd_strobe(SPIRIT1_STROBE_STANDBY); - BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, STATE_TIMEOUT); - if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_STANDBY) { - error("\r\nSpirit1: failed to enter standby (%x)\r\n", last_state>>1); - return 1; - } + /* Puts the SPIRIT1 in STANDBY */ + cmd_strobe(SPIRIT1_STROBE_STANDBY); + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, STATE_TIMEOUT); + if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_STANDBY) { + error("\r\nSpirit1: failed to enter standby (%x)\r\n", last_state>>1); + return 1; + } #endif // USE_STANDBY_STATE - spirit_on = OFF; - _nr_of_irq_disables = 1; - } - return 0; + spirit_on = OFF; + _nr_of_irq_disables = 1; + } + return 0; } int SimpleSpirit1::on(void) { - if(spirit_on == OFF) { - set_ready_state(); + if(spirit_on == OFF) { + set_ready_state(); - /* now we go to Rx */ - cmd_strobe(SPIRIT1_STROBE_RX); + /* now we go to Rx */ + cmd_strobe(SPIRIT1_STROBE_RX); - BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT); - if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) { - error("\r\nSpirit1: failed to enter rx (%x) => retry\r\n", last_state>>1); - } + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT); + if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) { + error("\r\nSpirit1: failed to enter rx (%x) => retry\r\n", last_state>>1); + } - /* Enables the mcu to get IRQ from the SPIRIT1 */ - spirit_on = ON; + /* Enables the mcu to get IRQ from the SPIRIT1 */ + spirit_on = ON; #ifndef NDEBUG - debug_if(!(_nr_of_irq_disables == 1), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); + debug_if(!(_nr_of_irq_disables == 1), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); #endif - enable_spirit_irq(); - } + enable_spirit_irq(); + } #ifndef NDEBUG - if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) { - debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1); - } + if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) { + debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1); + } #endif - return 0; + return 0; } uint8_t SimpleSpirit1::refresh_state(void) { - uint8_t mcstate; + uint8_t mcstate; - SpiritSpiReadRegisters(MC_STATE0_BASE, 1, &mcstate); + SpiritSpiReadRegisters(MC_STATE0_BASE, 1, &mcstate); - return mcstate; + return mcstate; } int SimpleSpirit1::read(void *buf, unsigned int bufsize) { - disable_spirit_irq(); + disable_spirit_irq(); - /* Checks if the RX buffer is empty */ - if(IS_RXBUF_EMPTY()) { + /* Checks if the RX buffer is empty */ + if(IS_RXBUF_EMPTY()) { #ifndef NDEBUG - debug("\r\nBuffer is empty\r\n"); + debug("\r\nBuffer is empty\r\n"); #endif - set_ready_state(); + set_ready_state(); - cmd_strobe(SPIRIT1_STROBE_RX); - BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT); - enable_spirit_irq(); - return 0; - } + cmd_strobe(SPIRIT1_STROBE_RX); + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT); + enable_spirit_irq(); + return 0; + } - if(bufsize < spirit_rx_len) { - enable_spirit_irq(); + if(bufsize < spirit_rx_len) { + enable_spirit_irq(); - /* If buf has the correct size */ + /* If buf has the correct size */ #ifndef NDEBUG - debug("\r\nTOO SMALL BUF\r\n"); + debug("\r\nTOO SMALL BUF\r\n"); #endif - return 0; - } else { - /* Copies the packet received */ - memcpy(buf, spirit_rx_buf, spirit_rx_len); + return 0; + } else { + /* Copies the packet received */ + memcpy(buf, spirit_rx_buf, spirit_rx_len); - bufsize = spirit_rx_len; - CLEAR_RXBUF(); + bufsize = spirit_rx_len; + CLEAR_RXBUF(); - enable_spirit_irq(); + enable_spirit_irq(); - return bufsize; - } + return bufsize; + } } int SimpleSpirit1::channel_clear(void) { - float rssi_value; - /* Local variable used to memorize the SPIRIT1 state */ - uint8_t spirit_state = ON; + float rssi_value; + /* Local variable used to memorize the SPIRIT1 state */ + uint8_t spirit_state = ON; - if(spirit_on == OFF) { - /* Wakes up the SPIRIT1 */ - on(); - spirit_state = OFF; - } + if(spirit_on == OFF) { + /* Wakes up the SPIRIT1 */ + on(); + spirit_state = OFF; + } #ifndef NDEBUG - if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) { - debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1); - } + if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) { + debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1); + } #endif - disable_spirit_irq(); + disable_spirit_irq(); - /* Reset State to Ready */ - set_ready_state(); + /* Reset State to Ready */ + set_ready_state(); - /* Stores the RSSI value */ - rssi_value = qi_get_rssi_dbm(); + /* Stores the RSSI value */ + rssi_value = qi_get_rssi_dbm(); - enable_spirit_irq(); + enable_spirit_irq(); - /* Puts the SPIRIT1 in its previous state */ - if(spirit_state==OFF) { - off(); + /* Puts the SPIRIT1 in its previous state */ + if(spirit_state==OFF) { + off(); #ifndef NDEBUG #ifdef USE_STANDBY_STATE - if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) { + if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) { #else - if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) { + if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) { #endif - debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1); - } + debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1); + } #endif - } else { - disable_spirit_irq(); + } else { + disable_spirit_irq(); - set_ready_state(); + set_ready_state(); - cmd_strobe(SPIRIT1_STROBE_RX); - BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT); - if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) { - error("\r\nSpirit1: (#2) failed to enter rx (%x) => retry\r\n", last_state>>1); - } + cmd_strobe(SPIRIT1_STROBE_RX); + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT); + if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) { + error("\r\nSpirit1: (#2) failed to enter rx (%x) => retry\r\n", last_state>>1); + } - enable_spirit_irq(); + enable_spirit_irq(); #ifndef NDEBUG - if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) { - debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1); - } + if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) { + debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1); + } #endif - } + } - /* Checks the RSSI value with the threshold */ - if(rssi_value<CCA_THRESHOLD) { - return 0; - } else { - return 1; - } -} + /* Checks the RSSI value with the threshold */ + if(rssi_value<CCA_THRESHOLD) { + return 0; + } else { + return 1; + } + } -int SimpleSpirit1::get_pending_packet(void) -{ - return !IS_RXBUF_EMPTY(); -} + int SimpleSpirit1::get_pending_packet(void) + { + return !IS_RXBUF_EMPTY(); + } -/** Spirit Irq Callback **/ -/* betzw - TODO: use threaded interrupt handling when `MBED_CONF_RTOS_PRESENT` is defined (see `atmel-rf-driver`) */ -void SimpleSpirit1::IrqHandler() { - st_lib_spirit_irqs x_irq_status; + /** Spirit Irq Callback **/ + /* betzw - TODO: use threaded interrupt handling when `MBED_CONF_RTOS_PRESENT` is defined (see `atmel-rf-driver`) */ + void SimpleSpirit1::IrqHandler() { + st_lib_spirit_irqs x_irq_status; - /* get interrupt source from radio */ - irq_get_status(&x_irq_status); + /* get interrupt source from radio */ + irq_get_status(&x_irq_status); - /* The IRQ_TX_DATA_SENT notifies the packet has been sent. Puts the SPIRIT1 in RX */ - if(x_irq_status.IRQ_TX_DATA_SENT) { /* betzw - NOTE: MUST be handled before `IRQ_RX_DATA_READY` for Nanostack integration! + /* The IRQ_TX_DATA_SENT notifies the packet has been sent. Puts the SPIRIT1 in RX */ + if(x_irq_status.IRQ_TX_DATA_SENT) { /* betzw - NOTE: MUST be handled before `IRQ_RX_DATA_READY` for Nanostack integration! Logically, Nanostack only expects the "DONE" after "SUCCESS" (if it gets DONE before SUCCESS, it assumes you're not going to bother to send SUCCESS). - */ + */ #ifdef DEBUG_IRQ - uint32_t *tmp = (uint32_t*)&x_irq_status; - debug_if(!_spirit_tx_started, "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); - debug_if(!((*tmp) & IRQ_TX_DATA_SENT_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); - debug_if(tx_fifo_remaining != 0, "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); + uint32_t *tmp = (uint32_t*)&x_irq_status; + debug_if(!((*tmp) & IRQ_TX_DATA_SENT_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); + debug_if(tx_fifo_remaining != 0, "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); #endif - tx_fifo_buffer = NULL; - _spirit_tx_started = false; + if(_spirit_tx_started) { + _spirit_tx_started = false; - /* call user callback */ - if(_current_irq_callback) { - _current_irq_callback(TX_DONE); - } + /* call user callback */ + if(_current_irq_callback) { + _current_irq_callback(TX_DONE); + } + } - /* Disable handling of other TX flags */ - x_irq_status.IRQ_TX_FIFO_ALMOST_EMPTY = S_RESET; - } + /* Disable handling of other TX flags */ + x_irq_status.IRQ_TX_FIFO_ALMOST_EMPTY = S_RESET; + tx_fifo_buffer = NULL; + } #ifndef RX_FIFO_THR_WA - /* The IRQ_TX_FIFO_ALMOST_EMPTY notifies an nearly empty TX fifo */ - if(x_irq_status.IRQ_TX_FIFO_ALMOST_EMPTY) { + /* The IRQ_TX_FIFO_ALMOST_EMPTY notifies an nearly empty TX fifo */ + if(x_irq_status.IRQ_TX_FIFO_ALMOST_EMPTY) { #ifdef DEBUG_IRQ - uint32_t *tmp = (uint32_t*)&x_irq_status; - debug_if(!((*tmp) & IRQ_TX_FIFO_ALMOST_EMPTY_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); - debug_if(!_spirit_tx_started, "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); - debug_if(tx_fifo_buffer == NULL, "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); + uint32_t *tmp = (uint32_t*)&x_irq_status; + debug_if(!((*tmp) & IRQ_TX_FIFO_ALMOST_EMPTY_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); + debug_if(!_spirit_tx_started, "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); + debug_if(tx_fifo_buffer == NULL, "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); #endif - int8_t fifo_available = SPIRIT_MAX_FIFO_LEN/2; // fill-up half fifo - int8_t to_send = (tx_fifo_remaining > fifo_available) ? fifo_available : tx_fifo_remaining; + int8_t fifo_available = SPIRIT_MAX_FIFO_LEN/2; // fill-up half fifo + int8_t to_send = (tx_fifo_remaining > fifo_available) ? fifo_available : tx_fifo_remaining; - tx_fifo_remaining -= to_send; + tx_fifo_remaining -= to_send; - /* Fill FIFO Buffer */ - if(to_send > 0) { - spi_write_linear_fifo(to_send, (uint8_t*)&tx_fifo_buffer[tx_buffer_pos]); - } - tx_buffer_pos += to_send; - } + /* Fill FIFO Buffer */ + if(to_send > 0) { + spi_write_linear_fifo(to_send, (uint8_t*)&tx_fifo_buffer[tx_buffer_pos]); + } + tx_buffer_pos += to_send; + } #endif // !RX_FIFO_THR_WA - /* TX FIFO underflow/overflow error */ - if(x_irq_status.IRQ_TX_FIFO_ERROR) { + /* TX FIFO underflow/overflow error */ + if(x_irq_status.IRQ_TX_FIFO_ERROR) { #ifdef DEBUG_IRQ - uint32_t *tmp = (uint32_t*)&x_irq_status; - debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp); - debug_if(!((*tmp) & IRQ_TX_FIFO_ERROR_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); + uint32_t *tmp = (uint32_t*)&x_irq_status; + debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp); + debug_if(!((*tmp) & IRQ_TX_FIFO_ERROR_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); #endif - if(_spirit_tx_started) { - _spirit_tx_started = false; - /* call user callback */ - if(_current_irq_callback) { - _current_irq_callback(TX_ERR); - } - } + if(_spirit_tx_started) { + _spirit_tx_started = false; + /* call user callback */ + if(_current_irq_callback) { + _current_irq_callback(TX_ERR); + } + } - /* reset data still to be sent */ - tx_fifo_remaining = 0; - } + /* reset data still to be sent */ + tx_fifo_remaining = 0; + } - /* The IRQ_RX_DATA_READY notifies a new packet arrived */ - if(x_irq_status.IRQ_RX_DATA_READY) { + /* The IRQ_RX_DATA_READY notifies a new packet arrived */ + if(x_irq_status.IRQ_RX_DATA_READY) { #ifdef DEBUG_IRQ - uint32_t *tmp = (uint32_t*)&x_irq_status; - debug_if(!((*tmp) & IRQ_RX_DATA_READY_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); + uint32_t *tmp = (uint32_t*)&x_irq_status; + debug_if(!((*tmp) & IRQ_RX_DATA_READY_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); #endif - if(!_is_receiving) { // spurious irq?!? (betzw: see comments on macro 'RX_FIFO_THR_WA'!) + if(!_is_receiving) { // spurious irq?!? (betzw: see comments on macro 'RX_FIFO_THR_WA'!) #ifdef HEAVY_DEBUG - debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp); + debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp); #endif - } else { - _is_receiving = false; // Finished receiving - stop_rx_timeout(); + } else { + _is_receiving = false; // Finished receiving + stop_rx_timeout(); - spirit_rx_len = pkt_basic_get_received_pkt_length(); + spirit_rx_len = pkt_basic_get_received_pkt_length(); #ifdef DEBUG_IRQ - debug_if(!(spirit_rx_len <= MAX_PACKET_LEN), "\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp); + debug_if(!(spirit_rx_len <= MAX_PACKET_LEN), "\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp); #endif - if(spirit_rx_len <= MAX_PACKET_LEN) { - uint8_t to_receive = spirit_rx_len - _spirit_rx_pos; - if(to_receive > 0) { - spi_read_linear_fifo(to_receive, &spirit_rx_buf[_spirit_rx_pos]); - _spirit_rx_pos += to_receive; - } - } + if(spirit_rx_len <= MAX_PACKET_LEN) { + uint8_t to_receive = spirit_rx_len - _spirit_rx_pos; + if(to_receive > 0) { + spi_read_linear_fifo(to_receive, &spirit_rx_buf[_spirit_rx_pos]); + _spirit_rx_pos += to_receive; + } + } - cmd_strobe(SPIRIT1_STROBE_FRX); + cmd_strobe(SPIRIT1_STROBE_FRX); - last_rssi = qi_get_rssi(); //MGR - last_sqi = qi_get_sqi(); //MGR + last_rssi = qi_get_rssi(); //MGR + last_sqi = qi_get_sqi(); //MGR - /* call user callback */ - if((_spirit_rx_pos == spirit_rx_len) && _current_irq_callback) { - _current_irq_callback(RX_DONE); - } + /* call user callback */ + if((_spirit_rx_pos == spirit_rx_len) && _current_irq_callback) { + _current_irq_callback(RX_DONE); + } - /* Disable handling of other RX flags */ - x_irq_status.IRQ_RX_FIFO_ALMOST_FULL = S_RESET; - } - } + /* Disable handling of other RX flags */ + x_irq_status.IRQ_RX_FIFO_ALMOST_FULL = S_RESET; + } + } #ifndef RX_FIFO_THR_WA - /* RX FIFO almost full */ - if(x_irq_status.IRQ_RX_FIFO_ALMOST_FULL) { + /* RX FIFO almost full */ + if(x_irq_status.IRQ_RX_FIFO_ALMOST_FULL) { #ifdef DEBUG_IRQ - uint32_t *tmp = (uint32_t*)&x_irq_status; - debug_if(!((*tmp) & IRQ_RX_FIFO_ALMOST_FULL_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); + uint32_t *tmp = (uint32_t*)&x_irq_status; + debug_if(!((*tmp) & IRQ_RX_FIFO_ALMOST_FULL_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); #endif - if(!_is_receiving) { // spurious irq?!? + if(!_is_receiving) { // spurious irq?!? #ifdef DEBUG_IRQ - debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp); + debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp); #endif - } else { - uint8_t fifo_available = linear_fifo_read_num_elements_rx_fifo(); - if((fifo_available + _spirit_rx_pos) <= MAX_PACKET_LEN) { - spi_read_linear_fifo(fifo_available, &spirit_rx_buf[_spirit_rx_pos]); - _spirit_rx_pos += fifo_available; - } else { + } else { + uint8_t fifo_available = linear_fifo_read_num_elements_rx_fifo(); + if((fifo_available + _spirit_rx_pos) <= MAX_PACKET_LEN) { + spi_read_linear_fifo(fifo_available, &spirit_rx_buf[_spirit_rx_pos]); + _spirit_rx_pos += fifo_available; + } else { #ifdef DEBUG_IRQ - debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp); + debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp); #endif - } - } - } + } + } + } #endif // !RX_FIFO_THR_WA - /* Reception errors */ - if((x_irq_status.IRQ_RX_FIFO_ERROR) || (x_irq_status.IRQ_RX_DATA_DISC)) { + /* Reception errors */ + if((x_irq_status.IRQ_RX_FIFO_ERROR) || (x_irq_status.IRQ_RX_DATA_DISC)) { #ifdef DEBUG_IRQ - uint32_t *tmp = (uint32_t*)&x_irq_status; - debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp); - debug_if(!((*tmp) & (IRQ_RX_FIFO_ERROR_MASK | IRQ_RX_DATA_DISC_MASK)), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); + uint32_t *tmp = (uint32_t*)&x_irq_status; + debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp); + debug_if(!((*tmp) & (IRQ_RX_FIFO_ERROR_MASK | IRQ_RX_DATA_DISC_MASK)), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); #endif - rx_timeout_handler(); - if(_spirit_tx_started) { - _spirit_tx_started = false; - /* call user callback */ - if(_current_irq_callback) { - _current_irq_callback(TX_ERR); - } - } - } + rx_timeout_handler(); + if(_spirit_tx_started) { + _spirit_tx_started = false; + /* call user callback */ + if(_current_irq_callback) { + _current_irq_callback(TX_ERR); + } + } + } - /* The IRQ_VALID_SYNC is used to notify a new packet is coming */ - if(x_irq_status.IRQ_VALID_SYNC) { + /* The IRQ_VALID_SYNC is used to notify a new packet is coming */ + if(x_irq_status.IRQ_VALID_SYNC) { #ifdef DEBUG_IRQ - uint32_t *tmp = (uint32_t*)&x_irq_status; - debug_if(!((*tmp) & IRQ_VALID_SYNC_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); + uint32_t *tmp = (uint32_t*)&x_irq_status; + debug_if(!((*tmp) & IRQ_VALID_SYNC_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__); #endif - /* betzw - NOTE: there is a race condition between Spirit1 receiving packets and - * the MCU trying to send a packet, which gets resolved in favor of - * sending. - */ - if(_spirit_tx_started) { + /* betzw - NOTE: there is a race condition between Spirit1 receiving packets and + * the MCU trying to send a packet, which gets resolved in favor of + * sending. + */ + if(_spirit_tx_started) { #ifdef DEBUG_IRQ - debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp); + debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp); #endif - } else { - _is_receiving = true; - start_rx_timeout(); - } - } -} + } else { + _is_receiving = true; + start_rx_timeout(); + } + } + }