JunMo Hong / stm-spirit1-rf-driver_for_cubebite

Fork of EV-COG-AD3029LZ by JunMo Hong

Committer:
Wolfgang Betz
Date:
Fri Nov 04 17:12:06 2016 +0100
Revision:
15:852b92eed64a
Parent:
14:898a9d48dd03
Child:
16:25dc4b811ad3
Backup commit with trials for K64F setting RXAFTHR

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