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 27:e68ffb6ac223, committed 2016-11-15
- 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)
X-NUCLEO-IDS01A4 Sub-1GHz RF Expansion Board