센서보드 RF IRQ 테스트 중
Fork of stm-spirit1-rf-driver by
Revision 82:a18c22d2b83a, committed 2018-02-02
- Comitter:
- Wolfgang Betz
- Date:
- Fri Feb 02 14:13:24 2018 +0100
- Parent:
- 81:b16caa776548
- Child:
- 83:54b207156a91
- Commit message:
- Correct comments/documentation
Changed in this revision
--- a/source/SimpleSpirit1.cpp Fri Feb 02 09:57:17 2018 +0100
+++ b/source/SimpleSpirit1.cpp Fri Feb 02 14:13:24 2018 +0100
@@ -131,7 +131,6 @@
radio_afc_freeze_on_sync(S_ENABLE);
calibration_rco(S_ENABLE);
- spirit_on = OFF;
CLEAR_TXBUF();
CLEAR_RXBUF();
_spirit_tx_started = false;
@@ -378,6 +377,7 @@
}
+/* betzw - TODO: CCA should be reviewed (completely)! */
int SimpleSpirit1::channel_clear(void)
{
float rssi_value;
@@ -407,228 +407,232 @@
enable_spirit_irq();
/* Puts the SPIRIT1 in its previous state */
- if(spirit_state==OFF) {
+ if(spirit_state == OFF) {
off();
+
#ifndef NDEBUG
#ifdef USE_STANDBY_STATE
if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) {
-#else
- if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
-#endif
- debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1);
- }
-#endif
- } else {
- disable_spirit_irq();
+ debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1);
+ }
+#else // !USE_STANDBY_STATE
+ if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
+ debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1);
+ }
+#endif // !USE_STANDBY_STATE
+#endif // NDEBUG
+ } else { // spirit_state != OFF
+ disable_spirit_irq();
- set_ready_state();
+ set_ready_state();
- cmd_strobe(SPIRIT1_STROBE_RX);
- BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
- if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) {
- error("\r\nSpirit1: (#2) failed to enter rx (%x) => retry\r\n", last_state>>1);
- }
+ cmd_strobe(SPIRIT1_STROBE_RX);
+ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
+ if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) {
+ error("\r\nSpirit1: (#2) failed to enter rx (%x) => retry\r\n", last_state>>1);
+ }
- enable_spirit_irq();
+ enable_spirit_irq();
#ifndef NDEBUG
- if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
- debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1);
+ if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
+ debug("\r\nAssert failed in: %s (%d): state=%x\r\n", __func__, __LINE__, last_state>>1);
+ }
+#endif
+ }
+
+ /* If the received signal strength is above a certain level the medium is considered busy! */
+ /* Compare RSSI value with threshold */
+ if(rssi_value < CCA_THRESHOLD) {
+ return 0; // idle
+ } else {
+ return 1; // busy
+ }
+}
+
+int SimpleSpirit1::get_pending_packet(void)
+{
+ return !IS_RXBUF_EMPTY();
+}
+
+/** Spirit Irq Callback **/
+/* betzw - TODO: use threaded interrupt handling when `MBED_CONF_RTOS_PRESENT` is defined (see `atmel-rf-driver`) */
+void SimpleSpirit1::IrqHandler() {
+ st_lib_spirit_irqs x_irq_status;
+
+ /* get interrupt source from radio */
+ irq_get_status(&x_irq_status);
+
+ /* The IRQ_TX_DATA_SENT notifies the packet has been sent. Puts the SPIRIT1 in RX */
+ if(x_irq_status.IRQ_TX_DATA_SENT) { /* betzw - NOTE: MUST be handled before `IRQ_RX_DATA_READY` for Nanostack integration!
+ Logically, Nanostack only expects the "DONE" after "SUCCESS" (if it gets
+ DONE before SUCCESS, it assumes you're not going to bother to send SUCCESS).
+ */
+#ifdef DEBUG_IRQ
+ uint32_t *tmp = (uint32_t*)&x_irq_status;
+ 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
+
+ if(_spirit_tx_started) {
+ _spirit_tx_started = false;
+
+ /* call user callback */
+ if(_current_irq_callback) {
+ _current_irq_callback(TX_DONE);
}
-#endif
}
- /* Checks the RSSI value with the threshold */
- if(rssi_value<CCA_THRESHOLD) {
- return 0;
- } else {
- return 1;
- }
- }
-
- int SimpleSpirit1::get_pending_packet(void)
- {
- return !IS_RXBUF_EMPTY();
+ /* Disable handling of other TX flags */
+ x_irq_status.IRQ_TX_FIFO_ALMOST_EMPTY = S_RESET;
+ tx_fifo_buffer = NULL;
}
- /** Spirit Irq Callback **/
- /* betzw - TODO: use threaded interrupt handling when `MBED_CONF_RTOS_PRESENT` is defined (see `atmel-rf-driver`) */
- void SimpleSpirit1::IrqHandler() {
- st_lib_spirit_irqs x_irq_status;
-
- /* get interrupt source from radio */
- irq_get_status(&x_irq_status);
-
- /* The IRQ_TX_DATA_SENT notifies the packet has been sent. Puts the SPIRIT1 in RX */
- if(x_irq_status.IRQ_TX_DATA_SENT) { /* betzw - NOTE: MUST be handled before `IRQ_RX_DATA_READY` for Nanostack integration!
- Logically, Nanostack only expects the "DONE" after "SUCCESS" (if it gets
- DONE before SUCCESS, it assumes you're not going to bother to send SUCCESS).
- */
+#ifndef RX_FIFO_THR_WA
+ /* The IRQ_TX_FIFO_ALMOST_EMPTY notifies an nearly empty TX fifo */
+ 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_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__);
+ uint32_t *tmp = (uint32_t*)&x_irq_status;
+ 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
- if(_spirit_tx_started) {
- _spirit_tx_started = false;
+ int8_t fifo_available = SPIRIT_MAX_FIFO_LEN/2; // fill-up half fifo
+ int8_t to_send = (tx_fifo_remaining > fifo_available) ? fifo_available : tx_fifo_remaining;
+
+ tx_fifo_remaining -= to_send;
+
+ /* Fill FIFO Buffer */
+ if(to_send > 0) {
+ spi_write_linear_fifo(to_send, (uint8_t*)&tx_fifo_buffer[tx_buffer_pos]);
+ }
+ tx_buffer_pos += to_send;
+ }
+#endif // !RX_FIFO_THR_WA
+
+ /* TX FIFO underflow/overflow error */
+ if(x_irq_status.IRQ_TX_FIFO_ERROR) {
+#ifdef DEBUG_IRQ
+ uint32_t *tmp = (uint32_t*)&x_irq_status;
+ 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;
+ /* call user callback */
+ if(_current_irq_callback) {
+ _current_irq_callback(TX_ERR);
+ }
+ }
- /* call user callback */
- if(_current_irq_callback) {
- _current_irq_callback(TX_DONE);
+ /* reset data still to be sent */
+ tx_fifo_remaining = 0;
+ }
+
+ /* The IRQ_RX_DATA_READY notifies a new packet arrived */
+ 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), "\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("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp);
+#endif
+ } else {
+ _is_receiving = false; // Finished receiving
+ stop_rx_timeout();
+
+ spirit_rx_len = pkt_basic_get_received_pkt_length();
+
+#ifdef DEBUG_IRQ
+ 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) {
+ 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;
}
}
- /* Disable handling of other TX flags */
- x_irq_status.IRQ_TX_FIFO_ALMOST_EMPTY = S_RESET;
- tx_fifo_buffer = NULL;
- }
-
-#ifndef RX_FIFO_THR_WA
- /* The IRQ_TX_FIFO_ALMOST_EMPTY notifies an nearly empty TX fifo */
- 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), "\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
- int8_t to_send = (tx_fifo_remaining > fifo_available) ? fifo_available : tx_fifo_remaining;
-
- tx_fifo_remaining -= to_send;
+ cmd_strobe(SPIRIT1_STROBE_FRX);
- /* Fill FIFO Buffer */
- if(to_send > 0) {
- spi_write_linear_fifo(to_send, (uint8_t*)&tx_fifo_buffer[tx_buffer_pos]);
- }
- tx_buffer_pos += to_send;
- }
-#endif // !RX_FIFO_THR_WA
+ last_rssi = qi_get_rssi(); //MGR
+ last_sqi = qi_get_sqi(); //MGR
- /* TX FIFO underflow/overflow error */
- if(x_irq_status.IRQ_TX_FIFO_ERROR) {
-#ifdef DEBUG_IRQ
- uint32_t *tmp = (uint32_t*)&x_irq_status;
- 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;
- /* call user callback */
- if(_current_irq_callback) {
- _current_irq_callback(TX_ERR);
- }
+ /* call user callback */
+ if((_spirit_rx_pos == spirit_rx_len) && _current_irq_callback) {
+ _current_irq_callback(RX_DONE);
}
- /* reset data still to be sent */
- tx_fifo_remaining = 0;
+ /* Disable handling of other RX flags */
+ x_irq_status.IRQ_RX_FIFO_ALMOST_FULL = S_RESET;
}
-
- /* The IRQ_RX_DATA_READY notifies a new packet arrived */
- 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), "\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("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp);
-#endif
- } else {
- _is_receiving = false; // Finished receiving
- stop_rx_timeout();
-
- spirit_rx_len = pkt_basic_get_received_pkt_length();
-
-#ifdef DEBUG_IRQ
- 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) {
- 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;
- }
- }
-
- cmd_strobe(SPIRIT1_STROBE_FRX);
-
- last_rssi = qi_get_rssi(); //MGR
- last_sqi = qi_get_sqi(); //MGR
-
- /* call user callback */
- if((_spirit_rx_pos == spirit_rx_len) && _current_irq_callback) {
- _current_irq_callback(RX_DONE);
- }
-
- /* Disable handling of other RX flags */
- x_irq_status.IRQ_RX_FIFO_ALMOST_FULL = S_RESET;
- }
- }
+ }
#ifndef RX_FIFO_THR_WA
- /* RX FIFO almost full */
- if(x_irq_status.IRQ_RX_FIFO_ALMOST_FULL) {
+ /* RX FIFO almost full */
+ 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), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__);
+#endif
+ if(!_is_receiving) { // spurious irq?!?
#ifdef DEBUG_IRQ
- uint32_t *tmp = (uint32_t*)&x_irq_status;
- debug_if(!((*tmp) & IRQ_RX_FIFO_ALMOST_FULL_MASK), "\r\nAssert failed in: %s (%d)\r\n", __func__, __LINE__);
+ debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp);
#endif
- if(!_is_receiving) { // spurious irq?!?
+ } else {
+ uint8_t fifo_available = linear_fifo_read_num_elements_rx_fifo();
+ if((fifo_available + _spirit_rx_pos) <= MAX_PACKET_LEN) {
+ spi_read_linear_fifo(fifo_available, &spirit_rx_buf[_spirit_rx_pos]);
+ _spirit_rx_pos += fifo_available;
+ } else {
#ifdef DEBUG_IRQ
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();
- if((fifo_available + _spirit_rx_pos) <= MAX_PACKET_LEN) {
- spi_read_linear_fifo(fifo_available, &spirit_rx_buf[_spirit_rx_pos]);
- _spirit_rx_pos += fifo_available;
- } else {
-#ifdef DEBUG_IRQ
- debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp);
-#endif
- }
}
}
+ }
#endif // !RX_FIFO_THR_WA
- /* Reception errors */
- if((x_irq_status.IRQ_RX_FIFO_ERROR) || (x_irq_status.IRQ_RX_DATA_DISC)) {
+ /* Reception errors */
+ 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("\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__);
+ uint32_t *tmp = (uint32_t*)&x_irq_status;
+ 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) {
- _spirit_tx_started = false;
- /* call user callback */
- if(_current_irq_callback) {
- _current_irq_callback(TX_ERR);
- }
- }
- }
-
- /* The IRQ_VALID_SYNC is used to notify a new packet is coming */
- 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), "\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
- * sending.
- */
- if(_spirit_tx_started) {
-#ifdef DEBUG_IRQ
- debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp);
-#endif
- } else {
- _is_receiving = true;
- start_rx_timeout();
+ rx_timeout_handler();
+ if(_spirit_tx_started) {
+ _spirit_tx_started = false;
+ /* call user callback */
+ if(_current_irq_callback) {
+ _current_irq_callback(TX_ERR);
}
}
}
+
+ /* The IRQ_VALID_SYNC is used to notify a new packet is coming */
+ 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), "\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
+ * sending.
+ */
+ if(_spirit_tx_started) {
+#ifdef DEBUG_IRQ
+ debug("\r\n%s (%d): irq=%x\r\n", __func__, __LINE__, *tmp);
+#endif
+ } else {
+ _is_receiving = true;
+ start_rx_timeout();
+ }
+ }
+}
--- a/stm-spirit1-rf-driver/SimpleSpirit1.h Fri Feb 02 09:57:17 2018 +0100
+++ b/stm-spirit1-rf-driver/SimpleSpirit1.h Fri Feb 02 14:13:24 2018 +0100
@@ -442,14 +442,7 @@
return *_singleton;
}
- /** Create singleton instance of 'SimpleSpirit1'
- *
- * @param mosi 'PinName' of mosi pin to use
- * @param miso 'PinName' of miso pin to use
- * @param sclk 'PinName' of clock pin to use
- * @param irq 'PinName' of interrupt pin to use
- * @param cs 'PinName' of chip-select pin pin to use
- * @param sdn 'PinName' of pin to use for device shutdown
+ /** Get singleton instance of 'SimpleSpirit1'
*
* @returns reference to singleton instance
*/
@@ -476,6 +469,7 @@
/** Switch Radio On
*/
int on(void);
+
/** Switch Radio Off
*/
int off(void);
@@ -509,9 +503,9 @@
*/
int read(void *buf, unsigned int bufsize);
- /** Perform a Clear-Channel Assessment (CCA) to find out if there is a packet in the air or not.
+ /** Perform a Clear-Channel Assessment (CCA) to find out whether the medium is idle or not.
*
- * @returns 1 if packet has been seen.
+ * @returns 1 if the medium is busy.
*/
int channel_clear(void);
