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 "SimpleSpirit1.h"
Wolfgang Betz 3:0df38cfb1e53 3 #include "radio_spi.h"
Wolfgang Betz 0:4fb29d9ee571 4
Wolfgang Betz 0:4fb29d9ee571 5
Wolfgang Betz 0:4fb29d9ee571 6 /*** Macros from Cube Implementation ***/
Wolfgang Betz 4:07537ca85c66 7 #define CLEAR_TXBUF() (spirit_tx_len = 0)
Wolfgang Betz 4:07537ca85c66 8 #define IS_RXBUF_EMPTY() (spirit_rx_len == 0)
Wolfgang Betz 6:f5d01793bf86 9 #define CLEAR_RXBUF() do { \
Wolfgang Betz 6:f5d01793bf86 10 spirit_rx_len = 0; \
Wolfgang Betz 6:f5d01793bf86 11 _spirit_rx_pos = 0; \
Wolfgang Betz 6:f5d01793bf86 12 } while(0)
Wolfgang Betz 0:4fb29d9ee571 13
Wolfgang Betz 7:e90fa8f6bc6c 14 #define NDEBUG
Wolfgang Betz 3:0df38cfb1e53 15 #ifndef NDEBUG
Wolfgang Betz 3:0df38cfb1e53 16 #include <stdio.h>
Wolfgang Betz 3:0df38cfb1e53 17 #define PRINTF(...) printf(__VA_ARGS__)
Wolfgang Betz 3:0df38cfb1e53 18 #else
Wolfgang Betz 3:0df38cfb1e53 19 #define PRINTF(...)
Wolfgang Betz 3:0df38cfb1e53 20 #endif
Wolfgang Betz 0:4fb29d9ee571 21
Wolfgang Betz 3:0df38cfb1e53 22 #if NULLRDC_CONF_802154_AUTOACK
Wolfgang Betz 3:0df38cfb1e53 23 #define ACK_LEN 3
Wolfgang Betz 3:0df38cfb1e53 24 static int wants_an_ack = 0; /* The packet sent expects an ack */
Wolfgang Betz 3:0df38cfb1e53 25 //#define ACKPRINTF printf
Wolfgang Betz 3:0df38cfb1e53 26 #define ACKPRINTF(...)
Wolfgang Betz 3:0df38cfb1e53 27 #endif /* NULLRDC_CONF_802154_AUTOACK */
Wolfgang Betz 3:0df38cfb1e53 28
Wolfgang Betz 4:07537ca85c66 29 #define SPIRIT_GPIO_IRQ (SPIRIT_GPIO_3)
Wolfgang Betz 3:0df38cfb1e53 30
Wolfgang Betz 4:07537ca85c66 31 #define SPIRIT1_STATUS() (arch_refresh_status() & SPIRIT1_STATE_STATEBITS)
Wolfgang Betz 3:0df38cfb1e53 32
Wolfgang Betz 4:07537ca85c66 33 #define SABORT_WAIT_US (400)
Wolfgang Betz 3:0df38cfb1e53 34
Wolfgang Betz 3:0df38cfb1e53 35 #define BUSYWAIT_UNTIL(cond, millisecs) \
Wolfgang Betz 3:0df38cfb1e53 36 do { \
Wolfgang Betz 7:e90fa8f6bc6c 37 uint32_t start = us_ticker_read(); \
Wolfgang Betz 7:e90fa8f6bc6c 38 while (!(cond) && ((us_ticker_read() - start) < ((uint32_t)millisecs)*1000U)); \
Wolfgang Betz 3:0df38cfb1e53 39 } while(0)
Wolfgang Betz 3:0df38cfb1e53 40
Wolfgang Betz 4:07537ca85c66 41 extern volatile SpiritStatus g_xStatus;
Wolfgang Betz 4:07537ca85c66 42 #define st_lib_g_x_status (g_xStatus)
Wolfgang Betz 4:07537ca85c66 43
Wolfgang Betz 4:07537ca85c66 44 #define st_lib_spirit_irqs SpiritIrqs
Wolfgang Betz 4:07537ca85c66 45
Wolfgang Betz 0:4fb29d9ee571 46
Wolfgang Betz 0:4fb29d9ee571 47 /*** Class Implementation ***/
Wolfgang Betz 3:0df38cfb1e53 48 /** Static Class Variables **/
Wolfgang Betz 3:0df38cfb1e53 49 SimpleSpirit1 *SimpleSpirit1::_singleton = NULL;
Wolfgang Betz 3:0df38cfb1e53 50
Wolfgang Betz 3:0df38cfb1e53 51 /** Constructor **/
Wolfgang Betz 0:4fb29d9ee571 52 SimpleSpirit1::SimpleSpirit1(PinName mosi, PinName miso, PinName sclk,
Wolfgang Betz 0:4fb29d9ee571 53 PinName irq, PinName cs, PinName sdn,
Wolfgang Betz 0:4fb29d9ee571 54 PinName led) :
Wolfgang Betz 0:4fb29d9ee571 55 _spi(mosi, miso, sclk),
Wolfgang Betz 0:4fb29d9ee571 56 _irq(irq),
Wolfgang Betz 0:4fb29d9ee571 57 _chip_select(cs),
Wolfgang Betz 0:4fb29d9ee571 58 _shut_down(sdn),
Wolfgang Betz 4:07537ca85c66 59 _led(led),
Wolfgang Betz 4:07537ca85c66 60 _current_irq_callback()
Wolfgang Betz 0:4fb29d9ee571 61 {
Wolfgang Betz 9:3db68ab23070 62 }
Wolfgang Betz 9:3db68ab23070 63
Wolfgang Betz 9:3db68ab23070 64 /** Init Function **/
Wolfgang Betz 9:3db68ab23070 65 void SimpleSpirit1::init() {
Wolfgang Betz 3:0df38cfb1e53 66 /* reset irq disable counter and irq callback & disable irq */
Wolfgang Betz 3:0df38cfb1e53 67 _nr_of_irq_disables = 0;
Wolfgang Betz 4:07537ca85c66 68 disable_spirit_irq();
Wolfgang Betz 0:4fb29d9ee571 69
Wolfgang Betz 0:4fb29d9ee571 70 /* unselect chip */
Wolfgang Betz 0:4fb29d9ee571 71 chip_unselect();
Wolfgang Betz 0:4fb29d9ee571 72
Wolfgang Betz 0:4fb29d9ee571 73 /* configure spi */
Wolfgang Betz 0:4fb29d9ee571 74 _spi.format(8, 0); /* 8-bit, mode = 0, [order = SPI_MSB] only available in mbed3 */
Wolfgang Betz 0:4fb29d9ee571 75 _spi.frequency(5000000); // 5MHz
Wolfgang Betz 3:0df38cfb1e53 76
Wolfgang Betz 5:c9c5bc673c64 77 /* install irq handler */
Wolfgang Betz 5:c9c5bc673c64 78 _irq.fall(Callback<void()>(this, &SimpleSpirit1::IrqHandler));
Wolfgang Betz 5:c9c5bc673c64 79
Wolfgang Betz 3:0df38cfb1e53 80 /* init cube vars */
Wolfgang Betz 3:0df38cfb1e53 81 spirit_on = OFF;
Wolfgang Betz 8:10967c884e38 82 #ifdef CONTIKI // betzw - TODO
Wolfgang Betz 3:0df38cfb1e53 83 packet_is_prepared = 0;
Wolfgang Betz 8:10967c884e38 84 just_got_an_ack = 0;
Wolfgang Betz 8:10967c884e38 85 #endif // CONTIKI
Wolfgang Betz 3:0df38cfb1e53 86 receiving_packet = 0;
Wolfgang Betz 4:07537ca85c66 87 last_rssi = 0 ; //MGR
Wolfgang Betz 4:07537ca85c66 88 last_lqi = 0 ; //MGR
Wolfgang Betz 0:4fb29d9ee571 89
Wolfgang Betz 0:4fb29d9ee571 90 /* set frequencies */
Wolfgang Betz 0:4fb29d9ee571 91 radio_set_xtal_freq(XTAL_FREQUENCY);
Wolfgang Betz 2:45642c5198a2 92 mgmt_set_freq_base((uint32_t)BASE_FREQUENCY);
Wolfgang Betz 0:4fb29d9ee571 93
Wolfgang Betz 0:4fb29d9ee571 94 /* restart board */
Wolfgang Betz 0:4fb29d9ee571 95 enter_shutdown();
Wolfgang Betz 0:4fb29d9ee571 96 exit_shutdown();
Wolfgang Betz 0:4fb29d9ee571 97
Wolfgang Betz 0:4fb29d9ee571 98 /* soft core reset */
Wolfgang Betz 4:07537ca85c66 99 cmd_strobe(SPIRIT1_STROBE_SRES);
Wolfgang Betz 0:4fb29d9ee571 100
Wolfgang Betz 0:4fb29d9ee571 101 /* Configures the SPIRIT1 radio part */
Wolfgang Betz 0:4fb29d9ee571 102 SRadioInit x_radio_init = {
Wolfgang Betz 0:4fb29d9ee571 103 XTAL_OFFSET_PPM,
Wolfgang Betz 0:4fb29d9ee571 104 (uint32_t)BASE_FREQUENCY,
Wolfgang Betz 0:4fb29d9ee571 105 (uint32_t)CHANNEL_SPACE,
Wolfgang Betz 0:4fb29d9ee571 106 CHANNEL_NUMBER,
Wolfgang Betz 0:4fb29d9ee571 107 MODULATION_SELECT,
Wolfgang Betz 0:4fb29d9ee571 108 DATARATE,
Wolfgang Betz 0:4fb29d9ee571 109 (uint32_t)FREQ_DEVIATION,
Wolfgang Betz 0:4fb29d9ee571 110 (uint32_t)BANDWIDTH
Wolfgang Betz 0:4fb29d9ee571 111 };
Wolfgang Betz 0:4fb29d9ee571 112 radio_init(&x_radio_init);
Wolfgang Betz 0:4fb29d9ee571 113 radio_set_pa_level_dbm(0,POWER_DBM);
Wolfgang Betz 0:4fb29d9ee571 114 radio_set_pa_level_max_index(0);
Wolfgang Betz 0:4fb29d9ee571 115
Wolfgang Betz 0:4fb29d9ee571 116 /* Configures the SPIRIT1 packet handler part*/
Wolfgang Betz 0:4fb29d9ee571 117 PktBasicInit x_basic_init = {
Wolfgang Betz 0:4fb29d9ee571 118 PREAMBLE_LENGTH,
Wolfgang Betz 0:4fb29d9ee571 119 SYNC_LENGTH,
Wolfgang Betz 0:4fb29d9ee571 120 SYNC_WORD,
Wolfgang Betz 0:4fb29d9ee571 121 LENGTH_TYPE,
Wolfgang Betz 0:4fb29d9ee571 122 LENGTH_WIDTH,
Wolfgang Betz 0:4fb29d9ee571 123 CRC_MODE,
Wolfgang Betz 0:4fb29d9ee571 124 CONTROL_LENGTH,
Wolfgang Betz 0:4fb29d9ee571 125 EN_ADDRESS,
Wolfgang Betz 0:4fb29d9ee571 126 EN_FEC,
Wolfgang Betz 0:4fb29d9ee571 127 EN_WHITENING
Wolfgang Betz 0:4fb29d9ee571 128 };
Wolfgang Betz 0:4fb29d9ee571 129 pkt_basic_init(&x_basic_init);
Wolfgang Betz 0:4fb29d9ee571 130
Wolfgang Betz 0:4fb29d9ee571 131 /* Enable the following interrupt sources, routed to GPIO */
Wolfgang Betz 0:4fb29d9ee571 132 irq_de_init(NULL);
Wolfgang Betz 0:4fb29d9ee571 133 irq_clear_status();
Wolfgang Betz 0:4fb29d9ee571 134 irq_set_status(TX_DATA_SENT, S_ENABLE);
Wolfgang Betz 0:4fb29d9ee571 135 irq_set_status(RX_DATA_READY,S_ENABLE);
Wolfgang Betz 0:4fb29d9ee571 136 irq_set_status(VALID_SYNC,S_ENABLE);
Wolfgang Betz 0:4fb29d9ee571 137 irq_set_status(RX_DATA_DISC, S_ENABLE);
Wolfgang Betz 0:4fb29d9ee571 138 irq_set_status(TX_FIFO_ERROR, S_ENABLE);
Wolfgang Betz 0:4fb29d9ee571 139 irq_set_status(RX_FIFO_ERROR, S_ENABLE);
Wolfgang Betz 6:f5d01793bf86 140 irq_set_status(RX_FIFO_ALMOST_FULL, S_ENABLE);
Wolfgang Betz 0:4fb29d9ee571 141
Wolfgang Betz 0:4fb29d9ee571 142 /* Configure Spirit1 */
Wolfgang Betz 0:4fb29d9ee571 143 radio_persisten_rx(S_ENABLE);
Wolfgang Betz 0:4fb29d9ee571 144 qi_set_sqi_threshold(SQI_TH_0);
Wolfgang Betz 0:4fb29d9ee571 145 qi_sqi_check(S_ENABLE);
Wolfgang Betz 0:4fb29d9ee571 146 qi_set_rssi_threshold_dbm(CCA_THRESHOLD);
Wolfgang Betz 0:4fb29d9ee571 147 timer_set_rx_timeout_stop_condition(SQI_ABOVE_THRESHOLD);
Wolfgang Betz 0:4fb29d9ee571 148 timer_set_infinite_rx_timeout();
Wolfgang Betz 0:4fb29d9ee571 149 radio_afc_freeze_on_sync(S_ENABLE);
Wolfgang Betz 0:4fb29d9ee571 150
Wolfgang Betz 0:4fb29d9ee571 151 /* Puts the SPIRIT1 in STANDBY mode (125us -> rx/tx) */
Wolfgang Betz 4:07537ca85c66 152 cmd_strobe(SPIRIT1_STROBE_STANDBY);
Wolfgang Betz 0:4fb29d9ee571 153 spirit_on = OFF;
Wolfgang Betz 6:f5d01793bf86 154 CLEAR_TXBUF();
Wolfgang Betz 0:4fb29d9ee571 155 CLEAR_RXBUF();
Wolfgang Betz 7:e90fa8f6bc6c 156 _spirit_tx_started = false;
Wolfgang Betz 6:f5d01793bf86 157 _spirit_rx_err = false;
Wolfgang Betz 0:4fb29d9ee571 158
Wolfgang Betz 0:4fb29d9ee571 159 /* Configure the radio to route the IRQ signal to its GPIO 3 */
Wolfgang Betz 0:4fb29d9ee571 160 SGpioInit x_gpio_init = {
Wolfgang Betz 0:4fb29d9ee571 161 SPIRIT_GPIO_IRQ,
Wolfgang Betz 0:4fb29d9ee571 162 SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP,
Wolfgang Betz 0:4fb29d9ee571 163 SPIRIT_GPIO_DIG_OUT_IRQ
Wolfgang Betz 0:4fb29d9ee571 164 };
Wolfgang Betz 0:4fb29d9ee571 165 spirit_gpio_init(&x_gpio_init);
Wolfgang Betz 0:4fb29d9ee571 166 }
Wolfgang Betz 3:0df38cfb1e53 167
Wolfgang Betz 8:10967c884e38 168 #ifdef CONTIKI // betzw - TODO
Wolfgang Betz 3:0df38cfb1e53 169 /** Prepare the radio with a packet to be sent. **/
Wolfgang Betz 5:c9c5bc673c64 170 int SimpleSpirit1::prepare_contiki(const void *payload, unsigned short payload_len) {
Wolfgang Betz 3:0df38cfb1e53 171 PRINTF("Spirit1: prep %u\n", payload_len);
Wolfgang Betz 3:0df38cfb1e53 172 packet_is_prepared = 0;
Wolfgang Betz 3:0df38cfb1e53 173
Wolfgang Betz 3:0df38cfb1e53 174 /* Checks if the payload length is supported */
Wolfgang Betz 3:0df38cfb1e53 175 if(payload_len > MAX_PACKET_LEN) {
Wolfgang Betz 3:0df38cfb1e53 176 return RADIO_TX_ERR;
Wolfgang Betz 3:0df38cfb1e53 177 }
Wolfgang Betz 3:0df38cfb1e53 178
Wolfgang Betz 3:0df38cfb1e53 179 /* Should we delay for an ack? */
Wolfgang Betz 3:0df38cfb1e53 180 #if NULLRDC_CONF_802154_AUTOACK
Wolfgang Betz 3:0df38cfb1e53 181 frame802154_t info154;
Wolfgang Betz 3:0df38cfb1e53 182 wants_an_ack = 0;
Wolfgang Betz 3:0df38cfb1e53 183 if(payload_len > ACK_LEN
Wolfgang Betz 3:0df38cfb1e53 184 && frame802154_parse((char*)payload, payload_len, &info154) != 0) {
Wolfgang Betz 3:0df38cfb1e53 185 if(info154.fcf.frame_type == FRAME802154_DATAFRAME
Wolfgang Betz 3:0df38cfb1e53 186 && info154.fcf.ack_required != 0) {
Wolfgang Betz 3:0df38cfb1e53 187 wants_an_ack = 1;
Wolfgang Betz 3:0df38cfb1e53 188 }
Wolfgang Betz 3:0df38cfb1e53 189 }
Wolfgang Betz 3:0df38cfb1e53 190 #endif /* NULLRDC_CONF_802154_AUTOACK */
Wolfgang Betz 3:0df38cfb1e53 191
Wolfgang Betz 3:0df38cfb1e53 192 /* Sets the length of the packet to send */
Wolfgang Betz 4:07537ca85c66 193 disable_spirit_irq();
Wolfgang Betz 4:07537ca85c66 194 cmd_strobe(SPIRIT1_STROBE_FTX);
Wolfgang Betz 3:0df38cfb1e53 195 pkt_basic_set_payload_length(payload_len);
Wolfgang Betz 3:0df38cfb1e53 196 spi_write_linear_fifo(payload_len, (uint8_t *)payload);
Wolfgang Betz 4:07537ca85c66 197 enable_spirit_irq();
Wolfgang Betz 3:0df38cfb1e53 198
Wolfgang Betz 3:0df38cfb1e53 199 PRINTF("PREPARE OUT\n");
Wolfgang Betz 3:0df38cfb1e53 200
Wolfgang Betz 3:0df38cfb1e53 201 packet_is_prepared = 1;
Wolfgang Betz 3:0df38cfb1e53 202 return RADIO_TX_OK;
Wolfgang Betz 3:0df38cfb1e53 203 }
Wolfgang Betz 3:0df38cfb1e53 204
Wolfgang Betz 3:0df38cfb1e53 205 /** Send the packet that has previously been prepared. **/
Wolfgang Betz 5:c9c5bc673c64 206 int SimpleSpirit1::transmit_contiki(unsigned short payload_len) {
Wolfgang Betz 3:0df38cfb1e53 207 /* This function blocks until the packet has been transmitted */
Wolfgang Betz 3:0df38cfb1e53 208 //rtimer_clock_t rtimer_txdone, rtimer_rxack;
Wolfgang Betz 3:0df38cfb1e53 209
Wolfgang Betz 3:0df38cfb1e53 210 PRINTF("TRANSMIT IN\n");
Wolfgang Betz 3:0df38cfb1e53 211 if(!packet_is_prepared) {
Wolfgang Betz 3:0df38cfb1e53 212 return RADIO_TX_ERR;
Wolfgang Betz 3:0df38cfb1e53 213 }
Wolfgang Betz 3:0df38cfb1e53 214
Wolfgang Betz 3:0df38cfb1e53 215 /* Stores the length of the packet to send */
Wolfgang Betz 3:0df38cfb1e53 216 /* Others spirit_radio_prepare will be in hold */
Wolfgang Betz 4:07537ca85c66 217 spirit_tx_len = payload_len;
Wolfgang Betz 3:0df38cfb1e53 218
Wolfgang Betz 3:0df38cfb1e53 219 /* Puts the SPIRIT1 in TX state */
Wolfgang Betz 3:0df38cfb1e53 220 receiving_packet = 0;
Wolfgang Betz 3:0df38cfb1e53 221 set_ready_state();
Wolfgang Betz 4:07537ca85c66 222 cmd_strobe(SPIRIT1_STROBE_TX);
Wolfgang Betz 3:0df38cfb1e53 223 just_got_an_ack = 0;
Wolfgang Betz 3:0df38cfb1e53 224 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_TX, 1);
Wolfgang Betz 3:0df38cfb1e53 225 //BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 4); //For GFSK with high data rate
Wolfgang Betz 3:0df38cfb1e53 226 BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 50); //For FSK with low data rate
Wolfgang Betz 3:0df38cfb1e53 227
Wolfgang Betz 3:0df38cfb1e53 228 /* Reset radio - needed for immediate RX of ack */
Wolfgang Betz 3:0df38cfb1e53 229 CLEAR_TXBUF();
Wolfgang Betz 3:0df38cfb1e53 230 CLEAR_RXBUF();
Wolfgang Betz 4:07537ca85c66 231 disable_spirit_irq();
Wolfgang Betz 3:0df38cfb1e53 232 irq_clear_status();
Wolfgang Betz 7:e90fa8f6bc6c 233 receiving_packet = 0;
Wolfgang Betz 4:07537ca85c66 234 cmd_strobe(SPIRIT1_STROBE_SABORT);
Wolfgang Betz 3:0df38cfb1e53 235 wait_us(SABORT_WAIT_US);
Wolfgang Betz 4:07537ca85c66 236 cmd_strobe(SPIRIT1_STROBE_READY);
Wolfgang Betz 3:0df38cfb1e53 237 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 1);
Wolfgang Betz 6:f5d01793bf86 238 cmd_strobe(SPIRIT1_STROBE_FRX);
Wolfgang Betz 4:07537ca85c66 239 cmd_strobe(SPIRIT1_STROBE_RX);
Wolfgang Betz 3:0df38cfb1e53 240 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1);
Wolfgang Betz 4:07537ca85c66 241 enable_spirit_irq();
Wolfgang Betz 3:0df38cfb1e53 242
Wolfgang Betz 3:0df38cfb1e53 243 #if XXX_ACK_WORKAROUND
Wolfgang Betz 3:0df38cfb1e53 244 just_got_an_ack = 1;
Wolfgang Betz 3:0df38cfb1e53 245 #endif /* XXX_ACK_WORKAROUND */
Wolfgang Betz 3:0df38cfb1e53 246
Wolfgang Betz 3:0df38cfb1e53 247 #if NULLRDC_CONF_802154_AUTOACK
Wolfgang Betz 3:0df38cfb1e53 248 if (wants_an_ack) {
Wolfgang Betz 7:e90fa8f6bc6c 249 rtimer_txdone = us_ticker_read();
Wolfgang Betz 3:0df38cfb1e53 250 BUSYWAIT_UNTIL(just_got_an_ack, 2);
Wolfgang Betz 7:e90fa8f6bc6c 251 rtimer_rxack = us_ticker_read();
Wolfgang Betz 3:0df38cfb1e53 252
Wolfgang Betz 3:0df38cfb1e53 253 if(just_got_an_ack) {
Wolfgang Betz 4:07537ca85c66 254 ACKPRINTF("debug_ack: ack received after %u us\n",
Wolfgang Betz 3:0df38cfb1e53 255 (uint32_t)(rtimer_rxack - rtimer_txdone));
Wolfgang Betz 3:0df38cfb1e53 256 } else {
Wolfgang Betz 3:0df38cfb1e53 257 ACKPRINTF("debug_ack: no ack received\n");
Wolfgang Betz 3:0df38cfb1e53 258 }
Wolfgang Betz 3:0df38cfb1e53 259 }
Wolfgang Betz 3:0df38cfb1e53 260 #endif /* NULLRDC_CONF_802154_AUTOACK */
Wolfgang Betz 3:0df38cfb1e53 261
Wolfgang Betz 3:0df38cfb1e53 262 PRINTF("TRANSMIT OUT\n");
Wolfgang Betz 3:0df38cfb1e53 263
Wolfgang Betz 3:0df38cfb1e53 264 CLEAR_TXBUF();
Wolfgang Betz 3:0df38cfb1e53 265
Wolfgang Betz 3:0df38cfb1e53 266 packet_is_prepared = 0;
Wolfgang Betz 3:0df38cfb1e53 267
Wolfgang Betz 3:0df38cfb1e53 268 wait_us(1);
Wolfgang Betz 3:0df38cfb1e53 269
Wolfgang Betz 3:0df38cfb1e53 270 return RADIO_TX_OK;
Wolfgang Betz 3:0df38cfb1e53 271 }
Wolfgang Betz 8:10967c884e38 272 #endif // CONTIKI
Wolfgang Betz 3:0df38cfb1e53 273
Wolfgang Betz 6:f5d01793bf86 274 int SimpleSpirit1::send(const void *payload, unsigned int payload_len) {
Wolfgang Betz 5:c9c5bc673c64 275 /* Checks if the payload length is supported */
Wolfgang Betz 5:c9c5bc673c64 276 if(payload_len > MAX_PACKET_LEN) {
Wolfgang Betz 5:c9c5bc673c64 277 return RADIO_TX_ERR;
Wolfgang Betz 5:c9c5bc673c64 278 }
Wolfgang Betz 5:c9c5bc673c64 279
Wolfgang Betz 5:c9c5bc673c64 280 disable_spirit_irq();
Wolfgang Betz 5:c9c5bc673c64 281
Wolfgang Betz 5:c9c5bc673c64 282 /* Reset State to Ready */
Wolfgang Betz 5:c9c5bc673c64 283 set_ready_state();
Wolfgang Betz 5:c9c5bc673c64 284
Wolfgang Betz 5:c9c5bc673c64 285 cmd_strobe(SPIRIT1_STROBE_FTX); // flush TX FIFO buffer
Wolfgang Betz 5:c9c5bc673c64 286 MBED_ASSERT(linear_fifo_read_num_elements_tx_fifo() == 0);
Wolfgang Betz 5:c9c5bc673c64 287
Wolfgang Betz 5:c9c5bc673c64 288 pkt_basic_set_payload_length(payload_len); // set desired payload len
Wolfgang Betz 5:c9c5bc673c64 289
Wolfgang Betz 5:c9c5bc673c64 290 int i = 0;
Wolfgang Betz 5:c9c5bc673c64 291 int remaining = payload_len;
Wolfgang Betz 5:c9c5bc673c64 292 bool trigger_tx = true;
Wolfgang Betz 5:c9c5bc673c64 293 do {
Wolfgang Betz 5:c9c5bc673c64 294 uint8_t fifo_available = SPIRIT_MAX_FIFO_LEN - linear_fifo_read_num_elements_tx_fifo();
Wolfgang Betz 5:c9c5bc673c64 295 uint8_t to_send = (remaining > fifo_available) ? fifo_available : remaining;
Wolfgang Betz 5:c9c5bc673c64 296 const uint8_t *buffer = (const uint8_t*)payload;
Wolfgang Betz 5:c9c5bc673c64 297
Wolfgang Betz 5:c9c5bc673c64 298 /* Fill FIFO Buffer */
Wolfgang Betz 5:c9c5bc673c64 299 spi_write_linear_fifo(to_send, (uint8_t*)&buffer[i]);
Wolfgang Betz 5:c9c5bc673c64 300
Wolfgang Betz 5:c9c5bc673c64 301 /* Start Transmit FIFO Buffer */
Wolfgang Betz 5:c9c5bc673c64 302 if(trigger_tx) {
Wolfgang Betz 5:c9c5bc673c64 303 MBED_ASSERT(linear_fifo_read_num_elements_tx_fifo() == to_send);
Wolfgang Betz 5:c9c5bc673c64 304 cmd_strobe(SPIRIT1_STROBE_TX);
Wolfgang Betz 5:c9c5bc673c64 305 trigger_tx = false;
Wolfgang Betz 5:c9c5bc673c64 306 }
Wolfgang Betz 5:c9c5bc673c64 307
Wolfgang Betz 5:c9c5bc673c64 308 i += to_send;
Wolfgang Betz 5:c9c5bc673c64 309 remaining -= to_send;
Wolfgang Betz 5:c9c5bc673c64 310 } while(remaining != 0);
Wolfgang Betz 5:c9c5bc673c64 311
Wolfgang Betz 7:e90fa8f6bc6c 312 _spirit_tx_started = true;
Wolfgang Betz 7:e90fa8f6bc6c 313
Wolfgang Betz 7:e90fa8f6bc6c 314 enable_spirit_irq();
Wolfgang Betz 7:e90fa8f6bc6c 315
Wolfgang Betz 5:c9c5bc673c64 316 BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 50);
Wolfgang Betz 11:b769d6caad82 317 // MBED_ASSERT(linear_fifo_read_num_elements_tx_fifo() == 0);
Wolfgang Betz 5:c9c5bc673c64 318
Wolfgang Betz 5:c9c5bc673c64 319 return RADIO_TX_OK;
Wolfgang Betz 5:c9c5bc673c64 320 }
Wolfgang Betz 5:c9c5bc673c64 321
Wolfgang Betz 3:0df38cfb1e53 322 /** Set Ready State **/
Wolfgang Betz 3:0df38cfb1e53 323 void SimpleSpirit1::set_ready_state(void) {
Wolfgang Betz 3:0df38cfb1e53 324 PRINTF("READY IN\n");
Wolfgang Betz 3:0df38cfb1e53 325
Wolfgang Betz 4:07537ca85c66 326 disable_spirit_irq();
Wolfgang Betz 3:0df38cfb1e53 327
Wolfgang Betz 3:0df38cfb1e53 328 if(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY) {
Wolfgang Betz 4:07537ca85c66 329 cmd_strobe(SPIRIT1_STROBE_READY);
Wolfgang Betz 3:0df38cfb1e53 330 } else if(SPIRIT1_STATUS() == SPIRIT1_STATE_RX) {
Wolfgang Betz 7:e90fa8f6bc6c 331 receiving_packet = 0;
Wolfgang Betz 4:07537ca85c66 332 cmd_strobe(SPIRIT1_STROBE_SABORT);
Wolfgang Betz 3:0df38cfb1e53 333 }
Wolfgang Betz 7:e90fa8f6bc6c 334 irq_clear_status();
Wolfgang Betz 3:0df38cfb1e53 335
Wolfgang Betz 4:07537ca85c66 336 enable_spirit_irq();
Wolfgang Betz 3:0df38cfb1e53 337
Wolfgang Betz 3:0df38cfb1e53 338 PRINTF("READY OUT\n");
Wolfgang Betz 3:0df38cfb1e53 339 }
Wolfgang Betz 3:0df38cfb1e53 340
Wolfgang Betz 4:07537ca85c66 341 int SimpleSpirit1::off(void) {
Wolfgang Betz 3:0df38cfb1e53 342 PRINTF("Spirit1: ->off\n");
Wolfgang Betz 3:0df38cfb1e53 343 if(spirit_on == ON) {
Wolfgang Betz 3:0df38cfb1e53 344 /* Disables the mcu to get IRQ from the SPIRIT1 */
Wolfgang Betz 4:07537ca85c66 345 disable_spirit_irq();
Wolfgang Betz 3:0df38cfb1e53 346
Wolfgang Betz 3:0df38cfb1e53 347 /* first stop rx/tx */
Wolfgang Betz 7:e90fa8f6bc6c 348 receiving_packet = 0;
Wolfgang Betz 4:07537ca85c66 349 cmd_strobe(SPIRIT1_STROBE_SABORT);
Wolfgang Betz 3:0df38cfb1e53 350
Wolfgang Betz 3:0df38cfb1e53 351 /* Clear any pending irqs */
Wolfgang Betz 3:0df38cfb1e53 352 irq_clear_status();
Wolfgang Betz 3:0df38cfb1e53 353
Wolfgang Betz 3:0df38cfb1e53 354 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 5);
Wolfgang Betz 3:0df38cfb1e53 355 if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
Wolfgang Betz 3:0df38cfb1e53 356 PRINTF("Spirit1: failed off->ready\n");
Wolfgang Betz 3:0df38cfb1e53 357 return 1;
Wolfgang Betz 3:0df38cfb1e53 358 }
Wolfgang Betz 3:0df38cfb1e53 359
Wolfgang Betz 3:0df38cfb1e53 360 /* Puts the SPIRIT1 in STANDBY */
Wolfgang Betz 4:07537ca85c66 361 cmd_strobe(SPIRIT1_STROBE_STANDBY);
Wolfgang Betz 3:0df38cfb1e53 362 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, 5);
Wolfgang Betz 3:0df38cfb1e53 363 if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) {
Wolfgang Betz 3:0df38cfb1e53 364 PRINTF("Spirit1: failed off->standby\n");
Wolfgang Betz 3:0df38cfb1e53 365 return 1;
Wolfgang Betz 3:0df38cfb1e53 366 }
Wolfgang Betz 3:0df38cfb1e53 367
Wolfgang Betz 3:0df38cfb1e53 368 spirit_on = OFF;
Wolfgang Betz 4:07537ca85c66 369 _nr_of_irq_disables = 1;
Wolfgang Betz 7:e90fa8f6bc6c 370 _spirit_tx_started = false;
Wolfgang Betz 3:0df38cfb1e53 371 CLEAR_TXBUF();
Wolfgang Betz 3:0df38cfb1e53 372 CLEAR_RXBUF();
Wolfgang Betz 3:0df38cfb1e53 373 }
Wolfgang Betz 3:0df38cfb1e53 374 PRINTF("Spirit1: off.\n");
Wolfgang Betz 3:0df38cfb1e53 375 return 0;
Wolfgang Betz 3:0df38cfb1e53 376 }
Wolfgang Betz 3:0df38cfb1e53 377
Wolfgang Betz 4:07537ca85c66 378 int SimpleSpirit1::on(void) {
Wolfgang Betz 3:0df38cfb1e53 379 PRINTF("Spirit1: on\n");
Wolfgang Betz 4:07537ca85c66 380 cmd_strobe(SPIRIT1_STROBE_SABORT);
Wolfgang Betz 3:0df38cfb1e53 381 wait_us(SABORT_WAIT_US);
Wolfgang Betz 3:0df38cfb1e53 382 if(spirit_on == OFF) {
Wolfgang Betz 3:0df38cfb1e53 383 /* ensure we are in READY state as we go from there to Rx */
Wolfgang Betz 4:07537ca85c66 384 cmd_strobe(SPIRIT1_STROBE_READY);
Wolfgang Betz 3:0df38cfb1e53 385 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 5);
Wolfgang Betz 3:0df38cfb1e53 386 if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
Wolfgang Betz 3:0df38cfb1e53 387 PRINTF("Spirit1: failed to turn on\n");
Wolfgang Betz 3:0df38cfb1e53 388 while(1);
Wolfgang Betz 3:0df38cfb1e53 389 //return 1;
Wolfgang Betz 3:0df38cfb1e53 390 }
Wolfgang Betz 3:0df38cfb1e53 391
Wolfgang Betz 3:0df38cfb1e53 392 /* now we go to Rx */
Wolfgang Betz 6:f5d01793bf86 393 cmd_strobe(SPIRIT1_STROBE_FRX);
Wolfgang Betz 4:07537ca85c66 394 cmd_strobe(SPIRIT1_STROBE_RX);
Wolfgang Betz 3:0df38cfb1e53 395 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5);
Wolfgang Betz 3:0df38cfb1e53 396 if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
Wolfgang Betz 3:0df38cfb1e53 397 PRINTF("Spirit1: failed to enter rx\n");
Wolfgang Betz 3:0df38cfb1e53 398 while(1);
Wolfgang Betz 3:0df38cfb1e53 399 //return 1;
Wolfgang Betz 3:0df38cfb1e53 400 }
Wolfgang Betz 6:f5d01793bf86 401 CLEAR_RXBUF();
Wolfgang Betz 7:e90fa8f6bc6c 402 receiving_packet = 0;
Wolfgang Betz 6:f5d01793bf86 403 _spirit_rx_err = false;
Wolfgang Betz 3:0df38cfb1e53 404
Wolfgang Betz 3:0df38cfb1e53 405 /* Enables the mcu to get IRQ from the SPIRIT1 */
Wolfgang Betz 3:0df38cfb1e53 406 spirit_on = ON;
Wolfgang Betz 5:c9c5bc673c64 407 MBED_ASSERT(_nr_of_irq_disables == 1);
Wolfgang Betz 5:c9c5bc673c64 408 enable_spirit_irq();
Wolfgang Betz 3:0df38cfb1e53 409 }
Wolfgang Betz 3:0df38cfb1e53 410
Wolfgang Betz 3:0df38cfb1e53 411 return 0;
Wolfgang Betz 3:0df38cfb1e53 412 }
Wolfgang Betz 3:0df38cfb1e53 413
Wolfgang Betz 3:0df38cfb1e53 414 uint16_t SimpleSpirit1::arch_refresh_status(void) {
Wolfgang Betz 3:0df38cfb1e53 415 uint16_t mcstate;
Wolfgang Betz 3:0df38cfb1e53 416 uint8_t header[2];
Wolfgang Betz 3:0df38cfb1e53 417 header[0]=READ_HEADER;
Wolfgang Betz 3:0df38cfb1e53 418 header[1]=MC_STATE1_BASE;
Wolfgang Betz 3:0df38cfb1e53 419
Wolfgang Betz 3:0df38cfb1e53 420 /* Puts the SPI chip select low to start the transaction */
Wolfgang Betz 3:0df38cfb1e53 421 chip_sync_select();
Wolfgang Betz 3:0df38cfb1e53 422
Wolfgang Betz 3:0df38cfb1e53 423 /* Write the aHeader bytes and read the SPIRIT1 status bytes */
Wolfgang Betz 3:0df38cfb1e53 424 mcstate = _spi.write(header[0]);
Wolfgang Betz 3:0df38cfb1e53 425 mcstate = mcstate<<8;
Wolfgang Betz 3:0df38cfb1e53 426
Wolfgang Betz 3:0df38cfb1e53 427 /* Write the aHeader bytes and read the SPIRIT1 status bytes */
Wolfgang Betz 3:0df38cfb1e53 428 mcstate |= _spi.write(header[1]);
Wolfgang Betz 3:0df38cfb1e53 429
Wolfgang Betz 3:0df38cfb1e53 430 /* Puts the SPI chip select high to end the transaction */
Wolfgang Betz 3:0df38cfb1e53 431 chip_sync_unselect();
Wolfgang Betz 3:0df38cfb1e53 432
Wolfgang Betz 3:0df38cfb1e53 433 return mcstate;
Wolfgang Betz 3:0df38cfb1e53 434 }
Wolfgang Betz 3:0df38cfb1e53 435
Wolfgang Betz 6:f5d01793bf86 436 int SimpleSpirit1::read(void *buf, unsigned int bufsize)
Wolfgang Betz 4:07537ca85c66 437 {
Wolfgang Betz 4:07537ca85c66 438 PRINTF("READ IN\n");
Wolfgang Betz 4:07537ca85c66 439
Wolfgang Betz 6:f5d01793bf86 440 disable_spirit_irq();
Wolfgang Betz 6:f5d01793bf86 441
Wolfgang Betz 4:07537ca85c66 442 /* Checks if the RX buffer is empty */
Wolfgang Betz 4:07537ca85c66 443 if(IS_RXBUF_EMPTY()) {
Wolfgang Betz 4:07537ca85c66 444 CLEAR_RXBUF();
Wolfgang Betz 7:e90fa8f6bc6c 445 receiving_packet = 0;
Wolfgang Betz 4:07537ca85c66 446 cmd_strobe(SPIRIT1_STROBE_SABORT);
Wolfgang Betz 4:07537ca85c66 447 wait_us(SABORT_WAIT_US);
Wolfgang Betz 4:07537ca85c66 448 cmd_strobe(SPIRIT1_STROBE_READY);
Wolfgang Betz 4:07537ca85c66 449 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 1);
Wolfgang Betz 6:f5d01793bf86 450 cmd_strobe(SPIRIT1_STROBE_FRX);
Wolfgang Betz 4:07537ca85c66 451 cmd_strobe(SPIRIT1_STROBE_RX);
Wolfgang Betz 4:07537ca85c66 452 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1);
Wolfgang Betz 6:f5d01793bf86 453 _spirit_rx_err = false;
Wolfgang Betz 4:07537ca85c66 454 PRINTF("READ OUT RX BUF EMPTY\n");
Wolfgang Betz 4:07537ca85c66 455 enable_spirit_irq();
Wolfgang Betz 4:07537ca85c66 456 return 0;
Wolfgang Betz 4:07537ca85c66 457 }
Wolfgang Betz 4:07537ca85c66 458
Wolfgang Betz 4:07537ca85c66 459 if(bufsize < spirit_rx_len) {
Wolfgang Betz 6:f5d01793bf86 460 enable_spirit_irq();
Wolfgang Betz 6:f5d01793bf86 461
Wolfgang Betz 6:f5d01793bf86 462 /* If buf has the correct size */
Wolfgang Betz 4:07537ca85c66 463 PRINTF("TOO SMALL BUF\n");
Wolfgang Betz 4:07537ca85c66 464 return 0;
Wolfgang Betz 4:07537ca85c66 465 } else {
Wolfgang Betz 4:07537ca85c66 466 /* Copies the packet received */
Wolfgang Betz 4:07537ca85c66 467 memcpy(buf, spirit_rx_buf, spirit_rx_len);
Wolfgang Betz 4:07537ca85c66 468
Wolfgang Betz 4:07537ca85c66 469 #ifdef CONTIKI // betzw - TODO
Wolfgang Betz 4:07537ca85c66 470 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, last_rssi); //MGR
Wolfgang Betz 4:07537ca85c66 471 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, last_lqi); //MGR
Wolfgang Betz 4:07537ca85c66 472 #endif
Wolfgang Betz 4:07537ca85c66 473
Wolfgang Betz 4:07537ca85c66 474 bufsize = spirit_rx_len;
Wolfgang Betz 4:07537ca85c66 475 CLEAR_RXBUF();
Wolfgang Betz 4:07537ca85c66 476
Wolfgang Betz 6:f5d01793bf86 477 enable_spirit_irq();
Wolfgang Betz 6:f5d01793bf86 478
Wolfgang Betz 4:07537ca85c66 479 PRINTF("READ OUT\n");
Wolfgang Betz 4:07537ca85c66 480
Wolfgang Betz 4:07537ca85c66 481 return bufsize;
Wolfgang Betz 4:07537ca85c66 482 }
Wolfgang Betz 4:07537ca85c66 483
Wolfgang Betz 4:07537ca85c66 484 }
Wolfgang Betz 4:07537ca85c66 485
Wolfgang Betz 4:07537ca85c66 486 int SimpleSpirit1::channel_clear(void)
Wolfgang Betz 4:07537ca85c66 487 {
Wolfgang Betz 4:07537ca85c66 488 float rssi_value;
Wolfgang Betz 4:07537ca85c66 489 /* Local variable used to memorize the SPIRIT1 state */
Wolfgang Betz 4:07537ca85c66 490 uint8_t spirit_state = ON;
Wolfgang Betz 4:07537ca85c66 491
Wolfgang Betz 4:07537ca85c66 492 PRINTF("CHANNEL CLEAR IN\n");
Wolfgang Betz 4:07537ca85c66 493
Wolfgang Betz 4:07537ca85c66 494 if(spirit_on == OFF) {
Wolfgang Betz 4:07537ca85c66 495 /* Wakes up the SPIRIT1 */
Wolfgang Betz 4:07537ca85c66 496 on();
Wolfgang Betz 4:07537ca85c66 497 spirit_state = OFF;
Wolfgang Betz 4:07537ca85c66 498 }
Wolfgang Betz 4:07537ca85c66 499
Wolfgang Betz 4:07537ca85c66 500 disable_spirit_irq();
Wolfgang Betz 7:e90fa8f6bc6c 501
Wolfgang Betz 7:e90fa8f6bc6c 502 /* Reset State to Ready */
Wolfgang Betz 7:e90fa8f6bc6c 503 set_ready_state();
Wolfgang Betz 4:07537ca85c66 504 {
Wolfgang Betz 7:e90fa8f6bc6c 505 uint32_t timeout = us_ticker_read() + 5000;
Wolfgang Betz 4:07537ca85c66 506 do {
Wolfgang Betz 4:07537ca85c66 507 mgmt_refresh_status();
Wolfgang Betz 7:e90fa8f6bc6c 508 } while((st_lib_g_x_status.MC_STATE != MC_STATE_READY) && (us_ticker_read() < timeout));
Wolfgang Betz 4:07537ca85c66 509 if(st_lib_g_x_status.MC_STATE != MC_STATE_READY) {
Wolfgang Betz 6:f5d01793bf86 510 enable_spirit_irq();
Wolfgang Betz 4:07537ca85c66 511 return 1;
Wolfgang Betz 4:07537ca85c66 512 }
Wolfgang Betz 4:07537ca85c66 513 }
Wolfgang Betz 4:07537ca85c66 514
Wolfgang Betz 4:07537ca85c66 515 /* Stores the RSSI value */
Wolfgang Betz 4:07537ca85c66 516 rssi_value = qi_get_rssi_dbm();
Wolfgang Betz 4:07537ca85c66 517
Wolfgang Betz 7:e90fa8f6bc6c 518 enable_spirit_irq();
Wolfgang Betz 7:e90fa8f6bc6c 519
Wolfgang Betz 4:07537ca85c66 520 /* Puts the SPIRIT1 in its previous state */
Wolfgang Betz 4:07537ca85c66 521 if(spirit_state==OFF) {
Wolfgang Betz 4:07537ca85c66 522 off();
Wolfgang Betz 4:07537ca85c66 523 } else {
Wolfgang Betz 6:f5d01793bf86 524 disable_spirit_irq();
Wolfgang Betz 6:f5d01793bf86 525 cmd_strobe(SPIRIT1_STROBE_FRX);
Wolfgang Betz 4:07537ca85c66 526 cmd_strobe(SPIRIT1_STROBE_RX);
Wolfgang Betz 4:07537ca85c66 527 /* SpiritCmdStrobeRx();*/
Wolfgang Betz 4:07537ca85c66 528 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5);
Wolfgang Betz 6:f5d01793bf86 529 CLEAR_RXBUF();
Wolfgang Betz 6:f5d01793bf86 530 _spirit_rx_err = false;
Wolfgang Betz 6:f5d01793bf86 531 enable_spirit_irq();
Wolfgang Betz 4:07537ca85c66 532 }
Wolfgang Betz 4:07537ca85c66 533
Wolfgang Betz 4:07537ca85c66 534 PRINTF("CHANNEL CLEAR OUT\n");
Wolfgang Betz 4:07537ca85c66 535
Wolfgang Betz 4:07537ca85c66 536 /* Checks the RSSI value with the threshold */
Wolfgang Betz 4:07537ca85c66 537 if(rssi_value<CCA_THRESHOLD) {
Wolfgang Betz 4:07537ca85c66 538 return 0;
Wolfgang Betz 4:07537ca85c66 539 } else {
Wolfgang Betz 4:07537ca85c66 540 return 1;
Wolfgang Betz 4:07537ca85c66 541 }
Wolfgang Betz 4:07537ca85c66 542 }
Wolfgang Betz 4:07537ca85c66 543
Wolfgang Betz 7:e90fa8f6bc6c 544 int SimpleSpirit1::get_pending_packet(void)
Wolfgang Betz 4:07537ca85c66 545 {
Wolfgang Betz 4:07537ca85c66 546 PRINTF("PENDING PACKET\n");
Wolfgang Betz 4:07537ca85c66 547 return !IS_RXBUF_EMPTY();
Wolfgang Betz 4:07537ca85c66 548 }
Wolfgang Betz 4:07537ca85c66 549
Wolfgang Betz 5:c9c5bc673c64 550 /** Spirit Irq Callback **/
Wolfgang Betz 5:c9c5bc673c64 551 void SimpleSpirit1::IrqHandler() {
Wolfgang Betz 4:07537ca85c66 552 st_lib_spirit_irqs x_irq_status;
Wolfgang Betz 4:07537ca85c66 553
Wolfgang Betz 4:07537ca85c66 554 /* get interrupt source from radio */
Wolfgang Betz 4:07537ca85c66 555 irq_get_status(&x_irq_status);
Wolfgang Betz 4:07537ca85c66 556 irq_clear_status();
Wolfgang Betz 4:07537ca85c66 557
Wolfgang Betz 6:f5d01793bf86 558 /* Reception errors */
Wolfgang Betz 6:f5d01793bf86 559 if((x_irq_status.IRQ_RX_FIFO_ERROR) || (x_irq_status.IRQ_RX_DATA_DISC) || (x_irq_status.IRQ_RX_TIMEOUT)) {
Wolfgang Betz 4:07537ca85c66 560 receiving_packet = 0;
Wolfgang Betz 6:f5d01793bf86 561 _spirit_rx_err = true;
Wolfgang Betz 6:f5d01793bf86 562 CLEAR_RXBUF();
Wolfgang Betz 4:07537ca85c66 563 cmd_strobe(SPIRIT1_STROBE_FRX);
Wolfgang Betz 7:e90fa8f6bc6c 564 if(_spirit_tx_started) {
Wolfgang Betz 7:e90fa8f6bc6c 565 _spirit_tx_started = false;
Wolfgang Betz 7:e90fa8f6bc6c 566 CLEAR_TXBUF();
Wolfgang Betz 7:e90fa8f6bc6c 567 /* call user callback */
Wolfgang Betz 7:e90fa8f6bc6c 568 if(_current_irq_callback) {
Wolfgang Betz 9:3db68ab23070 569 _current_irq_callback(TX_ERR);
Wolfgang Betz 7:e90fa8f6bc6c 570 }
Wolfgang Betz 7:e90fa8f6bc6c 571 }
Wolfgang Betz 4:07537ca85c66 572 }
Wolfgang Betz 4:07537ca85c66 573
Wolfgang Betz 6:f5d01793bf86 574 /* Transmission error */
Wolfgang Betz 4:07537ca85c66 575 if(x_irq_status.IRQ_TX_FIFO_ERROR) {
Wolfgang Betz 6:f5d01793bf86 576 error("IRQ_TX_FIFO_ERROR should never happen!\n");
Wolfgang Betz 4:07537ca85c66 577 receiving_packet = 0;
Wolfgang Betz 4:07537ca85c66 578 cmd_strobe(SPIRIT1_STROBE_FTX);
Wolfgang Betz 7:e90fa8f6bc6c 579 if(_spirit_tx_started) {
Wolfgang Betz 7:e90fa8f6bc6c 580 _spirit_tx_started = false;
Wolfgang Betz 7:e90fa8f6bc6c 581 CLEAR_TXBUF();
Wolfgang Betz 7:e90fa8f6bc6c 582 /* call user callback */
Wolfgang Betz 7:e90fa8f6bc6c 583 if(_current_irq_callback) {
Wolfgang Betz 9:3db68ab23070 584 _current_irq_callback(TX_ERR);
Wolfgang Betz 7:e90fa8f6bc6c 585 }
Wolfgang Betz 7:e90fa8f6bc6c 586 }
Wolfgang Betz 4:07537ca85c66 587 }
Wolfgang Betz 4:07537ca85c66 588
Wolfgang Betz 4:07537ca85c66 589 /* The IRQ_VALID_SYNC is used to notify a new packet is coming */
Wolfgang Betz 4:07537ca85c66 590 if(x_irq_status.IRQ_VALID_SYNC) {
Wolfgang Betz 4:07537ca85c66 591 receiving_packet = 1;
Wolfgang Betz 6:f5d01793bf86 592 _spirit_rx_err = false;
Wolfgang Betz 6:f5d01793bf86 593 CLEAR_RXBUF();
Wolfgang Betz 7:e90fa8f6bc6c 594 if(_spirit_tx_started) { // betzw - TOCHECK: is this really correct to be done here?
Wolfgang Betz 7:e90fa8f6bc6c 595 _spirit_tx_started = false;
Wolfgang Betz 7:e90fa8f6bc6c 596 CLEAR_TXBUF();
Wolfgang Betz 7:e90fa8f6bc6c 597 /* call user callback */
Wolfgang Betz 7:e90fa8f6bc6c 598 if(_current_irq_callback) {
Wolfgang Betz 9:3db68ab23070 599 _current_irq_callback(TX_ERR);
Wolfgang Betz 7:e90fa8f6bc6c 600 }
Wolfgang Betz 7:e90fa8f6bc6c 601 }
Wolfgang Betz 6:f5d01793bf86 602 }
Wolfgang Betz 6:f5d01793bf86 603
Wolfgang Betz 6:f5d01793bf86 604 /* RX FIFO almost full */
Wolfgang Betz 6:f5d01793bf86 605 if(x_irq_status.IRQ_RX_FIFO_ALMOST_FULL) {
Wolfgang Betz 6:f5d01793bf86 606 if(_spirit_rx_err) {
Wolfgang Betz 6:f5d01793bf86 607 cmd_strobe(SPIRIT1_STROBE_FRX);
Wolfgang Betz 6:f5d01793bf86 608 } else {
Wolfgang Betz 6:f5d01793bf86 609 uint8_t fifo_available = linear_fifo_read_num_elements_rx_fifo();
Wolfgang Betz 6:f5d01793bf86 610 unsigned int remaining = MAX_PACKET_LEN - _spirit_rx_pos;
Wolfgang Betz 6:f5d01793bf86 611 if(fifo_available > remaining) {
Wolfgang Betz 6:f5d01793bf86 612 receiving_packet = 0;
Wolfgang Betz 6:f5d01793bf86 613 _spirit_rx_err = true;
Wolfgang Betz 6:f5d01793bf86 614 CLEAR_RXBUF();
Wolfgang Betz 6:f5d01793bf86 615 cmd_strobe(SPIRIT1_STROBE_FRX);
Wolfgang Betz 6:f5d01793bf86 616 } else {
Wolfgang Betz 6:f5d01793bf86 617 spi_read_linear_fifo(fifo_available, &spirit_rx_buf[_spirit_rx_pos]);
Wolfgang Betz 6:f5d01793bf86 618 _spirit_rx_pos += fifo_available;
Wolfgang Betz 6:f5d01793bf86 619 }
Wolfgang Betz 6:f5d01793bf86 620 }
Wolfgang Betz 4:07537ca85c66 621 }
Wolfgang Betz 4:07537ca85c66 622
Wolfgang Betz 4:07537ca85c66 623 /* The IRQ_TX_DATA_SENT notifies the packet received. Puts the SPIRIT1 in RX */
Wolfgang Betz 4:07537ca85c66 624 if(x_irq_status.IRQ_TX_DATA_SENT) {
Wolfgang Betz 7:e90fa8f6bc6c 625 MBED_ASSERT(_spirit_tx_started);
Wolfgang Betz 7:e90fa8f6bc6c 626
Wolfgang Betz 6:f5d01793bf86 627 cmd_strobe(SPIRIT1_STROBE_FRX);
Wolfgang Betz 4:07537ca85c66 628 cmd_strobe(SPIRIT1_STROBE_RX);
Wolfgang Betz 4:07537ca85c66 629 /* SpiritCmdStrobeRx();*/
Wolfgang Betz 4:07537ca85c66 630 CLEAR_TXBUF();
Wolfgang Betz 6:f5d01793bf86 631 CLEAR_RXBUF();
Wolfgang Betz 6:f5d01793bf86 632 _spirit_rx_err = false;
Wolfgang Betz 7:e90fa8f6bc6c 633 _spirit_tx_started = false;
Wolfgang Betz 7:e90fa8f6bc6c 634
Wolfgang Betz 7:e90fa8f6bc6c 635 /* call user callback */
Wolfgang Betz 7:e90fa8f6bc6c 636 if(_current_irq_callback) {
Wolfgang Betz 9:3db68ab23070 637 _current_irq_callback(TX_DONE); // betzw - TODO: define enums for callback values
Wolfgang Betz 7:e90fa8f6bc6c 638 }
Wolfgang Betz 4:07537ca85c66 639 }
Wolfgang Betz 4:07537ca85c66 640
Wolfgang Betz 4:07537ca85c66 641 /* The IRQ_RX_DATA_READY notifies a new packet arrived */
Wolfgang Betz 4:07537ca85c66 642 if(x_irq_status.IRQ_RX_DATA_READY) {
Wolfgang Betz 6:f5d01793bf86 643 if(_spirit_rx_err) {
Wolfgang Betz 6:f5d01793bf86 644 receiving_packet = 0;
Wolfgang Betz 6:f5d01793bf86 645 _spirit_rx_err = false;
Wolfgang Betz 6:f5d01793bf86 646 CLEAR_RXBUF();
Wolfgang Betz 6:f5d01793bf86 647 cmd_strobe(SPIRIT1_STROBE_FRX);
Wolfgang Betz 6:f5d01793bf86 648 } else {
Wolfgang Betz 6:f5d01793bf86 649 spirit_rx_len = pkt_basic_get_received_pkt_length();
Wolfgang Betz 6:f5d01793bf86 650 unsigned int remaining = 0;
Wolfgang Betz 6:f5d01793bf86 651 uint8_t fifo_available = 0;
Wolfgang Betz 6:f5d01793bf86 652 uint8_t to_receive = 0;
Wolfgang Betz 6:f5d01793bf86 653
Wolfgang Betz 6:f5d01793bf86 654 MBED_ASSERT(spirit_rx_len <= MAX_PACKET_LEN);
Wolfgang Betz 5:c9c5bc673c64 655
Wolfgang Betz 6:f5d01793bf86 656 for(; _spirit_rx_pos < spirit_rx_len;) {
Wolfgang Betz 6:f5d01793bf86 657 remaining = spirit_rx_len - _spirit_rx_pos;
Wolfgang Betz 6:f5d01793bf86 658 fifo_available = linear_fifo_read_num_elements_rx_fifo();
Wolfgang Betz 6:f5d01793bf86 659 to_receive = (remaining < fifo_available) ? remaining : fifo_available;
Wolfgang Betz 6:f5d01793bf86 660 if(to_receive > 0) {
Wolfgang Betz 6:f5d01793bf86 661 spi_read_linear_fifo(to_receive, &spirit_rx_buf[_spirit_rx_pos]);
Wolfgang Betz 6:f5d01793bf86 662 _spirit_rx_pos += to_receive;
Wolfgang Betz 6:f5d01793bf86 663 }
Wolfgang Betz 6:f5d01793bf86 664 }
Wolfgang Betz 5:c9c5bc673c64 665
Wolfgang Betz 6:f5d01793bf86 666 cmd_strobe(SPIRIT1_STROBE_FRX);
Wolfgang Betz 4:07537ca85c66 667
Wolfgang Betz 6:f5d01793bf86 668 last_rssi = qi_get_rssi(); //MGR
Wolfgang Betz 6:f5d01793bf86 669 last_lqi = qi_get_lqi(); //MGR
Wolfgang Betz 4:07537ca85c66 670
Wolfgang Betz 6:f5d01793bf86 671 receiving_packet = 0;
Wolfgang Betz 4:07537ca85c66 672
Wolfgang Betz 4:07537ca85c66 673 #if NULLRDC_CONF_802154_AUTOACK
Wolfgang Betz 6:f5d01793bf86 674 if (spirit_rxbuf[0] == ACK_LEN) {
Wolfgang Betz 6:f5d01793bf86 675 /* For debugging purposes we assume this is an ack for us */
Wolfgang Betz 6:f5d01793bf86 676 just_got_an_ack = 1;
Wolfgang Betz 6:f5d01793bf86 677 }
Wolfgang Betz 4:07537ca85c66 678 #endif /* NULLRDC_CONF_802154_AUTOACK */
Wolfgang Betz 4:07537ca85c66 679
Wolfgang Betz 6:f5d01793bf86 680 /* call user callback */
Wolfgang Betz 6:f5d01793bf86 681 if(_current_irq_callback) {
Wolfgang Betz 9:3db68ab23070 682 _current_irq_callback(RX_DONE); // betzw - TODO: define enums for callback values
Wolfgang Betz 6:f5d01793bf86 683 }
Wolfgang Betz 6:f5d01793bf86 684 }
Wolfgang Betz 4:07537ca85c66 685 }
Wolfgang Betz 4:07537ca85c66 686 }