ST / stm-spirit1-rf-driver

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
Parent:
21:d5c10e5742f6
Child:
23:4192649f35da
--- 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;