Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of stm-spirit1-rf-driver by
Diff: SimpleSpirit1.cpp
- Revision:
- 25:2ec45788f28c
- Parent:
- 24:03e351bfc9c9
- Child:
- 26:45dae8d48029
--- 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;
