Contiki 3.x
spirit1.c
1 /*
2  * Copyright (c) 2012, STMicroelectronics.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  *
30  */
31 /*---------------------------------------------------------------------------*/
32 #include "spirit1.h"
33 #include "spirit1-arch.h"
34 #include "stm32l1xx.h"
35 #include "contiki.h"
36 #include "net/mac/frame802154.h"
37 #include "net/netstack.h"
38 #include "net/packetbuf.h"
39 #include "net/rime/rimestats.h"
40 #include "spirit1-arch.h"
41 #include <stdio.h>
42 #include "st-lib.h"
43 /*---------------------------------------------------------------------------*/
44 /* MGR extern st_lib_spirit_irqs st_lib_x_irq_status; */
45 extern volatile st_lib_spirit_flag_status rx_timeout;
46 /*---------------------------------------------------------------------------*/
47 #define XXX_ACK_WORKAROUND 1
48 /*---------------------------------------------------------------------------*/
49 #define DEBUG 0
50 #if DEBUG
51 #include <stdio.h>
52 #define PRINTF(...) printf(__VA_ARGS__)
53 #else
54 #define PRINTF(...)
55 #endif
56 
57 /*---------------------------------------------------------------------------*/
58 #define BUSYWAIT_UNTIL(cond, max_time) \
59  do { \
60  rtimer_clock_t t0; \
61  t0 = RTIMER_NOW(); \
62  while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))) ; \
63  } while(0)
64 
65 /*---------------------------------------------------------------------------*/
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)
71 /*---------------------------------------------------------------------------*/
72 /* transceiver state. */
73 #define ON 0
74 #define OFF 1
75 /*---------------------------------------------------------------------------*/
76 static volatile unsigned int spirit_on = OFF;
77 static volatile uint8_t receiving_packet = 0;
78 static packetbuf_attr_t last_rssi = 0; /* MGR */
79 static packetbuf_attr_t last_lqi = 0; /* MGR */
80 /*---------------------------------------------------------------------------*/
81 /*
82  * The buffers which hold incoming data.
83  * The +1 because of the first byte,
84  * which will contain the length of the packet.
85  */
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);
89 /*---------------------------------------------------------------------------*/
90 static int just_got_an_ack = 0; /* Interrupt callback just detected an ack */
91 #if NULLRDC_CONF_802154_AUTOACK
92 #define ACK_LEN 3
93 static int wants_an_ack = 0; /* The packet sent expects an ack */
94 /* static int just_got_an_ack = 0; / * Interrupt callback just detected an ack * / */
95 /* #define ACKPRINTF printf */
96 #define ACKPRINTF(...)
97 #endif /* NULLRDC_CONF_802154_AUTOACK */
98 /*---------------------------------------------------------------------------*/
99 static int packet_is_prepared = 0;
100 /*---------------------------------------------------------------------------*/
101 PROCESS(spirit_radio_process, "SPIRIT radio driver");
102 /*---------------------------------------------------------------------------*/
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);
113 /*---------------------------------------------------------------------------*/
114 const struct radio_driver spirit_radio_driver =
115 {
116  spirit_radio_init,
117  spirit_radio_prepare,
118  spirit_radio_transmit,
119  spirit_radio_send,
120  spirit_radio_read,
121  spirit_radio_channel_clear,
122  spirit_radio_receiving_packet,
123  spirit_radio_pending_packet,
124  spirit_radio_on,
125  spirit_radio_off,
126 };
127 /*---------------------------------------------------------------------------*/
128 void
129 spirit1_printstatus(void)
130 {
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");
140  } else {
141  printf("spirit1: status: %d\n", s);
142  }
143 }
144 /*---------------------------------------------------------------------------*/
145 /* Strobe a command. The rationale for this is to clean up the messy legacy code. */
146 static void
147 spirit1_strobe(uint8_t s)
148 {
149  st_lib_spirit_cmd_strobe_command(s);
150 }
151 /*---------------------------------------------------------------------------*/
152 void
153 spirit_set_ready_state(void)
154 {
155  PRINTF("READY IN\n");
156 
157  st_lib_spirit_irq_clear_status();
158  IRQ_DISABLE();
159 
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();
165  }
166 
167  IRQ_ENABLE();
168 
169  PRINTF("READY OUT\n");
170 }
171 /*---------------------------------------------------------------------------*/
172 static int
173 spirit_radio_init(void)
174 {
175 
176  PRINTF("RADIO INIT IN\n");
177 
178  st_lib_spirit_spi_init();
179 
180  /* Configure radio shut-down (SDN) pin and activate radio */
181  st_lib_radio_gpio_init(RADIO_GPIO_SDN, RADIO_MODE_GPIO_OUT);
182 
183  /* Configures the SPIRIT1 library */
184  st_lib_spirit_radio_set_xtal_frequency(XTAL_FREQUENCY);
185  st_lib_spirit_management_set_frequency_base(XTAL_FREQUENCY);
186 
187  /* wake up to READY state */
188  /* weirdly enough, this *should* actually *set* the pin, not clear it! The pins is declared as GPIO_pin13 == 0x2000 */
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);
191 
192  /* wait minimum 1.5 ms to allow SPIRIT1 a proper boot-up sequence */
193  BUSYWAIT_UNTIL(0, 3 * RTIMER_SECOND / 2000);
194 
195  /* Soft reset of core */
196  spirit1_strobe(SPIRIT1_STROBE_SRES);
197 
198  /* Configures the SPIRIT1 radio part */
199  st_lib_s_radio_init x_radio_init = {
200  /* XTAL_FREQUENCY, */
201  XTAL_OFFSET_PPM,
202  BASE_FREQUENCY,
203  CHANNEL_SPACE,
204  CHANNEL_NUMBER,
205  MODULATION_SELECT,
206  DATARATE,
207  FREQ_DEVIATION,
208  BANDWIDTH
209  };
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);
214 
215  /* Configures the SPIRIT1 packet handler part*/
216  st_lib_pkt_basic_init x_basic_init = {
217  PREAMBLE_LENGTH,
218  SYNC_LENGTH,
219  SYNC_WORD,
220  LENGTH_TYPE,
221  LENGTH_WIDTH,
222  CRC_MODE,
223  CONTROL_LENGTH,
224  EN_ADDRESS,
225  EN_FEC,
226  EN_WHITENING
227  };
228  st_lib_spirit_pkt_basic_init(&x_basic_init);
229 
230  /* Enable the following interrupt sources, routed to GPIO */
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);
239 
240  /* Configure Spirit1 */
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);
248 
249  /* Puts the SPIRIT1 in STANDBY mode (125us -> rx/tx) */
250  spirit1_strobe(SPIRIT1_STROBE_STANDBY);
251  spirit_on = OFF;
252  CLEAR_RXBUF();
253  CLEAR_TXBUF();
254 
255  /* Initializes the mcu pin as input, used for IRQ */
256  st_lib_radio_gpio_init(RADIO_GPIO_IRQ, RADIO_MODE_EXTI_IN);
257 
258  /* Configure the radio to route the IRQ signal to its GPIO 3 */
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 });
260 
261  process_start(&spirit_radio_process, NULL);
262 
263  PRINTF("Spirit1 init done\n");
264  return 0;
265 }
266 /*---------------------------------------------------------------------------*/
267 static int
268 spirit_radio_prepare(const void *payload, unsigned short payload_len)
269 {
270  PRINTF("Spirit1: prep %u\n", payload_len);
271  packet_is_prepared = 0;
272 
273  /* Checks if the payload length is supported */
274  if(payload_len > MAX_PACKET_LEN) {
275  return RADIO_TX_ERR;
276  }
277 
278  /* Should we delay for an ack? */
279 #if NULLRDC_CONF_802154_AUTOACK
280  frame802154_t info154;
281  wants_an_ack = 0;
282  if(payload_len > ACK_LEN
283  && frame802154_parse((char *)payload, payload_len, &info154) != 0) {
284  if(info154.fcf.frame_type == FRAME802154_DATAFRAME
285  && info154.fcf.ack_required != 0) {
286  wants_an_ack = 1;
287  }
288  }
289 #endif /* NULLRDC_CONF_802154_AUTOACK */
290 
291  /* Sets the length of the packet to send */
292  IRQ_DISABLE();
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);
296  IRQ_ENABLE();
297 
298  PRINTF("PREPARE OUT\n");
299 
300  packet_is_prepared = 1;
301  return RADIO_TX_OK;
302 }
303 /*---------------------------------------------------------------------------*/
304 static int
305 spirit_radio_transmit(unsigned short payload_len)
306 {
307  /* This function blocks until the packet has been transmitted */
308  rtimer_clock_t rtimer_txdone, rtimer_rxack;
309 
310  PRINTF("TRANSMIT IN\n");
311  if(!packet_is_prepared) {
312  return RADIO_TX_ERR;
313  }
314 
315  /* Stores the length of the packet to send */
316  /* Others spirit_radio_prepare will be in hold */
317  spirit_txbuf[0] = payload_len;
318 
319  /* Puts the SPIRIT1 in TX state */
320  receiving_packet = 0;
321  spirit_set_ready_state();
322  spirit1_strobe(SPIRIT1_STROBE_TX);
323  just_got_an_ack = 0;
324  BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_TX, 1 * RTIMER_SECOND / 1000);
325  /* BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 4 * RTIMER_SECOND/1000); //For GFSK with high data rate */
326  BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 50 * RTIMER_SECOND / 1000); /* For FSK with low data rate */
327 
328  /* Reset radio - needed for immediate RX of ack */
329  CLEAR_TXBUF();
330  CLEAR_RXBUF();
331  IRQ_DISABLE();
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);
339  IRQ_ENABLE();
340 
341 #if XXX_ACK_WORKAROUND
342  just_got_an_ack = 1;
343 #endif /* XXX_ACK_WORKAROUND */
344 
345 #if NULLRDC_CONF_802154_AUTOACK
346  if(wants_an_ack) {
347  rtimer_txdone = RTIMER_NOW();
348  BUSYWAIT_UNTIL(just_got_an_ack, 2 * RTIMER_SECOND / 1000);
349  rtimer_rxack = RTIMER_NOW();
350 
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);
354  } else {
355  ACKPRINTF("debug_ack: no ack received\n");
356  }
357  }
358 #endif /* NULLRDC_CONF_802154_AUTOACK */
359 
360  PRINTF("TRANSMIT OUT\n");
361 
362  CLEAR_TXBUF();
363 
364  packet_is_prepared = 0;
365 
366  clock_wait(1);
367 
368  return RADIO_TX_OK;
369 }
370 /*---------------------------------------------------------------------------*/
371 static int
372 spirit_radio_send(const void *payload, unsigned short payload_len)
373 {
374  if(spirit_radio_prepare(payload, payload_len) == RADIO_TX_ERR) {
375  return RADIO_TX_ERR;
376  }
377  return spirit_radio_transmit(payload_len);
378 }
379 /*---------------------------------------------------------------------------*/
380 static int
381 spirit_radio_read(void *buf, unsigned short bufsize)
382 {
383  PRINTF("READ IN\n");
384 
385  /* Checks if the RX buffer is empty */
386  if(IS_RXBUF_EMPTY()) {
387  IRQ_DISABLE();
388  CLEAR_RXBUF();
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");
396  IRQ_ENABLE();
397  return 0;
398  }
399 
400  if(bufsize < spirit_rxbuf[0]) {
401  /* If buf has the correct size */
402  PRINTF("TOO SMALL BUF\n");
403  return 0;
404  } else {
405  /* Copies the packet received */
406  memcpy(buf, spirit_rxbuf + 1, spirit_rxbuf[0]);
407 
408  packetbuf_set_attr(PACKETBUF_ATTR_RSSI, last_rssi); /* MGR */
409  packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, last_lqi); /* MGR */
410  bufsize = spirit_rxbuf[0];
411  CLEAR_RXBUF();
412 
413  PRINTF("READ OUT\n");
414 
415  return bufsize;
416  }
417 }
418 /*---------------------------------------------------------------------------*/
419 static int
420 spirit_radio_channel_clear(void)
421 {
422  float rssi_value;
423  /* Local variable used to memorize the SPIRIT1 state */
424  uint8_t spirit_state = ON;
425 
426  PRINTF("CHANNEL CLEAR IN\n");
427 
428  if(spirit_on == OFF) {
429  /* Wakes up the SPIRIT1 */
430  spirit_radio_on();
431  spirit_state = OFF;
432  }
433 
434  /* */
435  IRQ_DISABLE();
436  spirit1_strobe(SPIRIT1_STROBE_SABORT);
437 /* SpiritCmdStrobeSabort();*/
438  st_lib_spirit_irq_clear_status();
439  IRQ_ENABLE();
440  {
441  rtimer_clock_t timeout = RTIMER_NOW() + 5 * RTIMER_SECOND / 1000;
442  do {
443  st_lib_spirit_refresh_status();
444  } while((st_lib_g_x_status.MC_STATE != MC_STATE_READY) && (RTIMER_NOW() < timeout));
445  if(RTIMER_NOW() < timeout) {
446  return 1;
447  }
448  }
449 
450  /* Stores the RSSI value */
451  rssi_value = st_lib_spirit_qi_get_rssi_dbm();
452 
453  /* Puts the SPIRIT1 in its previous state */
454  if(spirit_state == OFF) {
455  spirit_radio_off();
456  } else {
457  spirit1_strobe(SPIRIT1_STROBE_RX);
458 /* SpiritCmdStrobeRx();*/
459  BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5 * RTIMER_SECOND / 1000);
460  }
461 
462  PRINTF("CHANNEL CLEAR OUT\n");
463 
464  /* Checks the RSSI value with the threshold */
465  if(rssi_value < CCA_THRESHOLD) {
466  return 0;
467  } else {
468  return 1;
469  }
470 }
471 /*---------------------------------------------------------------------------*/
472 static int
473 spirit_radio_receiving_packet(void)
474 {
475  return receiving_packet;
476 }
477 /*---------------------------------------------------------------------------*/
478 static int
479 spirit_radio_pending_packet(void)
480 {
481  PRINTF("PENDING PACKET\n");
482  return !IS_RXBUF_EMPTY();
483 }
484 /*---------------------------------------------------------------------------*/
485 static int
486 spirit_radio_off(void)
487 {
488  PRINTF("Spirit1: ->off\n");
489  if(spirit_on == ON) {
490  /* Disables the mcu to get IRQ from the SPIRIT1 */
491  IRQ_DISABLE();
492 
493  /* first stop rx/tx */
494  spirit1_strobe(SPIRIT1_STROBE_SABORT);
495 
496  /* Clear any pending irqs */
497  st_lib_spirit_irq_clear_status();
498 
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");
502  return 1;
503  }
504 
505  /* Puts the SPIRIT1 in STANDBY */
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");
510  return 1;
511  }
512 
513  spirit_on = OFF;
514  CLEAR_TXBUF();
515  CLEAR_RXBUF();
516  }
517  PRINTF("Spirit1: off.\n");
518  return 0;
519 }
520 /*---------------------------------------------------------------------------*/
521 static int
522 spirit_radio_on(void)
523 {
524 
525  PRINTF("Spirit1: on\n");
526  spirit1_strobe(SPIRIT1_STROBE_SABORT);
527  BUSYWAIT_UNTIL(0, RTIMER_SECOND / 2500);
528  if(spirit_on == OFF) {
529  IRQ_DISABLE();
530  /* ensure we are in READY state as we go from there to Rx */
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");
535  while(1) ;
536  /* return 1; */
537  }
538 
539  /* now we go to Rx */
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");
544  while(1) ;
545  /* return 1; */
546  }
547 
548  /* Enables the mcu to get IRQ from the SPIRIT1 */
549  IRQ_ENABLE();
550  spirit_on = ON;
551  }
552 
553  return 0;
554 }
555 /*---------------------------------------------------------------------------*/
556 static int interrupt_callback_in_progress = 0;
557 static int interrupt_callback_wants_poll = 0;
558 PROCESS_THREAD(spirit_radio_process, ev, data)
559 {
560  PROCESS_BEGIN();
561  PRINTF("Spirit1: process started\n");
562 
563  while(1) {
564  int len;
565 
566  PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
567  PRINTF("Spirit1: polled\n");
568 
569  packetbuf_clear();
570  len = spirit_radio_read(packetbuf_dataptr(), PACKETBUF_SIZE);
571 
572  if(len > 0) {
573 
574 #if NULLRDC_CONF_802154_AUTOACK
575  /* Check if the packet has an ACK request */
576  frame802154_t info154;
577  if(len > ACK_LEN &&
578  frame802154_parse((char *)packetbuf_dataptr(), len, &info154) != 0) {
579  if(info154.fcf.frame_type == FRAME802154_DATAFRAME &&
580  info154.fcf.ack_required != 0 &&
581  linkaddr_cmp((linkaddr_t *)&info154.dest_addr,
582  &linkaddr_node_addr)) {
583 
584 #if !XXX_ACK_WORKAROUND
585  /* Send an ACK packet */
586  uint8_t ack_frame[ACK_LEN] = {
587  FRAME802154_ACKFRAME,
588  0x00,
589  info154.seq
590  };
591  IRQ_DISABLE();
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);
595 
596  spirit_set_ready_state();
597  IRQ_ENABLE();
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]);
602 #endif /* !XXX_ACK_WORKAROUND */
603  }
604  }
605 #endif /* NULLRDC_CONF_802154_AUTOACK */
606 
608  NETSTACK_RDC.input();
609  }
610 
611  if(!IS_RXBUF_EMPTY()) {
612  process_poll(&spirit_radio_process);
613  }
614 
615  if(interrupt_callback_wants_poll) {
616  spirit1_interrupt_callback();
617 
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);
621  }
622  }
623  }
624 
625  PROCESS_END();
626 }
627 /*---------------------------------------------------------------------------*/
628 void
629 spirit1_interrupt_callback(void)
630 {
631 #define INTPRINTF(...) /* PRINTF */
632  st_lib_spirit_irqs x_irq_status;
633  if(spirit_spi_busy() || interrupt_callback_in_progress) {
634  process_poll(&spirit_radio_process);
635  interrupt_callback_wants_poll = 1;
636  return;
637  }
638 
639  interrupt_callback_wants_poll = 0;
640  interrupt_callback_in_progress = 1;
641 
642  /* get interrupt source from radio */
643  st_lib_spirit_irq_get_status(&x_irq_status);
644  st_lib_spirit_irq_clear_status();
645 
646  if(x_irq_status.IRQ_RX_FIFO_ERROR) {
647  receiving_packet = 0;
648  interrupt_callback_in_progress = 0;
649  spirit1_strobe(SPIRIT1_STROBE_FRX);
650  return;
651  }
652 
653  if(x_irq_status.IRQ_TX_FIFO_ERROR) {
654  receiving_packet = 0;
655  interrupt_callback_in_progress = 0;
656  spirit1_strobe(SPIRIT1_STROBE_FTX);
657  return;
658  }
659 
660  /* The IRQ_VALID_SYNC is used to notify a new packet is coming */
661  if(x_irq_status.IRQ_VALID_SYNC) {
662  INTPRINTF("SYNC\n");
663  receiving_packet = 1;
664  }
665 
666  /* The IRQ_TX_DATA_SENT notifies the packet received. Puts the SPIRIT1 in RX */
667  if(x_irq_status.IRQ_TX_DATA_SENT) {
668  spirit1_strobe(SPIRIT1_STROBE_RX);
669 /* SpiritCmdStrobeRx();*/
670  INTPRINTF("SENT\n");
671  CLEAR_TXBUF();
672  interrupt_callback_in_progress = 0;
673  return;
674  }
675 
676  /* The IRQ_RX_DATA_READY notifies a new packet arrived */
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(),
679  &spirit_rxbuf[1]);
680  spirit_rxbuf[0] = st_lib_spirit_pkt_basic_get_received_pkt_length();
681  spirit1_strobe(SPIRIT1_STROBE_FRX);
682 
683  INTPRINTF("RECEIVED\n");
684 
685  process_poll(&spirit_radio_process);
686 
687  last_rssi = (packetbuf_attr_t)st_lib_spirit_qi_get_rssi(); /* MGR */
688  last_lqi = (packetbuf_attr_t)st_lib_spirit_qi_get_lqi(); /* MGR */
689 
690  receiving_packet = 0;
691 
692 #if NULLRDC_CONF_802154_AUTOACK
693  if(spirit_rxbuf[0] == ACK_LEN) {
694  /* For debugging purposes we assume this is an ack for us */
695  just_got_an_ack = 1;
696  }
697 #endif /* NULLRDC_CONF_802154_AUTOACK */
698 
699  interrupt_callback_in_progress = 0;
700  return;
701  }
702 
703  if(x_irq_status.IRQ_RX_DATA_DISC) {
704  /* RX command - to ensure the device will be ready for the next reception */
705  if(x_irq_status.IRQ_RX_TIMEOUT) {
706  st_lib_spirit_cmd_strobe_flush_rx_fifo();
707  rx_timeout = SET;
708  }
709  }
710 
711  interrupt_callback_in_progress = 0;
712 }
713 /*---------------------------------------------------------------------------*/
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
Definition: packetbuf.c:158
void process_poll(struct process *p)
Request a process to be polled.
Definition: process.c:371
uint8_t dest_addr[8]
Destination address.
Definition: frame802154.h:196
frame802154_fcf_t fcf
Frame control field.
Definition: frame802154.h:198
Header file for the STM32Cube HAL APIs.
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:135
void packetbuf_clear(void)
Clear and reset the packetbuf.
Definition: packetbuf.c:76
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
uint8_t seq
Sequence number.
Definition: frame802154.h:199
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition: process.h:273
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
Definition: packetbuf.h:66
int(* receiving_packet)(void)
Check if the radio driver is currently receiving a packet.
Definition: radio.h:258
The structure of a device driver for a radio in Contiki.
Definition: radio.h:237
Header file for the Rime buffer (packetbuf) management
#define NULL
The null pointer.
uint8_t frame_type
3 bit.
Definition: frame802154.h:147
802.15.4 frame creation and parsing functions
int frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
Parses an input frame.
Definition: frame802154.c:465
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
Definition: packetbuf.c:151
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
Definition: process.h:178
uint8_t ack_required
1 bit.
Definition: frame802154.h:150
void clock_wait(clock_time_t t)
Wait for a given number of ticks.
Definition: clock.c:162
Header file for Rime statistics
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two Rime addresses.
Definition: linkaddr.c:66
linkaddr_t linkaddr_node_addr
The Rime address of the node.
Definition: linkaddr.c:48
Parameters used by the frame802154_create() function.
Definition: frame802154.h:192
Include file for the Contiki low-layer network stack (NETSTACK)
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120