Contiki-Inga 3.x
cc2538-rf.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/
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  *
14  * 3. Neither the name of the copyright holder nor the names of its
15  * contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29  * OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 /**
32  * \addtogroup cc2538-rf
33  * @{
34  *
35  * \file
36  * Implementation of the cc2538 RF driver
37  */
38 #include "contiki.h"
39 #include "dev/radio.h"
40 #include "sys/clock.h"
41 #include "sys/rtimer.h"
42 #include "net/packetbuf.h"
43 #include "net/rime/rimestats.h"
44 #include "net/linkaddr.h"
45 #include "net/netstack.h"
46 #include "sys/energest.h"
47 #include "dev/cc2538-rf.h"
48 #include "dev/rfcore.h"
49 #include "dev/sys-ctrl.h"
50 #include "dev/udma.h"
51 #include "reg.h"
52 
53 #include <string.h>
54 /*---------------------------------------------------------------------------*/
55 #define CHECKSUM_LEN 2
56 
57 /* uDMA channel control persistent flags */
58 #define UDMA_TX_FLAGS (UDMA_CHCTL_ARBSIZE_128 | UDMA_CHCTL_XFERMODE_AUTO \
59  | UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_DSTSIZE_8 \
60  | UDMA_CHCTL_SRCINC_8 | UDMA_CHCTL_DSTINC_NONE)
61 
62 #define UDMA_RX_FLAGS (UDMA_CHCTL_ARBSIZE_128 | UDMA_CHCTL_XFERMODE_AUTO \
63  | UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_DSTSIZE_8 \
64  | UDMA_CHCTL_SRCINC_NONE | UDMA_CHCTL_DSTINC_8)
65 
66 /*
67  * uDMA transfer threshold. DMA will only be used to read an incoming frame
68  * if its size is above this threshold
69  */
70 #define UDMA_RX_SIZE_THRESHOLD 3
71 /*---------------------------------------------------------------------------*/
72 #include <stdio.h>
73 #define DEBUG 0
74 #if DEBUG
75 #define PRINTF(...) printf(__VA_ARGS__)
76 #else
77 #define PRINTF(...)
78 #endif
79 /*---------------------------------------------------------------------------*/
80 /* Local RF Flags */
81 #define RX_ACTIVE 0x80
82 #define RF_MUST_RESET 0x40
83 #define WAS_OFF 0x10
84 #define RF_ON 0x01
85 
86 /* Bit Masks for the last byte in the RX FIFO */
87 #define CRC_BIT_MASK 0x80
88 #define LQI_BIT_MASK 0x7F
89 /* RSSI Offset */
90 #define RSSI_OFFSET 73
91 
92 /* 192 usec off -> on interval (RX Callib -> SFD Wait). We wait a bit more */
93 #define ONOFF_TIME RTIMER_ARCH_SECOND / 3125
94 /*---------------------------------------------------------------------------*/
95 /* Sniffer configuration */
96 #ifndef CC2538_RF_CONF_SNIFFER_USB
97 #define CC2538_RF_CONF_SNIFFER_USB 0
98 #endif
99 
100 #if CC2538_RF_CONF_SNIFFER
101 static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /** Snif */
102 
103 #if CC2538_RF_CONF_SNIFFER_USB
104 #include "usb/usb-serial.h"
105 #define write_byte(b) usb_serial_writeb(b)
106 #define flush() usb_serial_flush()
107 #else
108 #include "dev/uart.h"
109 #define write_byte(b) uart_write_byte(b)
110 #define flush()
111 #endif
112 
113 #else /* CC2538_RF_CONF_SNIFFER */
114 #define write_byte(b)
115 #define flush()
116 #endif /* CC2538_RF_CONF_SNIFFER */
117 /*---------------------------------------------------------------------------*/
118 #ifdef CC2538_RF_CONF_AUTOACK
119 #define CC2538_RF_AUTOACK CC2538_RF_CONF_AUTOACK
120 #else
121 #define CC2538_RF_AUTOACK 1
122 #endif
123 /*---------------------------------------------------------------------------*/
124 static uint8_t rf_flags;
125 
126 static int on(void);
127 static int off(void);
128 /*---------------------------------------------------------------------------*/
129 PROCESS(cc2538_rf_process, "cc2538 RF driver");
130 /*---------------------------------------------------------------------------*/
131 uint8_t
133 {
134  uint8_t chan = REG(RFCORE_XREG_FREQCTRL) & RFCORE_XREG_FREQCTRL_FREQ;
135 
136  return ((chan - CC2538_RF_CHANNEL_MIN) / CC2538_RF_CHANNEL_SPACING
137  + CC2538_RF_CHANNEL_MIN);
138 }
139 /*---------------------------------------------------------------------------*/
140 int8_t
141 cc2538_rf_channel_set(uint8_t channel)
142 {
143  PRINTF("RF: Set Channel\n");
144 
145  if((channel < CC2538_RF_CHANNEL_MIN) || (channel > CC2538_RF_CHANNEL_MAX)) {
146  return -1;
147  }
148 
149  /* Changes to FREQCTRL take effect after the next recalibration */
150  off();
151  REG(RFCORE_XREG_FREQCTRL) = (CC2538_RF_CHANNEL_MIN
152  + (channel - CC2538_RF_CHANNEL_MIN) * CC2538_RF_CHANNEL_SPACING);
153  on();
154 
155  return (int8_t) channel;
156 }
157 /*---------------------------------------------------------------------------*/
158 uint8_t
159 cc2538_rf_power_set(uint8_t new_power)
160 {
161  PRINTF("RF: Set Power\n");
162 
163  REG(RFCORE_XREG_TXPOWER) = new_power;
164 
165  return (REG(RFCORE_XREG_TXPOWER) & 0xFF);
166 }
167 /*---------------------------------------------------------------------------*/
168 /* ToDo: Check once we have info on the... infopage */
169 void
170 cc2538_rf_set_addr(uint16_t pan)
171 {
172 #if LINKADDR_SIZE==8
173  /* EXT_ADDR[7:0] is ignored when using short addresses */
174  int i;
175 
176  for(i = (LINKADDR_SIZE - 1); i >= 0; --i) {
177  ((uint32_t *)RFCORE_FFSM_EXT_ADDR0)[i] =
178  linkaddr_node_addr.u8[LINKADDR_SIZE - 1 - i];
179  }
180 #endif
181 
182  REG(RFCORE_FFSM_PAN_ID0) = pan & 0xFF;
183  REG(RFCORE_FFSM_PAN_ID1) = pan >> 8;
184 
185  REG(RFCORE_FFSM_SHORT_ADDR0) = linkaddr_node_addr.u8[LINKADDR_SIZE - 1];
186  REG(RFCORE_FFSM_SHORT_ADDR1) = linkaddr_node_addr.u8[LINKADDR_SIZE - 2];
187 }
188 /*---------------------------------------------------------------------------*/
189 int
191 {
192  int rssi;
193 
194  /* If we are off, turn on first */
196  rf_flags |= WAS_OFF;
197  on();
198  }
199 
200  /* Wait on RSSI_VALID */
202 
203  rssi = ((int8_t)REG(RFCORE_XREG_RSSI)) - RSSI_OFFSET;
204 
205  /* If we were off, turn back off */
206  if((rf_flags & WAS_OFF) == WAS_OFF) {
207  rf_flags &= ~WAS_OFF;
208  off();
209  }
210 
211  return rssi;
212 }
213 /*---------------------------------------------------------------------------*/
214 /* Netstack API radio driver functions */
215 /*---------------------------------------------------------------------------*/
216 static int
217 channel_clear(void)
218 {
219  int cca;
220 
221  PRINTF("RF: CCA\n");
222 
223  /* If we are off, turn on first */
225  rf_flags |= WAS_OFF;
226  on();
227  }
228 
229  /* Wait on RSSI_VALID */
231 
233  cca = CC2538_RF_CCA_CLEAR;
234  } else {
235  cca = CC2538_RF_CCA_BUSY;
236  }
237 
238  /* If we were off, turn back off */
239  if((rf_flags & WAS_OFF) == WAS_OFF) {
240  rf_flags &= ~WAS_OFF;
241  off();
242  }
243 
244  return cca;
245 }
246 /*---------------------------------------------------------------------------*/
247 static int
248 on(void)
249 {
250  PRINTF("RF: On\n");
251 
252  if(!(rf_flags & RX_ACTIVE)) {
255 
256  rf_flags |= RX_ACTIVE;
257  }
258 
259  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
260  return 1;
261 }
262 /*---------------------------------------------------------------------------*/
263 static int
264 off(void)
265 {
266  PRINTF("RF: Off\n");
267 
268  /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */
270 
272 
273  /* Don't turn off if we are off as this will trigger a Strobe Error */
274  if(REG(RFCORE_XREG_RXENABLE) != 0) {
276  }
277 
278  rf_flags &= ~RX_ACTIVE;
279 
280  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
281  return 1;
282 }
283 /*---------------------------------------------------------------------------*/
284 static int
285 init(void)
286 {
287  PRINTF("RF: Init\n");
288 
289  if(rf_flags & RF_ON) {
290  return 0;
291  }
292 
293  /* Enable clock for the RF Core while Running, in Sleep and Deep Sleep */
294  REG(SYS_CTRL_RCGCRFC) = 1;
295  REG(SYS_CTRL_SCGCRFC) = 1;
296  REG(SYS_CTRL_DCGCRFC) = 1;
297 
298  REG(RFCORE_XREG_CCACTRL0) = CC2538_RF_CCA_THRES_USER_GUIDE;
299 
300  /*
301  * Changes from default values
302  * See User Guide, section "Register Settings Update"
303  */
304  REG(RFCORE_XREG_TXFILTCFG) = 0x09; /** TX anti-aliasing filter bandwidth */
305  REG(RFCORE_XREG_AGCCTRL1) = 0x15; /** AGC target value */
306  REG(ANA_REGS_IVCTRL) = 0x0B; /** Bias currents */
307 
308  /*
309  * Defaults:
310  * Auto CRC; Append RSSI, CRC-OK and Corr. Val.; CRC calculation;
311  * RX and TX modes with FIFOs
312  */
314 
315 #if CC2538_RF_AUTOACK
317 #endif
318 
319  /* If we are a sniffer, turn off frame filtering */
320 #if CC2538_RF_CONF_SNIFFER
322 #endif
323 
324  /* Disable source address matching and autopend */
325  REG(RFCORE_XREG_SRCMATCH) = 0;
326 
327  /* MAX FIFOP threshold */
328  REG(RFCORE_XREG_FIFOPCTRL) = CC2538_RF_MAX_PACKET_LEN;
329 
330  cc2538_rf_power_set(CC2538_RF_TX_POWER);
331  cc2538_rf_channel_set(CC2538_RF_CHANNEL);
332 
333  /* Acknowledge RF interrupts, FIFOP only */
336 
337  /* Acknowledge all RF Error interrupts */
340 
342  /* Disable peripheral triggers for the channel */
344 
345  /*
346  * Set the channel's DST. SRC can not be set yet since it will change for
347  * each transfer
348  */
350  }
351 
353  /* Disable peripheral triggers for the channel */
355 
356  /*
357  * Set the channel's SRC. DST can not be set yet since it will change for
358  * each transfer
359  */
361  }
362 
363  process_start(&cc2538_rf_process, NULL);
364 
365  rf_flags |= RF_ON;
366 
367  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
368 
369  return 1;
370 }
371 /*---------------------------------------------------------------------------*/
372 static int
373 prepare(const void *payload, unsigned short payload_len)
374 {
375  uint8_t i;
376 
377  PRINTF("RF: Prepare 0x%02x bytes\n", payload_len + CHECKSUM_LEN);
378 
379  /*
380  * When we transmit in very quick bursts, make sure previous transmission
381  * is not still in progress before re-writing to the TX FIFO
382  */
383  while(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE);
384 
385  if((rf_flags & RX_ACTIVE) == 0) {
386  on();
387  }
388 
390 
391  PRINTF("RF: data = ");
392  /* Send the phy length byte first */
393  REG(RFCORE_SFR_RFDATA) = payload_len + CHECKSUM_LEN;
394 
396  PRINTF("<uDMA payload>");
397 
398  /* Set the transfer source's end address */
400  (uint32_t)(payload) + payload_len - 1);
401 
402  /* Configure the control word */
404  UDMA_TX_FLAGS | udma_xfer_size(payload_len));
405 
406  /* Enabled the RF TX uDMA channel */
408 
409  /* Trigger the uDMA transfer */
411 
412  /*
413  * No need to wait for this to end. Even if transmit() gets called
414  * immediately, the uDMA controller will stream the frame to the TX FIFO
415  * faster than transmit() can empty it
416  */
417  } else {
418  for(i = 0; i < payload_len; i++) {
419  REG(RFCORE_SFR_RFDATA) = ((unsigned char *)(payload))[i];
420  PRINTF("%02x", ((unsigned char *)(payload))[i]);
421  }
422  }
423  PRINTF("\n");
424 
425  return 0;
426 }
427 /*---------------------------------------------------------------------------*/
428 static int
429 transmit(unsigned short transmit_len)
430 {
431  uint8_t counter;
432  int ret = RADIO_TX_ERR;
433  rtimer_clock_t t0;
434 
435  PRINTF("RF: Transmit\n");
436 
437  if(!(rf_flags & RX_ACTIVE)) {
438  t0 = RTIMER_NOW();
439  on();
440  rf_flags |= WAS_OFF;
441  while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ONOFF_TIME));
442  }
443 
444  if(channel_clear() == CC2538_RF_CCA_BUSY) {
445  RIMESTATS_ADD(contentiondrop);
446  return RADIO_TX_COLLISION;
447  }
448 
449  /*
450  * prepare() double checked that TX_ACTIVE is low. If SFD is high we are
451  * receiving. Abort transmission and bail out with RADIO_TX_COLLISION
452  */
454  RIMESTATS_ADD(contentiondrop);
455  return RADIO_TX_COLLISION;
456  }
457 
458  /* Start the transmission */
459  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
460  ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
461 
463 
464  counter = 0;
465  while(!((REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE))
466  && (counter++ < 3)) {
467  clock_delay_usec(6);
468  }
469 
470  if(!(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE)) {
471  PRINTF("RF: TX never active.\n");
473  ret = RADIO_TX_ERR;
474  } else {
475  /* Wait for the transmission to finish */
476  while(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE);
477  ret = RADIO_TX_OK;
478  }
479  ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
480  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
481 
482  if(rf_flags & WAS_OFF) {
483  rf_flags &= ~WAS_OFF;
484  off();
485  }
486 
487  RIMESTATS_ADD(lltx);
488 
489  return ret;
490 }
491 /*---------------------------------------------------------------------------*/
492 static int
493 send(const void *payload, unsigned short payload_len)
494 {
495  prepare(payload, payload_len);
496  return transmit(payload_len);
497 }
498 /*---------------------------------------------------------------------------*/
499 static int
500 read(void *buf, unsigned short bufsize)
501 {
502  uint8_t i;
503  uint8_t len;
504  uint8_t crc_corr;
505  int8_t rssi;
506 
507  PRINTF("RF: Read\n");
508 
510  return 0;
511  }
512 
513  /* Check the length */
514  len = REG(RFCORE_SFR_RFDATA);
515 
516  /* Check for validity */
517  if(len > CC2538_RF_MAX_PACKET_LEN) {
518  /* Oops, we must be out of sync. */
519  PRINTF("RF: bad sync\n");
520 
521  RIMESTATS_ADD(badsynch);
523  return 0;
524  }
525 
526  if(len <= CC2538_RF_MIN_PACKET_LEN) {
527  PRINTF("RF: too short\n");
528 
529  RIMESTATS_ADD(tooshort);
531  return 0;
532  }
533 
534  if(len - CHECKSUM_LEN > bufsize) {
535  PRINTF("RF: too long\n");
536 
537  RIMESTATS_ADD(toolong);
539  return 0;
540  }
541 
542  /* If we reach here, chances are the FIFO is holding a valid frame */
543  PRINTF("RF: read (0x%02x bytes) = ", len);
544  len -= CHECKSUM_LEN;
545 
546  /* Don't bother with uDMA for short frames (e.g. ACKs) */
547  if(CC2538_RF_CONF_RX_USE_DMA && len > UDMA_RX_SIZE_THRESHOLD) {
548  PRINTF("<uDMA payload>");
549 
550  /* Set the transfer destination's end address */
552  (uint32_t)(buf) + len - 1);
553 
554  /* Configure the control word */
556  UDMA_RX_FLAGS | udma_xfer_size(len));
557 
558  /* Enabled the RF RX uDMA channel */
560 
561  /* Trigger the uDMA transfer */
563 
564  /* Wait for the transfer to complete. */
566  } else {
567  for(i = 0; i < len; ++i) {
568  ((unsigned char *)(buf))[i] = REG(RFCORE_SFR_RFDATA);
569  PRINTF("%02x", ((unsigned char *)(buf))[i]);
570  }
571  }
572 
573  /* Read the RSSI and CRC/Corr bytes */
574  rssi = ((int8_t)REG(RFCORE_SFR_RFDATA)) - RSSI_OFFSET;
575  crc_corr = REG(RFCORE_SFR_RFDATA);
576 
577  PRINTF("%02x%02x\n", (uint8_t)rssi, crc_corr);
578 
579  /* MS bit CRC OK/Not OK, 7 LS Bits, Correlation value */
580  if(crc_corr & CRC_BIT_MASK) {
581  packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);
582  packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_corr & LQI_BIT_MASK);
583  RIMESTATS_ADD(llrx);
584  } else {
585  RIMESTATS_ADD(badcrc);
586  PRINTF("RF: Bad CRC\n");
588  return 0;
589  }
590 
591 #if CC2538_RF_CONF_SNIFFER
592  write_byte(magic[0]);
593  write_byte(magic[1]);
594  write_byte(magic[2]);
595  write_byte(magic[3]);
596  write_byte(len + 2);
597  for(i = 0; i < len; ++i) {
598  write_byte(((unsigned char *)(buf))[i]);
599  }
600  write_byte(rssi);
601  write_byte(crc_corr);
602  flush();
603 #endif
604 
605  /* If FIFOP==1 and FIFO==0 then we had a FIFO overflow at some point. */
606  if(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP) {
608  process_poll(&cc2538_rf_process);
609  } else {
611  }
612  }
613 
614  return (len);
615 }
616 /*---------------------------------------------------------------------------*/
617 static int
618 receiving_packet(void)
619 {
620  PRINTF("RF: Receiving\n");
621 
622  /*
623  * SFD high while transmitting and receiving.
624  * TX_ACTIVE high only when transmitting
625  *
626  * FSMSTAT1 & (TX_ACTIVE | SFD) == SFD <=> receiving
627  */
628  return ((REG(RFCORE_XREG_FSMSTAT1)
629  & (RFCORE_XREG_FSMSTAT1_TX_ACTIVE | RFCORE_XREG_FSMSTAT1_SFD))
630  == RFCORE_XREG_FSMSTAT1_SFD);
631 }
632 /*---------------------------------------------------------------------------*/
633 static int
634 pending_packet(void)
635 {
636  PRINTF("RF: Pending\n");
637 
638  return (REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP);
639 }
640 /*---------------------------------------------------------------------------*/
642  init,
643  prepare,
644  transmit,
645  send,
646  read,
650  on,
651  off,
652 };
653 /*---------------------------------------------------------------------------*/
654 /**
655  * \brief Implementation of the cc2538 RF driver process
656  *
657  * This process is started by init(). It simply sits there waiting for
658  * an event. Upon frame reception, the RX ISR will poll this process.
659  * Subsequently, the contiki core will generate an event which will
660  * call this process so that the received frame can be picked up from
661  * the RF RX FIFO
662  *
663  */
664 PROCESS_THREAD(cc2538_rf_process, ev, data)
665 {
666  int len;
667  PROCESS_BEGIN();
668 
669  while(1) {
670  PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
671 
672  packetbuf_clear();
674 
675  if(len > 0) {
677 
678  NETSTACK_RDC.input();
679  }
680 
681  /* If we were polled due to an RF error, reset the transceiver */
682  if(rf_flags & RF_MUST_RESET) {
683  rf_flags = 0;
684 
685  off();
686  init();
687  }
688  }
689 
690  PROCESS_END();
691 }
692 /*---------------------------------------------------------------------------*/
693 /**
694  * \brief The cc2538 RF RX/TX ISR
695  *
696  * This is the interrupt service routine for all RF interrupts relating
697  * to RX and TX. Error conditions are handled by cc2538_rf_err_isr().
698  * Currently, we only acknowledge the FIFOP interrupt source.
699  */
700 void
702 {
703  ENERGEST_ON(ENERGEST_TYPE_IRQ);
704 
705  process_poll(&cc2538_rf_process);
706 
707  /* We only acknowledge FIFOP so we can safely wipe out the entire SFR */
708  REG(RFCORE_SFR_RFIRQF0) = 0;
709 
710  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
711 }
712 /*---------------------------------------------------------------------------*/
713 /**
714  * \brief The cc2538 RF Error ISR
715  *
716  * This is the interrupt service routine for all RF errors. We
717  * acknowledge every error type and instead of trying to be smart and
718  * act differently depending on error condition, we simply reset the
719  * transceiver. RX FIFO overflow is an exception, we ignore this error
720  * since read() handles it anyway.
721  *
722  * However, we don't want to reset within this ISR. If the error occurs
723  * while we are reading a frame out of the FIFO, trashing the FIFO in
724  * the middle of read(), would result in further errors (RX underflows).
725  *
726  * Instead, we set a flag and poll the driver process. The process will
727  * reset the transceiver without any undesirable consequences.
728  */
729 void
731 {
732  ENERGEST_ON(ENERGEST_TYPE_IRQ);
733 
734  PRINTF("RF Error: 0x%08lx\n", REG(RFCORE_SFR_RFERRF));
735 
736  /* If the error is not an RX FIFO overflow, set a flag */
738  rf_flags |= RF_MUST_RESET;
739  }
740 
741  REG(RFCORE_SFR_RFERRF) = 0;
742 
743  process_poll(&cc2538_rf_process);
744 
745  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
746 }
747 /*---------------------------------------------------------------------------*/
748 void
750 {
751  if(p) {
753  } else {
755  }
756 }
757 /*---------------------------------------------------------------------------*/
758 /** @} */