33 #include "spirit1-arch.h"
34 #include "stm32l1xx.h"
40 #include "spirit1-arch.h"
45 extern volatile st_lib_spirit_flag_status rx_timeout;
47 #define XXX_ACK_WORKAROUND 1
52 #define PRINTF(...) printf(__VA_ARGS__)
58 #define BUSYWAIT_UNTIL(cond, max_time) \
62 while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))) ; \
66 #define CLEAR_TXBUF() (spirit_txbuf[0] = 0)
67 #define CLEAR_RXBUF() (spirit_rxbuf[0] = 0)
68 #define IS_TXBUF_EMPTY() (spirit_txbuf[0] == 0)
69 #define IS_RXBUF_EMPTY() (spirit_rxbuf[0] == 0)
70 #define IS_RXBUF_FULL() (spirit_rxbuf[0] != 0)
76 static volatile unsigned int spirit_on = OFF;
77 static volatile uint8_t receiving_packet = 0;
78 static packetbuf_attr_t last_rssi = 0;
79 static packetbuf_attr_t last_lqi = 0;
86 static uint8_t spirit_rxbuf[MAX_PACKET_LEN + 1];
87 static uint8_t spirit_txbuf[MAX_PACKET_LEN + 1 - SPIRIT_MAX_FIFO_LEN];
88 void st_lib_spirit_management_set_frequency_base(uint32_t);
90 static int just_got_an_ack = 0;
91 #if NULLRDC_CONF_802154_AUTOACK
93 static int wants_an_ack = 0;
96 #define ACKPRINTF(...)
99 static int packet_is_prepared = 0;
101 PROCESS(spirit_radio_process,
"SPIRIT radio driver");
103 static int spirit_radio_init(
void);
104 static int spirit_radio_prepare(
const void *payload,
unsigned short payload_len);
105 static int spirit_radio_transmit(
unsigned short payload_len);
106 static int spirit_radio_send(
const void *data,
unsigned short len);
107 static int spirit_radio_read(
void *buf,
unsigned short bufsize);
108 static int spirit_radio_channel_clear(
void);
109 static int spirit_radio_receiving_packet(
void);
110 static int spirit_radio_pending_packet(
void);
111 static int spirit_radio_on(
void);
112 static int spirit_radio_off(
void);
117 spirit_radio_prepare,
118 spirit_radio_transmit,
121 spirit_radio_channel_clear,
122 spirit_radio_receiving_packet,
123 spirit_radio_pending_packet,
129 spirit1_printstatus(
void)
131 int s = SPIRIT1_STATUS();
132 if(s == SPIRIT1_STATE_STANDBY) {
133 printf(
"spirit1: SPIRIT1_STATE_STANDBY\n");
134 }
else if(s == SPIRIT1_STATE_READY) {
135 printf(
"spirit1: SPIRIT1_STATE_READY\n");
136 }
else if(s == SPIRIT1_STATE_TX) {
137 printf(
"spirit1: SPIRIT1_STATE_TX\n");
138 }
else if(s == SPIRIT1_STATE_RX) {
139 printf(
"spirit1: SPIRIT1_STATE_RX\n");
141 printf(
"spirit1: status: %d\n", s);
147 spirit1_strobe(uint8_t s)
149 st_lib_spirit_cmd_strobe_command(s);
153 spirit_set_ready_state(
void)
155 PRINTF(
"READY IN\n");
157 st_lib_spirit_irq_clear_status();
160 if(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY) {
161 spirit1_strobe(SPIRIT1_STROBE_READY);
162 }
else if(SPIRIT1_STATUS() == SPIRIT1_STATE_RX) {
163 spirit1_strobe(SPIRIT1_STROBE_SABORT);
164 st_lib_spirit_irq_clear_status();
169 PRINTF(
"READY OUT\n");
173 spirit_radio_init(
void)
176 PRINTF(
"RADIO INIT IN\n");
178 st_lib_spirit_spi_init();
181 st_lib_radio_gpio_init(RADIO_GPIO_SDN, RADIO_MODE_GPIO_OUT);
184 st_lib_spirit_radio_set_xtal_frequency(XTAL_FREQUENCY);
185 st_lib_spirit_management_set_frequency_base(XTAL_FREQUENCY);
189 RADIO_GPIO_SDN_PORT->BSRR = RADIO_GPIO_SDN_PIN;
190 st_lib_hal_gpio_write_pin(RADIO_GPIO_SDN_PORT, RADIO_GPIO_SDN_PIN, GPIO_PIN_RESET);
193 BUSYWAIT_UNTIL(0, 3 * RTIMER_SECOND / 2000);
196 spirit1_strobe(SPIRIT1_STROBE_SRES);
199 st_lib_s_radio_init x_radio_init = {
210 st_lib_spirit_radio_init(&x_radio_init);
211 st_lib_spirit_radio_set_xtal_frequency(XTAL_FREQUENCY);
212 st_lib_spirit_radio_set_pa_level_dbm(0, POWER_DBM);
213 st_lib_spirit_radio_set_pa_level_max_index(0);
216 st_lib_pkt_basic_init x_basic_init = {
228 st_lib_spirit_pkt_basic_init(&x_basic_init);
231 st_lib_spirit_irq_de_init(
NULL);
232 st_lib_spirit_irq_clear_status();
233 st_lib_spirit_irq(TX_DATA_SENT, S_ENABLE);
234 st_lib_spirit_irq(RX_DATA_READY, S_ENABLE);
235 st_lib_spirit_irq(VALID_SYNC, S_ENABLE);
236 st_lib_spirit_irq(RX_DATA_DISC, S_ENABLE);
237 st_lib_spirit_irq(TX_FIFO_ERROR, S_ENABLE);
238 st_lib_spirit_irq(RX_FIFO_ERROR, S_ENABLE);
241 st_lib_spirit_radio_persisten_rx(S_ENABLE);
242 st_lib_spirit_qi_set_sqi_threshold(SQI_TH_0);
243 st_lib_spirit_qi_sqi_check(S_ENABLE);
244 st_lib_spirit_qi_set_rssi_threshold_dbm(CCA_THRESHOLD);
245 st_lib_spirit_timer_set_rx_timeout_stop_condition(SQI_ABOVE_THRESHOLD);
246 SET_INFINITE_RX_TIMEOUT();
247 st_lib_spirit_radio_afc_freeze_on_sync(S_ENABLE);
250 spirit1_strobe(SPIRIT1_STROBE_STANDBY);
256 st_lib_radio_gpio_init(RADIO_GPIO_IRQ, RADIO_MODE_EXTI_IN);
259 st_lib_spirit_gpio_init(&(st_lib_s_gpio_init){SPIRIT_GPIO_IRQ, SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP, SPIRIT_GPIO_DIG_OUT_IRQ });
263 PRINTF(
"Spirit1 init done\n");
268 spirit_radio_prepare(
const void *payload,
unsigned short payload_len)
270 PRINTF(
"Spirit1: prep %u\n", payload_len);
271 packet_is_prepared = 0;
274 if(payload_len > MAX_PACKET_LEN) {
279 #if NULLRDC_CONF_802154_AUTOACK
282 if(payload_len > ACK_LEN
293 spirit1_strobe(SPIRIT1_STROBE_FTX);
294 st_lib_spirit_pkt_basic_set_payload_length(payload_len);
295 st_lib_spirit_spi_write_linear_fifo(payload_len, (uint8_t *)payload);
298 PRINTF(
"PREPARE OUT\n");
300 packet_is_prepared = 1;
305 spirit_radio_transmit(
unsigned short payload_len)
308 rtimer_clock_t rtimer_txdone, rtimer_rxack;
310 PRINTF(
"TRANSMIT IN\n");
311 if(!packet_is_prepared) {
317 spirit_txbuf[0] = payload_len;
321 spirit_set_ready_state();
322 spirit1_strobe(SPIRIT1_STROBE_TX);
324 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_TX, 1 * RTIMER_SECOND / 1000);
326 BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 50 * RTIMER_SECOND / 1000);
332 st_lib_spirit_irq_clear_status();
333 spirit1_strobe(SPIRIT1_STROBE_SABORT);
334 BUSYWAIT_UNTIL(0, RTIMER_SECOND / 2500);
335 spirit1_strobe(SPIRIT1_STROBE_READY);
336 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 1 * RTIMER_SECOND / 1000);
337 spirit1_strobe(SPIRIT1_STROBE_RX);
338 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1 * RTIMER_SECOND / 1000);
341 #if XXX_ACK_WORKAROUND
345 #if NULLRDC_CONF_802154_AUTOACK
348 BUSYWAIT_UNTIL(just_got_an_ack, 2 * RTIMER_SECOND / 1000);
351 if(just_got_an_ack) {
352 ACKPRINTF(
"debug_ack: ack received after %u/%u ticks\n",
353 (uint32_t)(rtimer_rxack - rtimer_txdone), 2 * RTIMER_SECOND / 1000);
355 ACKPRINTF(
"debug_ack: no ack received\n");
360 PRINTF(
"TRANSMIT OUT\n");
364 packet_is_prepared = 0;
372 spirit_radio_send(
const void *payload,
unsigned short payload_len)
374 if(spirit_radio_prepare(payload, payload_len) == RADIO_TX_ERR) {
377 return spirit_radio_transmit(payload_len);
381 spirit_radio_read(
void *buf,
unsigned short bufsize)
386 if(IS_RXBUF_EMPTY()) {
389 spirit1_strobe(SPIRIT1_STROBE_SABORT);
390 BUSYWAIT_UNTIL(0, RTIMER_SECOND / 2500);
391 spirit1_strobe(SPIRIT1_STROBE_READY);
392 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 1 * RTIMER_SECOND / 1000);
393 spirit1_strobe(SPIRIT1_STROBE_RX);
394 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1 * RTIMER_SECOND / 1000);
395 PRINTF(
"READ OUT RX BUF EMPTY\n");
400 if(bufsize < spirit_rxbuf[0]) {
402 PRINTF(
"TOO SMALL BUF\n");
406 memcpy(buf, spirit_rxbuf + 1, spirit_rxbuf[0]);
408 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, last_rssi);
409 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, last_lqi);
410 bufsize = spirit_rxbuf[0];
413 PRINTF(
"READ OUT\n");
420 spirit_radio_channel_clear(
void)
424 uint8_t spirit_state = ON;
426 PRINTF(
"CHANNEL CLEAR IN\n");
428 if(spirit_on == OFF) {
436 spirit1_strobe(SPIRIT1_STROBE_SABORT);
438 st_lib_spirit_irq_clear_status();
441 rtimer_clock_t timeout =
RTIMER_NOW() + 5 * RTIMER_SECOND / 1000;
443 st_lib_spirit_refresh_status();
444 }
while((st_lib_g_x_status.MC_STATE != MC_STATE_READY) && (
RTIMER_NOW() < timeout));
451 rssi_value = st_lib_spirit_qi_get_rssi_dbm();
454 if(spirit_state == OFF) {
457 spirit1_strobe(SPIRIT1_STROBE_RX);
459 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5 * RTIMER_SECOND / 1000);
462 PRINTF(
"CHANNEL CLEAR OUT\n");
465 if(rssi_value < CCA_THRESHOLD) {
473 spirit_radio_receiving_packet(
void)
479 spirit_radio_pending_packet(
void)
481 PRINTF(
"PENDING PACKET\n");
482 return !IS_RXBUF_EMPTY();
486 spirit_radio_off(
void)
488 PRINTF(
"Spirit1: ->off\n");
489 if(spirit_on == ON) {
494 spirit1_strobe(SPIRIT1_STROBE_SABORT);
497 st_lib_spirit_irq_clear_status();
499 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 5 * RTIMER_SECOND / 1000);
500 if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
501 PRINTF(
"Spirit1: failed off->ready\n");
506 spirit1_strobe(SPIRIT1_STROBE_STANDBY);
507 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, 5 * RTIMER_SECOND / 1000);
508 if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) {
509 PRINTF(
"Spirit1: failed off->stdby\n");
517 PRINTF(
"Spirit1: off.\n");
522 spirit_radio_on(
void)
525 PRINTF(
"Spirit1: on\n");
526 spirit1_strobe(SPIRIT1_STROBE_SABORT);
527 BUSYWAIT_UNTIL(0, RTIMER_SECOND / 2500);
528 if(spirit_on == OFF) {
531 spirit1_strobe(SPIRIT1_STROBE_READY);
532 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 5 * RTIMER_SECOND / 1000);
533 if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
534 PRINTF(
"Spirit1: failed to turn on\n");
540 spirit1_strobe(SPIRIT1_STROBE_RX);
541 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5 * RTIMER_SECOND / 1000);
542 if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
543 PRINTF(
"Spirit1: failed to enter rx\n");
556 static int interrupt_callback_in_progress = 0;
557 static int interrupt_callback_wants_poll = 0;
561 PRINTF(
"Spirit1: process started\n");
567 PRINTF(
"Spirit1: polled\n");
574 #if NULLRDC_CONF_802154_AUTOACK
584 #if !XXX_ACK_WORKAROUND
586 uint8_t ack_frame[ACK_LEN] = {
587 FRAME802154_ACKFRAME,
592 spirit1_strobe(SPIRIT1_STROBE_FTX);
593 st_lib_spirit_pkt_basic_set_payload_length((uint16_t)ACK_LEN);
594 st_lib_spirit_spi_write_linear_fifo((uint16_t)ACK_LEN, (uint8_t *)ack_frame);
596 spirit_set_ready_state();
598 spirit1_strobe(SPIRIT1_STROBE_TX);
599 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_TX, 1 * RTIMER_SECOND / 1000);
600 BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 1 * RTIMER_SECOND / 1000);
601 ACKPRINTF(
"debug_ack: sent ack %d\n", ack_frame[2]);
608 NETSTACK_RDC.input();
611 if(!IS_RXBUF_EMPTY()) {
615 if(interrupt_callback_wants_poll) {
616 spirit1_interrupt_callback();
618 if(SPIRIT1_STATUS() == SPIRIT1_STATE_READY) {
619 spirit1_strobe(SPIRIT1_STROBE_RX);
620 BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1 * RTIMER_SECOND / 1000);
629 spirit1_interrupt_callback(
void)
631 #define INTPRINTF(...)
632 st_lib_spirit_irqs x_irq_status;
633 if(spirit_spi_busy() || interrupt_callback_in_progress) {
635 interrupt_callback_wants_poll = 1;
639 interrupt_callback_wants_poll = 0;
640 interrupt_callback_in_progress = 1;
643 st_lib_spirit_irq_get_status(&x_irq_status);
644 st_lib_spirit_irq_clear_status();
646 if(x_irq_status.IRQ_RX_FIFO_ERROR) {
648 interrupt_callback_in_progress = 0;
649 spirit1_strobe(SPIRIT1_STROBE_FRX);
653 if(x_irq_status.IRQ_TX_FIFO_ERROR) {
655 interrupt_callback_in_progress = 0;
656 spirit1_strobe(SPIRIT1_STROBE_FTX);
661 if(x_irq_status.IRQ_VALID_SYNC) {
667 if(x_irq_status.IRQ_TX_DATA_SENT) {
668 spirit1_strobe(SPIRIT1_STROBE_RX);
672 interrupt_callback_in_progress = 0;
677 if(x_irq_status.IRQ_RX_DATA_READY) {
678 st_lib_spirit_spi_read_linear_fifo(st_lib_spirit_linear_fifo_read_num_elements_rx_fifo(),
680 spirit_rxbuf[0] = st_lib_spirit_pkt_basic_get_received_pkt_length();
681 spirit1_strobe(SPIRIT1_STROBE_FRX);
683 INTPRINTF(
"RECEIVED\n");
687 last_rssi = (packetbuf_attr_t)st_lib_spirit_qi_get_rssi();
688 last_lqi = (packetbuf_attr_t)st_lib_spirit_qi_get_lqi();
692 #if NULLRDC_CONF_802154_AUTOACK
693 if(spirit_rxbuf[0] == ACK_LEN) {
699 interrupt_callback_in_progress = 0;
703 if(x_irq_status.IRQ_RX_DATA_DISC) {
705 if(x_irq_status.IRQ_RX_TIMEOUT) {
706 st_lib_spirit_cmd_strobe_flush_rx_fifo();
711 interrupt_callback_in_progress = 0;
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
void process_poll(struct process *p)
Request a process to be polled.
uint8_t dest_addr[8]
Destination address.
frame802154_fcf_t fcf
Frame control field.
Header file for the STM32Cube HAL APIs.
#define RTIMER_NOW()
Get the current clock time.
void packetbuf_clear(void)
Clear and reset the packetbuf.
#define PROCESS_END()
Define the end of a process.
#define PROCESS(name, strname)
Declare a process.
uint8_t seq
Sequence number.
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
int(* receiving_packet)(void)
Check if the radio driver is currently receiving a packet.
The structure of a device driver for a radio in Contiki.
Header file for the Rime buffer (packetbuf) management
#define NULL
The null pointer.
802.15.4 frame creation and parsing functions
int frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
Parses an input frame.
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
void process_start(struct process *p, process_data_t data)
Start a process.
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
uint8_t ack_required
1 bit.
void clock_wait(clock_time_t t)
Wait for a given number of ticks.
Header file for Rime statistics
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two Rime addresses.
linkaddr_t linkaddr_node_addr
The Rime address of the node.
Parameters used by the frame802154_create() function.
Include file for the Contiki low-layer network stack (NETSTACK)
#define PROCESS_BEGIN()
Define the beginning of a process.