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 Jul 06 14:15:57 2017 +0200
Parent:
67:93bec0baf1de
Child:
69:22e9b407effa
Commit message:
Better handling of persisten CCA timeouts

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
stm-spirit1-rf-driver/SimpleSpirit1.h Show annotated file Show diff for this revision Revisions of this file
--- a/source/NanostackRfPhySpirit1.cpp	Thu Jul 06 11:13:31 2017 +0200
+++ b/source/NanostackRfPhySpirit1.cpp	Thu Jul 06 14:15:57 2017 +0200
@@ -64,12 +64,12 @@
 #define FC_ACK_FRAME            0x02
 #define FC_CMD_FRAME            0x03
 
-static void rf_if_lock(void)
+static inline void rf_if_lock(void)
 {
     platform_enter_critical();
 }
 
-static void rf_if_unlock(void)
+static inline void rf_if_unlock(void)
 {
     platform_exit_critical();
 }
@@ -81,205 +81,6 @@
     return ret;
 }
 
-static int8_t rf_trigger_send(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol)
-{
-#ifndef NDEBUG
-    debug_if(!(data_length >= 3), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
-#endif
-
-    /* Give 'rf_ack_sender' a better chance to run */
-    Thread::yield();
-
-    /* Get Lock */
-    rf_if_lock();
-
-    /*Check if transmitter is busy*/
-    if(rf_device->is_receiving()) { /* betzw - WAS: (rf_device->channel_clear() != 0)), do NOT use this but rather study and enable automatic CCA */
-#ifdef HEAVY_TRACING
-        tr_debug("%s (%d)", __func__, __LINE__);
-#endif
-
-        /* Release Lock */
-        rf_if_unlock();
-
-        /*Return busy*/
-        return -1;
-    } else {
-        uint16_t fcf = rf_read_16_bit(data_ptr);
-
-        /*Check if transmitted data needs to be acked*/
-        if((fcf & MAC_FCF_ACK_REQ_BIT_MASK) >> MAC_FCF_ACK_REQ_BIT_SHIFT)
-            need_ack = true;
-        else
-            need_ack = false;
-
-        /*Store the sequence number for ACK handling*/
-        tx_sequence = *(data_ptr + 2);
-
-        /*Store TX handle*/
-        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,
-                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
-
-        /*Send the packet*/
-        rf_device->send(data_ptr, data_length);
-
-        /* Release Lock */
-        rf_if_unlock();
-    }
-
-    /*Return success*/
-    return 0;
-}
-
-static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel)
-{
-    int8_t ret_val = 0;
-    switch (new_state)
-    {
-        /*Reset PHY driver and set to idle*/
-        case PHY_INTERFACE_RESET:
-            tr_debug("%s (%d)", __func__, __LINE__);
-            rf_device->reset_board();
-            break;
-            /*Disable PHY Interface driver*/
-        case PHY_INTERFACE_DOWN:
-            tr_debug("%s (%d)", __func__, __LINE__);
-            ret_val = rf_device->off();
-            if(ret_val != 0) ret_val = -1;
-            break;
-            /*Enable PHY Interface driver*/
-        case PHY_INTERFACE_UP:
-            ret_val = rf_device->on();
-            if(ret_val != 0) {
-                tr_debug("%s (%d)", __func__, __LINE__);
-                ret_val = -1;
-                break;
-            }
-            tr_debug("%s (%d) - channel: %d", __func__, __LINE__, (int)rf_channel);
-            rf_device->set_channel(rf_channel);
-            break;
-            /*Enable wireless interface ED scan mode*/
-        case PHY_INTERFACE_RX_ENERGY_STATE:
-            tr_debug("%s (%d)", __func__, __LINE__);
-            break;
-            /*Enable Sniffer state*/
-        case PHY_INTERFACE_SNIFFER_STATE:
-            // TODO - if we really need this - WAS: rf_setup_sniffer(rf_channel);
-            tr_debug("%s (%d)", __func__, __LINE__);
-            ret_val = -1;
-            break;
-        default:
-            tr_debug("%s (%d)", __func__, __LINE__);
-            break;
-    }
-    return ret_val;
-}
-
-static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr)
-{
-    switch (extension_type)
-    {
-        /*Control MAC pending bit for Indirect data transmission*/
-        case PHY_EXTENSION_CTRL_PENDING_BIT:
-            tr_debug("%s (%d)", __func__, __LINE__);
-            break;
-
-            /*Return frame pending status*/
-        case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS:
-            tr_debug("%s (%d)", __func__, __LINE__);
-            *data_ptr = 0;
-            break;
-
-            /*Set channel, used for setting channel for energy scan*/
-        case PHY_EXTENSION_SET_CHANNEL:
-            tr_debug("%s (%d)", __func__, __LINE__);
-            break;
-
-            /*Read energy on the channel*/
-        case PHY_EXTENSION_READ_CHANNEL_ENERGY:
-            // TODO: *data_ptr = rf_get_channel_energy();
-            tr_debug("%s (%d)", __func__, __LINE__);
-            *data_ptr = (int8_t)rf_device->get_last_rssi_dbm();
-            break;
-
-            /*Read status of the link*/
-        case PHY_EXTENSION_READ_LINK_STATUS:
-            // TODO: *data_ptr = rf_get_link_status();
-            tr_debug("%s (%d)", __func__, __LINE__);
-            *data_ptr = rf_device->get_last_sqi(); // use SQI as link quality
-            break;
-
-        default:
-            tr_debug("%s (%d)", __func__, __LINE__);
-            break;
-    }
-    return 0;
-}
-
-static inline void rf_set_mac_address(uint8_t *ptr) {
-    tr_debug("%s (%d), adr0=%x, adr1=%x, adr2=%x, adr3=%x, adr4=%x, adr5=%x, adr6=%x, adr7=%x",
-             __func__, __LINE__,
-             ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]);
-    for(int i = 0; i < 8; i++) {
-        stored_mac_address[i] = ptr[i];
-    }
-}
-
-static inline void rf_get_mac_address(uint8_t *ptr) {
-    for(int i = 0; i < 8; i++) {
-        ptr[i] = stored_mac_address[i];
-    }
-    tr_debug("%s (%d), adr0=%x, adr1=%x, adr2=%x, adr3=%x, adr4=%x, adr5=%x, adr6=%x, adr7=%x",
-             __func__, __LINE__,
-             ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]);
-}
-
-static inline void rf_set_short_adr(uint8_t *ptr) {
-    stored_short_adr = (ptr[0] << 8) + ptr[1]; // big-endian
-    tr_debug("%s (%d), adr0=%x, adr1=%x, val=%d",
-             __func__, __LINE__,
-             ptr[0], ptr[1], stored_short_adr);
-}
-
-static inline void rf_set_pan_id(uint8_t *ptr) {
-    stored_pan_id = (ptr[0] << 8) + ptr[1]; // big-endian
-    tr_debug("%s (%d), adr0=%x, adr1=%x, val=%d",
-            __func__, __LINE__,
-            ptr[0], ptr[1], stored_pan_id);
-}
-
-static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr)
-{
-    switch (address_type)
-    {
-        /*Set 48-bit address*/
-        case PHY_MAC_48BIT:
-            /* Not used in this example */
-            // betzw - WAS: rf_set_mac_48bit(address_ptr);
-            break;
-            /*Set 64-bit address*/
-        case PHY_MAC_64BIT:
-            rf_set_mac_address(address_ptr);
-            break;
-            /*Set 16-bit address*/
-        case PHY_MAC_16BIT:
-            rf_set_short_adr(address_ptr);
-            break;
-            /*Set PAN Id*/
-        case PHY_MAC_PANID:
-            rf_set_pan_id(address_ptr);
-            break;
-    }
-
-    return 0;
-}
-
 /* Note: we are in IRQ context */
 static inline void rf_send_signal(int32_t signal) {
 #ifdef HEAVY_TRACING
@@ -568,12 +369,12 @@
     }
 }
 
