JunMo Hong / stm-spirit1-rf-driver_for_cubebite

Fork of EV-COG-AD3029LZ by JunMo Hong

Committer:
Wolfgang Betz
Date:
Mon Nov 07 10:01:36 2016 +0100
Revision:
18:d6f789f6f4c9
Parent:
16:25dc4b811ad3
Child:
19:42df12d5f750
Add 'RX_FIFO_THR_WA' RX FIFO threshold trigger workaround (for K64F boards)

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