센서보드 RF IRQ 테스트 중

Fork of stm-spirit1-rf-driver by ST

Committer:
Wolfgang Betz
Date:
Fri Jul 21 13:54:39 2017 +0200
Revision:
72:413cb97ac077
Parent:
68:247fd6e0ab66
Child:
73:a1342eb7974c
Better commenting of public `SimpleSpirit1` API

Who changed what in which revision?

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