-/* Note: we are in IRQ context */
-static inline void rf_handle_tx_err(void) {
+/* Note: we might be in IRQ context */
+static inline void rf_handle_tx_err(phy_link_tx_status_e phy_val = PHY_LINK_TX_FAIL) {
     /*Call PHY TX Done API*/
     if(device_driver.phy_tx_done_cb){
         need_ack = false;
-        phy_status = PHY_LINK_TX_FAIL;
+        phy_status = phy_val;
         rf_send_signal(RF_SIG_CB_TX_DONE);
     }
 }
@@ -596,6 +397,208 @@
     }
 }
 
+static int8_t rf_trigger_send(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol)
+{
+#ifndef NDEBUG
+    debug_if(!(data_length >= 3), "\r\nassert failed in: %s (%d)\r\n", __func__, __LINE__);
+#endif
+
+    /* Give 'rf_ack_sender' a better chance to run */
+    Thread::yield();
+
+    /* Get Lock */
+    rf_if_lock();
+
+    /*Check if transmitter is busy*/
+    if(rf_device->is_receiving()) { /* betzw - WAS: (rf_device->channel_clear() != 0)), do NOT use this but rather study and enable automatic CCA */
+#ifdef HEAVY_TRACING
+        tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+
+        /* Release Lock */
+        rf_if_unlock();
+
+        /*Return busy*/
+        return -1;
+    } else {
+        uint16_t fcf = rf_read_16_bit(data_ptr);
+
+        /*Check if transmitted data needs to be acked*/
+        if((fcf & MAC_FCF_ACK_REQ_BIT_MASK) >> MAC_FCF_ACK_REQ_BIT_SHIFT)
+            need_ack = true;
+        else
+            need_ack = false;
+
+        /*Store the sequence number for ACK handling*/
+        tx_sequence = *(data_ptr + 2);
+
+        /*Store TX handle*/
+        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,
+                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
+
+        /*Send the packet*/
+        int ret = rf_device->send(data_ptr, data_length);
+        if(ret != RADIO_TX_OK) {
+            rf_handle_tx_err(PHY_LINK_CCA_FAIL);
+        }
+
+        /* Release Lock */
+        rf_if_unlock();
+    }
+
+    /*Return success*/
+    return 0;
+}
+
+static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel)
+{
+    int8_t ret_val = 0;
+    switch (new_state)
+    {
+        /*Reset PHY driver and set to idle*/
+        case PHY_INTERFACE_RESET:
+            tr_debug("%s (%d)", __func__, __LINE__);
+            rf_device->reset_board();
+            break;
+            /*Disable PHY Interface driver*/
+        case PHY_INTERFACE_DOWN:
+            tr_debug("%s (%d)", __func__, __LINE__);
+            ret_val = rf_device->off();
+            if(ret_val != 0) ret_val = -1;
+            break;
+            /*Enable PHY Interface driver*/
+        case PHY_INTERFACE_UP:
+            ret_val = rf_device->on();
+            if(ret_val != 0) {
+                tr_debug("%s (%d)", __func__, __LINE__);
+                ret_val = -1;
+                break;
+            }
+            tr_debug("%s (%d) - channel: %d", __func__, __LINE__, (int)rf_channel);
+            rf_device->set_channel(rf_channel);
+            break;
+            /*Enable wireless interface ED scan mode*/
+        case PHY_INTERFACE_RX_ENERGY_STATE:
+            tr_debug("%s (%d)", __func__, __LINE__);
+            break;
+            /*Enable Sniffer state*/
+        case PHY_INTERFACE_SNIFFER_STATE:
+            // TODO - if we really need this - WAS: rf_setup_sniffer(rf_channel);
+            tr_debug("%s (%d)", __func__, __LINE__);
+            ret_val = -1;
+            break;
+        default:
+            tr_debug("%s (%d)", __func__, __LINE__);
+            break;
+    }
+    return ret_val;
+}
+
+static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr)
+{
+    switch (extension_type)
+    {
+        /*Control MAC pending bit for Indirect data transmission*/
+        case PHY_EXTENSION_CTRL_PENDING_BIT:
+            tr_debug("%s (%d)", __func__, __LINE__);
+            break;
+
+            /*Return frame pending status*/
+        case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS:
+            tr_debug("%s (%d)", __func__, __LINE__);
+            *data_ptr = 0;
+            break;
+
+            /*Set channel, used for setting channel for energy scan*/
+        case PHY_EXTENSION_SET_CHANNEL:
+            tr_debug("%s (%d)", __func__, __LINE__);
+            break;
+
+            /*Read energy on the channel*/
+        case PHY_EXTENSION_READ_CHANNEL_ENERGY:
+            // TODO: *data_ptr = rf_get_channel_energy();
+            tr_debug("%s (%d)", __func__, __LINE__);
+            *data_ptr = (int8_t)rf_device->get_last_rssi_dbm();
+            break;
+
+            /*Read status of the link*/
+        case PHY_EXTENSION_READ_LINK_STATUS:
+            // TODO: *data_ptr = rf_get_link_status();
+            tr_debug("%s (%d)", __func__, __LINE__);
+            *data_ptr = rf_device->get_last_sqi(); // use SQI as link quality
+            break;
+
+        default:
+            tr_debug("%s (%d)", __func__, __LINE__);
+            break;
+    }
+    return 0;
+}
+
+static inline void rf_set_mac_address(uint8_t *ptr) {
+    tr_debug("%s (%d), adr0=%x, adr1=%x, adr2=%x, adr3=%x, adr4=%x, adr5=%x, adr6=%x, adr7=%x",
+             __func__, __LINE__,
+             ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]);
+    for(int i = 0; i < 8; i++) {
+        stored_mac_address[i] = ptr[i];
+    }
+}
+
+static inline void rf_get_mac_address(uint8_t *ptr) {
+    for(int i = 0; i < 8; i++) {
+        ptr[i] = stored_mac_address[i];
+    }
+    tr_debug("%s (%d), adr0=%x, adr1=%x, adr2=%x, adr3=%x, adr4=%x, adr5=%x, adr6=%x, adr7=%x",
+             __func__, __LINE__,
+             ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]);
+}
+
+static inline void rf_set_short_adr(uint8_t *ptr) {
+    stored_short_adr = (ptr[0] << 8) + ptr[1]; // big-endian
+    tr_debug("%s (%d), adr0=%x, adr1=%x, val=%d",
+             __func__, __LINE__,
+             ptr[0], ptr[1], stored_short_adr);
+}
+
+static inline void rf_set_pan_id(uint8_t *ptr) {
+    stored_pan_id = (ptr[0] << 8) + ptr[1]; // big-endian
+    tr_debug("%s (%d), adr0=%x, adr1=%x, val=%d",
+            __func__, __LINE__,
+            ptr[0], ptr[1], stored_pan_id);
+}
+
+static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr)
+{
+    switch (address_type)
+    {
+        /*Set 48-bit address*/
+        case PHY_MAC_48BIT:
+            /* Not used in this example */
+            // betzw - WAS: rf_set_mac_48bit(address_ptr);
+            break;
+            /*Set 64-bit address*/
+        case PHY_MAC_64BIT:
+            rf_set_mac_address(address_ptr);
+            break;
+            /*Set 16-bit address*/
+        case PHY_MAC_16BIT:
+            rf_set_short_adr(address_ptr);
+            break;
+            /*Set PAN Id*/
+        case PHY_MAC_PANID:
+            rf_set_pan_id(address_ptr);
+            break;
+    }
+
+    return 0;
+}
+
 static void rf_ack_loop(void) {
     static uint16_t buffer[2] = {
             (FC_ACK_FRAME << MAC_FCF_FRAME_TYPE_SHIFT),
@@ -657,7 +660,8 @@
         }
 
         if(signals & RF_SIG_CB_TX_DONE) {
-            device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, phy_status, 0, 0);
+            device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, phy_status,
+                                         (phy_status == PHY_LINK_CCA_FAIL) ? 0xFF : 0, 0);
 #ifdef HEAVY_TRACING
             tr_debug("%s (%d)", __func__, __LINE__);
 #endif
