Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of EV-COG-AD3029LZ by
SimpleSpirit1.cpp@5:c9c5bc673c64, 2016-10-18 (annotated)
- Committer:
- Wolfgang Betz
- Date:
- Tue Oct 18 11:45:43 2016 +0200
- Revision:
- 5:c9c5bc673c64
- Parent:
- 4:07537ca85c66
- Child:
- 6:f5d01793bf86
First version of send()
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| Wolfgang Betz |
0:4fb29d9ee571 | 1 | /*** Mbed Includes ***/ |
| Wolfgang Betz |
0:4fb29d9ee571 | 2 | #include "SimpleSpirit1.h" |
| Wolfgang Betz |
3:0df38cfb1e53 | 3 | #include "radio_spi.h" |
| Wolfgang Betz |
0:4fb29d9ee571 | 4 | |
| Wolfgang Betz |
0:4fb29d9ee571 | 5 | |
| Wolfgang Betz |
0:4fb29d9ee571 | 6 | /*** Macros from Cube Implementation ***/ |
| Wolfgang Betz |
4:07537ca85c66 | 7 | #define CLEAR_TXBUF() (spirit_tx_len = 0) |
| Wolfgang Betz |
4:07537ca85c66 | 8 | #define CLEAR_RXBUF() (spirit_rx_len = 0) |
| Wolfgang Betz |
4:07537ca85c66 | 9 | #define IS_RXBUF_EMPTY() (spirit_rx_len == 0) |
| Wolfgang Betz |
0:4fb29d9ee571 | 10 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 11 | #ifndef NDEBUG |
| Wolfgang Betz |
3:0df38cfb1e53 | 12 | #include <stdio.h> |
| Wolfgang Betz |
3:0df38cfb1e53 | 13 | #define PRINTF(...) printf(__VA_ARGS__) |
| Wolfgang Betz |
3:0df38cfb1e53 | 14 | #else |
| Wolfgang Betz |
3:0df38cfb1e53 | 15 | #define PRINTF(...) |
| Wolfgang Betz |
3:0df38cfb1e53 | 16 | #endif |
| Wolfgang Betz |
0:4fb29d9ee571 | 17 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 18 | #if NULLRDC_CONF_802154_AUTOACK |
| Wolfgang Betz |
3:0df38cfb1e53 | 19 | #define ACK_LEN 3 |
| Wolfgang Betz |
3:0df38cfb1e53 | 20 | static int wants_an_ack = 0; /* The packet sent expects an ack */ |
| Wolfgang Betz |
3:0df38cfb1e53 | 21 | //#define ACKPRINTF printf |
| Wolfgang Betz |
3:0df38cfb1e53 | 22 | #define ACKPRINTF(...) |
| Wolfgang Betz |
3:0df38cfb1e53 | 23 | #endif /* NULLRDC_CONF_802154_AUTOACK */ |
| Wolfgang Betz |
3:0df38cfb1e53 | 24 | |
| Wolfgang Betz |
4:07537ca85c66 | 25 | #define SPIRIT_GPIO_IRQ (SPIRIT_GPIO_3) |
| Wolfgang Betz |
3:0df38cfb1e53 | 26 | |
| Wolfgang Betz |
4:07537ca85c66 | 27 | #define SPIRIT1_STATUS() (arch_refresh_status() & SPIRIT1_STATE_STATEBITS) |
| Wolfgang Betz |
3:0df38cfb1e53 | 28 | |
| Wolfgang Betz |
4:07537ca85c66 | 29 | #define SABORT_WAIT_US (400) |
| Wolfgang Betz |
3:0df38cfb1e53 | 30 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 31 | #define BUSYWAIT_UNTIL(cond, millisecs) \ |
| Wolfgang Betz |
3:0df38cfb1e53 | 32 | do { \ |
| Wolfgang Betz |
4:07537ca85c66 | 33 | uint32_t start = _busywait_timer.read_us(); \ |
| Wolfgang Betz |
4:07537ca85c66 | 34 | while (!(cond) && ((((uint32_t)(_busywait_timer.read_us())) - start) < ((uint32_t)millisecs)*1000U)); \ |
| Wolfgang Betz |
3:0df38cfb1e53 | 35 | } while(0) |
| Wolfgang Betz |
3:0df38cfb1e53 | 36 | |
| Wolfgang Betz |
4:07537ca85c66 | 37 | extern volatile SpiritStatus g_xStatus; |
| Wolfgang Betz |
4:07537ca85c66 | 38 | #define st_lib_g_x_status (g_xStatus) |
| Wolfgang Betz |
4:07537ca85c66 | 39 | |
| Wolfgang Betz |
4:07537ca85c66 | 40 | #define st_lib_spirit_irqs SpiritIrqs |
| Wolfgang Betz |
4:07537ca85c66 | 41 | |
| Wolfgang Betz |
0:4fb29d9ee571 | 42 | |
| Wolfgang Betz |
0:4fb29d9ee571 | 43 | /*** Class Implementation ***/ |
| Wolfgang Betz |
3:0df38cfb1e53 | 44 | /** Static Class Variables **/ |
| Wolfgang Betz |
3:0df38cfb1e53 | 45 | SimpleSpirit1 *SimpleSpirit1::_singleton = NULL; |
| Wolfgang Betz |
3:0df38cfb1e53 | 46 | Timer SimpleSpirit1::_busywait_timer; |
| Wolfgang Betz |
3:0df38cfb1e53 | 47 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 48 | /** Constructor **/ |
| Wolfgang Betz |
0:4fb29d9ee571 | 49 | SimpleSpirit1::SimpleSpirit1(PinName mosi, PinName miso, PinName sclk, |
| Wolfgang Betz |
0:4fb29d9ee571 | 50 | PinName irq, PinName cs, PinName sdn, |
| Wolfgang Betz |
0:4fb29d9ee571 | 51 | PinName led) : |
| Wolfgang Betz |
0:4fb29d9ee571 | 52 | _spi(mosi, miso, sclk), |
| Wolfgang Betz |
0:4fb29d9ee571 | 53 | _irq(irq), |
| Wolfgang Betz |
0:4fb29d9ee571 | 54 | _chip_select(cs), |
| Wolfgang Betz |
0:4fb29d9ee571 | 55 | _shut_down(sdn), |
| Wolfgang Betz |
4:07537ca85c66 | 56 | _led(led), |
| Wolfgang Betz |
4:07537ca85c66 | 57 | _current_irq_callback() |
| Wolfgang Betz |
0:4fb29d9ee571 | 58 | { |
| Wolfgang Betz |
3:0df38cfb1e53 | 59 | /* reset irq disable counter and irq callback & disable irq */ |
| Wolfgang Betz |
3:0df38cfb1e53 | 60 | _nr_of_irq_disables = 0; |
| Wolfgang Betz |
4:07537ca85c66 | 61 | disable_spirit_irq(); |
| Wolfgang Betz |
0:4fb29d9ee571 | 62 | |
| Wolfgang Betz |
0:4fb29d9ee571 | 63 | /* unselect chip */ |
| Wolfgang Betz |
0:4fb29d9ee571 | 64 | chip_unselect(); |
| Wolfgang Betz |
0:4fb29d9ee571 | 65 | |
| Wolfgang Betz |
0:4fb29d9ee571 | 66 | /* configure spi */ |
| Wolfgang Betz |
0:4fb29d9ee571 | 67 | _spi.format(8, 0); /* 8-bit, mode = 0, [order = SPI_MSB] only available in mbed3 */ |
| Wolfgang Betz |
0:4fb29d9ee571 | 68 | _spi.frequency(5000000); // 5MHz |
| Wolfgang Betz |
3:0df38cfb1e53 | 69 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 70 | /* start timer */ |
| Wolfgang Betz |
3:0df38cfb1e53 | 71 | _busywait_timer.start(); |
| Wolfgang Betz |
3:0df38cfb1e53 | 72 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 73 | /* install irq handler */ |
| Wolfgang Betz |
5:c9c5bc673c64 | 74 | _irq.fall(Callback<void()>(this, &SimpleSpirit1::IrqHandler)); |
| Wolfgang Betz |
5:c9c5bc673c64 | 75 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 76 | /* init cube vars */ |
| Wolfgang Betz |
3:0df38cfb1e53 | 77 | spirit_on = OFF; |
| Wolfgang Betz |
3:0df38cfb1e53 | 78 | packet_is_prepared = 0; |
| Wolfgang Betz |
3:0df38cfb1e53 | 79 | receiving_packet = 0; |
| Wolfgang Betz |
3:0df38cfb1e53 | 80 | just_got_an_ack = 0; |
| Wolfgang Betz |
4:07537ca85c66 | 81 | last_rssi = 0 ; //MGR |
| Wolfgang Betz |
4:07537ca85c66 | 82 | last_lqi = 0 ; //MGR |
| Wolfgang Betz |
2:45642c5198a2 | 83 | } |
| Wolfgang Betz |
0:4fb29d9ee571 | 84 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 85 | /** Init Function **/ |
| Wolfgang Betz |
2:45642c5198a2 | 86 | void SimpleSpirit1::init() { |
| Wolfgang Betz |
0:4fb29d9ee571 | 87 | /* set frequencies */ |
| Wolfgang Betz |
0:4fb29d9ee571 | 88 | radio_set_xtal_freq(XTAL_FREQUENCY); |
| Wolfgang Betz |
2:45642c5198a2 | 89 | mgmt_set_freq_base((uint32_t)BASE_FREQUENCY); |
| Wolfgang Betz |
0:4fb29d9ee571 | 90 | |
| Wolfgang Betz |
0:4fb29d9ee571 | 91 | /* restart board */ |
| Wolfgang Betz |
0:4fb29d9ee571 | 92 | enter_shutdown(); |
| Wolfgang Betz |
0:4fb29d9ee571 | 93 | exit_shutdown(); |
| Wolfgang Betz |
0:4fb29d9ee571 | 94 | |
| Wolfgang Betz |
0:4fb29d9ee571 | 95 | /* soft core reset */ |
| Wolfgang Betz |
4:07537ca85c66 | 96 | cmd_strobe(SPIRIT1_STROBE_SRES); |
| Wolfgang Betz |
0:4fb29d9ee571 | 97 | |
| Wolfgang Betz |
0:4fb29d9ee571 | 98 | /* Configures the SPIRIT1 radio part */ |
| Wolfgang Betz |
0:4fb29d9ee571 | 99 | SRadioInit x_radio_init = { |
| Wolfgang Betz |
0:4fb29d9ee571 | 100 | XTAL_OFFSET_PPM, |
| Wolfgang Betz |
0:4fb29d9ee571 | 101 | (uint32_t)BASE_FREQUENCY, |
| Wolfgang Betz |
0:4fb29d9ee571 | 102 | (uint32_t)CHANNEL_SPACE, |
| Wolfgang Betz |
0:4fb29d9ee571 | 103 | CHANNEL_NUMBER, |
| Wolfgang Betz |
0:4fb29d9ee571 | 104 | MODULATION_SELECT, |
| Wolfgang Betz |
0:4fb29d9ee571 | 105 | DATARATE, |
| Wolfgang Betz |
0:4fb29d9ee571 | 106 | (uint32_t)FREQ_DEVIATION, |
| Wolfgang Betz |
0:4fb29d9ee571 | 107 | (uint32_t)BANDWIDTH |
| Wolfgang Betz |
0:4fb29d9ee571 | 108 | }; |
| Wolfgang Betz |
0:4fb29d9ee571 | 109 | radio_init(&x_radio_init); |
| Wolfgang Betz |
0:4fb29d9ee571 | 110 | radio_set_pa_level_dbm(0,POWER_DBM); |
| Wolfgang Betz |
0:4fb29d9ee571 | 111 | radio_set_pa_level_max_index(0); |
| Wolfgang Betz |
0:4fb29d9ee571 | 112 | |
| Wolfgang Betz |
0:4fb29d9ee571 | 113 | /* Configures the SPIRIT1 packet handler part*/ |
| Wolfgang Betz |
0:4fb29d9ee571 | 114 | PktBasicInit x_basic_init = { |
| Wolfgang Betz |
0:4fb29d9ee571 | 115 | PREAMBLE_LENGTH, |
| Wolfgang Betz |
0:4fb29d9ee571 | 116 | SYNC_LENGTH, |
| Wolfgang Betz |
0:4fb29d9ee571 | 117 | SYNC_WORD, |
| Wolfgang Betz |
0:4fb29d9ee571 | 118 | LENGTH_TYPE, |
| Wolfgang Betz |
0:4fb29d9ee571 | 119 | LENGTH_WIDTH, |
| Wolfgang Betz |
0:4fb29d9ee571 | 120 | CRC_MODE, |
| Wolfgang Betz |
0:4fb29d9ee571 | 121 | CONTROL_LENGTH, |
| Wolfgang Betz |
0:4fb29d9ee571 | 122 | EN_ADDRESS, |
| Wolfgang Betz |
0:4fb29d9ee571 | 123 | EN_FEC, |
| Wolfgang Betz |
0:4fb29d9ee571 | 124 | EN_WHITENING |
| Wolfgang Betz |
0:4fb29d9ee571 | 125 | }; |
| Wolfgang Betz |
0:4fb29d9ee571 | 126 | pkt_basic_init(&x_basic_init); |
| Wolfgang Betz |
0:4fb29d9ee571 | 127 | |
| Wolfgang Betz |
0:4fb29d9ee571 | 128 | /* Enable the following interrupt sources, routed to GPIO */ |
| Wolfgang Betz |
0:4fb29d9ee571 | 129 | irq_de_init(NULL); |
| Wolfgang Betz |
0:4fb29d9ee571 | 130 | irq_clear_status(); |
| Wolfgang Betz |
0:4fb29d9ee571 | 131 | irq_set_status(TX_DATA_SENT, S_ENABLE); |
| Wolfgang Betz |
0:4fb29d9ee571 | 132 | irq_set_status(RX_DATA_READY,S_ENABLE); |
| Wolfgang Betz |
0:4fb29d9ee571 | 133 | irq_set_status(VALID_SYNC,S_ENABLE); |
| Wolfgang Betz |
0:4fb29d9ee571 | 134 | irq_set_status(RX_DATA_DISC, S_ENABLE); |
| Wolfgang Betz |
0:4fb29d9ee571 | 135 | irq_set_status(TX_FIFO_ERROR, S_ENABLE); |
| Wolfgang Betz |
0:4fb29d9ee571 | 136 | irq_set_status(RX_FIFO_ERROR, S_ENABLE); |
| Wolfgang Betz |
0:4fb29d9ee571 | 137 | |
| Wolfgang Betz |
0:4fb29d9ee571 | 138 | /* Configure Spirit1 */ |
| Wolfgang Betz |
0:4fb29d9ee571 | 139 | radio_persisten_rx(S_ENABLE); |
| Wolfgang Betz |
0:4fb29d9ee571 | 140 | qi_set_sqi_threshold(SQI_TH_0); |
| Wolfgang Betz |
0:4fb29d9ee571 | 141 | qi_sqi_check(S_ENABLE); |
| Wolfgang Betz |
0:4fb29d9ee571 | 142 | qi_set_rssi_threshold_dbm(CCA_THRESHOLD); |
| Wolfgang Betz |
0:4fb29d9ee571 | 143 | timer_set_rx_timeout_stop_condition(SQI_ABOVE_THRESHOLD); |
| Wolfgang Betz |
0:4fb29d9ee571 | 144 | timer_set_infinite_rx_timeout(); |
| Wolfgang Betz |
0:4fb29d9ee571 | 145 | radio_afc_freeze_on_sync(S_ENABLE); |
| Wolfgang Betz |
0:4fb29d9ee571 | 146 | |
| Wolfgang Betz |
0:4fb29d9ee571 | 147 | /* Puts the SPIRIT1 in STANDBY mode (125us -> rx/tx) */ |
| Wolfgang Betz |
4:07537ca85c66 | 148 | cmd_strobe(SPIRIT1_STROBE_STANDBY); |
| Wolfgang Betz |
0:4fb29d9ee571 | 149 | spirit_on = OFF; |
| Wolfgang Betz |
0:4fb29d9ee571 | 150 | CLEAR_RXBUF(); |
| Wolfgang Betz |
0:4fb29d9ee571 | 151 | CLEAR_TXBUF(); |
| Wolfgang Betz |
0:4fb29d9ee571 | 152 | |
| Wolfgang Betz |
0:4fb29d9ee571 | 153 | /* Configure the radio to route the IRQ signal to its GPIO 3 */ |
| Wolfgang Betz |
0:4fb29d9ee571 | 154 | SGpioInit x_gpio_init = { |
| Wolfgang Betz |
0:4fb29d9ee571 | 155 | SPIRIT_GPIO_IRQ, |
| Wolfgang Betz |
0:4fb29d9ee571 | 156 | SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP, |
| Wolfgang Betz |
0:4fb29d9ee571 | 157 | SPIRIT_GPIO_DIG_OUT_IRQ |
| Wolfgang Betz |
0:4fb29d9ee571 | 158 | }; |
| Wolfgang Betz |
0:4fb29d9ee571 | 159 | spirit_gpio_init(&x_gpio_init); |
| Wolfgang Betz |
0:4fb29d9ee571 | 160 | } |
| Wolfgang Betz |
3:0df38cfb1e53 | 161 | |
| 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 |
4:07537ca85c66 | 226 | cmd_strobe(SPIRIT1_STROBE_SABORT); |
| Wolfgang Betz |
3:0df38cfb1e53 | 227 | wait_us(SABORT_WAIT_US); |
| Wolfgang Betz |
4:07537ca85c66 | 228 | cmd_strobe(SPIRIT1_STROBE_READY); |
| Wolfgang Betz |
3:0df38cfb1e53 | 229 | BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 1); |
| Wolfgang Betz |
4:07537ca85c66 | 230 | cmd_strobe(SPIRIT1_STROBE_RX); |
| Wolfgang Betz |
3:0df38cfb1e53 | 231 | BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1); |
| Wolfgang Betz |
4:07537ca85c66 | 232 | enable_spirit_irq(); |
| Wolfgang Betz |
3:0df38cfb1e53 | 233 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 234 | #if XXX_ACK_WORKAROUND |
| Wolfgang Betz |
3:0df38cfb1e53 | 235 | just_got_an_ack = 1; |
| Wolfgang Betz |
3:0df38cfb1e53 | 236 | #endif /* XXX_ACK_WORKAROUND */ |
| Wolfgang Betz |
3:0df38cfb1e53 | 237 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 238 | #if NULLRDC_CONF_802154_AUTOACK |
| Wolfgang Betz |
3:0df38cfb1e53 | 239 | if (wants_an_ack) { |
| Wolfgang Betz |
4:07537ca85c66 | 240 | rtimer_txdone = _busywait_timer.read_us(); |
| Wolfgang Betz |
3:0df38cfb1e53 | 241 | BUSYWAIT_UNTIL(just_got_an_ack, 2); |
| Wolfgang Betz |
4:07537ca85c66 | 242 | rtimer_rxack = _busywait_timer.read_us(); |
| Wolfgang Betz |
3:0df38cfb1e53 | 243 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 244 | if(just_got_an_ack) { |
| Wolfgang Betz |
4:07537ca85c66 | 245 | ACKPRINTF("debug_ack: ack received after %u us\n", |
| Wolfgang Betz |
3:0df38cfb1e53 | 246 | (uint32_t)(rtimer_rxack - rtimer_txdone)); |
| Wolfgang Betz |
3:0df38cfb1e53 | 247 | } else { |
| Wolfgang Betz |
3:0df38cfb1e53 | 248 | ACKPRINTF("debug_ack: no ack received\n"); |
| Wolfgang Betz |
3:0df38cfb1e53 | 249 | } |
| Wolfgang Betz |
3:0df38cfb1e53 | 250 | } |
| Wolfgang Betz |
3:0df38cfb1e53 | 251 | #endif /* NULLRDC_CONF_802154_AUTOACK */ |
| Wolfgang Betz |
3:0df38cfb1e53 | 252 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 253 | PRINTF("TRANSMIT OUT\n"); |
| Wolfgang Betz |
3:0df38cfb1e53 | 254 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 255 | CLEAR_TXBUF(); |
| Wolfgang Betz |
3:0df38cfb1e53 | 256 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 257 | packet_is_prepared = 0; |
| Wolfgang Betz |
3:0df38cfb1e53 | 258 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 259 | wait_us(1); |
| Wolfgang Betz |
3:0df38cfb1e53 | 260 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 261 | return RADIO_TX_OK; |
| Wolfgang Betz |
3:0df38cfb1e53 | 262 | } |
| Wolfgang Betz |
3:0df38cfb1e53 | 263 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 264 | int SimpleSpirit1::send(const void *payload, unsigned short payload_len) { |
| Wolfgang Betz |
5:c9c5bc673c64 | 265 | /* Checks if the payload length is supported */ |
| Wolfgang Betz |
5:c9c5bc673c64 | 266 | if(payload_len > MAX_PACKET_LEN) { |
| Wolfgang Betz |
5:c9c5bc673c64 | 267 | return RADIO_TX_ERR; |
| Wolfgang Betz |
5:c9c5bc673c64 | 268 | } |
| Wolfgang Betz |
5:c9c5bc673c64 | 269 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 270 | disable_spirit_irq(); |
| Wolfgang Betz |
5:c9c5bc673c64 | 271 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 272 | /* Reset State to Ready */ |
| Wolfgang Betz |
5:c9c5bc673c64 | 273 | set_ready_state(); |
| Wolfgang Betz |
5:c9c5bc673c64 | 274 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 275 | cmd_strobe(SPIRIT1_STROBE_FTX); // flush TX FIFO buffer |
| Wolfgang Betz |
5:c9c5bc673c64 | 276 | MBED_ASSERT(linear_fifo_read_num_elements_tx_fifo() == 0); |
| Wolfgang Betz |
5:c9c5bc673c64 | 277 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 278 | pkt_basic_set_payload_length(payload_len); // set desired payload len |
| Wolfgang Betz |
5:c9c5bc673c64 | 279 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 280 | int i = 0; |
| Wolfgang Betz |
5:c9c5bc673c64 | 281 | int remaining = payload_len; |
| Wolfgang Betz |
5:c9c5bc673c64 | 282 | bool trigger_tx = true; |
| Wolfgang Betz |
5:c9c5bc673c64 | 283 | do { |
| Wolfgang Betz |
5:c9c5bc673c64 | 284 | uint8_t fifo_available = SPIRIT_MAX_FIFO_LEN - linear_fifo_read_num_elements_tx_fifo(); |
| Wolfgang Betz |
5:c9c5bc673c64 | 285 | uint8_t to_send = (remaining > fifo_available) ? fifo_available : remaining; |
| Wolfgang Betz |
5:c9c5bc673c64 | 286 | const uint8_t *buffer = (const uint8_t*)payload; |
| Wolfgang Betz |
5:c9c5bc673c64 | 287 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 288 | /* Fill FIFO Buffer */ |
| Wolfgang Betz |
5:c9c5bc673c64 | 289 | spi_write_linear_fifo(to_send, (uint8_t*)&buffer[i]); |
| Wolfgang Betz |
5:c9c5bc673c64 | 290 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 291 | /* Start Transmit FIFO Buffer */ |
| Wolfgang Betz |
5:c9c5bc673c64 | 292 | if(trigger_tx) { |
| Wolfgang Betz |
5:c9c5bc673c64 | 293 | MBED_ASSERT(linear_fifo_read_num_elements_tx_fifo() == to_send); |
| Wolfgang Betz |
5:c9c5bc673c64 | 294 | cmd_strobe(SPIRIT1_STROBE_TX); |
| Wolfgang Betz |
5:c9c5bc673c64 | 295 | trigger_tx = false; |
| Wolfgang Betz |
5:c9c5bc673c64 | 296 | } |
| Wolfgang Betz |
5:c9c5bc673c64 | 297 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 298 | i += to_send; |
| Wolfgang Betz |
5:c9c5bc673c64 | 299 | remaining -= to_send; |
| Wolfgang Betz |
5:c9c5bc673c64 | 300 | } while(remaining != 0); |
| Wolfgang Betz |
5:c9c5bc673c64 | 301 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 302 | PRINTF("betzw(%s, %d): #fifo=%d\n", __FILE__, __LINE__, linear_fifo_read_num_elements_tx_fifo()); |
| Wolfgang Betz |
5:c9c5bc673c64 | 303 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 304 | BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 50); |
| Wolfgang Betz |
5:c9c5bc673c64 | 305 | MBED_ASSERT(linear_fifo_read_num_elements_tx_fifo() == 0); |
| Wolfgang Betz |
5:c9c5bc673c64 | 306 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 307 | enable_spirit_irq(); |
| Wolfgang Betz |
5:c9c5bc673c64 | 308 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 309 | return RADIO_TX_OK; |
| Wolfgang Betz |
5:c9c5bc673c64 | 310 | } |
| Wolfgang Betz |
5:c9c5bc673c64 | 311 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 312 | /** Set Ready State **/ |
| Wolfgang Betz |
3:0df38cfb1e53 | 313 | void SimpleSpirit1::set_ready_state(void) { |
| Wolfgang Betz |
3:0df38cfb1e53 | 314 | PRINTF("READY IN\n"); |
| Wolfgang Betz |
3:0df38cfb1e53 | 315 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 316 | irq_clear_status(); |
| Wolfgang Betz |
4:07537ca85c66 | 317 | disable_spirit_irq(); |
| Wolfgang Betz |
3:0df38cfb1e53 | 318 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 319 | if(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY) { |
| Wolfgang Betz |
4:07537ca85c66 | 320 | cmd_strobe(SPIRIT1_STROBE_READY); |
| Wolfgang Betz |
3:0df38cfb1e53 | 321 | } else if(SPIRIT1_STATUS() == SPIRIT1_STATE_RX) { |
| Wolfgang Betz |
4:07537ca85c66 | 322 | cmd_strobe(SPIRIT1_STROBE_SABORT); |
| Wolfgang Betz |
3:0df38cfb1e53 | 323 | irq_clear_status(); |
| Wolfgang Betz |
3:0df38cfb1e53 | 324 | } |
| Wolfgang Betz |
3:0df38cfb1e53 | 325 | |
| Wolfgang Betz |
4:07537ca85c66 | 326 | enable_spirit_irq(); |
| Wolfgang Betz |
3:0df38cfb1e53 | 327 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 328 | PRINTF("READY OUT\n"); |
| Wolfgang Betz |
3:0df38cfb1e53 | 329 | } |
| Wolfgang Betz |
3:0df38cfb1e53 | 330 | |
| Wolfgang Betz |
4:07537ca85c66 | 331 | int SimpleSpirit1::off(void) { |
| Wolfgang Betz |
3:0df38cfb1e53 | 332 | PRINTF("Spirit1: ->off\n"); |
| Wolfgang Betz |
3:0df38cfb1e53 | 333 | if(spirit_on == ON) { |
| Wolfgang Betz |
3:0df38cfb1e53 | 334 | /* Disables the mcu to get IRQ from the SPIRIT1 */ |
| Wolfgang Betz |
4:07537ca85c66 | 335 | disable_spirit_irq(); |
| Wolfgang Betz |
3:0df38cfb1e53 | 336 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 337 | /* first stop rx/tx */ |
| Wolfgang Betz |
4:07537ca85c66 | 338 | cmd_strobe(SPIRIT1_STROBE_SABORT); |
| Wolfgang Betz |
3:0df38cfb1e53 | 339 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 340 | /* Clear any pending irqs */ |
| Wolfgang Betz |
3:0df38cfb1e53 | 341 | irq_clear_status(); |
| Wolfgang Betz |
3:0df38cfb1e53 | 342 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 343 | BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 5); |
| Wolfgang Betz |
3:0df38cfb1e53 | 344 | if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) { |
| Wolfgang Betz |
3:0df38cfb1e53 | 345 | PRINTF("Spirit1: failed off->ready\n"); |
| Wolfgang Betz |
3:0df38cfb1e53 | 346 | return 1; |
| Wolfgang Betz |
3:0df38cfb1e53 | 347 | } |
| Wolfgang Betz |
3:0df38cfb1e53 | 348 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 349 | /* Puts the SPIRIT1 in STANDBY */ |
| Wolfgang Betz |
4:07537ca85c66 | 350 | cmd_strobe(SPIRIT1_STROBE_STANDBY); |
| Wolfgang Betz |
3:0df38cfb1e53 | 351 | BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, 5); |
| Wolfgang Betz |
3:0df38cfb1e53 | 352 | if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) { |
| Wolfgang Betz |
3:0df38cfb1e53 | 353 | PRINTF("Spirit1: failed off->standby\n"); |
| Wolfgang Betz |
3:0df38cfb1e53 | 354 | return 1; |
| Wolfgang Betz |
3:0df38cfb1e53 | 355 | } |
| Wolfgang Betz |
3:0df38cfb1e53 | 356 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 357 | spirit_on = OFF; |
| Wolfgang Betz |
4:07537ca85c66 | 358 | _nr_of_irq_disables = 1; |
| Wolfgang Betz |
3:0df38cfb1e53 | 359 | CLEAR_TXBUF(); |
| Wolfgang Betz |
3:0df38cfb1e53 | 360 | CLEAR_RXBUF(); |
| Wolfgang Betz |
3:0df38cfb1e53 | 361 | } |
| Wolfgang Betz |
3:0df38cfb1e53 | 362 | PRINTF("Spirit1: off.\n"); |
| Wolfgang Betz |
3:0df38cfb1e53 | 363 | return 0; |
| Wolfgang Betz |
3:0df38cfb1e53 | 364 | } |
| Wolfgang Betz |
3:0df38cfb1e53 | 365 | |
| Wolfgang Betz |
4:07537ca85c66 | 366 | int SimpleSpirit1::on(void) { |
| Wolfgang Betz |
3:0df38cfb1e53 | 367 | PRINTF("Spirit1: on\n"); |
| Wolfgang Betz |
4:07537ca85c66 | 368 | cmd_strobe(SPIRIT1_STROBE_SABORT); |
| Wolfgang Betz |
3:0df38cfb1e53 | 369 | wait_us(SABORT_WAIT_US); |
| Wolfgang Betz |
3:0df38cfb1e53 | 370 | if(spirit_on == OFF) { |
| Wolfgang Betz |
3:0df38cfb1e53 | 371 | /* ensure we are in READY state as we go from there to Rx */ |
| Wolfgang Betz |
4:07537ca85c66 | 372 | cmd_strobe(SPIRIT1_STROBE_READY); |
| Wolfgang Betz |
3:0df38cfb1e53 | 373 | BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 5); |
| Wolfgang Betz |
3:0df38cfb1e53 | 374 | if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) { |
| Wolfgang Betz |
3:0df38cfb1e53 | 375 | PRINTF("Spirit1: failed to turn on\n"); |
| Wolfgang Betz |
3:0df38cfb1e53 | 376 | while(1); |
| Wolfgang Betz |
3:0df38cfb1e53 | 377 | //return 1; |
| Wolfgang Betz |
3:0df38cfb1e53 | 378 | } |
| Wolfgang Betz |
3:0df38cfb1e53 | 379 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 380 | /* now we go to Rx */ |
| Wolfgang Betz |
4:07537ca85c66 | 381 | cmd_strobe(SPIRIT1_STROBE_RX); |
| Wolfgang Betz |
3:0df38cfb1e53 | 382 | BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5); |
| Wolfgang Betz |
3:0df38cfb1e53 | 383 | if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) { |
| Wolfgang Betz |
3:0df38cfb1e53 | 384 | PRINTF("Spirit1: failed to enter rx\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 | /* Enables the mcu to get IRQ from the SPIRIT1 */ |
| Wolfgang Betz |
3:0df38cfb1e53 | 390 | spirit_on = ON; |
| Wolfgang Betz |
5:c9c5bc673c64 | 391 | MBED_ASSERT(_nr_of_irq_disables == 1); |
| Wolfgang Betz |
5:c9c5bc673c64 | 392 | enable_spirit_irq(); |
| Wolfgang Betz |
3:0df38cfb1e53 | 393 | } |
| Wolfgang Betz |
3:0df38cfb1e53 | 394 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 395 | return 0; |
| Wolfgang Betz |
3:0df38cfb1e53 | 396 | } |
| Wolfgang Betz |
3:0df38cfb1e53 | 397 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 398 | uint16_t SimpleSpirit1::arch_refresh_status(void) { |
| Wolfgang Betz |
3:0df38cfb1e53 | 399 | uint16_t mcstate; |
| Wolfgang Betz |
3:0df38cfb1e53 | 400 | uint8_t header[2]; |
| Wolfgang Betz |
3:0df38cfb1e53 | 401 | header[0]=READ_HEADER; |
| Wolfgang Betz |
3:0df38cfb1e53 | 402 | header[1]=MC_STATE1_BASE; |
| Wolfgang Betz |
3:0df38cfb1e53 | 403 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 404 | /* Puts the SPI chip select low to start the transaction */ |
| Wolfgang Betz |
3:0df38cfb1e53 | 405 | chip_sync_select(); |
| Wolfgang Betz |
3:0df38cfb1e53 | 406 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 407 | /* Write the aHeader bytes and read the SPIRIT1 status bytes */ |
| Wolfgang Betz |
3:0df38cfb1e53 | 408 | mcstate = _spi.write(header[0]); |
| Wolfgang Betz |
3:0df38cfb1e53 | 409 | mcstate = mcstate<<8; |
| Wolfgang Betz |
3:0df38cfb1e53 | 410 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 411 | /* Write the aHeader bytes and read the SPIRIT1 status bytes */ |
| Wolfgang Betz |
3:0df38cfb1e53 | 412 | mcstate |= _spi.write(header[1]); |
| Wolfgang Betz |
3:0df38cfb1e53 | 413 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 414 | /* Puts the SPI chip select high to end the transaction */ |
| Wolfgang Betz |
3:0df38cfb1e53 | 415 | chip_sync_unselect(); |
| Wolfgang Betz |
3:0df38cfb1e53 | 416 | |
| Wolfgang Betz |
3:0df38cfb1e53 | 417 | return mcstate; |
| Wolfgang Betz |
3:0df38cfb1e53 | 418 | } |
| Wolfgang Betz |
3:0df38cfb1e53 | 419 | |
| Wolfgang Betz |
4:07537ca85c66 | 420 | int SimpleSpirit1::read(void *buf, unsigned short bufsize) |
| Wolfgang Betz |
4:07537ca85c66 | 421 | { |
| Wolfgang Betz |
4:07537ca85c66 | 422 | PRINTF("READ IN\n"); |
| Wolfgang Betz |
4:07537ca85c66 | 423 | |
| Wolfgang Betz |
4:07537ca85c66 | 424 | /* Checks if the RX buffer is empty */ |
| Wolfgang Betz |
4:07537ca85c66 | 425 | if(IS_RXBUF_EMPTY()) { |
| Wolfgang Betz |
4:07537ca85c66 | 426 | disable_spirit_irq(); |
| Wolfgang Betz |
4:07537ca85c66 | 427 | CLEAR_RXBUF(); |
| Wolfgang Betz |
4:07537ca85c66 | 428 | cmd_strobe(SPIRIT1_STROBE_SABORT); |
| Wolfgang Betz |
4:07537ca85c66 | 429 | wait_us(SABORT_WAIT_US); |
| Wolfgang Betz |
4:07537ca85c66 | 430 | cmd_strobe(SPIRIT1_STROBE_READY); |
| Wolfgang Betz |
4:07537ca85c66 | 431 | BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 1); |
| Wolfgang Betz |
4:07537ca85c66 | 432 | cmd_strobe(SPIRIT1_STROBE_RX); |
| Wolfgang Betz |
4:07537ca85c66 | 433 | BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1); |
| Wolfgang Betz |
4:07537ca85c66 | 434 | PRINTF("READ OUT RX BUF EMPTY\n"); |
| Wolfgang Betz |
4:07537ca85c66 | 435 | enable_spirit_irq(); |
| Wolfgang Betz |
4:07537ca85c66 | 436 | return 0; |
| Wolfgang Betz |
4:07537ca85c66 | 437 | } |
| Wolfgang Betz |
4:07537ca85c66 | 438 | |
| Wolfgang Betz |
4:07537ca85c66 | 439 | if(bufsize < spirit_rx_len) { |
| Wolfgang Betz |
4:07537ca85c66 | 440 | /* If buf has the correct size */ |
| Wolfgang Betz |
4:07537ca85c66 | 441 | PRINTF("TOO SMALL BUF\n"); |
| Wolfgang Betz |
4:07537ca85c66 | 442 | return 0; |
| Wolfgang Betz |
4:07537ca85c66 | 443 | } else { |
| Wolfgang Betz |
4:07537ca85c66 | 444 | /* Copies the packet received */ |
| Wolfgang Betz |
4:07537ca85c66 | 445 | memcpy(buf, spirit_rx_buf, spirit_rx_len); |
| Wolfgang Betz |
4:07537ca85c66 | 446 | |
| Wolfgang Betz |
4:07537ca85c66 | 447 | #ifdef CONTIKI // betzw - TODO |
| Wolfgang Betz |
4:07537ca85c66 | 448 | packetbuf_set_attr(PACKETBUF_ATTR_RSSI, last_rssi); //MGR |
| Wolfgang Betz |
4:07537ca85c66 | 449 | packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, last_lqi); //MGR |
| Wolfgang Betz |
4:07537ca85c66 | 450 | #endif |
| Wolfgang Betz |
4:07537ca85c66 | 451 | |
| Wolfgang Betz |
4:07537ca85c66 | 452 | bufsize = spirit_rx_len; |
| Wolfgang Betz |
4:07537ca85c66 | 453 | CLEAR_RXBUF(); |
| Wolfgang Betz |
4:07537ca85c66 | 454 | |
| Wolfgang Betz |
4:07537ca85c66 | 455 | PRINTF("READ OUT\n"); |
| Wolfgang Betz |
4:07537ca85c66 | 456 | |
| Wolfgang Betz |
4:07537ca85c66 | 457 | return bufsize; |
| Wolfgang Betz |
4:07537ca85c66 | 458 | } |
| Wolfgang Betz |
4:07537ca85c66 | 459 | |
| Wolfgang Betz |
4:07537ca85c66 | 460 | } |
| Wolfgang Betz |
4:07537ca85c66 | 461 | |
| Wolfgang Betz |
4:07537ca85c66 | 462 | /*---------------------------------------------------------------------------*/ |
| Wolfgang Betz |
4:07537ca85c66 | 463 | int SimpleSpirit1::channel_clear(void) |
| Wolfgang Betz |
4:07537ca85c66 | 464 | { |
| Wolfgang Betz |
4:07537ca85c66 | 465 | float rssi_value; |
| Wolfgang Betz |
4:07537ca85c66 | 466 | /* Local variable used to memorize the SPIRIT1 state */ |
| Wolfgang Betz |
4:07537ca85c66 | 467 | uint8_t spirit_state = ON; |
| Wolfgang Betz |
4:07537ca85c66 | 468 | |
| Wolfgang Betz |
4:07537ca85c66 | 469 | PRINTF("CHANNEL CLEAR IN\n"); |
| Wolfgang Betz |
4:07537ca85c66 | 470 | |
| Wolfgang Betz |
4:07537ca85c66 | 471 | if(spirit_on == OFF) { |
| Wolfgang Betz |
4:07537ca85c66 | 472 | /* Wakes up the SPIRIT1 */ |
| Wolfgang Betz |
4:07537ca85c66 | 473 | on(); |
| Wolfgang Betz |
4:07537ca85c66 | 474 | spirit_state = OFF; |
| Wolfgang Betz |
4:07537ca85c66 | 475 | } |
| Wolfgang Betz |
4:07537ca85c66 | 476 | |
| Wolfgang Betz |
4:07537ca85c66 | 477 | /* */ |
| Wolfgang Betz |
4:07537ca85c66 | 478 | disable_spirit_irq(); |
| Wolfgang Betz |
4:07537ca85c66 | 479 | cmd_strobe(SPIRIT1_STROBE_SABORT); |
| Wolfgang Betz |
4:07537ca85c66 | 480 | /* SpiritCmdStrobeSabort();*/ |
| Wolfgang Betz |
4:07537ca85c66 | 481 | irq_clear_status(); |
| Wolfgang Betz |
4:07537ca85c66 | 482 | enable_spirit_irq(); |
| Wolfgang Betz |
4:07537ca85c66 | 483 | { |
| Wolfgang Betz |
4:07537ca85c66 | 484 | uint32_t timeout = _busywait_timer.read_us() + 5000; |
| Wolfgang Betz |
4:07537ca85c66 | 485 | do { |
| Wolfgang Betz |
4:07537ca85c66 | 486 | mgmt_refresh_status(); |
| Wolfgang Betz |
4:07537ca85c66 | 487 | } while((st_lib_g_x_status.MC_STATE != MC_STATE_READY) && (((uint32_t)_busywait_timer.read_us()) < timeout)); |
| Wolfgang Betz |
4:07537ca85c66 | 488 | if(st_lib_g_x_status.MC_STATE != MC_STATE_READY) { |
| Wolfgang Betz |
4:07537ca85c66 | 489 | return 1; |
| Wolfgang Betz |
4:07537ca85c66 | 490 | } |
| Wolfgang Betz |
4:07537ca85c66 | 491 | } |
| Wolfgang Betz |
4:07537ca85c66 | 492 | |
| Wolfgang Betz |
4:07537ca85c66 | 493 | /* Stores the RSSI value */ |
| Wolfgang Betz |
4:07537ca85c66 | 494 | rssi_value = qi_get_rssi_dbm(); |
| Wolfgang Betz |
4:07537ca85c66 | 495 | |
| Wolfgang Betz |
4:07537ca85c66 | 496 | /* Puts the SPIRIT1 in its previous state */ |
| Wolfgang Betz |
4:07537ca85c66 | 497 | if(spirit_state==OFF) { |
| Wolfgang Betz |
4:07537ca85c66 | 498 | off(); |
| Wolfgang Betz |
4:07537ca85c66 | 499 | } else { |
| Wolfgang Betz |
4:07537ca85c66 | 500 | cmd_strobe(SPIRIT1_STROBE_RX); |
| Wolfgang Betz |
4:07537ca85c66 | 501 | /* SpiritCmdStrobeRx();*/ |
| Wolfgang Betz |
4:07537ca85c66 | 502 | BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5); |
| Wolfgang Betz |
4:07537ca85c66 | 503 | } |
| Wolfgang Betz |
4:07537ca85c66 | 504 | |
| Wolfgang Betz |
4:07537ca85c66 | 505 | PRINTF("CHANNEL CLEAR OUT\n"); |
| Wolfgang Betz |
4:07537ca85c66 | 506 | |
| Wolfgang Betz |
4:07537ca85c66 | 507 | /* Checks the RSSI value with the threshold */ |
| Wolfgang Betz |
4:07537ca85c66 | 508 | if(rssi_value<CCA_THRESHOLD) { |
| Wolfgang Betz |
4:07537ca85c66 | 509 | return 0; |
| Wolfgang Betz |
4:07537ca85c66 | 510 | } else { |
| Wolfgang Betz |
4:07537ca85c66 | 511 | return 1; |
| Wolfgang Betz |
4:07537ca85c66 | 512 | } |
| Wolfgang Betz |
4:07537ca85c66 | 513 | } |
| Wolfgang Betz |
4:07537ca85c66 | 514 | |
| Wolfgang Betz |
4:07537ca85c66 | 515 | int SimpleSpirit1::incoming_packet(void) |
| Wolfgang Betz |
4:07537ca85c66 | 516 | { |
| Wolfgang Betz |
4:07537ca85c66 | 517 | return receiving_packet; |
| Wolfgang Betz |
4:07537ca85c66 | 518 | } |
| Wolfgang Betz |
4:07537ca85c66 | 519 | |
| Wolfgang Betz |
4:07537ca85c66 | 520 | int SimpleSpirit1::pending_packet(void) |
| Wolfgang Betz |
4:07537ca85c66 | 521 | { |
| Wolfgang Betz |
4:07537ca85c66 | 522 | PRINTF("PENDING PACKET\n"); |
| Wolfgang Betz |
4:07537ca85c66 | 523 | return !IS_RXBUF_EMPTY(); |
| Wolfgang Betz |
4:07537ca85c66 | 524 | } |
| Wolfgang Betz |
4:07537ca85c66 | 525 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 526 | /** Spirit Irq Callback **/ |
| Wolfgang Betz |
5:c9c5bc673c64 | 527 | void SimpleSpirit1::IrqHandler() { |
| Wolfgang Betz |
4:07537ca85c66 | 528 | st_lib_spirit_irqs x_irq_status; |
| Wolfgang Betz |
4:07537ca85c66 | 529 | |
| Wolfgang Betz |
4:07537ca85c66 | 530 | /* get interrupt source from radio */ |
| Wolfgang Betz |
4:07537ca85c66 | 531 | irq_get_status(&x_irq_status); |
| Wolfgang Betz |
4:07537ca85c66 | 532 | irq_clear_status(); |
| Wolfgang Betz |
4:07537ca85c66 | 533 | |
| Wolfgang Betz |
4:07537ca85c66 | 534 | if(x_irq_status.IRQ_RX_FIFO_ERROR) { |
| Wolfgang Betz |
4:07537ca85c66 | 535 | receiving_packet = 0; |
| Wolfgang Betz |
4:07537ca85c66 | 536 | cmd_strobe(SPIRIT1_STROBE_FRX); |
| Wolfgang Betz |
4:07537ca85c66 | 537 | return; |
| Wolfgang Betz |
4:07537ca85c66 | 538 | } |
| Wolfgang Betz |
4:07537ca85c66 | 539 | |
| Wolfgang Betz |
4:07537ca85c66 | 540 | if(x_irq_status.IRQ_TX_FIFO_ERROR) { |
| Wolfgang Betz |
4:07537ca85c66 | 541 | receiving_packet = 0; |
| Wolfgang Betz |
4:07537ca85c66 | 542 | cmd_strobe(SPIRIT1_STROBE_FTX); |
| Wolfgang Betz |
4:07537ca85c66 | 543 | return; |
| Wolfgang Betz |
4:07537ca85c66 | 544 | } |
| Wolfgang Betz |
4:07537ca85c66 | 545 | |
| Wolfgang Betz |
4:07537ca85c66 | 546 | /* The IRQ_VALID_SYNC is used to notify a new packet is coming */ |
| Wolfgang Betz |
4:07537ca85c66 | 547 | if(x_irq_status.IRQ_VALID_SYNC) { |
| Wolfgang Betz |
4:07537ca85c66 | 548 | receiving_packet = 1; |
| Wolfgang Betz |
4:07537ca85c66 | 549 | } |
| Wolfgang Betz |
4:07537ca85c66 | 550 | |
| Wolfgang Betz |
4:07537ca85c66 | 551 | /* The IRQ_TX_DATA_SENT notifies the packet received. Puts the SPIRIT1 in RX */ |
| Wolfgang Betz |
4:07537ca85c66 | 552 | if(x_irq_status.IRQ_TX_DATA_SENT) { |
| Wolfgang Betz |
4:07537ca85c66 | 553 | cmd_strobe(SPIRIT1_STROBE_RX); |
| Wolfgang Betz |
4:07537ca85c66 | 554 | /* SpiritCmdStrobeRx();*/ |
| Wolfgang Betz |
4:07537ca85c66 | 555 | CLEAR_TXBUF(); |
| Wolfgang Betz |
4:07537ca85c66 | 556 | return; |
| Wolfgang Betz |
4:07537ca85c66 | 557 | } |
| Wolfgang Betz |
4:07537ca85c66 | 558 | |
| Wolfgang Betz |
4:07537ca85c66 | 559 | /* The IRQ_RX_DATA_READY notifies a new packet arrived */ |
| Wolfgang Betz |
4:07537ca85c66 | 560 | if(x_irq_status.IRQ_RX_DATA_READY) { |
| Wolfgang Betz |
5:c9c5bc673c64 | 561 | spirit_rx_len = pkt_basic_get_received_pkt_length(); |
| Wolfgang Betz |
5:c9c5bc673c64 | 562 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 563 | for(int i = 0; i < spirit_rx_len; ) { |
| Wolfgang Betz |
5:c9c5bc673c64 | 564 | uint8_t fifo_available = linear_fifo_read_num_elements_rx_fifo(); |
| Wolfgang Betz |
5:c9c5bc673c64 | 565 | if(fifo_available > 0) |
| Wolfgang Betz |
5:c9c5bc673c64 | 566 | spi_read_linear_fifo(fifo_available, &spirit_rx_buf[i]); |
| Wolfgang Betz |
5:c9c5bc673c64 | 567 | i += fifo_available; |
| Wolfgang Betz |
5:c9c5bc673c64 | 568 | } |
| Wolfgang Betz |
5:c9c5bc673c64 | 569 | |
| Wolfgang Betz |
4:07537ca85c66 | 570 | cmd_strobe(SPIRIT1_STROBE_FRX); |
| Wolfgang Betz |
4:07537ca85c66 | 571 | |
| Wolfgang Betz |
4:07537ca85c66 | 572 | last_rssi = qi_get_rssi(); //MGR |
| Wolfgang Betz |
4:07537ca85c66 | 573 | last_lqi = qi_get_lqi(); //MGR |
| Wolfgang Betz |
4:07537ca85c66 | 574 | |
| Wolfgang Betz |
4:07537ca85c66 | 575 | receiving_packet = 0; |
| Wolfgang Betz |
4:07537ca85c66 | 576 | |
| Wolfgang Betz |
4:07537ca85c66 | 577 | #if NULLRDC_CONF_802154_AUTOACK |
| Wolfgang Betz |
4:07537ca85c66 | 578 | if (spirit_rxbuf[0] == ACK_LEN) { |
| Wolfgang Betz |
4:07537ca85c66 | 579 | /* For debugging purposes we assume this is an ack for us */ |
| Wolfgang Betz |
4:07537ca85c66 | 580 | just_got_an_ack = 1; |
| Wolfgang Betz |
4:07537ca85c66 | 581 | } |
| Wolfgang Betz |
4:07537ca85c66 | 582 | #endif /* NULLRDC_CONF_802154_AUTOACK */ |
| Wolfgang Betz |
4:07537ca85c66 | 583 | |
| Wolfgang Betz |
5:c9c5bc673c64 | 584 | /* call user callback */ |
| Wolfgang Betz |
5:c9c5bc673c64 | 585 | if(_current_irq_callback) { |
| Wolfgang Betz |
5:c9c5bc673c64 | 586 | _current_irq_callback(); |
| Wolfgang Betz |
5:c9c5bc673c64 | 587 | } |
| Wolfgang Betz |
5:c9c5bc673c64 | 588 | |
| Wolfgang Betz |
4:07537ca85c66 | 589 | return; |
| Wolfgang Betz |
4:07537ca85c66 | 590 | } |
| Wolfgang Betz |
4:07537ca85c66 | 591 | |
| Wolfgang Betz |
4:07537ca85c66 | 592 | if(x_irq_status.IRQ_RX_DATA_DISC) |
| Wolfgang Betz |
4:07537ca85c66 | 593 | { |
| Wolfgang Betz |
4:07537ca85c66 | 594 | /* RX command - to ensure the device will be ready for the next reception */ |
| Wolfgang Betz |
4:07537ca85c66 | 595 | if(x_irq_status.IRQ_RX_TIMEOUT) { |
| Wolfgang Betz |
4:07537ca85c66 | 596 | cmd_strobe_flush_rx_fifo(); |
| Wolfgang Betz |
4:07537ca85c66 | 597 | } |
| Wolfgang Betz |
4:07537ca85c66 | 598 | } |
| Wolfgang Betz |
4:07537ca85c66 | 599 | } |
