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 26:45dae8d48029, committed 2016-11-14
- Comitter:
- Wolfgang Betz
- Date:
- Mon Nov 14 15:01:31 2016 +0100
- Parent:
- 25:2ec45788f28c
- Child:
- 27:e68ffb6ac223
- Commit message:
- Set SPI clock freq to 1MHz
Changed in this revision
| SimpleSpirit1.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/SimpleSpirit1.cpp Mon Nov 14 11:26:03 2016 +0100
+++ b/SimpleSpirit1.cpp Mon Nov 14 15:01:31 2016 +0100
@@ -4,7 +4,8 @@
#define SPIRIT_GPIO_IRQ (SPIRIT_GPIO_3)
-#define SPIRIT1_STATUS() (((uint16_t)refresh_state()) & SPIRIT1_STATE_STATEBITS)
+static uint16_t last_state;
+#define SPIRIT1_STATUS() (last_state = (((uint16_t)refresh_state()) & SPIRIT1_STATE_STATEBITS))
#define BUSYWAIT_UNTIL(cond, millisecs) \
do { \
@@ -48,7 +49,7 @@
/* configure spi */
_spi.format(8, 0); /* 8-bit, mode = 0, [order = SPI_MSB] only available in mbed3 */
- _spi.frequency(5000000); // 5MHz
+ _spi.frequency(1000000); // 1MHz
/* install irq handler */
_irq.mode(PullUp);
@@ -163,7 +164,9 @@
}
#ifndef NDEBUG
- debug_if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX, "\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, SPIRIT1_STATUS()>>1);
+ if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
+ debug("\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+ }
#endif
disable_spirit_irq();
@@ -178,26 +181,24 @@
#endif
pkt_basic_set_payload_length(payload_len); // set desired payload len
+
+#ifdef RX_FIFO_THR_WA
+ // betzw - TODO: seems to be incompatible with TX FIFO usage (to be investigated)
csma_ca_state(S_ENABLE); // enable CSMA/CA
+#endif
+
+ cmd_strobe(SPIRIT1_STROBE_TX);
int i = 0;
int remaining = payload_len;
- bool trigger_tx = true;
+ const uint8_t *buffer = (const uint8_t*)payload;
do {
uint8_t fifo_available = SPIRIT_MAX_FIFO_LEN - linear_fifo_read_num_elements_tx_fifo();
uint8_t to_send = (remaining > fifo_available) ? fifo_available : remaining;
- const uint8_t *buffer = (const uint8_t*)payload;
/* Fill FIFO Buffer */
- spi_write_linear_fifo(to_send, (uint8_t*)&buffer[i]);
-
- /* Start Transmit FIFO Buffer */
- if(trigger_tx) {
-#ifndef NDEBUG
- debug_if(!(linear_fifo_read_num_elements_tx_fifo() == to_send), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
-#endif
- cmd_strobe(SPIRIT1_STROBE_TX);
- trigger_tx = false;
+ if(to_send > 0) {
+ spi_write_linear_fifo(to_send, (uint8_t*)&buffer[i]);
}
i += to_send;
@@ -211,7 +212,9 @@
BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
#ifndef NDEBUG
- debug_if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX, "\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, SPIRIT1_STATUS()>>1);
+ if(last_state != SPIRIT1_STATE_RX) {
+ debug("\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+ }
#endif
return RADIO_TX_OK;
@@ -238,8 +241,8 @@
}
BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, STATE_TIMEOUT);
- if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
- error("\n\rSpirit1: failed to become ready (%x) => pls. reset!\n\r", SPIRIT1_STATUS()>>1);
+ if(last_state != SPIRIT1_STATE_READY) {
+ error("\n\rSpirit1: failed to become ready (%x) => pls. reset!\n\r", last_state>>1);
enable_spirit_irq();
return;
}
@@ -260,8 +263,8 @@
/* Puts the SPIRIT1 in STANDBY */
cmd_strobe(SPIRIT1_STROBE_STANDBY);
BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, STATE_TIMEOUT);
- if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) {
- error("\n\rSpirit1: failed to enter standby (%x)\n\r", SPIRIT1_STATUS()>>1);
+ if(last_state != SPIRIT1_STATE_STANDBY) {
+ error("\n\rSpirit1: failed to enter standby (%x)\n\r", last_state>>1);
return 1;
}
@@ -285,8 +288,8 @@
cmd_strobe(SPIRIT1_STROBE_RX);
BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
- if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
- error("\n\rSpirit1: failed to enter rx (%x) => retry\n\r", SPIRIT1_STATUS()>>1);
+ if(last_state != SPIRIT1_STATE_RX) {
+ error("\n\rSpirit1: failed to enter rx (%x) => retry\n\r", last_state>>1);
}
cmd_strobe(SPIRIT1_STROBE_FRX);
@@ -304,7 +307,9 @@
}
#ifndef NDEBUG
- debug_if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX, "\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, SPIRIT1_STATUS()>>1);
+ if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
+ debug("\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+ }
#endif
return 0;
@@ -374,7 +379,9 @@
}
#ifndef NDEBUG
- debug_if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX, "\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, SPIRIT1_STATUS()>>1);
+ if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
+ debug("\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+ }
#endif
disable_spirit_irq();
@@ -391,7 +398,9 @@
if(spirit_state==OFF) {
off();
#ifndef NDEBUG
- debug_if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY, "\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, SPIRIT1_STATUS()>>1);
+ if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) {
+ debug("\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+ }
#endif
} else {
disable_spirit_irq();
@@ -400,8 +409,8 @@
cmd_strobe(SPIRIT1_STROBE_RX);
BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
- if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
- error("\n\rSpirit1: (#2) failed to enter rx (%x) => retry\n\r", SPIRIT1_STATUS()>>1);
+ if(last_state != SPIRIT1_STATE_RX) {
+ error("\n\rSpirit1: (#2) failed to enter rx (%x) => retry\n\r", last_state>>1);
}
CLEAR_RXBUF();
@@ -411,7 +420,9 @@
enable_spirit_irq();
#ifndef NDEBUG
- debug_if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX, "\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, SPIRIT1_STATUS()>>1);
+ if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
+ debug("\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+ }
#endif
}
@@ -436,7 +447,7 @@
irq_get_status(&x_irq_status);
/* Reception errors */
- if((x_irq_status.IRQ_RX_FIFO_ERROR) || (x_irq_status.IRQ_RX_DATA_DISC) || (x_irq_status.IRQ_RX_TIMEOUT)) {
+ if((x_irq_status.IRQ_RX_FIFO_ERROR) || (x_irq_status.IRQ_RX_DATA_DISC)) {
#ifndef NDEBUG
debug("\n\r%s (%d)", __func__, __LINE__);
#endif
X-NUCLEO-IDS01A4 Sub-1GHz RF Expansion Board