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:
Wed Oct 26 15:08:44 2016 +0200
Revision:
11:b769d6caad82
Parent:
9:3db68ab23070
Child:
12:b8056eda4028
Extend nanostack interface

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