Prototype RF driver for STM Sub-1 GHz RF expansion board based on the SPSGRF-868 module for STM32 Nucleo.
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).
Revision 22:9165bd73c61e, committed 2016-11-09
- Comitter:
- Wolfgang Betz
- Date:
- Wed Nov 09 11:21:55 2016 +0100
- Parent:
- 21:d5c10e5742f6
- Child:
- 23:4192649f35da
- Commit message:
- Substitute 'MBED_ASSERT' with debug messages
Changed in this revision
--- a/SimpleSpirit1.cpp Tue Nov 08 11:04:30 2016 +0100
+++ b/SimpleSpirit1.cpp Wed Nov 09 11:21:55 2016 +0100
@@ -2,14 +2,6 @@
#include "SimpleSpirit1.h"
#include "radio_spi.h"
-#define NDEBUG
-#ifndef NDEBUG
-#include <stdio.h>
-#define PRINTF(...) printf(__VA_ARGS__)
-#else
-#define PRINTF(...)
-#endif
-
#if NULLRDC_CONF_802154_AUTOACK
#define ACK_LEN 3
static int wants_an_ack = 0; /* The packet sent expects an ack */
@@ -170,7 +162,9 @@
set_ready_state();
cmd_strobe(SPIRIT1_STROBE_FTX); // flush TX FIFO buffer
- MBED_ASSERT(linear_fifo_read_num_elements_tx_fifo() == 0);
+#ifndef NDEBUG
+ debug_if(!(linear_fifo_read_num_elements_tx_fifo() == 0), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
pkt_basic_set_payload_length(payload_len); // set desired payload len
@@ -187,7 +181,9 @@
/* Start Transmit FIFO Buffer */
if(trigger_tx) {
- MBED_ASSERT(linear_fifo_read_num_elements_tx_fifo() == to_send);
+#ifndef NDEBUG
+ debug_if(!(linear_fifo_read_num_elements_tx_fifo() == to_send), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
cmd_strobe(SPIRIT1_STROBE_TX);
trigger_tx = false;
}
@@ -201,15 +197,13 @@
enable_spirit_irq();
BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 50);
- // MBED_ASSERT(linear_fifo_read_num_elements_tx_fifo() == 0);
+ // debug_if(!(linear_fifo_read_num_elements_tx_fifo() == 0), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
return RADIO_TX_OK;
}
/** Set Ready State **/
void SimpleSpirit1::set_ready_state(void) {
- PRINTF("READY IN\n");
-
disable_spirit_irq();
_is_receiving = false;
@@ -223,12 +217,9 @@
irq_clear_status();
enable_spirit_irq();
-
- 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();
@@ -239,17 +230,21 @@
/* Clear any pending irqs */
irq_clear_status();
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 5);
+ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 10);
if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
- PRINTF("Spirit1: failed off->ready\n");
+#ifndef NDEBUG
+ debug("\n\rSpirit1: failed off->ready\n\r");
+#endif
return 1;
}
/* Puts the SPIRIT1 in STANDBY */
cmd_strobe(SPIRIT1_STROBE_STANDBY);
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, 5);
+ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, 10);
if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) {
- PRINTF("Spirit1: failed off->standby\n");
+#ifndef NDEBUG
+ debug("\n\rSpirit1: failed off->standby\n\r");
+#endif
return 1;
}
@@ -262,32 +257,32 @@
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);
+ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 10);
if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
- PRINTF("Spirit1: failed to turn on\n");
- while(1);
- //return 1;
+#ifndef NDEBUG
+ debug("\n\rSpirit1: failed to turn on\n\r");
+#endif
+ 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);
+ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 10);
if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
- PRINTF("Spirit1: failed to enter rx\n");
- while(1);
- //return 1;
+#ifndef NDEBUG
+ debug("\n\rSpirit1: failed to enter rx\n\r");
+#endif
+ return 1;
}
CLEAR_RXBUF();
_spirit_rx_err = false;
@@ -296,7 +291,9 @@
/* Enables the mcu to get IRQ from the SPIRIT1 */
spirit_on = ON;
- MBED_ASSERT(_nr_of_irq_disables == 1);
+#ifndef NDEBUG
+ debug_if(!(_nr_of_irq_disables == 1), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
enable_spirit_irq();
}
@@ -327,8 +324,6 @@
int SimpleSpirit1::read(void *buf, unsigned int bufsize)
{
- PRINTF("READ IN\n");
-
disable_spirit_irq();
/* Checks if the RX buffer is empty */
@@ -344,7 +339,6 @@
_spirit_rx_err = false;
_is_receiving = false;
stop_rx_timeout();
- PRINTF("READ OUT RX BUF EMPTY\n");
enable_spirit_irq();
return 0;
}
@@ -353,7 +347,9 @@
enable_spirit_irq();
/* If buf has the correct size */
- PRINTF("TOO SMALL BUF\n");
+#ifndef NDEBUG
+ debug("\n\rTOO SMALL BUF\n\r");
+#endif
return 0;
} else {
/* Copies the packet received */
@@ -366,8 +362,6 @@
enable_spirit_irq();
- PRINTF("READ OUT\n");
-
return bufsize;
}
@@ -379,8 +373,6 @@
/* Local variable used to memorize the SPIRIT1 state */
uint8_t spirit_state = ON;
- PRINTF("CHANNEL CLEAR IN\n");
-
if(spirit_on == OFF) {
/* Wakes up the SPIRIT1 */
on();
@@ -415,7 +407,7 @@
cmd_strobe(SPIRIT1_STROBE_FRX);
cmd_strobe(SPIRIT1_STROBE_RX);
/* SpiritCmdStrobeRx();*/
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5);
+ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 10);
CLEAR_RXBUF();
_spirit_rx_err = false;
_is_receiving = false;
@@ -423,8 +415,6 @@
enable_spirit_irq();
}
- PRINTF("CHANNEL CLEAR OUT\n");
-
/* Checks the RSSI value with the threshold */
if(rssi_value<CCA_THRESHOLD) {
return 0;
@@ -435,7 +425,6 @@
int SimpleSpirit1::get_pending_packet(void)
{
- PRINTF("PENDING PACKET\n");
return !IS_RXBUF_EMPTY();
}
@@ -466,6 +455,9 @@
/* Transmission error */
if(x_irq_status.IRQ_TX_FIFO_ERROR) {
+#ifndef NDEBUG
+ debug("\n\r%s (%d)", __func__, __LINE__);
+#endif
cmd_strobe(SPIRIT1_STROBE_FTX);
if(_spirit_tx_started) {
_spirit_tx_started = false;
@@ -482,13 +474,17 @@
_is_receiving = true;
_spirit_rx_err = false;
CLEAR_RXBUF();
- MBED_ASSERT(!_spirit_tx_started);
+#ifndef NDEBUG
+ debug_if(_spirit_tx_started, "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
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);
+#ifndef NDEBUG
+ debug_if(!_spirit_tx_started, "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
cmd_strobe(SPIRIT1_STROBE_FRX);
cmd_strobe(SPIRIT1_STROBE_RX);
@@ -546,7 +542,9 @@
// 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);
+#ifndef NDEBUG
+ debug_if(!(spirit_rx_len <= MAX_PACKET_LEN), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
for(; _spirit_rx_pos < spirit_rx_len;) {
remaining = spirit_rx_len - _spirit_rx_pos;
--- a/SimpleSpirit1.h Tue Nov 08 11:04:30 2016 +0100
+++ b/SimpleSpirit1.h Wed Nov 09 11:21:55 2016 +0100
@@ -1,5 +1,6 @@
/*** Mbed Includes ***/
#include "mbed.h"
+#include "mbed_debug.h"
/*** Cube Includes ***/
@@ -78,6 +79,9 @@
CLEAR_RXBUF();
_spirit_rx_err = false;
_spirit_tx_started = false;
+#ifndef NDEBUG
+ debug("\n\r%s (%d)\n\r", __func__, __LINE__);
+#endif
}
void start_rx_timeout(void) {
@@ -114,11 +118,15 @@
void disable_spirit_irq(void) {
_irq.disable_irq();
_nr_of_irq_disables++;
- MBED_ASSERT(_nr_of_irq_disables != 0);
+#ifndef NDEBUG
+ debug_if(_nr_of_irq_disables == 0, "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
}
void enable_spirit_irq(void) {
- MBED_ASSERT(_nr_of_irq_disables > 0);
+#ifndef NDEBUG
+ debug_if(_nr_of_irq_disables == 0, "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
if(--_nr_of_irq_disables == 0)
_irq.enable_irq();
}
--- a/mbed_driver_api.cpp Tue Nov 08 11:04:30 2016 +0100
+++ b/mbed_driver_api.cpp Wed Nov 09 11:21:55 2016 +0100
@@ -105,7 +105,12 @@
static int8_t rf_trigger_send(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol)
{
- MBED_ASSERT(data_length >= 3);
+#ifndef NDEBUG
+ debug_if(!(data_length >= 3), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
+
+ /* Give 'rf_ack_sender' a better chance to run */
+ Thread::yield();
/* Get Lock */
rf_if_lock();
@@ -537,7 +542,8 @@
#endif // !SHORT_ACK_FRAMES
}
-#ifdef HEAVY_tr_debug tr_debug("%s (%d), ret=%d, ack=%d", __func__, __LINE__, ret, (*ack_requested));
+#ifdef HEAVY_TRACING
+ tr_debug("%s (%d), ret=%d, ack=%d", __func__, __LINE__, ret, (*ack_requested));
#endif
return ret;
}
@@ -696,10 +702,14 @@
/*Send the packet*/
rf_device->send((uint8_t*)buffer, 3);
- /* Release Lock */
+ tr_debug("%s (%d), hdr=%x, nr=%x", __func__, __LINE__, buffer[0], ptr[0]);
+
+ /* Release Lock */
rf_if_unlock();
+#ifdef HEAVY_TRACING
tr_debug("%s (%d)", __func__, __LINE__);
+#endif
} while(true);
}
#else // !SHORT_ACK_FRAMES
X-NUCLEO-IDS01A4 Sub-1GHz RF Expansion Board