@@ -694,7 +698,7 @@
                 rf_ack_sender.start(rf_ack_loop);
 
 #ifndef NDEBUG
-        debug_if(!(ret == osOK), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+        debug_if(!(ret == osOK), "\r\nassert failed in: %s (%d)\r\n", __func__, __LINE__);
 #endif
     }
 }
--- a/source/SimpleSpirit1.cpp	Thu Jul 06 11:13:31 2017 +0200
+++ b/source/SimpleSpirit1.cpp	Thu Jul 06 14:15:57 2017 +0200
@@ -172,7 +172,7 @@
 	BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
 #ifndef NDEBUG
 	if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) {
-		debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+		debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1);
 	}
 #endif
 
@@ -182,7 +182,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), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__);
 #endif
 
 	pkt_basic_set_payload_length(payload_len); // set desired payload len
@@ -217,18 +217,21 @@
 
 	BUSYWAIT_UNTIL(!_spirit_tx_started, STATE_TIMEOUT);
 #ifdef HEAVY_DEBUG
-	debug("\n\r%s (%d): state=%x, _spirit_tx_started=%d\n\r", __func__, __LINE__, SPIRIT1_STATUS()>>1, _spirit_tx_started);
+	debug("\r\n%s (%d): state=%x, _spirit_tx_started=%d\r\n", __func__, __LINE__, SPIRIT1_STATUS()>>1, _spirit_tx_started);
 #endif
 
