Fork of my original MQTTGateway

Dependencies:   mbed-http

Committer:
vpcola
Date:
Sat Apr 08 14:43:14 2017 +0000
Revision:
0:a1734fe1ec4b
Initial commit

Who changed what in which revision?

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