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:
Tue Nov 15 12:07:07 2016 +0100
Parent:
26:45dae8d48029
Child:
28:6a71e15d5272
Commit message:
Working without tracing

Changed in this revision

SimpleSpirit1.cpp 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	Mon Nov 14 15:01:31 2016 +0100
+++ b/SimpleSpirit1.cpp	Tue Nov 15 12:07:07 2016 +0100
@@ -49,7 +49,7 @@
 
 	/* configure spi */
 	_spi.format(8, 0); /* 8-bit, mode = 0, [order = SPI_MSB] only available in mbed3 */
-	_spi.frequency(1000000); // 1MHz
+	_spi.frequency(1000000); // 1MHz // betzw - NOTE: higher frequencies lead to instability of Spirit1
 
 	/* install irq handler */
 	_irq.mode(PullUp);
@@ -165,7 +165,7 @@
 
 #ifndef NDEBUG
 	if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
-		debug("\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+		debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
 	}
 #endif
 
@@ -177,7 +177,7 @@
 	cmd_strobe(SPIRIT1_STROBE_FTX); // flush TX FIFO buffer
 
 #ifndef NDEBUG
-	debug_if(!(linear_fifo_read_num_elements_tx_fifo() == 0), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+	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
@@ -213,7 +213,7 @@
 
 #ifndef NDEBUG
 	if(last_state != SPIRIT1_STATE_RX) {
-		debug("\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+		debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
 	}
 #endif
 
@@ -236,7 +236,7 @@
 		cmd_strobe(SPIRIT1_STROBE_SABORT);
 	} else if(state != SPIRIT1_STATE_READY) {
 #ifndef NDEBUG
-		debug("\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, state>>1);
+		debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, state>>1);
 #endif
 	}
 
@@ -301,14 +301,14 @@
 		/* Enables the mcu to get IRQ from the SPIRIT1 */
 		spirit_on = ON;
 #ifndef NDEBUG
-		debug_if(!(_nr_of_irq_disables == 1), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+		debug_if(!(_nr_of_irq_disables == 1), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
 #endif
 		enable_spirit_irq();
 	}
 
 #ifndef NDEBUG
 	if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
-		debug("\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+		debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
 	}
 #endif
 
@@ -380,7 +380,7 @@
 
 #ifndef NDEBUG
 	if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
-		debug("\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+		debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
 	}
 #endif
 
@@ -399,7 +399,7 @@
 		off();
 #ifndef NDEBUG
 		if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) {
-			debug("\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+			debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
 		}
 #endif
 	} else {
@@ -421,7 +421,7 @@
 
 #ifndef NDEBUG
 		if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
-			debug("\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+			debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
 		}
 #endif
 	}
@@ -490,7 +490,7 @@
 		_spirit_rx_err = false;
 		CLEAR_RXBUF();
 #ifndef NDEBUG
-		debug_if(_spirit_tx_started, "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+		debug_if(_spirit_tx_started, "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
 #endif
 		start_rx_timeout();
 	}
@@ -498,7 +498,7 @@
 	/* The IRQ_TX_DATA_SENT notifies the packet received. Puts the SPIRIT1 in RX */
 	if(x_irq_status.IRQ_TX_DATA_SENT) {
 #ifndef NDEBUG
-		debug_if(!_spirit_tx_started, "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+		debug_if(!_spirit_tx_started, "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
 #endif
 
 		csma_ca_state(S_DISABLE); // disable CSMA/CA
@@ -555,7 +555,7 @@
 			spirit_rx_len = pkt_basic_get_received_pkt_length();
 
 #ifndef NDEBUG
-			debug_if(!(spirit_rx_len <= MAX_PACKET_LEN), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+			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;) {
--- a/mbed_driver_api.cpp	Mon Nov 14 15:01:31 2016 +0100
+++ b/mbed_driver_api.cpp	Tue Nov 15 12:07:07 2016 +0100
@@ -41,7 +41,6 @@
     {CHANNEL_PAGE_0, NULL}
 };
 
-static uint8_t need_ack = 0;
 static uint8_t tx_sequence = 0xff;
 static uint8_t mac_tx_handle = 0;
 
@@ -54,12 +53,12 @@
 
 #define RF_SIG_ACK_NEEDED (1<<0)
 static Thread rf_ack_sender(osPriorityRealtime);
-static uint8_t rf_rx_sequence;
+static volatile uint8_t rf_rx_sequence;
 #ifndef SHORT_ACK_FRAMES
-static uint8_t rf_src_adr[8];
-static uint8_t rf_src_adr_len = 0;
+static volatile uint8_t rf_src_adr[8];
+static volatile uint8_t rf_src_adr_len = 0;
 #endif
-static bool rf_ack_sent = false;
+static volatile bool rf_ack_sent = false;
 
 /* MAC frame helper macros */
 #define MAC_FCF_FRAME_TYPE_MASK         0x0007
@@ -126,11 +125,15 @@
     } else {
     	uint16_t fcf = rf_read_16_bit(data_ptr);
 
+#ifdef HEAVY_TRACING
+    	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;
     	else
     		need_ack = 0;
+#endif
 
     	/*Store the sequence number for ACK handling*/
     	tx_sequence = *(data_ptr + 2);
@@ -138,14 +141,14 @@
     	/*Store TX handle*/
     	mac_tx_handle = tx_handle;
 
-// #ifdef HEAVY_TRACING
+#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,
-    			data_ptr[3], data_ptr[4], data_ptr[5], data_ptr[6],
+				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
+#endif
 
-        /*Send the packet*/
+    	    	    	/*Send the packet*/
         rf_device->send(data_ptr, data_length);
 
     	/* Release Lock */
@@ -211,8 +214,8 @@
 
         /*Return frame pending status*/
         case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS:
-        	tr_debug("%s (%d), need_ack=%x", __func__, __LINE__, (unsigned int)need_ack);
-            *data_ptr = need_ack;
+        	tr_debug("%s (%d)", __func__, __LINE__);
+            *data_ptr = 0;
             break;
 
         /*Set channel, used for setting channel for energy scan*/
@@ -274,7 +277,6 @@
 
 static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr)
 {
-
     switch (address_type)
     {
         /*Set 48-bit address*/
@@ -305,16 +307,17 @@
     /*Received ACK sequence must be equal with transmitted packet sequence*/
     if(tx_sequence == seq_number)
     {
-    	/* Reset 'need_ack' */
-    	need_ack = 0;
+#ifdef HEAVY_TRACING
+    	tr_info("%s (%d)", __func__, __LINE__);
+#endif
 
-    	/*Call PHY TX Done API*/
+    			/*Call PHY TX Done API*/
         if(device_driver.phy_tx_done_cb){
             device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_DONE, 0, 0);
         }
     } else {
 #ifdef HEAVY_TRACING
-		tr_debug("%s (%d)", __func__, __LINE__);
+		tr_info("%s (%d)", __func__, __LINE__);
 #endif
     }
 }
@@ -337,9 +340,9 @@
 	uint8_t src_addr_mode = 0x0; /*0x00 = no address 0x01 = reserved 0x02 = 16-bit short address 0x03 = 64-bit extended address */
 	uint8_t min_size = 3; // FCF & SeqNr
 	bool ret = false;
-// #if !defined(SHORT_ACK_FRAMES) || defined(HEAVY_TRACING)
+#if !defined(SHORT_ACK_FRAMES) || defined(HEAVY_TRACING)
 	bool panid_compr = false;
-// #endif
+#endif
 
 	if(len < 3) {
     	tr_debug("%s (%d)", __func__, __LINE__);
@@ -355,10 +358,10 @@
 	panid_compr = ((fcf & MAC_FCF_INTRA_PANID_MASK) >> MAC_FCF_INTRA_PANID_SHIFT);
 #endif
 
-// #ifdef HEAVY_TRACING
+#ifdef HEAVY_TRACING
 	tr_info("%s (%d): len=%d, ftype=%x, snr=%x, ack=%d, dst=%x, src=%x, intra=%d", __func__, __LINE__, len, frame_type,
 			rf_rx_buf[2], (*ack_requested), dst_addr_mode, src_addr_mode, panid_compr);
-// #endif
+#endif
 
 	if(frame_type == FC_ACK_FRAME) { // betzw: we support up to two different forms of ACK frames!
 #ifdef SHORT_ACK_FRAMES
@@ -392,7 +395,7 @@
 #endif // !SHORT_ACK_FRAMES
 
 #ifdef HEAVY_TRACING
-		tr_debug("%s (%d): ret=%d", __func__, __LINE__, ret);
+		tr_info("%s (%d): ret=%d", __func__, __LINE__, ret);
 #endif
 		(*ack_requested) = 0;  // Never acknowledge ACK frames
 		return ret;
@@ -696,7 +699,7 @@
 		/* Wait for device not receiving */
 		while(rf_device->is_receiving()) {
 #ifdef HEAVY_TRACING
-	    	tr_debug("%s (%d)", __func__, __LINE__);
+	    	tr_info("%s (%d)", __func__, __LINE__);
 #endif
 			wait_us(10);
 		}
@@ -792,10 +795,21 @@
 #endif // !SHORT_ACK_FRAMES
 
 static void rf_init(void) {
+#ifndef NDEBUG
+	osStatus ret;
+#endif
+
 	rf_device = &SimpleSpirit1::CreateInstance(D11, D12, D13, D9, D10, D2);
 	rf_device->attach_irq_callback(rf_callback_func);
 
+#ifndef NDEBUG
+	ret =
+#endif
 	rf_ack_sender.start(rf_ack_loop);
+
+#ifndef NDEBUG
+	debug_if(!(ret == osOK), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
 }
 
 extern "C" int8_t rf_device_register(void)