JunMo Hong / stm-spirit1-rf-driver_for_cubebite

Fork of EV-COG-AD3029LZ by JunMo Hong

Committer:
Wolfgang Betz
Date:
Fri Nov 04 15:29:59 2016 +0100
Revision:
14:898a9d48dd03
Parent:
12:b8056eda4028
Child:
15:852b92eed64a
Backup commit for NUCLEO boards all sizes

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