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:
64:28ef790e4ef7
Parent:
63:d7530f62ed93
Child:
65:a16f0064110a
--- a/source/NanostackRfPhySpirit1.cpp	Mon Jun 26 18:04:11 2017 +0200
+++ b/source/NanostackRfPhySpirit1.cpp	Mon Jul 03 14:39:01 2017 +0200
@@ -37,6 +37,7 @@
 static Thread rf_ack_sender(osPriorityRealtime);
 static volatile uint8_t rf_rx_sequence;
 static volatile bool rf_ack_sent = false;
+static volatile bool expecting_ack = false;
 
 /* MAC frame helper macros */
 #define MAC_FCF_FRAME_TYPE_MASK         0x0007
@@ -103,16 +104,13 @@
         /*Return busy*/
         return -1;
     } else {
-#ifdef HEAVY_TRACING
         uint16_t fcf = rf_read_16_bit(data_ptr);
-        uint16_t need_ack;
 
         /*Check if transmitted data needs to be acked*/
         if((fcf & MAC_FCF_ACK_REQ_BIT_MASK) >> MAC_FCF_ACK_REQ_BIT_SHIFT)
-            need_ack = 1;
+            expecting_ack = true;
         else
-            need_ack = 0;
-#endif
+            expecting_ack = false;
 
         /*Store the sequence number for ACK handling*/
         tx_sequence = *(data_ptr + 2);
@@ -121,8 +119,8 @@
         mac_tx_handle = tx_handle;
 
 #ifdef HEAVY_TRACING
-        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,
+        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,
                 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
@@ -289,7 +287,7 @@
     rf_ack_sender.signal_set(signal);
 }
 
-static phy_link_tx_status_e phy_status;
+static volatile phy_link_tx_status_e phy_status;
 /* Note: we are in IRQ context */
 static void rf_handle_ack(uint8_t seq_number)
 {
@@ -309,6 +307,12 @@
 #ifdef HEAVY_TRACING
         tr_info("%s (%d)", __func__, __LINE__);
 #endif
+
+        /*Call PHY TX Done API*/
+        if(device_driver.phy_tx_done_cb){
+            phy_status = PHY_LINK_TX_FAIL;
+            rf_send_signal(RF_SIG_CB_TX_DONE);
+        }
     }
 }
 
@@ -493,14 +497,24 @@
     }
 
     /* If waiting for ACK, check here if the packet is an ACK to a message previously sent */
-    uint16_t fcf = rf_read_16_bit(rf_rx_buf);
-    if(((fcf & MAC_FCF_FRAME_TYPE_MASK) >> MAC_FCF_FRAME_TYPE_SHIFT) == FC_ACK_FRAME) {
-        /*Send sequence number in ACK handler*/
+    if(expecting_ack) {
+        uint16_t fcf = rf_read_16_bit(rf_rx_buf);
+        expecting_ack = false;
+
+        if(((fcf & MAC_FCF_FRAME_TYPE_MASK) >> MAC_FCF_FRAME_TYPE_SHIFT) == FC_ACK_FRAME) {
+            /*Send sequence number in ACK handler*/
 #ifdef HEAVY_TRACING
-        tr_debug("%s (%d), len=%u", __func__, __LINE__, (unsigned int)rf_buffer_len);
+            tr_debug("%s (%d), len=%u", __func__, __LINE__, (unsigned int)rf_buffer_len);
 #endif
-        rf_handle_ack(rf_rx_buf[2]);
-        return;
+            rf_handle_ack(rf_rx_buf[2]);
+            return;
+        } else {
+            /*Call PHY TX Done API*/
+            if(device_driver.phy_tx_done_cb){
+                phy_status = PHY_LINK_TX_FAIL;
+                rf_send_signal(RF_SIG_CB_TX_DONE);
+            }
+        }
     }
 
     /* Kick off ACK sending */
@@ -542,7 +556,7 @@
 
     /*Call PHY TX Done API*/
     if(device_driver.phy_tx_done_cb){
-        phy_status = PHY_LINK_TX_SUCCESS;
+        phy_status = expecting_ack ? PHY_LINK_TX_DONE_PENDING : PHY_LINK_TX_SUCCESS;
         rf_send_signal(RF_SIG_CB_TX_DONE);
     }
 }
@@ -551,6 +565,7 @@
 static inline void rf_handle_tx_err(void) {
     /*Call PHY TX Done API*/
     if(device_driver.phy_tx_done_cb){
+        expecting_ack = false;
         phy_status = PHY_LINK_TX_FAIL;
         rf_send_signal(RF_SIG_CB_TX_DONE);
     }
@@ -627,7 +642,7 @@
             rf_ack_sent = true;
 
             /*Send the packet*/
-            rf_device->send((uint8_t*)buffer, 3);
+            rf_device->send((uint8_t*)buffer, 3, false);
 
 #ifdef HEAVY_TRACING
             tr_debug("%s (%d), hdr=%x, nr=%x", __func__, __LINE__, buffer[0], ptr[0]);