Version of easy-connect with the u-blox cellular platforms C027 and C030 added.

Dependents:   HelloMQTT

Committer:
RobMeades
Date:
Fri Nov 03 13:01:23 2017 +0000
Revision:
6:304d3ba87a01
Parent:
0:19aa55d66228
Add comment concerning N2XX baud rate.

Who changed what in which revision?

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