-	_spirit_tx_started = false; // in case of state timeout
-
     if(use_csma_ca) {
         csma_ca_state(S_DISABLE); // disable CSMA/CA
     }
 
 	cmd_strobe(SPIRIT1_STROBE_RX); // Return to RX state
 
-	return RADIO_TX_OK;
+	if(_spirit_tx_started) { // in case of state timeout
+	    _spirit_tx_started = false;
+	    return RADIO_TX_ERR;
+	} else {
+	    return RADIO_TX_OK;
+	}
 }
 
 /** Set Ready State **/
@@ -252,13 +255,13 @@
 		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("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, state>>1);
 #endif
 	}
 
 	BUSYWAIT_UNTIL((SPIRIT1_STATUS() == SPIRIT1_STATE_READY) && ((last_state & XO_ON) == XO_ON), STATE_TIMEOUT);
 	if(last_state != (SPIRIT1_STATE_READY | XO_ON)) {
-		error("\n\rSpirit1: failed to become ready (%x) => pls. reset!\n\r", last_state);
+		error("\r\nSpirit1: failed to become ready (%x) => pls. reset!\r\n", last_state);
 		enable_spirit_irq();
 		return;
 	}
@@ -281,7 +284,7 @@
 		cmd_strobe(SPIRIT1_STROBE_STANDBY);
 		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, STATE_TIMEOUT);
 		if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_STANDBY) {
-			error("\n\rSpirit1: failed to enter standby (%x)\n\r", last_state>>1);
+			error("\r\nSpirit1: failed to enter standby (%x)\r\n", last_state>>1);
 			return 1;
 		}
 #endif // USE_STANDBY_STATE
