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).

Files at this revision

API Documentation at this revision

Comitter:
Wolfgang Betz
Date:
Thu Nov 10 15:25:59 2016 +0100
Parent:
23:4192649f35da
Child:
25:2ec45788f28c
Commit message:
Relax bootup times

Changed in this revision

SimpleSpirit1.cpp Show annotated file Show diff for this revision Revisions of this file
SimpleSpirit1.h Show annotated file Show diff for this revision Revisions of this file
mbed_driver_api.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/SimpleSpirit1.cpp	Wed Nov 09 14:02:18 2016 +0100
+++ b/SimpleSpirit1.cpp	Thu Nov 10 15:25:59 2016 +0100
@@ -6,8 +6,6 @@
 
 #define SPIRIT1_STATUS()		(arch_refresh_status() & SPIRIT1_STATE_STATEBITS)
 
-#define SABORT_WAIT_US			(400)
-
 #define BUSYWAIT_UNTIL(cond, millisecs)                                        					\
 		do {                                                                 					 		\
 			uint32_t start = us_ticker_read();                         							\
@@ -238,7 +236,7 @@
 		/* Clear any pending irqs */
 		irq_clear_status();
 
-		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 10);
+		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 3000);
 		if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
 #ifndef NDEBUG
 			debug("\n\rSpirit1: failed off->ready\n\r");
@@ -248,7 +246,7 @@
 
 		/* Puts the SPIRIT1 in STANDBY */
 		cmd_strobe(SPIRIT1_STROBE_STANDBY);
-		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, 10);
+		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, 3000);
 		if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) {
 #ifndef NDEBUG
 			debug("\n\rSpirit1: failed off->standby\n\r");
@@ -270,11 +268,10 @@
 
 int SimpleSpirit1::on(void) {
 	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, 10);
+		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 3000);
 		if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
 #ifndef NDEBUG
 			debug("\n\rSpirit1: failed to turn on\n\r");
@@ -285,7 +282,7 @@
 		/* now we go to Rx */
 		cmd_strobe(SPIRIT1_STROBE_FRX);
 		cmd_strobe(SPIRIT1_STROBE_RX);
-		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 10);
+		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 3000);
 		if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
 #ifndef NDEBUG
 			debug("\n\rSpirit1: failed to enter rx\n\r");
@@ -338,12 +335,11 @@
 	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);
+		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 3000);
 		cmd_strobe(SPIRIT1_STROBE_FRX);
 		cmd_strobe(SPIRIT1_STROBE_RX);
-		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1);
+		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 3000);
 		_spirit_rx_err = false;
 		_is_receiving = false;
 		stop_rx_timeout();
@@ -398,6 +394,9 @@
 		} 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();
+#ifndef NDEBUG
+			debug("\n\rSpirit1: channel clear failed\n\r");
+#endif
 			return 1;
 		}
 	}
--- a/SimpleSpirit1.h	Wed Nov 09 14:02:18 2016 +0100
+++ b/SimpleSpirit1.h	Thu Nov 10 15:25:59 2016 +0100
@@ -85,7 +85,7 @@
     }
 
     void start_rx_timeout(void) {
-    	_rx_receiving_timeout.attach_us(Callback<void()>(this, &SimpleSpirit1::rx_timeout_handler), 500 * 1000); // 5ms
+    	_rx_receiving_timeout.attach_us(Callback<void()>(this, &SimpleSpirit1::rx_timeout_handler), 500 * 1000); // 500ms
     }
 
     void stop_rx_timeout(void) {
@@ -136,8 +136,9 @@
 
     void enter_shutdown() { _shut_down = 1; }
     void exit_shutdown() {
+    	wait_ms(2); // wait two milliseconds (to allow Spirit1 to shut down)
     	_shut_down = 0;
-    	wait_ms(2); // wait two milliseconds (to allow Spirit1 a proper boot-up sequence)
+    	wait_ms(10); // wait ten milliseconds (to allow Spirit1 a proper boot-up sequence)
     }
 
     void cs_to_sclk_delay(void) {
--- a/mbed_driver_api.cpp	Wed Nov 09 14:02:18 2016 +0100
+++ b/mbed_driver_api.cpp	Thu Nov 10 15:25:59 2016 +0100
@@ -33,7 +33,6 @@
 };
 static phy_device_driver_s device_driver;
 static int8_t rf_radio_driver_id = -1;
-static uint8_t rf_rnd_rssi = 0;
 
 const phy_rf_channel_configuration_s phy_subghz = {868000000, 1000000, 250000, 11, M_GFSK};
 
@@ -602,7 +601,11 @@
     /* TODO - betzw: what to do? */
     // rf_buffer_len -= 2;
 
-    /* Send received data and link information to the network stack */
+#ifdef HEAVY_TRACING
+      	tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+
+        	/* Send received data and link information to the network stack */
     if( device_driver.phy_rx_cb ){
         device_driver.phy_rx_cb(rf_rx_buf, rf_buffer_len, rf_lqi, rf_rssi, rf_radio_driver_id);
     }
@@ -856,8 +859,14 @@
  */
 extern "C" int8_t rf_read_random(void)
 {
-	tr_debug("%s (%d)", __func__, __LINE__);
-    return rf_rnd_rssi;
+	float tmp;
+
+	rf_device->channel_clear();
+	tmp = rf_device->get_last_rssi_dbm();
+	tmp *= -10;
+
+	tr_debug("%s (%d): ret=%d", __func__, __LINE__, (uint8_t)tmp);
+    return (uint8_t)tmp;
 }
 
 /*