Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Prototype RF Driver for STM Sub-1 GHz RF Expansion Boards based on the SPSGRF-868 and SPSGRF-915 Modules for STM32 Nucleo
Currently supported boards:
Note, in order to use expansion board X-NUCLEO-IDS01A4 in mbed you need to perform the following HW modifications on the board:
- Unmount resistor
R4 - Mount resistor
R7
Furthermore, on some Nucleo development boards (e.g. the NUCLEO_F429ZI), in order to be able to use Ethernet together with these Sub-1 GHz RF expansion boards, you need to compile this driver with macro SPIRIT1_SPI_MOSI=PB_5 defined, while the development board typically requires some HW modification as e.g. described here!
This driver can be used together with the 6LoWPAN stack (a.k.a. Nanostack).
Diff: SimpleSpirit1.cpp
- Revision:
- 16:25dc4b811ad3
- Parent:
- 15:852b92eed64a
- Child:
- 18:d6f789f6f4c9
--- a/SimpleSpirit1.cpp Fri Nov 04 17:12:06 2016 +0100
+++ b/SimpleSpirit1.cpp Mon Nov 07 08:38:38 2016 +0100
@@ -24,10 +24,10 @@
#define SABORT_WAIT_US (400)
#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)
extern volatile SpiritStatus g_xStatus;
#define st_lib_g_x_status (g_xStatus)
@@ -41,126 +41,121 @@
/** 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 */
+ /* reset irq disable counter and irq callback & disable irq */
_nr_of_irq_disables = 0;
- disable_spirit_irq();
+ 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(5000000); // 5MHz
+ /* configure spi */
+ _spi.format(8, 0); /* 8-bit, mode = 0, [order = SPI_MSB] only available in mbed3 */
+ _spi.frequency(5000000); // 5MHz
- /* 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;
+ /* init cube vars */
+ spirit_on = OFF;
#ifdef CONTIKI // betzw - TODO
- packet_is_prepared = 0;
- just_got_an_ack = 0;
+ packet_is_prepared = 0;
+ just_got_an_ack = 0;
#endif // CONTIKI
- last_rssi = 0 ; //MGR
- last_lqi = 0 ; //MGR
+ last_rssi = 0 ; //MGR
+ last_lqi = 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);
-
- printf("SpiritLinearFifoSetAlmostFullThresholdRx(6): ");
- SpiritLinearFifoSetAlmostFullThresholdRx(6);
+ /* 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(TX_FIFO_ERROR, S_ENABLE);
- irq_set_status(RX_FIFO_ERROR, S_ENABLE);
- irq_set_status(RX_FIFO_ALMOST_FULL, S_ENABLE);
- irq_set_status(VALID_SYNC, 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(TX_FIFO_ERROR, S_ENABLE);
+ irq_set_status(RX_FIFO_ERROR, S_ENABLE);
+ irq_set_status(RX_FIFO_ALMOST_FULL, S_ENABLE);
+ irq_set_status(VALID_SYNC, S_ENABLE);
- /* Configure Spirit1 */
- radio_persisten_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);
+ /* Configure Spirit1 */
+ radio_persisten_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);
- /* Puts the SPIRIT1 in STANDBY mode (125us -> rx/tx) */
- cmd_strobe(SPIRIT1_STROBE_STANDBY);
- spirit_on = OFF;
- CLEAR_TXBUF();
- CLEAR_RXBUF();
- _spirit_tx_started = false;
- _spirit_rx_err = false;
- _is_receiving = false;
+ /* Puts the SPIRIT1 in STANDBY mode (125us -> rx/tx) */
+ cmd_strobe(SPIRIT1_STROBE_STANDBY);
+ spirit_on = OFF;
+ CLEAR_TXBUF();
+ CLEAR_RXBUF();
+ _spirit_tx_started = false;
+ _spirit_rx_err = 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);
-
- printf("%d\n", SpiritLinearFifoGetAlmostFullThresholdRx());
+ /* 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);
}
#ifdef CONTIKI // betzw - TODO
@@ -233,7 +228,7 @@
wait_us(SABORT_WAIT_US);
cmd_strobe(SPIRIT1_STROBE_READY);
BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 1);
- cmd_strobe(SPIRIT1_STROBE_FRX);
+ cmd_strobe(SPIRIT1_STROBE_FRX);
cmd_strobe(SPIRIT1_STROBE_RX);
BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1);
enable_spirit_irq();
@@ -319,396 +314,379 @@
/** Set Ready State **/
void SimpleSpirit1::set_ready_state(void) {
- PRINTF("READY IN\n");
+ PRINTF("READY IN\n");
- disable_spirit_irq();
+ disable_spirit_irq();
- _is_receiving = false;
- stop_rx_timeout();
+ _is_receiving = false;
+ stop_rx_timeout();
- if(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY) {
- cmd_strobe(SPIRIT1_STROBE_READY);
- } else if(SPIRIT1_STATUS() == SPIRIT1_STATE_RX) {
- cmd_strobe(SPIRIT1_STROBE_SABORT);
- }
- irq_clear_status();
+ if(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY) {
+ cmd_strobe(SPIRIT1_STROBE_READY);
+ } else if(SPIRIT1_STATUS() == SPIRIT1_STATE_RX) {
+ cmd_strobe(SPIRIT1_STROBE_SABORT);
+ }
+ irq_clear_status();
- enable_spirit_irq();
+ enable_spirit_irq();
- PRINTF("READY OUT\n");
+ PRINTF("READY OUT\n");
}
int SimpleSpirit1::off(void) {
- PRINTF("Spirit1: ->off\n");
- if(spirit_on == ON) {
- /* Disables the mcu to get IRQ from the SPIRIT1 */
- disable_spirit_irq();
+ PRINTF("Spirit1: ->off\n");
+ if(spirit_on == ON) {
+ /* Disables the mcu to get IRQ from the SPIRIT1 */
+ disable_spirit_irq();
- /* first stop rx/tx */
- cmd_strobe(SPIRIT1_STROBE_SABORT);
+ /* first stop rx/tx */
+ cmd_strobe(SPIRIT1_STROBE_SABORT);
- /* Clear any pending irqs */
- irq_clear_status();
+ /* Clear any pending irqs */
+ irq_clear_status();
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 5);
- if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
- PRINTF("Spirit1: failed off->ready\n");
- return 1;
- }
+ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 5);
+ if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
+ PRINTF("Spirit1: failed off->ready\n");
+ return 1;
+ }
- /* Puts the SPIRIT1 in STANDBY */
- cmd_strobe(SPIRIT1_STROBE_STANDBY);
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, 5);
- if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) {
- PRINTF("Spirit1: failed off->standby\n");
- return 1;
- }
+ /* Puts the SPIRIT1 in STANDBY */
+ cmd_strobe(SPIRIT1_STROBE_STANDBY);
+ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, 5);
+ if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) {
+ PRINTF("Spirit1: failed off->standby\n");
+ return 1;
+ }
- spirit_on = OFF;
- _nr_of_irq_disables = 1;
- _spirit_tx_started = false;
- _is_receiving = false;
- stop_rx_timeout();
+ spirit_on = OFF;
+ _nr_of_irq_disables = 1;
+ _spirit_tx_started = false;
+ _is_receiving = false;
+ stop_rx_timeout();
- CLEAR_TXBUF();
- CLEAR_RXBUF();
- }
- PRINTF("Spirit1: off.\n");
- return 0;
+ CLEAR_TXBUF();
+ CLEAR_RXBUF();
+ }
+ PRINTF("Spirit1: off.\n");
+ return 0;
}
int SimpleSpirit1::on(void) {
- PRINTF("Spirit1: on\n");
- cmd_strobe(SPIRIT1_STROBE_SABORT);
- wait_us(SABORT_WAIT_US);
- if(spirit_on == OFF) {
- /* ensure we are in READY state as we go from there to Rx */
- cmd_strobe(SPIRIT1_STROBE_READY);
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 5);
- if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
- PRINTF("Spirit1: failed to turn on\n");
- while(1);
- //return 1;
- }
+ PRINTF("Spirit1: on\n");
+ cmd_strobe(SPIRIT1_STROBE_SABORT);
+ wait_us(SABORT_WAIT_US);
+ if(spirit_on == OFF) {
+ /* ensure we are in READY state as we go from there to Rx */
+ cmd_strobe(SPIRIT1_STROBE_READY);
+ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 5);
+ if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
+ PRINTF("Spirit1: failed to turn on\n");
+ while(1);
+ //return 1;
+ }
- /* now we go to Rx */
- cmd_strobe(SPIRIT1_STROBE_FRX);
- cmd_strobe(SPIRIT1_STROBE_RX);
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5);
- if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
- PRINTF("Spirit1: failed to enter rx\n");
- while(1);
- //return 1;
- }
- CLEAR_RXBUF();
- _spirit_rx_err = false;
- _is_receiving = false;
- stop_rx_timeout();
+ /* now we go to Rx */
+ cmd_strobe(SPIRIT1_STROBE_FRX);
+ cmd_strobe(SPIRIT1_STROBE_RX);
+ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5);
+ if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
+ PRINTF("Spirit1: failed to enter rx\n");
+ while(1);
+ //return 1;
+ }
+ CLEAR_RXBUF();
+ _spirit_rx_err = false;
+ _is_receiving = false;
+ stop_rx_timeout();
- /* Enables the mcu to get IRQ from the SPIRIT1 */
- spirit_on = ON;
- MBED_ASSERT(_nr_of_irq_disables == 1);
- enable_spirit_irq();
- }
+ /* Enables the mcu to get IRQ from the SPIRIT1 */
+ spirit_on = ON;
+ MBED_ASSERT(_nr_of_irq_disables == 1);
+ enable_spirit_irq();
+ }
- return 0;
+ return 0;
}
uint16_t SimpleSpirit1::arch_refresh_status(void) {
- uint16_t mcstate;
- uint8_t header[2];
- header[0]=READ_HEADER;
- header[1]=MC_STATE1_BASE;
+ uint16_t mcstate;
+ uint8_t header[2];
+ header[0]=READ_HEADER;
+ header[1]=MC_STATE1_BASE;
- /* Puts the SPI chip select low to start the transaction */
- chip_sync_select();
+ /* Puts the SPI chip select low to start the transaction */
+ chip_sync_select();
- /* Write the aHeader bytes and read the SPIRIT1 status bytes */
- mcstate = _spi.write(header[0]);
- mcstate = mcstate<<8;
+ /* Write the aHeader bytes and read the SPIRIT1 status bytes */
+ mcstate = _spi.write(header[0]);
+ mcstate = mcstate<<8;
- /* Write the aHeader bytes and read the SPIRIT1 status bytes */
- mcstate |= _spi.write(header[1]);
+ /* Write the aHeader bytes and read the SPIRIT1 status bytes */
+ mcstate |= _spi.write(header[1]);
- /* Puts the SPI chip select high to end the transaction */
- chip_sync_unselect();
+ /* Puts the SPI chip select high to end the transaction */
+ chip_sync_unselect();
- return mcstate;
+ return mcstate;
}
int SimpleSpirit1::read(void *buf, unsigned int bufsize)
{
- PRINTF("READ IN\n");
+ PRINTF("READ IN\n");
- disable_spirit_irq();
+ disable_spirit_irq();
- /* Checks if the RX buffer is empty */
- if(IS_RXBUF_EMPTY()) {
- CLEAR_RXBUF();
- cmd_strobe(SPIRIT1_STROBE_SABORT);
- wait_us(SABORT_WAIT_US);
- cmd_strobe(SPIRIT1_STROBE_READY);
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 1);
- cmd_strobe(SPIRIT1_STROBE_FRX);
- cmd_strobe(SPIRIT1_STROBE_RX);
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1);
- _spirit_rx_err = false;
- _is_receiving = false;
- stop_rx_timeout();
- PRINTF("READ OUT RX BUF EMPTY\n");
- enable_spirit_irq();
- return 0;
- }
+ /* Checks if the RX buffer is empty */
+ if(IS_RXBUF_EMPTY()) {
+ CLEAR_RXBUF();
+ cmd_strobe(SPIRIT1_STROBE_SABORT);
+ wait_us(SABORT_WAIT_US);
+ cmd_strobe(SPIRIT1_STROBE_READY);
+ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 1);
+ cmd_strobe(SPIRIT1_STROBE_FRX);
+ cmd_strobe(SPIRIT1_STROBE_RX);
+ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1);
+ _spirit_rx_err = false;
+ _is_receiving = false;
+ stop_rx_timeout();
+ PRINTF("READ OUT RX BUF EMPTY\n");
+ 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 */
- PRINTF("TOO SMALL BUF\n");
- return 0;
- } else {
- /* Copies the packet received */
- memcpy(buf, spirit_rx_buf, spirit_rx_len);
+ /* If buf has the correct size */
+ PRINTF("TOO SMALL BUF\n");
+ return 0;
+ } else {
+ /* Copies the packet received */
+ memcpy(buf, spirit_rx_buf, spirit_rx_len);
#ifdef CONTIKI // betzw - TODO
- packetbuf_set_attr(PACKETBUF_ATTR_RSSI, last_rssi); //MGR
- packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, last_lqi); //MGR
+ packetbuf_set_attr(PACKETBUF_ATTR_RSSI, last_rssi); //MGR
+ packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, last_lqi); //MGR
#endif
- bufsize = spirit_rx_len;
- _is_receiving = false;
- stop_rx_timeout();
- CLEAR_RXBUF();
+ bufsize = spirit_rx_len;
+ _is_receiving = false;
+ stop_rx_timeout();
+ CLEAR_RXBUF();
- enable_spirit_irq();
+ enable_spirit_irq();
- PRINTF("READ OUT\n");
+ PRINTF("READ OUT\n");
- 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;
- PRINTF("CHANNEL CLEAR IN\n");
+ PRINTF("CHANNEL CLEAR IN\n");
- if(spirit_on == OFF) {
- /* Wakes up the SPIRIT1 */
- on();
- spirit_state = OFF;
- }
+ if(spirit_on == OFF) {
+ /* Wakes up the SPIRIT1 */
+ on();
+ spirit_state = OFF;
+ }
- disable_spirit_irq();
+ disable_spirit_irq();
- /* Reset State to Ready */
- set_ready_state();
- {
- uint32_t timeout = us_ticker_read() + 5000;
- do {
- mgmt_refresh_status();
- } while((st_lib_g_x_status.MC_STATE != MC_STATE_READY) && (us_ticker_read() < timeout));
- if(st_lib_g_x_status.MC_STATE != MC_STATE_READY) {
- enable_spirit_irq();
- return 1;
- }
- }
+ /* Reset State to Ready */
+ set_ready_state();
+ {
+ uint32_t timeout = us_ticker_read() + 5000;
+ do {
+ mgmt_refresh_status();
+ } while((st_lib_g_x_status.MC_STATE != MC_STATE_READY) && (us_ticker_read() < timeout));
+ if(st_lib_g_x_status.MC_STATE != MC_STATE_READY) {
+ enable_spirit_irq();
+ return 1;
+ }
+ }
- /* 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();
- } else {
- disable_spirit_irq();
- cmd_strobe(SPIRIT1_STROBE_FRX);
- cmd_strobe(SPIRIT1_STROBE_RX);
- /* SpiritCmdStrobeRx();*/
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5);
- CLEAR_RXBUF();
- _spirit_rx_err = false;
- _is_receiving = false;
- stop_rx_timeout();
- enable_spirit_irq();
- }
+ /* Puts the SPIRIT1 in its previous state */
+ if(spirit_state==OFF) {
+ off();
+ } else {
+ disable_spirit_irq();
+ cmd_strobe(SPIRIT1_STROBE_FRX);
+ cmd_strobe(SPIRIT1_STROBE_RX);
+ /* SpiritCmdStrobeRx();*/
+ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5);
+ CLEAR_RXBUF();
+ _spirit_rx_err = false;
+ _is_receiving = false;
+ stop_rx_timeout();
+ enable_spirit_irq();
+ }
- PRINTF("CHANNEL CLEAR OUT\n");
+ PRINTF("CHANNEL CLEAR OUT\n");
- /* 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)
{
- PRINTF("PENDING PACKET\n");
- return !IS_RXBUF_EMPTY();
+ PRINTF("PENDING PACKET\n");
+ return !IS_RXBUF_EMPTY();
}
/** Spirit Irq Callback **/
void SimpleSpirit1::IrqHandler() {
- st_lib_spirit_irqs x_irq_status;
- // st_lib_spirit_irqs mask;
-
- /* get interrupt source from radio */
- irq_get_status(&x_irq_status);
- // betzw - WAS: irq_clear_status(); BUT already cleared by get status!
-
- // SpiritIrqGetMask(&mask);
- // uint32_t *tmp = (uint32_t*)&x_irq_status;
- // uint32_t *tmp_mask = (uint32_t*)&mask;
- // printf("0x%x:0x%x\n", *tmp, *tmp_mask);
+ st_lib_spirit_irqs x_irq_status;
- /* Reception errors */
- if((x_irq_status.IRQ_RX_FIFO_ERROR) || (x_irq_status.IRQ_RX_DATA_DISC) || (x_irq_status.IRQ_RX_TIMEOUT)) {
- printf("%s (%d)\n", __func__, __LINE__);
- _spirit_rx_err = true;
- _is_receiving = false;
- CLEAR_RXBUF();
- cmd_strobe(SPIRIT1_STROBE_FRX);
- stop_rx_timeout();
- if(_spirit_tx_started) {
- _spirit_tx_started = false;
- CLEAR_TXBUF();
- /* call user callback */
- if(_current_irq_callback) {
- _current_irq_callback(TX_ERR);
- }
- }
- }
-
- /* Transmission error */
- if(x_irq_status.IRQ_TX_FIFO_ERROR) {
- error("IRQ_TX_FIFO_ERROR should never happen!\n");
-
- cmd_strobe(SPIRIT1_STROBE_FTX);
- if(_spirit_tx_started) {
- _spirit_tx_started = false;
- CLEAR_TXBUF();
- /* call user callback */
- if(_current_irq_callback) {
- _current_irq_callback(TX_ERR);
- }
- }
- }
+ /* get interrupt source from radio */
+ irq_get_status(&x_irq_status);
+ // betzw - WAS: irq_clear_status(); BUT already cleared by get status!
- /* The IRQ_VALID_SYNC is used to notify a new packet is coming */
- if(x_irq_status.IRQ_VALID_SYNC) {
- printf("S\n");
- _is_receiving = true;
- _spirit_rx_err = false;
- CLEAR_RXBUF();
- MBED_ASSERT(!_spirit_tx_started);
- start_rx_timeout();
- }
-
- /* The IRQ_TX_DATA_SENT notifies the packet received. Puts the SPIRIT1 in RX */
- if(x_irq_status.IRQ_TX_DATA_SENT) {
- MBED_ASSERT(_spirit_tx_started);
-
- cmd_strobe(SPIRIT1_STROBE_FRX);
- cmd_strobe(SPIRIT1_STROBE_RX);
- /* SpiritCmdStrobeRx();*/
- CLEAR_TXBUF();
- CLEAR_RXBUF();
- _spirit_rx_err = false;
- _spirit_tx_started = false;
-
- /* call user callback */
- if(_current_irq_callback) {
- _current_irq_callback(TX_DONE); // betzw - TODO: define enums for callback values
- }
- printf("s\n");
- }
-
- /* The IRQ_RX_DATA_READY notifies a new packet arrived */
- if(x_irq_status.IRQ_RX_DATA_READY) {
- _is_receiving = false; // Finished receiving
- stop_rx_timeout();
-
- if(_spirit_rx_err) {
- printf("%s (%d)\n", __func__, __LINE__);
- _spirit_rx_err = false;
- CLEAR_RXBUF();
+ /* Reception errors */
+ if((x_irq_status.IRQ_RX_FIFO_ERROR) || (x_irq_status.IRQ_RX_DATA_DISC) || (x_irq_status.IRQ_RX_TIMEOUT)) {
+ _spirit_rx_err = true;
+ _is_receiving = false;
+ CLEAR_RXBUF();
cmd_strobe(SPIRIT1_STROBE_FRX);
- } else {
- spirit_rx_len = pkt_basic_get_received_pkt_length();
- unsigned int remaining = 0;
- // uint8_t fifo_available = 0;
- uint8_t to_receive = 0;
-
- MBED_ASSERT(spirit_rx_len <= MAX_PACKET_LEN);
-
- for(; _spirit_rx_pos < spirit_rx_len;) {
- remaining = spirit_rx_len - _spirit_rx_pos;
- // fifo_available = linear_fifo_read_num_elements_rx_fifo();
- to_receive = remaining; // betzw - WAS: (remaining < fifo_available) ? remaining : fifo_available;
- if(to_receive > 0) {
- spi_read_linear_fifo(to_receive, &spirit_rx_buf[_spirit_rx_pos]);
- _spirit_rx_pos += to_receive;
+ stop_rx_timeout();
+ if(_spirit_tx_started) {
+ _spirit_tx_started = false;
+ CLEAR_TXBUF();
+ /* call user callback */
+ if(_current_irq_callback) {
+ _current_irq_callback(TX_ERR);
}
}
+ }
+
+ /* Transmission error */
+ if(x_irq_status.IRQ_TX_FIFO_ERROR) {
+ error("IRQ_TX_FIFO_ERROR should never happen!\n");
+
+ cmd_strobe(SPIRIT1_STROBE_FTX);
+ if(_spirit_tx_started) {
+ _spirit_tx_started = false;
+ CLEAR_TXBUF();
+ /* 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) {
+ _is_receiving = true;
+ _spirit_rx_err = false;
+ CLEAR_RXBUF();
+ MBED_ASSERT(!_spirit_tx_started);
+ start_rx_timeout();
+ }
+
+ /* The IRQ_TX_DATA_SENT notifies the packet received. Puts the SPIRIT1 in RX */
+ if(x_irq_status.IRQ_TX_DATA_SENT) {
+ MBED_ASSERT(_spirit_tx_started);
cmd_strobe(SPIRIT1_STROBE_FRX);
-
- last_rssi = qi_get_rssi(); //MGR
- last_lqi = qi_get_lqi(); //MGR
-
-#if NULLRDC_CONF_802154_AUTOACK
- if (spirit_rxbuf[0] == ACK_LEN) {
- /* For debugging purposes we assume this is an ack for us */
- just_got_an_ack = 1;
- }
-#endif /* NULLRDC_CONF_802154_AUTOACK */
+ cmd_strobe(SPIRIT1_STROBE_RX);
+ /* SpiritCmdStrobeRx();*/
+ CLEAR_TXBUF();
+ CLEAR_RXBUF();
+ _spirit_rx_err = false;
+ _spirit_tx_started = false;
/* call user callback */
if(_current_irq_callback) {
- _current_irq_callback(RX_DONE); // betzw - TODO: define enums for callback values
+ _current_irq_callback(TX_DONE); // betzw - TODO: define enums for callback values
}
+ }
- x_irq_status.IRQ_RX_FIFO_ALMOST_FULL = S_RESET; // skip FIFO handling
+ /* RX FIFO almost full */
+ if(x_irq_status.IRQ_RX_FIFO_ALMOST_FULL) {
+ if(_spirit_rx_err) {
+ _is_receiving = false;
+ cmd_strobe(SPIRIT1_STROBE_FRX);
+ CLEAR_RXBUF();
+ stop_rx_timeout();
+ } else {
+ uint8_t fifo_available = linear_fifo_read_num_elements_rx_fifo();
+ unsigned int remaining = MAX_PACKET_LEN - _spirit_rx_pos;
+ if(fifo_available > remaining) {
+ _spirit_rx_err = true;
+ _is_receiving = false;
+ CLEAR_RXBUF();
+ cmd_strobe(SPIRIT1_STROBE_FRX);
+ stop_rx_timeout();
+ } else {
+ spi_read_linear_fifo(fifo_available, &spirit_rx_buf[_spirit_rx_pos]);
+ _spirit_rx_pos += fifo_available;
+ if(!_is_receiving) {
+ _is_receiving = true;
+ start_rx_timeout();
+ }
+ }
+ }
+ }
- printf("D\n");
- }
- }
+ /* The IRQ_RX_DATA_READY notifies a new packet arrived */
+ if(x_irq_status.IRQ_RX_DATA_READY) {
+ _is_receiving = false; // Finished receiving
+ stop_rx_timeout();
- /* RX FIFO almost full */
- if(x_irq_status.IRQ_RX_FIFO_ALMOST_FULL) {
- if(_spirit_rx_err) {
- printf("%s (%d)\n", __func__, __LINE__);
- _is_receiving = false;
- cmd_strobe(SPIRIT1_STROBE_FRX);
- CLEAR_RXBUF();
- stop_rx_timeout();
- } else {
- uint8_t fifo_available = linear_fifo_read_num_elements_rx_fifo();
- unsigned int remaining = MAX_PACKET_LEN - _spirit_rx_pos;
- if(fifo_available > remaining) {
- printf("%s (%d)\n", __func__, __LINE__);
- _spirit_rx_err = true;
- _is_receiving = false;
- CLEAR_RXBUF();
- cmd_strobe(SPIRIT1_STROBE_FRX);
- stop_rx_timeout();
- } else {
- spi_read_linear_fifo(fifo_available, &spirit_rx_buf[_spirit_rx_pos]);
- _spirit_rx_pos += fifo_available;
- if(!_is_receiving) {
- _is_receiving = true;
- start_rx_timeout();
- }
- printf("F\n");
- }
- }
- }
+ if(_spirit_rx_err) {
+ _spirit_rx_err = false;
+ CLEAR_RXBUF();
+ cmd_strobe(SPIRIT1_STROBE_FRX);
+ } else {
+ spirit_rx_len = pkt_basic_get_received_pkt_length();
+ unsigned int remaining = 0;
+ // uint8_t fifo_available = 0; // betzw: optimized out in favor of a request less to SPIRIT device
+ uint8_t to_receive = 0;
+
+ MBED_ASSERT(spirit_rx_len <= MAX_PACKET_LEN);
+
+ for(; _spirit_rx_pos < spirit_rx_len;) {
+ remaining = spirit_rx_len - _spirit_rx_pos;
+ // fifo_available = linear_fifo_read_num_elements_rx_fifo(); // betzw: optimized out in favor of a request less to SPIRIT device
+ to_receive = remaining; // betzw - WAS: (remaining < fifo_available) ? remaining : fifo_available;
+ 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);
+
+ last_rssi = qi_get_rssi(); //MGR
+ last_lqi = qi_get_lqi(); //MGR
+
+#if NULLRDC_CONF_802154_AUTOACK
+ if (spirit_rxbuf[0] == ACK_LEN) {
+ /* For debugging purposes we assume this is an ack for us */
+ just_got_an_ack = 1;
+ }
+#endif /* NULLRDC_CONF_802154_AUTOACK */
+
+ /* call user callback */
+ if(_current_irq_callback) {
+ _current_irq_callback(RX_DONE); // betzw - TODO: define enums for callback values
+ }
+ }
+ }
}
X-NUCLEO-IDS01A4 Sub-1GHz RF Expansion Board