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).

Committer:
Wolfgang Betz
Date:
Mon Nov 21 09:41:37 2016 +0100
Revision:
31:a4d8072139f2
Parent:
30:9c6dcfc47619
Enable standby mode

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wolfgang Betz 0:4fb29d9ee571 1 /*** Mbed Includes ***/
Wolfgang Betz 0:4fb29d9ee571 2 #include "mbed.h"
Wolfgang Betz 22:9165bd73c61e 3 #include "mbed_debug.h"
Wolfgang Betz 0:4fb29d9ee571 4
Wolfgang Betz 0:4fb29d9ee571 5
Wolfgang Betz 0:4fb29d9ee571 6 /*** Cube Includes ***/
Wolfgang Betz 0:4fb29d9ee571 7 #include "SPIRIT_Radio.h"
Wolfgang Betz 0:4fb29d9ee571 8 #include "SPIRIT_Management.h"
Wolfgang Betz 0:4fb29d9ee571 9 #include "SPIRIT_Commands.h"
Wolfgang Betz 0:4fb29d9ee571 10 #include "MCU_Interface.h"
Wolfgang Betz 0:4fb29d9ee571 11
Wolfgang Betz 0:4fb29d9ee571 12
Wolfgang Betz 0:4fb29d9ee571 13 /*** Contiki Lib Includes ***/
Wolfgang Betz 0:4fb29d9ee571 14 #include "spirit1.h"
Wolfgang Betz 0:4fb29d9ee571 15 #include "spirit1-config.h"
Wolfgang Betz 0:4fb29d9ee571 16 #include "spirit1-const.h"
Wolfgang Betz 0:4fb29d9ee571 17
Wolfgang Betz 0:4fb29d9ee571 18
Wolfgang Betz 31:a4d8072139f2 19 // betzw: enable beyond macro if you want debug messages also from IRQ handler
Wolfgang Betz 31:a4d8072139f2 20 #define DEBUG_IRQ
Wolfgang Betz 31:a4d8072139f2 21
Wolfgang Betz 31:a4d8072139f2 22
Wolfgang Betz 4:07537ca85c66 23 /*** Macros from Cube Implementation ***/
Wolfgang Betz 14:898a9d48dd03 24 #define CLEAR_TXBUF() (spirit_tx_len = 0)
Wolfgang Betz 14:898a9d48dd03 25 #define IS_RXBUF_EMPTY() (spirit_rx_len == 0)
Wolfgang Betz 14:898a9d48dd03 26 #define CLEAR_RXBUF() do { \
Wolfgang Betz 14:898a9d48dd03 27 spirit_rx_len = 0; \
Wolfgang Betz 14:898a9d48dd03 28 _spirit_rx_pos = 0; \
Wolfgang Betz 14:898a9d48dd03 29 } while(0)
Wolfgang Betz 14:898a9d48dd03 30
Wolfgang Betz 14:898a9d48dd03 31
Wolfgang Betz 14:898a9d48dd03 32 /*** Macros from Cube Implementation ***/
Wolfgang Betz 4:07537ca85c66 33 /* transceiver state. */
Wolfgang Betz 4:07537ca85c66 34 #define ON 0
Wolfgang Betz 4:07537ca85c66 35 #define OFF 1
Wolfgang Betz 4:07537ca85c66 36
Wolfgang Betz 4:07537ca85c66 37
Wolfgang Betz 0:4fb29d9ee571 38 /*** Missing Cube External Declarations ***/
Wolfgang Betz 0:4fb29d9ee571 39 extern "C" void SpiritManagementSetFrequencyBase(uint32_t);
Wolfgang Betz 0:4fb29d9ee571 40
Wolfgang Betz 0:4fb29d9ee571 41
Wolfgang Betz 7:e90fa8f6bc6c 42 /*** UnlockedSPI for Performance (due to singleton) ***/
Wolfgang Betz 7:e90fa8f6bc6c 43 class UnlockedSPI : public SPI {
Wolfgang Betz 7:e90fa8f6bc6c 44 public:
Wolfgang Betz 7:e90fa8f6bc6c 45 UnlockedSPI(PinName mosi, PinName miso, PinName sclk) :
Wolfgang Betz 7:e90fa8f6bc6c 46 SPI(mosi, miso, sclk) { }
Wolfgang Betz 28:6a71e15d5272 47 virtual ~UnlockedSPI() {}
Wolfgang Betz 7:e90fa8f6bc6c 48 virtual void lock() { }
Wolfgang Betz 7:e90fa8f6bc6c 49 virtual void unlock() { }
Wolfgang Betz 7:e90fa8f6bc6c 50 };
Wolfgang Betz 7:e90fa8f6bc6c 51
Wolfgang Betz 7:e90fa8f6bc6c 52
Wolfgang Betz 0:4fb29d9ee571 53 /*** A Simple Spirit1 Class ***/
Wolfgang Betz 9:3db68ab23070 54 // NOTE: must be a singleton (due to mix of MBED/CUBE code)!!!
Wolfgang Betz 9:3db68ab23070 55 // NOTE: implementation is IRQ-save but (intentionally) NOT thread-safe!!!
Wolfgang Betz 9:3db68ab23070 56 class SimpleSpirit1 {
Wolfgang Betz 0:4fb29d9ee571 57 protected:
Wolfgang Betz 0:4fb29d9ee571 58 static SimpleSpirit1 *_singleton;
Wolfgang Betz 0:4fb29d9ee571 59
Wolfgang Betz 0:4fb29d9ee571 60 /** Communication Interface Instance Variables **/
Wolfgang Betz 7:e90fa8f6bc6c 61 UnlockedSPI _spi; // betzw - NOTE: Arduino pins are valid only for NUCLEO-F401RE
Wolfgang Betz 7:e90fa8f6bc6c 62 // mosi: PA_7 (D11)
Wolfgang Betz 7:e90fa8f6bc6c 63 // miso: PA_6 (D12)
Wolfgang Betz 7:e90fa8f6bc6c 64 // sclk: PB_3 (D3) or
Wolfgang Betz 7:e90fa8f6bc6c 65 // PA_5 (D13) (only in case you unmount R4 & mount R7,
Wolfgang Betz 7:e90fa8f6bc6c 66 // (note: in this case you may not use LED1 on some platforms)
Wolfgang Betz 7:e90fa8f6bc6c 67 // bits: 8-bit
Wolfgang Betz 7:e90fa8f6bc6c 68 // mode: 0
Wolfgang Betz 7:e90fa8f6bc6c 69 // ordr: MSB
Wolfgang Betz 7:e90fa8f6bc6c 70 // freq: max 10MHz
Wolfgang Betz 2:45642c5198a2 71 InterruptIn _irq; // PC_7 (D9) (falling)
Wolfgang Betz 2:45642c5198a2 72 DigitalOut _chip_select; // PB_6 (D10) ('1' == chip unselected)
Wolfgang Betz 2:45642c5198a2 73 DigitalOut _shut_down; // PA_10 (D2) ('1' == shut_down)
Wolfgang Betz 2:45642c5198a2 74 DigitalOut _led; // PB_4 (D5) (optional)
Wolfgang Betz 0:4fb29d9ee571 75
Wolfgang Betz 7:e90fa8f6bc6c 76 Callback<void(int)> _current_irq_callback;
Wolfgang Betz 14:898a9d48dd03 77 Timeout _rx_receiving_timeout;
Wolfgang Betz 14:898a9d48dd03 78
Wolfgang Betz 14:898a9d48dd03 79 void rx_timeout_handler(void) {
Wolfgang Betz 14:898a9d48dd03 80 set_ready_state();
Wolfgang Betz 14:898a9d48dd03 81 cmd_strobe(SPIRIT1_STROBE_RX);
Wolfgang Betz 31:a4d8072139f2 82 #ifdef DEBUG_IRQ
Wolfgang Betz 22:9165bd73c61e 83 debug("\n\r%s (%d)\n\r", __func__, __LINE__);
Wolfgang Betz 22:9165bd73c61e 84 #endif
Wolfgang Betz 14:898a9d48dd03 85 }
Wolfgang Betz 14:898a9d48dd03 86
Wolfgang Betz 14:898a9d48dd03 87 void start_rx_timeout(void) {
Wolfgang Betz 24:03e351bfc9c9 88 _rx_receiving_timeout.attach_us(Callback<void()>(this, &SimpleSpirit1::rx_timeout_handler), 500 * 1000); // 500ms
Wolfgang Betz 14:898a9d48dd03 89 }
Wolfgang Betz 14:898a9d48dd03 90
Wolfgang Betz 14:898a9d48dd03 91 void stop_rx_timeout(void) {
Wolfgang Betz 14:898a9d48dd03 92 _rx_receiving_timeout.detach();
Wolfgang Betz 14:898a9d48dd03 93 }
Wolfgang Betz 3:0df38cfb1e53 94
Wolfgang Betz 0:4fb29d9ee571 95 /** Static Variables from Cube Implementation **/
Wolfgang Betz 0:4fb29d9ee571 96 /*
Wolfgang Betz 0:4fb29d9ee571 97 * The buffers which hold incoming data.
Wolfgang Betz 0:4fb29d9ee571 98 * The +1 because of the first byte,
Wolfgang Betz 0:4fb29d9ee571 99 * which will contain the length of the packet.
Wolfgang Betz 0:4fb29d9ee571 100 */
Wolfgang Betz 12:b8056eda4028 101 volatile uint16_t spirit_tx_len;
Wolfgang Betz 12:b8056eda4028 102 volatile bool _spirit_tx_started;
Wolfgang Betz 12:b8056eda4028 103 volatile uint16_t spirit_rx_len;
Wolfgang Betz 12:b8056eda4028 104 volatile uint16_t _spirit_rx_pos;
Wolfgang Betz 12:b8056eda4028 105 volatile bool _spirit_rx_err;
Wolfgang Betz 6:f5d01793bf86 106 uint8_t spirit_rx_buf[MAX_PACKET_LEN];
Wolfgang Betz 12:b8056eda4028 107 volatile bool _is_receiving;
Wolfgang Betz 6:f5d01793bf86 108
Wolfgang Betz 6:f5d01793bf86 109 /** Status Variables from Cube Implementation **/
Wolfgang Betz 12:b8056eda4028 110 unsigned int spirit_on;
Wolfgang Betz 8:10967c884e38 111 uint8_t last_rssi; //MGR
Wolfgang Betz 30:9c6dcfc47619 112 uint8_t last_sqi; //MGR
Wolfgang Betz 0:4fb29d9ee571 113
Wolfgang Betz 0:4fb29d9ee571 114 /** Low Level Instance Variables **/
Wolfgang Betz 0:4fb29d9ee571 115 unsigned int _nr_of_irq_disables;
Wolfgang Betz 0:4fb29d9ee571 116
Wolfgang Betz 3:0df38cfb1e53 117 /** Low Level Instance Methods **/
Wolfgang Betz 4:07537ca85c66 118 void disable_spirit_irq(void) {
Wolfgang Betz 0:4fb29d9ee571 119 _irq.disable_irq();
Wolfgang Betz 0:4fb29d9ee571 120 _nr_of_irq_disables++;
Wolfgang Betz 22:9165bd73c61e 121 #ifndef NDEBUG
Wolfgang Betz 22:9165bd73c61e 122 debug_if(_nr_of_irq_disables == 0, "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
Wolfgang Betz 22:9165bd73c61e 123 #endif
Wolfgang Betz 0:4fb29d9ee571 124 }
Wolfgang Betz 0:4fb29d9ee571 125
Wolfgang Betz 4:07537ca85c66 126 void enable_spirit_irq(void) {
Wolfgang Betz 22:9165bd73c61e 127 #ifndef NDEBUG
Wolfgang Betz 22:9165bd73c61e 128 debug_if(_nr_of_irq_disables == 0, "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
Wolfgang Betz 22:9165bd73c61e 129 #endif
Wolfgang Betz 0:4fb29d9ee571 130 if(--_nr_of_irq_disables == 0)
Wolfgang Betz 0:4fb29d9ee571 131 _irq.enable_irq();
Wolfgang Betz 0:4fb29d9ee571 132 }
Wolfgang Betz 0:4fb29d9ee571 133
Wolfgang Betz 0:4fb29d9ee571 134 void chip_select() { _chip_select = 0; }
Wolfgang Betz 0:4fb29d9ee571 135 void chip_unselect() { _chip_select = 1; }
Wolfgang Betz 0:4fb29d9ee571 136
Wolfgang Betz 25:2ec45788f28c 137 void enter_shutdown() {
Wolfgang Betz 25:2ec45788f28c 138 _shut_down = 1;
Wolfgang Betz 25:2ec45788f28c 139 wait_ms(5); // wait 5 milliseconds (to allow Spirit1 to shut down)
Wolfgang Betz 25:2ec45788f28c 140 }
Wolfgang Betz 25:2ec45788f28c 141
Wolfgang Betz 0:4fb29d9ee571 142 void exit_shutdown() {
Wolfgang Betz 0:4fb29d9ee571 143 _shut_down = 0;
Wolfgang Betz 25:2ec45788f28c 144 wait_ms(10); // wait 10 milliseconds (to allow Spirit1 a proper boot-up sequence)
Wolfgang Betz 0:4fb29d9ee571 145 }
Wolfgang Betz 0:4fb29d9ee571 146
Wolfgang Betz 0:4fb29d9ee571 147 void cs_to_sclk_delay(void) {
Wolfgang Betz 0:4fb29d9ee571 148 wait_us(1); // heuristic value
Wolfgang Betz 0:4fb29d9ee571 149 }
Wolfgang Betz 0:4fb29d9ee571 150
Wolfgang Betz 3:0df38cfb1e53 151 /**
Wolfgang Betz 3:0df38cfb1e53 152 * @brief Write and read a buffer to/from the SPI peripheral device at the same time
Wolfgang Betz 3:0df38cfb1e53 153 * in 8-bit data mode using synchronous SPI communication.
Wolfgang Betz 3:0df38cfb1e53 154 * @param[in] pBufferToWrite pointer to the buffer of data to send.
Wolfgang Betz 3:0df38cfb1e53 155 * @param[out] pBufferToRead pointer to the buffer to read data into.
Wolfgang Betz 3:0df38cfb1e53 156 * @param[in] NumBytes number of bytes to read and write.
Wolfgang Betz 3:0df38cfb1e53 157 * @retval 0 if ok.
Wolfgang Betz 3:0df38cfb1e53 158 * @retval -1 if data format error.
Wolfgang Betz 3:0df38cfb1e53 159 * @note When using the SPI in Interrupt-mode, remember to disable interrupts
Wolfgang Betz 3:0df38cfb1e53 160 * before calling this function and to enable them again after.
Wolfgang Betz 3:0df38cfb1e53 161 */
Wolfgang Betz 3:0df38cfb1e53 162 void spi_write_read(uint8_t* pBufferToWrite, uint8_t* pBufferToRead, uint16_t NumBytes)
Wolfgang Betz 3:0df38cfb1e53 163 {
Wolfgang Betz 3:0df38cfb1e53 164 /* Read and write data at the same time. */
Wolfgang Betz 3:0df38cfb1e53 165 for (int i = 0; i < NumBytes; i++) {
Wolfgang Betz 3:0df38cfb1e53 166 pBufferToRead[i] = _spi.write(pBufferToWrite[i]);
Wolfgang Betz 3:0df38cfb1e53 167 }
Wolfgang Betz 3:0df38cfb1e53 168 }
Wolfgang Betz 3:0df38cfb1e53 169
Wolfgang Betz 0:4fb29d9ee571 170 /** Radio Instance Methods **/
Wolfgang Betz 0:4fb29d9ee571 171 void radio_set_xtal_freq(uint32_t freq) {
Wolfgang Betz 0:4fb29d9ee571 172 SpiritRadioSetXtalFrequency(freq);
Wolfgang Betz 0:4fb29d9ee571 173 }
Wolfgang Betz 0:4fb29d9ee571 174
Wolfgang Betz 0:4fb29d9ee571 175 void radio_set_pa_level_dbm(uint8_t cIndex, float fPowerdBm) {
Wolfgang Betz 0:4fb29d9ee571 176 SpiritRadioSetPALeveldBm(cIndex, fPowerdBm);
Wolfgang Betz 0:4fb29d9ee571 177 }
Wolfgang Betz 0:4fb29d9ee571 178
Wolfgang Betz 0:4fb29d9ee571 179 void radio_set_pa_level_max_index(uint8_t cIndex) {
Wolfgang Betz 0:4fb29d9ee571 180 SpiritRadioSetPALevelMaxIndex(cIndex);
Wolfgang Betz 0:4fb29d9ee571 181 }
Wolfgang Betz 0:4fb29d9ee571 182
Wolfgang Betz 0:4fb29d9ee571 183 uint8_t radio_init(SRadioInit *init_struct) {
Wolfgang Betz 0:4fb29d9ee571 184 return SpiritRadioInit(init_struct);
Wolfgang Betz 0:4fb29d9ee571 185 }
Wolfgang Betz 3:0df38cfb1e53 186
Wolfgang Betz 28:6a71e15d5272 187 void radio_persistent_rx(SpiritFunctionalState xNewState) {
Wolfgang Betz 0:4fb29d9ee571 188 SpiritRadioPersistenRx(xNewState);
Wolfgang Betz 0:4fb29d9ee571 189 }
Wolfgang Betz 0:4fb29d9ee571 190
Wolfgang Betz 0:4fb29d9ee571 191 void radio_afc_freeze_on_sync(SpiritFunctionalState xNewState) {
Wolfgang Betz 0:4fb29d9ee571 192 SpiritRadioAFCFreezeOnSync(xNewState);
Wolfgang Betz 0:4fb29d9ee571 193 }
Wolfgang Betz 0:4fb29d9ee571 194
Wolfgang Betz 0:4fb29d9ee571 195 /** Packet System Instance Methods **/
Wolfgang Betz 0:4fb29d9ee571 196 void pkt_basic_init(PktBasicInit* pxPktBasicInit) {
Wolfgang Betz 0:4fb29d9ee571 197 SpiritPktBasicInit(pxPktBasicInit);
Wolfgang Betz 0:4fb29d9ee571 198 }
Wolfgang Betz 0:4fb29d9ee571 199
Wolfgang Betz 3:0df38cfb1e53 200 void pkt_basic_set_payload_length(uint16_t nPayloadLength) {
Wolfgang Betz 3:0df38cfb1e53 201 SpiritPktBasicSetPayloadLength(nPayloadLength);
Wolfgang Betz 3:0df38cfb1e53 202 }
Wolfgang Betz 3:0df38cfb1e53 203
Wolfgang Betz 4:07537ca85c66 204 uint16_t pkt_basic_get_received_pkt_length(void) {
Wolfgang Betz 4:07537ca85c66 205 return SpiritPktBasicGetReceivedPktLength();
Wolfgang Betz 4:07537ca85c66 206 }
Wolfgang Betz 4:07537ca85c66 207
Wolfgang Betz 3:0df38cfb1e53 208 /** IRQ Instance Methods **/
Wolfgang Betz 0:4fb29d9ee571 209 void irq_de_init(SpiritIrqs* pxIrqInit) {
Wolfgang Betz 0:4fb29d9ee571 210 SpiritIrqDeInit(pxIrqInit);
Wolfgang Betz 0:4fb29d9ee571 211 }
Wolfgang Betz 0:4fb29d9ee571 212
Wolfgang Betz 0:4fb29d9ee571 213 void irq_clear_status(void) {
Wolfgang Betz 0:4fb29d9ee571 214 SpiritIrqClearStatus();
Wolfgang Betz 0:4fb29d9ee571 215 }
Wolfgang Betz 0:4fb29d9ee571 216
Wolfgang Betz 0:4fb29d9ee571 217 void irq_set_status(IrqList xIrq, SpiritFunctionalState xNewState) {
Wolfgang Betz 0:4fb29d9ee571 218 SpiritIrq(xIrq, xNewState);
Wolfgang Betz 0:4fb29d9ee571 219 }
Wolfgang Betz 0:4fb29d9ee571 220
Wolfgang Betz 4:07537ca85c66 221 void irq_get_status(SpiritIrqs* pxIrqStatus) {
Wolfgang Betz 4:07537ca85c66 222 SpiritIrqGetStatus(pxIrqStatus);
Wolfgang Betz 4:07537ca85c66 223 }
Wolfgang Betz 4:07537ca85c66 224
Wolfgang Betz 0:4fb29d9ee571 225 /** Management Instance Methods **/
Wolfgang Betz 0:4fb29d9ee571 226 void mgmt_set_freq_base(uint32_t freq) {
Wolfgang Betz 0:4fb29d9ee571 227 SpiritManagementSetFrequencyBase(freq);
Wolfgang Betz 0:4fb29d9ee571 228 }
Wolfgang Betz 0:4fb29d9ee571 229
Wolfgang Betz 4:07537ca85c66 230 void mgmt_refresh_status(void) {
Wolfgang Betz 4:07537ca85c66 231 SpiritRefreshStatus();
Wolfgang Betz 4:07537ca85c66 232 }
Wolfgang Betz 4:07537ca85c66 233
Wolfgang Betz 0:4fb29d9ee571 234 /** Spirit GPIO Instance Methods **/
Wolfgang Betz 0:4fb29d9ee571 235 void spirit_gpio_init(SGpioInit* pxGpioInitStruct) {
Wolfgang Betz 0:4fb29d9ee571 236 SpiritGpioInit(pxGpioInitStruct);
Wolfgang Betz 0:4fb29d9ee571 237 }
Wolfgang Betz 0:4fb29d9ee571 238
Wolfgang Betz 0:4fb29d9ee571 239 /** Qi Instance Methods **/
Wolfgang Betz 0:4fb29d9ee571 240 void qi_set_sqi_threshold(SqiThreshold xSqiThr) {
Wolfgang Betz 0:4fb29d9ee571 241 SpiritQiSetSqiThreshold(xSqiThr);
Wolfgang Betz 0:4fb29d9ee571 242 }
Wolfgang Betz 0:4fb29d9ee571 243
Wolfgang Betz 0:4fb29d9ee571 244 void qi_sqi_check(SpiritFunctionalState xNewState) {
Wolfgang Betz 0:4fb29d9ee571 245 SpiritQiSqiCheck(xNewState);
Wolfgang Betz 0:4fb29d9ee571 246 }
Wolfgang Betz 0:4fb29d9ee571 247
Wolfgang Betz 0:4fb29d9ee571 248 void qi_set_rssi_threshold_dbm(int nDbmValue) {
Wolfgang Betz 0:4fb29d9ee571 249 SpiritQiSetRssiThresholddBm(nDbmValue);
Wolfgang Betz 0:4fb29d9ee571 250 }
Wolfgang Betz 0:4fb29d9ee571 251
Wolfgang Betz 4:07537ca85c66 252 float qi_get_rssi_dbm() {
Wolfgang Betz 8:10967c884e38 253 last_rssi = qi_get_rssi();
Wolfgang Betz 8:10967c884e38 254 return get_last_rssi_dbm();
Wolfgang Betz 4:07537ca85c66 255 }
Wolfgang Betz 4:07537ca85c66 256
Wolfgang Betz 4:07537ca85c66 257 uint8_t qi_get_rssi() {
Wolfgang Betz 4:07537ca85c66 258 return SpiritQiGetRssi();
Wolfgang Betz 4:07537ca85c66 259 }
Wolfgang Betz 4:07537ca85c66 260
Wolfgang Betz 30:9c6dcfc47619 261 uint8_t qi_get_sqi() {
Wolfgang Betz 30:9c6dcfc47619 262 return SpiritQiGetSqi();
Wolfgang Betz 4:07537ca85c66 263 }
Wolfgang Betz 4:07537ca85c66 264
Wolfgang Betz 0:4fb29d9ee571 265 /** Timer Instance Methods **/
Wolfgang Betz 0:4fb29d9ee571 266 void timer_set_rx_timeout_stop_condition(RxTimeoutStopCondition xStopCondition) {
Wolfgang Betz 0:4fb29d9ee571 267 SpiritTimerSetRxTimeoutStopCondition(xStopCondition);
Wolfgang Betz 0:4fb29d9ee571 268 }
Wolfgang Betz 0:4fb29d9ee571 269
Wolfgang Betz 0:4fb29d9ee571 270 void timer_set_rx_timeout_counter(uint8_t cCounter) {
Wolfgang Betz 0:4fb29d9ee571 271 SpiritTimerSetRxTimeoutCounter(cCounter);
Wolfgang Betz 0:4fb29d9ee571 272 }
Wolfgang Betz 0:4fb29d9ee571 273
Wolfgang Betz 0:4fb29d9ee571 274 void timer_set_infinite_rx_timeout(void) {
Wolfgang Betz 0:4fb29d9ee571 275 timer_set_rx_timeout_counter(0);
Wolfgang Betz 0:4fb29d9ee571 276 }
Wolfgang Betz 0:4fb29d9ee571 277
Wolfgang Betz 23:4192649f35da 278 /** CSMA/CA Instance Methods **/
Wolfgang Betz 23:4192649f35da 279 void csma_ca_state(SpiritFunctionalState xNewState) {
Wolfgang Betz 23:4192649f35da 280 SpiritCsma(xNewState);
Wolfgang Betz 23:4192649f35da 281 }
Wolfgang Betz 23:4192649f35da 282
Wolfgang Betz 23:4192649f35da 283 void csma_ca_init(CsmaInit* pxCsmaInit) {
Wolfgang Betz 23:4192649f35da 284 csma_ca_state(S_DISABLE); // Disabled at init
Wolfgang Betz 23:4192649f35da 285 SpiritCsmaInit(pxCsmaInit);
Wolfgang Betz 23:4192649f35da 286 SpiritCsmaSeedReloadMode(S_DISABLE); // always disable seed reload
Wolfgang Betz 23:4192649f35da 287 }
Wolfgang Betz 23:4192649f35da 288
Wolfgang Betz 0:4fb29d9ee571 289 /** Command Instance Methods**/
Wolfgang Betz 4:07537ca85c66 290 void cmd_strobe(uint8_t cmd) {
Wolfgang Betz 0:4fb29d9ee571 291 SpiritCmdStrobeCommand((SpiritCmd)cmd);
Wolfgang Betz 0:4fb29d9ee571 292 }
Wolfgang Betz 0:4fb29d9ee571 293
Wolfgang Betz 4:07537ca85c66 294 void cmd_strobe_flush_rx_fifo() {
Wolfgang Betz 4:07537ca85c66 295 SpiritCmdStrobeCommand(CMD_FLUSHRXFIFO);
Wolfgang Betz 4:07537ca85c66 296 }
Wolfgang Betz 4:07537ca85c66 297
Wolfgang Betz 3:0df38cfb1e53 298 /** SPI Instance Methods **/
Wolfgang Betz 3:0df38cfb1e53 299 StatusBytes spi_write_linear_fifo(uint8_t cNbBytes, uint8_t* pcBuffer) {
Wolfgang Betz 3:0df38cfb1e53 300 return SdkEvalSpiWriteFifo(cNbBytes, pcBuffer);
Wolfgang Betz 3:0df38cfb1e53 301 }
Wolfgang Betz 3:0df38cfb1e53 302
Wolfgang Betz 4:07537ca85c66 303 StatusBytes spi_read_linear_fifo(uint8_t cNbBytes, uint8_t* pcBuffer) {
Wolfgang Betz 4:07537ca85c66 304 return SdkEvalSpiReadFifo(cNbBytes, pcBuffer);
Wolfgang Betz 4:07537ca85c66 305 }
Wolfgang Betz 4:07537ca85c66 306
Wolfgang Betz 4:07537ca85c66 307 /** Linear FIFO Instance Methods **/
Wolfgang Betz 4:07537ca85c66 308 uint8_t linear_fifo_read_num_elements_rx_fifo(void) {
Wolfgang Betz 4:07537ca85c66 309 return SpiritLinearFifoReadNumElementsRxFifo();
Wolfgang Betz 4:07537ca85c66 310 }
Wolfgang Betz 4:07537ca85c66 311
Wolfgang Betz 5:c9c5bc673c64 312 uint8_t linear_fifo_read_num_elements_tx_fifo(void) {
Wolfgang Betz 5:c9c5bc673c64 313 return SpiritLinearFifoReadNumElementsTxFifo();
Wolfgang Betz 5:c9c5bc673c64 314 }
Wolfgang Betz 5:c9c5bc673c64 315
Wolfgang Betz 16:25dc4b811ad3 316 void linear_fifo_set_almost_full_thr_rx(uint8_t cThrRxFifo) {
Wolfgang Betz 16:25dc4b811ad3 317 SpiritLinearFifoSetAlmostFullThresholdRx(cThrRxFifo);
Wolfgang Betz 16:25dc4b811ad3 318 }
Wolfgang Betz 16:25dc4b811ad3 319
Wolfgang Betz 25:2ec45788f28c 320 /** Calibration Instance Methods **/
Wolfgang Betz 25:2ec45788f28c 321 void calibration_rco(SpiritFunctionalState xNewState) {
Wolfgang Betz 25:2ec45788f28c 322 SpiritCalibrationRco(xNewState);
Wolfgang Betz 25:2ec45788f28c 323 }
Wolfgang Betz 25:2ec45788f28c 324
Wolfgang Betz 3:0df38cfb1e53 325 /** Internal Spirit Methods */
Wolfgang Betz 3:0df38cfb1e53 326 void set_ready_state(void);
Wolfgang Betz 25:2ec45788f28c 327 uint8_t refresh_state(void);
Wolfgang Betz 3:0df38cfb1e53 328
Wolfgang Betz 0:4fb29d9ee571 329 /** Friend Functions **/
Wolfgang Betz 0:4fb29d9ee571 330 friend StatusBytes SdkEvalSpiWriteRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer);
Wolfgang Betz 0:4fb29d9ee571 331 friend StatusBytes SdkEvalSpiReadRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer);
Wolfgang Betz 0:4fb29d9ee571 332 friend StatusBytes SdkEvalSpiCommandStrobes(uint8_t cCommandCode);
Wolfgang Betz 0:4fb29d9ee571 333 friend StatusBytes SdkEvalSpiWriteFifo(uint8_t cNbBytes, uint8_t* pcBuffer);
Wolfgang Betz 0:4fb29d9ee571 334 friend StatusBytes SdkEvalSpiReadFifo(uint8_t cNbBytes, uint8_t* pcBuffer);
Wolfgang Betz 0:4fb29d9ee571 335
Wolfgang Betz 0:4fb29d9ee571 336 /** Sdk Instance Methods **/
Wolfgang Betz 0:4fb29d9ee571 337 StatusBytes SdkEvalSpiWriteRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer);
Wolfgang Betz 0:4fb29d9ee571 338 StatusBytes SdkEvalSpiReadRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer);
Wolfgang Betz 0:4fb29d9ee571 339 StatusBytes SdkEvalSpiCommandStrobes(uint8_t cCommandCode);
Wolfgang Betz 0:4fb29d9ee571 340 StatusBytes SdkEvalSpiWriteFifo(uint8_t cNbBytes, uint8_t* pcBuffer);
Wolfgang Betz 0:4fb29d9ee571 341 StatusBytes SdkEvalSpiReadFifo(uint8_t cNbBytes, uint8_t* pcBuffer);
Wolfgang Betz 0:4fb29d9ee571 342
Wolfgang Betz 0:4fb29d9ee571 343 /** Helper Instance Methods **/
Wolfgang Betz 0:4fb29d9ee571 344 void chip_sync_select() {
Wolfgang Betz 4:07537ca85c66 345 disable_spirit_irq();
Wolfgang Betz 0:4fb29d9ee571 346 chip_select();
Wolfgang Betz 0:4fb29d9ee571 347 cs_to_sclk_delay();
Wolfgang Betz 0:4fb29d9ee571 348 }
Wolfgang Betz 0:4fb29d9ee571 349
Wolfgang Betz 0:4fb29d9ee571 350 void chip_sync_unselect() {
Wolfgang Betz 0:4fb29d9ee571 351 chip_unselect();
Wolfgang Betz 4:07537ca85c66 352 enable_spirit_irq();
Wolfgang Betz 0:4fb29d9ee571 353 }
Wolfgang Betz 0:4fb29d9ee571 354
Wolfgang Betz 2:45642c5198a2 355 /** Init Instance Method **/
Wolfgang Betz 25:2ec45788f28c 356 void init();
Wolfgang Betz 2:45642c5198a2 357
Wolfgang Betz 5:c9c5bc673c64 358 /** Spirit Irq Callback */
Wolfgang Betz 5:c9c5bc673c64 359 void IrqHandler();
Wolfgang Betz 5:c9c5bc673c64 360
Wolfgang Betz 0:4fb29d9ee571 361 /** Constructor **/
Wolfgang Betz 0:4fb29d9ee571 362 SimpleSpirit1(PinName mosi, PinName miso, PinName sclk,
Wolfgang Betz 0:4fb29d9ee571 363 PinName irq, PinName cs, PinName sdn,
Wolfgang Betz 0:4fb29d9ee571 364 PinName led);
Wolfgang Betz 0:4fb29d9ee571 365
Wolfgang Betz 0:4fb29d9ee571 366 /** Destructor **/
Wolfgang Betz 0:4fb29d9ee571 367 ~SimpleSpirit1(void); // should never be called!
Wolfgang Betz 0:4fb29d9ee571 368
Wolfgang Betz 0:4fb29d9ee571 369 public:
Wolfgang Betz 9:3db68ab23070 370 enum {
Wolfgang Betz 9:3db68ab23070 371 RX_DONE,
Wolfgang Betz 9:3db68ab23070 372 TX_DONE,
Wolfgang Betz 9:3db68ab23070 373 TX_ERR
Wolfgang Betz 9:3db68ab23070 374 };
Wolfgang Betz 9:3db68ab23070 375
Wolfgang Betz 0:4fb29d9ee571 376 static SimpleSpirit1& CreateInstance(PinName mosi, PinName miso, PinName sclk,
Wolfgang Betz 0:4fb29d9ee571 377 PinName irq, PinName cs, PinName sdn,
Wolfgang Betz 0:4fb29d9ee571 378 PinName led = NC) {
Wolfgang Betz 0:4fb29d9ee571 379
Wolfgang Betz 0:4fb29d9ee571 380 if(_singleton == NULL) {
Wolfgang Betz 0:4fb29d9ee571 381 _singleton = new SimpleSpirit1(mosi, miso, sclk,
Wolfgang Betz 0:4fb29d9ee571 382 irq, cs, sdn, led);
Wolfgang Betz 2:45642c5198a2 383 _singleton->init();
Wolfgang Betz 0:4fb29d9ee571 384 } else {
Wolfgang Betz 2:45642c5198a2 385 error("SimpleSpirit1 singleton already created!\n");
Wolfgang Betz 0:4fb29d9ee571 386 }
Wolfgang Betz 0:4fb29d9ee571 387
Wolfgang Betz 0:4fb29d9ee571 388 return *_singleton;
Wolfgang Betz 0:4fb29d9ee571 389 }
Wolfgang Betz 0:4fb29d9ee571 390
Wolfgang Betz 0:4fb29d9ee571 391 static SimpleSpirit1& Instance() {
Wolfgang Betz 0:4fb29d9ee571 392 if(_singleton == NULL) {
Wolfgang Betz 2:45642c5198a2 393 error("SimpleSpirit1 must be created before used!\n");
Wolfgang Betz 0:4fb29d9ee571 394 }
Wolfgang Betz 0:4fb29d9ee571 395
Wolfgang Betz 0:4fb29d9ee571 396 return *_singleton;
Wolfgang Betz 0:4fb29d9ee571 397 }
Wolfgang Betz 0:4fb29d9ee571 398
Wolfgang Betz 6:f5d01793bf86 399 /** Attach a function to be called by the Spirit Irq handler when packet has arrived
Wolfgang Betz 0:4fb29d9ee571 400 *
Wolfgang Betz 3:0df38cfb1e53 401 * @param func A void() callback, or 0 to set as none
Wolfgang Betz 0:4fb29d9ee571 402 *
Wolfgang Betz 0:4fb29d9ee571 403 * @note Function 'func' will be executed in interrupt context!
Wolfgang Betz 0:4fb29d9ee571 404 */
Wolfgang Betz 7:e90fa8f6bc6c 405 void attach_irq_callback(Callback<void(int)> func) {
Wolfgang Betz 4:07537ca85c66 406 _current_irq_callback = func;
Wolfgang Betz 0:4fb29d9ee571 407 }
Wolfgang Betz 3:0df38cfb1e53 408
Wolfgang Betz 4:07537ca85c66 409 /** Switch Radio On/Off **/
Wolfgang Betz 4:07537ca85c66 410 int on(void);
Wolfgang Betz 4:07537ca85c66 411 int off(void);
Wolfgang Betz 4:07537ca85c66 412
Wolfgang Betz 8:10967c884e38 413 /** Set Channel **/
Wolfgang Betz 8:10967c884e38 414 void set_channel(uint8_t channel) {
Wolfgang Betz 8:10967c884e38 415 SpiritRadioSetChannel(channel);
Wolfgang Betz 8:10967c884e38 416 }
Wolfgang Betz 8:10967c884e38 417
Wolfgang Betz 7:e90fa8f6bc6c 418 /** Send a Buffer **/
Wolfgang Betz 6:f5d01793bf86 419 int send(const void *payload, unsigned int payload_len);
Wolfgang Betz 5:c9c5bc673c64 420
Wolfgang Betz 4:07537ca85c66 421 /** Read into Buffer **/
Wolfgang Betz 6:f5d01793bf86 422 int read(void *buf, unsigned int bufsize);
Wolfgang Betz 4:07537ca85c66 423
Wolfgang Betz 4:07537ca85c66 424 /** Perform a Clear-Channel Assessment (CCA) to find out if there is
Wolfgang Betz 4:07537ca85c66 425 a packet in the air or not.
Wolfgang Betz 23:4192649f35da 426 Returns 1 if packet has been seen.
Wolfgang Betz 4:07537ca85c66 427 */
Wolfgang Betz 4:07537ca85c66 428 int channel_clear(void);
Wolfgang Betz 4:07537ca85c66 429
Wolfgang Betz 4:07537ca85c66 430 /** Check if the radio driver has just received a packet **/
Wolfgang Betz 7:e90fa8f6bc6c 431 int get_pending_packet(void);
Wolfgang Betz 7:e90fa8f6bc6c 432
Wolfgang Betz 12:b8056eda4028 433 /** Is radio currently receiving **/
Wolfgang Betz 12:b8056eda4028 434 bool is_receiving(void) {
Wolfgang Betz 12:b8056eda4028 435 return _is_receiving;
Wolfgang Betz 12:b8056eda4028 436 }
Wolfgang Betz 12:b8056eda4028 437
Wolfgang Betz 30:9c6dcfc47619 438 /** Get latest value of RSSI (in dBm) **/
Wolfgang Betz 8:10967c884e38 439 float get_last_rssi_dbm(void) {
Wolfgang Betz 30:9c6dcfc47619 440 get_last_rssi_raw();
Wolfgang Betz 30:9c6dcfc47619 441 return (-120.0+((float)(last_rssi-20))/2);
Wolfgang Betz 30:9c6dcfc47619 442 }
Wolfgang Betz 30:9c6dcfc47619 443
Wolfgang Betz 30:9c6dcfc47619 444 /** Get latest value of RSSI (as Spirit1 raw value) **/
Wolfgang Betz 30:9c6dcfc47619 445 uint8_t get_last_rssi_raw(void) {
Wolfgang Betz 11:b769d6caad82 446 if(last_rssi == 0) {
Wolfgang Betz 11:b769d6caad82 447 last_rssi = qi_get_rssi();
Wolfgang Betz 11:b769d6caad82 448 }
Wolfgang Betz 30:9c6dcfc47619 449 return last_rssi;
Wolfgang Betz 7:e90fa8f6bc6c 450 }
Wolfgang Betz 7:e90fa8f6bc6c 451
Wolfgang Betz 30:9c6dcfc47619 452 /** Get latest value of LQI (scaled to 8-bit) **/
Wolfgang Betz 30:9c6dcfc47619 453 uint8_t get_last_sqi(void) {
Wolfgang Betz 30:9c6dcfc47619 454 const uint8_t max_sqi = 8 * ((SYNC_LENGTH>>1)+1);
Wolfgang Betz 30:9c6dcfc47619 455 if(last_sqi == 0) {
Wolfgang Betz 30:9c6dcfc47619 456 last_sqi = qi_get_sqi();
Wolfgang Betz 11:b769d6caad82 457 }
Wolfgang Betz 30:9c6dcfc47619 458 if(last_sqi > max_sqi) last_sqi = max_sqi;
Wolfgang Betz 30:9c6dcfc47619 459
Wolfgang Betz 30:9c6dcfc47619 460 return (last_sqi * 255 / max_sqi);
Wolfgang Betz 7:e90fa8f6bc6c 461 }
Wolfgang Betz 9:3db68ab23070 462
Wolfgang Betz 9:3db68ab23070 463 /** Reset Board **/
Wolfgang Betz 25:2ec45788f28c 464 void reset_board() {
Wolfgang Betz 9:3db68ab23070 465 init();
Wolfgang Betz 9:3db68ab23070 466 }
Wolfgang Betz 0:4fb29d9ee571 467 };