@@ -301,20 +304,20 @@
 
 		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
 		if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) {
-			error("\n\rSpirit1: failed to enter rx (%x) => retry\n\r", last_state>>1);
+			error("\r\nSpirit1: failed to enter rx (%x) => retry\r\n", last_state>>1);
 		}
 
 		/* 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), "\r\nAssert failed in: %s (%d)\r\n", __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("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1);
 	}
 #endif
 
@@ -336,7 +339,7 @@
 	/* Checks if the RX buffer is empty */
 	if(IS_RXBUF_EMPTY()) {
 #ifndef NDEBUG
-		debug("\n\rBuffer is empty\n\r");
+		debug("\r\nBuffer is empty\r\n");
 #endif
 		set_ready_state();
 
@@ -351,7 +354,7 @@
 
 		/* If buf has the correct size */
 #ifndef NDEBUG
-		debug("\n\rTOO SMALL BUF\n\r");
+		debug("\r\nTOO SMALL BUF\r\n");
 #endif
 		return 0;
 	} else {
@@ -382,7 +385,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("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1);
 	}
 #endif
 
@@ -405,7 +408,7 @@
 #else
 		if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
 #endif
-			debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+			debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1);
 		}
 #endif
 	} else {
@@ -416,14 +419,14 @@
 		cmd_strobe(SPIRIT1_STROBE_RX);
 		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
 		if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) {
-			error("\n\rSpirit1: (#2) failed to enter rx (%x) => retry\n\r", last_state>>1);
+			error("\r\nSpirit1: (#2) failed to enter rx (%x) => retry\r\n", last_state>>1);
 		}
 
 		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("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1);
 		}
 #endif
 	}
