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:
Mon Jul 03 16:42:03 2017 +0200
Parent:
64:28ef790e4ef7
Child:
66:1e09d233280b
Commit message:
Delay setting of `expecting_ack` to when TX was successful

Changed in this revision

source/NanostackRfPhySpirit1.cpp Show annotated file Show diff for this revision Revisions of this file
source/SimpleSpirit1.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/source/NanostackRfPhySpirit1.cpp	Mon Jul 03 14:39:01 2017 +0200
+++ b/source/NanostackRfPhySpirit1.cpp	Mon Jul 03 16:42:03 2017 +0200
@@ -38,6 +38,7 @@
 static volatile uint8_t rf_rx_sequence;
 static volatile bool rf_ack_sent = false;
 static volatile bool expecting_ack = false;
+static volatile bool need_ack = false;
 
 /* MAC frame helper macros */
 #define MAC_FCF_FRAME_TYPE_MASK         0x0007
@@ -108,9 +109,9 @@
 
         /*Check if transmitted data needs to be acked*/
         if((fcf & MAC_FCF_ACK_REQ_BIT_MASK) >> MAC_FCF_ACK_REQ_BIT_SHIFT)
-            expecting_ack = true;
+            need_ack = true;
         else
-            expecting_ack = false;
+            need_ack = false;
 
         /*Store the sequence number for ACK handling*/
         tx_sequence = *(data_ptr + 2);
@@ -119,8 +120,8 @@
         mac_tx_handle = tx_handle;
 
 #ifdef HEAVY_TRACING
-        tr_info("%s (%d), len=%d, tx_handle=%x, tx_seq=%x, expecting_ack=%d (%x:%x, %x:%x, %x:%x, %x:%x)", __func__, __LINE__,
-                data_length, tx_handle, tx_sequence, expecting_ack,
+        tr_info("%s (%d), len=%d, tx_handle=%x, tx_seq=%x, need_ack=%d (%x:%x, %x:%x, %x:%x, %x:%x)", __func__, __LINE__,
+                data_length, tx_handle, tx_sequence, need_ack,
                 data_ptr[3], data_ptr[4], data_ptr[5], data_ptr[6],
                 data_ptr[7], data_ptr[8], data_ptr[9], data_ptr[10]);
 #endif
@@ -554,9 +555,15 @@
         return; // no need to inform stack
     }
 
+    /* Transform `need_ack` in `expecting_ack` */
+    if(need_ack) {
+        need_ack = false;
+        expecting_ack = true;
+    }
+
     /*Call PHY TX Done API*/
     if(device_driver.phy_tx_done_cb){
-        phy_status = expecting_ack ? PHY_LINK_TX_DONE_PENDING : PHY_LINK_TX_SUCCESS;
+        phy_status = PHY_LINK_TX_SUCCESS;
         rf_send_signal(RF_SIG_CB_TX_DONE);
     }
 }
@@ -565,7 +572,7 @@
 static inline void rf_handle_tx_err(void) {
     /*Call PHY TX Done API*/
     if(device_driver.phy_tx_done_cb){
-        expecting_ack = false;
+        need_ack = false;
         phy_status = PHY_LINK_TX_FAIL;
         rf_send_signal(RF_SIG_CB_TX_DONE);
     }
--- a/source/SimpleSpirit1.cpp	Mon Jul 03 14:39:01 2017 +0200
+++ b/source/SimpleSpirit1.cpp	Mon Jul 03 16:42:03 2017 +0200
@@ -450,7 +450,10 @@
 	irq_get_status(&x_irq_status);
 
 	/* The IRQ_TX_DATA_SENT notifies the packet received. Puts the SPIRIT1 in RX */
-	if(x_irq_status.IRQ_TX_DATA_SENT) {
+	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, "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);