Prototype RF driver for STM Sub-1 GHz RF expansion board based on the SPSGRF-868 module for STM32 Nucleo.
Dependents: DISCO_IOT-wifi_client
Fork of stm-spirit1-rf-driver by
Revision 25:2ec45788f28c, committed 2016-11-14
- Comitter:
- Wolfgang Betz
- Date:
- Mon Nov 14 11:26:03 2016 +0100
- Parent:
- 24:03e351bfc9c9
- Child:
- 26:45dae8d48029
- Commit message:
- Enable the automatic RCO calibration
Changed in this revision
--- a/SimpleSpirit1.cpp Thu Nov 10 15:25:59 2016 +0100
+++ b/SimpleSpirit1.cpp Mon Nov 14 11:26:03 2016 +0100
@@ -4,7 +4,7 @@
#define SPIRIT_GPIO_IRQ (SPIRIT_GPIO_3)
-#define SPIRIT1_STATUS() (arch_refresh_status() & SPIRIT1_STATE_STATEBITS)
+#define SPIRIT1_STATUS() (((uint16_t)refresh_state()) & SPIRIT1_STATE_STATEBITS)
#define BUSYWAIT_UNTIL(cond, millisecs) \
do { \
@@ -17,6 +17,7 @@
#define st_lib_spirit_irqs SpiritIrqs
+#define STATE_TIMEOUT (1000)
/*** Class Implementation ***/
/** Static Class Variables **/
@@ -119,9 +120,8 @@
timer_set_rx_timeout_stop_condition(SQI_ABOVE_THRESHOLD);
timer_set_infinite_rx_timeout();
radio_afc_freeze_on_sync(S_ENABLE);
+ calibration_rco(S_ENABLE);
- /* Puts the SPIRIT1 in STANDBY mode (125us -> rx/tx) */
- cmd_strobe(SPIRIT1_STROBE_STANDBY);
spirit_on = OFF;
CLEAR_TXBUF();
CLEAR_RXBUF();
@@ -151,6 +151,9 @@
#ifdef RX_FIFO_THR_WA
linear_fifo_set_almost_full_thr_rx(SPIRIT_MAX_FIFO_LEN-(MAX_PACKET_LEN+1));
#endif
+
+ /* Puts the SPIRIT1 in STANDBY mode (125us -> rx/tx) */
+ cmd_strobe(SPIRIT1_STROBE_STANDBY);
}
int SimpleSpirit1::send(const void *payload, unsigned int payload_len) {
@@ -159,12 +162,17 @@
return RADIO_TX_ERR;
}
+#ifndef NDEBUG
+ debug_if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX, "\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, SPIRIT1_STATUS()>>1);
+#endif
+
disable_spirit_irq();
/* Reset State to Ready */
set_ready_state();
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__);
#endif
@@ -200,9 +208,10 @@
enable_spirit_irq();
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 50);
+ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
+
#ifndef NDEBUG
- // debug_if(!(linear_fifo_read_num_elements_tx_fifo() == 0), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+ debug_if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX, "\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, SPIRIT1_STATUS()>>1);
#endif
return RADIO_TX_OK;
@@ -210,16 +219,31 @@
/** Set Ready State **/
void SimpleSpirit1::set_ready_state(void) {
+ uint16_t state;
+
disable_spirit_irq();
_is_receiving = false;
stop_rx_timeout();
- if(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY) {
+ state = SPIRIT1_STATUS();
+ if(state == SPIRIT1_STATE_STANDBY) {
cmd_strobe(SPIRIT1_STROBE_READY);
- } else if(SPIRIT1_STATUS() == SPIRIT1_STATE_RX) {
+ } else if(state == SPIRIT1_STATE_RX) {
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);
+#endif
}
+
+ 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);
+ enable_spirit_irq();
+ return;
+ }
+
irq_clear_status();
enable_spirit_irq();
@@ -231,26 +255,13 @@
disable_spirit_irq();
/* first stop rx/tx */
- cmd_strobe(SPIRIT1_STROBE_SABORT);
-
- /* Clear any pending irqs */
- irq_clear_status();
-
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 3000);
- if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
-#ifndef NDEBUG
- debug("\n\rSpirit1: failed off->ready\n\r");
-#endif
- return 1;
- }
+ set_ready_state();
/* Puts the SPIRIT1 in STANDBY */
cmd_strobe(SPIRIT1_STROBE_STANDBY);
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, 3000);
+ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, STATE_TIMEOUT);
if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) {
-#ifndef NDEBUG
- debug("\n\rSpirit1: failed off->standby\n\r");
-#endif
+ error("\n\rSpirit1: failed to enter standby (%x)\n\r", SPIRIT1_STATUS()>>1);
return 1;
}
@@ -267,28 +278,18 @@
}
int SimpleSpirit1::on(void) {
- cmd_strobe(SPIRIT1_STROBE_SABORT);
if(spirit_on == OFF) {
- /* ensure we are in READY state as we go from there to Rx */
- cmd_strobe(SPIRIT1_STROBE_READY);
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 3000);
- if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
-#ifndef NDEBUG
- debug("\n\rSpirit1: failed to turn on\n\r");
-#endif
- return 1;
+ set_ready_state();
+
+ /* now we go to Rx */
+ 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);
}
- /* now we go to Rx */
cmd_strobe(SPIRIT1_STROBE_FRX);
- cmd_strobe(SPIRIT1_STROBE_RX);
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 3000);
- if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
-#ifndef NDEBUG
- debug("\n\rSpirit1: failed to enter rx\n\r");
-#endif
- return 1;
- }
CLEAR_RXBUF();
_spirit_rx_err = false;
_is_receiving = false;
@@ -302,27 +303,17 @@
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);
+#endif
+
return 0;
}
-uint16_t SimpleSpirit1::arch_refresh_status(void) {
- uint16_t mcstate;
- uint8_t header[2];
- header[0]=READ_HEADER;
- header[1]=MC_STATE1_BASE;
-
- /* Puts the SPI chip select low to start the transaction */
- chip_sync_select();
+uint8_t SimpleSpirit1::refresh_state(void) {
+ uint8_t mcstate;
- /* Write the aHeader bytes and read the SPIRIT1 status bytes */
- mcstate = _spi.write(header[0]);
- mcstate = mcstate<<8;
-
- /* Write the aHeader bytes and read the SPIRIT1 status bytes */
- mcstate |= _spi.write(header[1]);
-
- /* Puts the SPI chip select high to end the transaction */
- chip_sync_unselect();
+ SpiritSpiReadRegisters(MC_STATE0_BASE, 1, &mcstate);
return mcstate;
}
@@ -334,12 +325,11 @@
/* Checks if the RX buffer is empty */
if(IS_RXBUF_EMPTY()) {
CLEAR_RXBUF();
- cmd_strobe(SPIRIT1_STROBE_SABORT);
- cmd_strobe(SPIRIT1_STROBE_READY);
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 3000);
+ set_ready_state();
+
cmd_strobe(SPIRIT1_STROBE_FRX);
cmd_strobe(SPIRIT1_STROBE_RX);
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 3000);
+ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
_spirit_rx_err = false;
_is_receiving = false;
stop_rx_timeout();
@@ -383,23 +373,14 @@
spirit_state = OFF;
}
+#ifndef NDEBUG
+ debug_if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX, "\n\rassert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, SPIRIT1_STATUS()>>1);
+#endif
+
disable_spirit_irq();
/* Reset State to Ready */
set_ready_state();
- {
- uint32_t timeout = us_ticker_read() + 5000;
- do {
- mgmt_refresh_status();
- } while((st_lib_g_x_status.MC_STATE != MC_STATE_READY) && (us_ticker_read() < timeout));
- if(st_lib_g_x_status.MC_STATE != MC_STATE_READY) {
- enable_spirit_irq();
-#ifndef NDEBUG
- debug("\n\rSpirit1: channel clear failed\n\r");
-#endif
- return 1;
- }
- }
/* Stores the RSSI value */
rssi_value = qi_get_rssi_dbm();
@@ -409,16 +390,29 @@
/* Puts the SPIRIT1 in its previous state */
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);
+#endif
} else {
disable_spirit_irq();
- cmd_strobe(SPIRIT1_STROBE_FRX);
+
+ set_ready_state();
+
cmd_strobe(SPIRIT1_STROBE_RX);
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 10);
+ 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);
+ }
+
CLEAR_RXBUF();
_spirit_rx_err = false;
_is_receiving = false;
stop_rx_timeout();
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);
+#endif
}
/* Checks the RSSI value with the threshold */
@@ -440,7 +434,6 @@
/* get interrupt source from radio */
irq_get_status(&x_irq_status);
- // betzw - WAS: irq_clear_status(); BUT already cleared by get status!
/* Reception errors */
if((x_irq_status.IRQ_RX_FIFO_ERROR) || (x_irq_status.IRQ_RX_DATA_DISC) || (x_irq_status.IRQ_RX_TIMEOUT)) {
@@ -469,6 +462,7 @@
#endif
csma_ca_state(S_DISABLE); // disable CSMA/CA
cmd_strobe(SPIRIT1_STROBE_FTX);
+ cmd_strobe(SPIRIT1_STROBE_RX);
if(_spirit_tx_started) {
_spirit_tx_started = false;
CLEAR_TXBUF();
@@ -548,18 +542,13 @@
cmd_strobe(SPIRIT1_STROBE_FRX);
} else {
spirit_rx_len = pkt_basic_get_received_pkt_length();
- unsigned int remaining = 0;
- // uint8_t fifo_available = 0; // betzw: optimized out in favor of a request less to SPIRIT device
- uint8_t to_receive = 0;
#ifndef NDEBUG
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;) {
- remaining = spirit_rx_len - _spirit_rx_pos;
- // fifo_available = linear_fifo_read_num_elements_rx_fifo(); // betzw: optimized out in favor of a request less to SPIRIT device
- to_receive = remaining; // betzw - WAS: (remaining < fifo_available) ? remaining : fifo_available;
+ uint8_t to_receive = spirit_rx_len - _spirit_rx_pos;
if(to_receive > 0) {
spi_read_linear_fifo(to_receive, &spirit_rx_buf[_spirit_rx_pos]);
_spirit_rx_pos += to_receive;
--- a/SimpleSpirit1.h Thu Nov 10 15:25:59 2016 +0100
+++ b/SimpleSpirit1.h Mon Nov 14 11:26:03 2016 +0100
@@ -134,11 +134,14 @@
void chip_select() { _chip_select = 0; }
void chip_unselect() { _chip_select = 1; }
- void enter_shutdown() { _shut_down = 1; }
+ void enter_shutdown() {
+ _shut_down = 1;
+ wait_ms(5); // wait 5 milliseconds (to allow Spirit1 to shut down)
+ }
+
void exit_shutdown() {
- wait_ms(2); // wait two milliseconds (to allow Spirit1 to shut down)
_shut_down = 0;
- wait_ms(10); // wait ten milliseconds (to allow Spirit1 a proper boot-up sequence)
+ wait_ms(10); // wait 10 milliseconds (to allow Spirit1 a proper boot-up sequence)
}
void cs_to_sclk_delay(void) {
@@ -314,9 +317,14 @@
SpiritLinearFifoSetAlmostFullThresholdRx(cThrRxFifo);
}
+ /** Calibration Instance Methods **/
+ void calibration_rco(SpiritFunctionalState xNewState) {
+ SpiritCalibrationRco(xNewState);
+ }
+
/** Internal Spirit Methods */
void set_ready_state(void);
- uint16_t arch_refresh_status(void);
+ uint8_t refresh_state(void);
/** Friend Functions **/
friend StatusBytes SdkEvalSpiWriteRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer);
@@ -345,7 +353,7 @@
}
/** Init Instance Method **/
- void init(void);
+ void init();
/** Spirit Irq Callback */
void IrqHandler();
@@ -444,7 +452,7 @@
}
/** Reset Board **/
- void reset_board(void) {
+ void reset_board() {
init();
}
};
--- a/mbed_driver_api.cpp Thu Nov 10 15:25:59 2016 +0100
+++ b/mbed_driver_api.cpp Mon Nov 14 11:26:03 2016 +0100
@@ -138,10 +138,12 @@
/*Store TX handle*/
mac_tx_handle = tx_handle;
- tr_debug("%s (%d), len=%d, tx_handle=%x, tx_seq=%x, need_ack=%d (%x:%x, %x:%x, %x:%x, %x:%x)", __func__, __LINE__,
+// #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);
@@ -335,9 +337,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__);
@@ -353,10 +355,10 @@
panid_compr = ((fcf & MAC_FCF_INTRA_PANID_MASK) >> MAC_FCF_INTRA_PANID_SHIFT);
#endif
-#ifdef HEAVY_TRACING
- tr_debug("%s (%d): len=%d, ftype=%x, snr=%x, ack=%d, dst=%x, src=%x, intra=%d", __func__, __LINE__, len, frame_type,
+// #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
@@ -542,7 +544,7 @@
}
#ifdef HEAVY_TRACING
- tr_debug("%s (%d), ret=%d, ack=%d", __func__, __LINE__, ret, (*ack_requested));
+ tr_info("%s (%d), ret=%d, ack=%d", __func__, __LINE__, ret, (*ack_requested));
#endif
return ret;
}
@@ -565,7 +567,11 @@
if(!rf_buffer_len)
return;
- /* Check if packet should be accepted */
+#ifdef HEAVY_TRACING
+ tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+
+ /* Check if packet should be accepted */
if(!rf_check_destination(rf_buffer_len, &ack_requested)) {
#ifdef HEAVY_TRACING
tr_debug("%s (%d)", __func__, __LINE__);