@@ -456,9 +459,9 @@
                                          */
 #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__);
-		debug_if(!((*tmp) & IRQ_TX_DATA_SENT_MASK), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
-		debug_if(tx_fifo_remaining != 0, "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+		debug_if(!_spirit_tx_started, "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__);
+		debug_if(!((*tmp) & IRQ_TX_DATA_SENT_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__);
+		debug_if(tx_fifo_remaining != 0, "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__);
 #endif
 
 		tx_fifo_buffer = NULL;
@@ -478,9 +481,9 @@
 	if(x_irq_status.IRQ_TX_FIFO_ALMOST_EMPTY) {
 #ifdef DEBUG_IRQ
 		uint32_t *tmp = (uint32_t*)&x_irq_status;
-		debug_if(!((*tmp) & IRQ_TX_FIFO_ALMOST_EMPTY_MASK), "\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__);
-		debug_if(tx_fifo_buffer == NULL, "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+		debug_if(!((*tmp) & IRQ_TX_FIFO_ALMOST_EMPTY_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__);
+		debug_if(!_spirit_tx_started, "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__);
+		debug_if(tx_fifo_buffer == NULL, "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__);
 #endif
 
 		int8_t fifo_available = SPIRIT_MAX_FIFO_LEN/2; // fill-up half fifo
@@ -500,8 +503,8 @@
 	if(x_irq_status.IRQ_TX_FIFO_ERROR) {
 #ifdef DEBUG_IRQ
 		uint32_t *tmp = (uint32_t*)&x_irq_status;
-		debug("\n\r%s (%d): irq=%x\n\r", __func__, __LINE__, *tmp);
-		debug_if(!((*tmp) & IRQ_TX_FIFO_ERROR_MASK), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+		debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp);
+		debug_if(!((*tmp) & IRQ_TX_FIFO_ERROR_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__);
 #endif
 		if(_spirit_tx_started) {
 			_spirit_tx_started = false;
@@ -519,12 +522,12 @@
 	if(x_irq_status.IRQ_RX_DATA_READY) {
 #ifdef DEBUG_IRQ
 		uint32_t *tmp = (uint32_t*)&x_irq_status;
-		debug_if(!((*tmp) & IRQ_RX_DATA_READY_MASK), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+		debug_if(!((*tmp) & IRQ_RX_DATA_READY_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__);
 #endif
 
 		if(!_is_receiving) { // spurious irq?!? (betzw: see comments on macro 'RX_FIFO_THR_WA'!)
 #ifdef HEAVY_DEBUG
-			debug("\n\r%s (%d): irq=%x\n\r", __func__, __LINE__, *tmp);
+			debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp);
 #endif
 		} else {
 			_is_receiving = false; // Finished receiving
@@ -533,7 +536,7 @@
 			spirit_rx_len = pkt_basic_get_received_pkt_length();
 
 #ifdef DEBUG_IRQ
-			debug_if(!(spirit_rx_len <= MAX_PACKET_LEN), "\n\r%s (%d): irq=%x\n\r", __func__, __LINE__, *tmp);
+			debug_if(!(spirit_rx_len <= MAX_PACKET_LEN), "\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp);
 #endif
 
 			if(spirit_rx_len <= MAX_PACKET_LEN) {
@@ -564,11 +567,11 @@
 	if(x_irq_status.IRQ_RX_FIFO_ALMOST_FULL) {
 #ifdef DEBUG_IRQ
 		uint32_t *tmp = (uint32_t*)&x_irq_status;
-		debug_if(!((*tmp) & IRQ_RX_FIFO_ALMOST_FULL_MASK), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+		debug_if(!((*tmp) & IRQ_RX_FIFO_ALMOST_FULL_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__);
 #endif
 		if(!_is_receiving) { // spurious irq?!?
 #ifdef DEBUG_IRQ
-			debug("\n\r%s (%d): irq=%x\n\r", __func__, __LINE__, *tmp);
+			debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp);
 #endif
 		} else {
 			uint8_t fifo_available = linear_fifo_read_num_elements_rx_fifo();
@@ -577,7 +580,7 @@
 				_spirit_rx_pos += fifo_available;
 			} else {
 #ifdef DEBUG_IRQ
-				debug("\n\r%s (%d): irq=%x\n\r", __func__, __LINE__, *tmp);
+				debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp);
 #endif
 			}
 		}
@@ -588,8 +591,8 @@
 	if((x_irq_status.IRQ_RX_FIFO_ERROR) || (x_irq_status.IRQ_RX_DATA_DISC)) {
 #ifdef DEBUG_IRQ
 		uint32_t *tmp = (uint32_t*)&x_irq_status;
-		debug("\n\r%s (%d): irq=%x\n\r", __func__, __LINE__, *tmp);
-		debug_if(!((*tmp) & (IRQ_RX_FIFO_ERROR_MASK | IRQ_RX_DATA_DISC_MASK)), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+		debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp);
+		debug_if(!((*tmp) & (IRQ_RX_FIFO_ERROR_MASK | IRQ_RX_DATA_DISC_MASK)), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__);
 #endif
 		rx_timeout_handler();
 		if(_spirit_tx_started) {
@@ -605,7 +608,7 @@
 	if(x_irq_status.IRQ_VALID_SYNC) {
 #ifdef DEBUG_IRQ
 		uint32_t *tmp = (uint32_t*)&x_irq_status;
-		debug_if(!((*tmp) & IRQ_VALID_SYNC_MASK), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+		debug_if(!((*tmp) & IRQ_VALID_SYNC_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__);
 #endif
 		/* betzw - NOTE: there is a race condition between Spirit1 receiving packets and
 		 *               the MCU trying to send a packet, which gets resolved in favor of
@@ -613,7 +616,7 @@
 		 */
 		if(_spirit_tx_started) {
 #ifdef DEBUG_IRQ
-			debug("\n\r%s (%d): irq=%x\n\r", __func__, __LINE__, *tmp);
+			debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp);
 #endif
 		} else {
 			_is_receiving = true;
--- a/stm-spirit1-rf-driver/SimpleSpirit1.h	Thu Jul 06 11:13:31 2017 +0200
+++ b/stm-spirit1-rf-driver/SimpleSpirit1.h	Thu Jul 06 14:15:57 2017 +0200
@@ -80,7 +80,7 @@
     	set_ready_state();
 	    cmd_strobe(SPIRIT1_STROBE_RX);
 #ifdef DEBUG_IRQ
-	    debug("\n\r%s (%d)\n\r", __func__, __LINE__);
+	    debug("\r\n%s (%d)\r\n", __func__, __LINE__);
 #endif
     }
 
@@ -119,13 +119,13 @@
     	_irq.disable_irq();
     	_nr_of_irq_disables++;
 #ifndef NDEBUG
-    	debug_if(_nr_of_irq_disables == 0, "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+    	debug_if(_nr_of_irq_disables == 0, "\r\nassert failed in: %s (%d)\r\n", __func__, __LINE__);
 #endif
     }
 
     void enable_spirit_irq(void) {
 #ifndef NDEBUG
-    	debug_if(_nr_of_irq_disables == 0, "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+    	debug_if(_nr_of_irq_disables == 0, "\r\nassert failed in: %s (%d)\r\n", __func__, __LINE__);
 #endif
     	if(--_nr_of_irq_disables == 0)
     		_irq.enable_irq();