Contiki 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(CC2538_RF_CONF_SNIFFER_UART, 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 /* TX Power dBm lookup table. Values from SmartRF Studio v1.16.0 */
130 typedef struct output_config {
131  radio_value_t power;
132  uint8_t txpower_val;
133 } output_config_t;
134 
135 static const output_config_t output_power[] = {
136  { 7, 0xFF },
137  { 5, 0xED },
138  { 3, 0xD5 },
139  { 1, 0xC5 },
140  { 0, 0xB6 },
141  { -1, 0xB0 },
142  { -3, 0xA1 },
143  { -5, 0x91 },
144  { -7, 0x88 },
145  { -9, 0x72 },
146  {-11, 0x62 },
147  {-13, 0x58 },
148  {-15, 0x42 },
149  {-24, 0x00 },
150 };
151 
152 #define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t))
153 
154 /* Max and Min Output Power in dBm */
155 #define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].power)
156 #define OUTPUT_POWER_MAX (output_power[0].power)
157 /*---------------------------------------------------------------------------*/
158 PROCESS(cc2538_rf_process, "cc2538 RF driver");
159 /*---------------------------------------------------------------------------*/
160 /**
161  * \brief Get the current operating channel
162  * \return Returns a value in [11,26] representing the current channel
163  */
164 static uint8_t
165 get_channel()
166 {
167  uint8_t chan = REG(RFCORE_XREG_FREQCTRL) & RFCORE_XREG_FREQCTRL_FREQ;
168 
169  return ((chan - CC2538_RF_CHANNEL_MIN) / CC2538_RF_CHANNEL_SPACING
170  + CC2538_RF_CHANNEL_MIN);
171 }
172 /*---------------------------------------------------------------------------*/
173 /**
174  * \brief Set the current operating channel
175  * \param channel The desired channel as a value in [11,26]
176  * \return Returns a value in [11,26] representing the current channel
177  * or a negative value if \e channel was out of bounds
178  */
179 static int8_t
180 set_channel(uint8_t channel)
181 {
182  PRINTF("RF: Set Channel\n");
183 
184  if((channel < CC2538_RF_CHANNEL_MIN) || (channel > CC2538_RF_CHANNEL_MAX)) {
185  return CC2538_RF_CHANNEL_SET_ERROR;
186  }
187 
188  /* Changes to FREQCTRL take effect after the next recalibration */
189  off();
190  REG(RFCORE_XREG_FREQCTRL) = (CC2538_RF_CHANNEL_MIN
191  + (channel - CC2538_RF_CHANNEL_MIN) * CC2538_RF_CHANNEL_SPACING);
192  on();
193 
194  return (int8_t) channel;
195 }
196 /*---------------------------------------------------------------------------*/
197 static radio_value_t
198 get_pan_id(void)
199 {
200  return (radio_value_t)(REG(RFCORE_FFSM_PAN_ID1) << 8 | REG(RFCORE_FFSM_PAN_ID0));
201 }
202 /*---------------------------------------------------------------------------*/
203 static void
204 set_pan_id(uint16_t pan)
205 {
206  REG(RFCORE_FFSM_PAN_ID0) = pan & 0xFF;
207  REG(RFCORE_FFSM_PAN_ID1) = pan >> 8;
208 }
209 /*---------------------------------------------------------------------------*/
210 static radio_value_t
211 get_short_addr(void)
212 {
214 }
215 /*---------------------------------------------------------------------------*/
216 static void
217 set_short_addr(uint16_t addr)
218 {
219  REG(RFCORE_FFSM_SHORT_ADDR0) = addr & 0xFF;
220  REG(RFCORE_FFSM_SHORT_ADDR1) = addr >> 8;
221 }
222 /*---------------------------------------------------------------------------*/
223 /**
224  * \brief Reads the current signal strength (RSSI)
225  * \return The current RSSI in dBm
226  *
227  * This function reads the current RSSI on the currently configured
228  * channel.
229  */
230 static radio_value_t
231 get_rssi(void)
232 {
233  int8_t rssi;
234 
235  /* If we are off, turn on first */
237  rf_flags |= WAS_OFF;
238  on();
239  }
240 
241  /* Wait on RSSI_VALID */
243 
244  rssi = (int8_t)(REG(RFCORE_XREG_RSSI) & RFCORE_XREG_RSSI_RSSI_VAL) - RSSI_OFFSET;
245 
246  /* If we were off, turn back off */
247  if((rf_flags & WAS_OFF) == WAS_OFF) {
248  rf_flags &= ~WAS_OFF;
249  off();
250  }
251 
252  return rssi;
253 }
254 /*---------------------------------------------------------------------------*/
255 /* Returns the current CCA threshold in dBm */
256 static radio_value_t
257 get_cca_threshold(void)
258 {
259  return (int8_t)(REG(RFCORE_XREG_CCACTRL0) & RFCORE_XREG_CCACTRL0_CCA_THR) - RSSI_OFFSET;
260 }
261 /*---------------------------------------------------------------------------*/
262 /* Sets the CCA threshold in dBm */
263 static void
264 set_cca_threshold(radio_value_t value)
265 {
266  REG(RFCORE_XREG_CCACTRL0) = (value & 0xFF) + RSSI_OFFSET;
267 }
268 /*---------------------------------------------------------------------------*/
269 /* Returns the current TX power in dBm */
270 static radio_value_t
271 get_tx_power(void)
272 {
273  int i;
274  uint8_t reg_val = REG(RFCORE_XREG_TXPOWER) & 0xFF;
275 
276  /*
277  * Find the TXPOWER value in the lookup table
278  * If the value has been written with set_tx_power, we should be able to
279  * find the exact value. However, in case the register has been written in
280  * a different fashion, we return the immediately lower value of the lookup
281  */
282  for(i = 0; i < OUTPUT_CONFIG_COUNT; i++) {
283  if(reg_val >= output_power[i].txpower_val) {
284  return output_power[i].power;
285  }
286  }
287  return OUTPUT_POWER_MIN;
288 }
289 /*---------------------------------------------------------------------------*/
290 /*
291  * Set TX power to 'at least' power dBm
292  * This works with a lookup table. If the value of 'power' does not exist in
293  * the lookup table, TXPOWER will be set to the immediately higher available
294  * value
295  */
296 static void
297 set_tx_power(radio_value_t power)
298 {
299  int i;
300 
301  for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) {
302  if(power <= output_power[i].power) {
303  REG(RFCORE_XREG_TXPOWER) = output_power[i].txpower_val;
304  return;
305  }
306  }
307 }
308 /*---------------------------------------------------------------------------*/
309 static void
310 set_frame_filtering(uint8_t enable)
311 {
312  if(enable) {
314  } else {
316  }
317 }
318 /*---------------------------------------------------------------------------*/
319 static void
320 set_auto_ack(uint8_t enable)
321 {
322  if(enable) {
324  } else {
326  }
327 }
328 /*---------------------------------------------------------------------------*/
329 /* Netstack API radio driver functions */
330 /*---------------------------------------------------------------------------*/
331 static int
332 channel_clear(void)
333 {
334  int cca;
335 
336  PRINTF("RF: CCA\n");
337 
338  /* If we are off, turn on first */
339  if((REG(RFCORE_XREG_FSMSTAT0) & RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE) == 0) {
340  rf_flags |= WAS_OFF;
341  on();
342  }
343 
344  /* Wait on RSSI_VALID */
345  while((REG(RFCORE_XREG_RSSISTAT) & RFCORE_XREG_RSSISTAT_RSSI_VALID) == 0);
346 
348  cca = CC2538_RF_CCA_CLEAR;
349  } else {
350  cca = CC2538_RF_CCA_BUSY;
351  }
352 
353  /* If we were off, turn back off */
354  if((rf_flags & WAS_OFF) == WAS_OFF) {
355  rf_flags &= ~WAS_OFF;
356  off();
357  }
358 
359  return cca;
360 }
361 /*---------------------------------------------------------------------------*/
362 static int
363 on(void)
364 {
365  PRINTF("RF: On\n");
366 
367  if(!(rf_flags & RX_ACTIVE)) {
370 
371  rf_flags |= RX_ACTIVE;
372  }
373 
374  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
375  return 1;
376 }
377 /*---------------------------------------------------------------------------*/
378 static int
379 off(void)
380 {
381  PRINTF("RF: Off\n");
382 
383  /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */
385 
387 
388  /* Don't turn off if we are off as this will trigger a Strobe Error */
389  if(REG(RFCORE_XREG_RXENABLE) != 0) {
391  }
392 
393  rf_flags &= ~RX_ACTIVE;
394 
395  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
396  return 1;
397 }
398 /*---------------------------------------------------------------------------*/
399 static int
400 init(void)
401 {
402  PRINTF("RF: Init\n");
403 
404  if(rf_flags & RF_ON) {
405  return 0;
406  }
407 
408  /* Enable clock for the RF Core while Running, in Sleep and Deep Sleep */
409  REG(SYS_CTRL_RCGCRFC) = 1;
410  REG(SYS_CTRL_SCGCRFC) = 1;
411  REG(SYS_CTRL_DCGCRFC) = 1;
412 
413  REG(RFCORE_XREG_CCACTRL0) = CC2538_RF_CCA_THRES_USER_GUIDE;
414 
415  /*
416  * Changes from default values
417  * See User Guide, section "Register Settings Update"
418  */
419  REG(RFCORE_XREG_TXFILTCFG) = 0x09; /** TX anti-aliasing filter bandwidth */
420  REG(RFCORE_XREG_AGCCTRL1) = 0x15; /** AGC target value */
421  REG(ANA_REGS_IVCTRL) = 0x0B; /** Bias currents */
422 
423  /*
424  * Defaults:
425  * Auto CRC; Append RSSI, CRC-OK and Corr. Val.; CRC calculation;
426  * RX and TX modes with FIFOs
427  */
429 
430 #if CC2538_RF_AUTOACK
432 #endif
433 
434  /* If we are a sniffer, turn off frame filtering */
435 #if CC2538_RF_CONF_SNIFFER
437 #endif
438 
439  /* Disable source address matching and autopend */
440  REG(RFCORE_XREG_SRCMATCH) = 0;
441 
442  /* MAX FIFOP threshold */
443  REG(RFCORE_XREG_FIFOPCTRL) = CC2538_RF_MAX_PACKET_LEN;
444 
445  /* Set TX Power */
446  REG(RFCORE_XREG_TXPOWER) = CC2538_RF_TX_POWER;
447 
448  set_channel(CC2538_RF_CHANNEL);
449 
450  /* Acknowledge RF interrupts, FIFOP only */
453 
454  /* Acknowledge all RF Error interrupts */
457 
459  /* Disable peripheral triggers for the channel */
461 
462  /*
463  * Set the channel's DST. SRC can not be set yet since it will change for
464  * each transfer
465  */
467  }
468 
470  /* Disable peripheral triggers for the channel */
472 
473  /*
474  * Set the channel's SRC. DST can not be set yet since it will change for
475  * each transfer
476  */
478  }
479 
480  process_start(&cc2538_rf_process, NULL);
481 
482  rf_flags |= RF_ON;
483 
484  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
485 
486  return 1;
487 }
488 /*---------------------------------------------------------------------------*/
489 static int
490 prepare(const void *payload, unsigned short payload_len)
491 {
492  uint8_t i;
493 
494  PRINTF("RF: Prepare 0x%02x bytes\n", payload_len + CHECKSUM_LEN);
495 
496  /*
497  * When we transmit in very quick bursts, make sure previous transmission
498  * is not still in progress before re-writing to the TX FIFO
499  */
500  while(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE);
501 
502  if((rf_flags & RX_ACTIVE) == 0) {
503  on();
504  }
505 
507 
508  PRINTF("RF: data = ");
509  /* Send the phy length byte first */
510  REG(RFCORE_SFR_RFDATA) = payload_len + CHECKSUM_LEN;
511 
513  PRINTF("<uDMA payload>");
514 
515  /* Set the transfer source's end address */
517  (uint32_t)(payload) + payload_len - 1);
518 
519  /* Configure the control word */
521  UDMA_TX_FLAGS | udma_xfer_size(payload_len));
522 
523  /* Enabled the RF TX uDMA channel */
525 
526  /* Trigger the uDMA transfer */
528 
529  /*
530  * No need to wait for this to end. Even if transmit() gets called
531  * immediately, the uDMA controller will stream the frame to the TX FIFO
532  * faster than transmit() can empty it
533  */
534  } else {
535  for(i = 0; i < payload_len; i++) {
536  REG(RFCORE_SFR_RFDATA) = ((unsigned char *)(payload))[i];
537  PRINTF("%02x", ((unsigned char *)(payload))[i]);
538  }
539  }
540  PRINTF("\n");
541 
542  return 0;
543 }
544 /*---------------------------------------------------------------------------*/
545 static int
546 transmit(unsigned short transmit_len)
547 {
548  uint8_t counter;
549  int ret = RADIO_TX_ERR;
550  rtimer_clock_t t0;
551 
552  PRINTF("RF: Transmit\n");
553 
554  if(!(rf_flags & RX_ACTIVE)) {
555  t0 = RTIMER_NOW();
556  on();
557  rf_flags |= WAS_OFF;
558  while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ONOFF_TIME));
559  }
560 
561  if(channel_clear() == CC2538_RF_CCA_BUSY) {
562  RIMESTATS_ADD(contentiondrop);
563  return RADIO_TX_COLLISION;
564  }
565 
566  /*
567  * prepare() double checked that TX_ACTIVE is low. If SFD is high we are
568  * receiving. Abort transmission and bail out with RADIO_TX_COLLISION
569  */
571  RIMESTATS_ADD(contentiondrop);
572  return RADIO_TX_COLLISION;
573  }
574 
575  /* Start the transmission */
576  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
577  ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
578 
580 
581  counter = 0;
582  while(!((REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE))
583  && (counter++ < 3)) {
584  clock_delay_usec(6);
585  }
586 
587  if(!(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE)) {
588  PRINTF("RF: TX never active.\n");
590  ret = RADIO_TX_ERR;
591  } else {
592  /* Wait for the transmission to finish */
593  while(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE);
594  ret = RADIO_TX_OK;
595  }
596  ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
597  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
598 
599  if(rf_flags & WAS_OFF) {
600  rf_flags &= ~WAS_OFF;
601  off();
602  }
603 
604  RIMESTATS_ADD(lltx);
605 
606  return ret;
607 }
608 /*---------------------------------------------------------------------------*/
609 static int
610 send(const void *payload, unsigned short payload_len)
611 {
612  prepare(payload, payload_len);
613  return transmit(payload_len);
614 }
615 /*---------------------------------------------------------------------------*/
616 static int
617 read(void *buf, unsigned short bufsize)
618 {
619  uint8_t i;
620  uint8_t len;
621  uint8_t crc_corr;
622  int8_t rssi;
623 
624  PRINTF("RF: Read\n");
625 
627  return 0;
628  }
629 
630  /* Check the length */
631  len = REG(RFCORE_SFR_RFDATA);
632 
633  /* Check for validity */
634  if(len > CC2538_RF_MAX_PACKET_LEN) {
635  /* Oops, we must be out of sync. */
636  PRINTF("RF: bad sync\n");
637 
638  RIMESTATS_ADD(badsynch);
640  return 0;
641  }
642 
643  if(len <= CC2538_RF_MIN_PACKET_LEN) {
644  PRINTF("RF: too short\n");
645 
646  RIMESTATS_ADD(tooshort);
648  return 0;
649  }
650 
651  if(len - CHECKSUM_LEN > bufsize) {
652  PRINTF("RF: too long\n");
653 
654  RIMESTATS_ADD(toolong);
656  return 0;
657  }
658 
659  /* If we reach here, chances are the FIFO is holding a valid frame */
660  PRINTF("RF: read (0x%02x bytes) = ", len);
661  len -= CHECKSUM_LEN;
662 
663  /* Don't bother with uDMA for short frames (e.g. ACKs) */
664  if(CC2538_RF_CONF_RX_USE_DMA && len > UDMA_RX_SIZE_THRESHOLD) {
665  PRINTF("<uDMA payload>");
666 
667  /* Set the transfer destination's end address */
669  (uint32_t)(buf) + len - 1);
670 
671  /* Configure the control word */
673  UDMA_RX_FLAGS | udma_xfer_size(len));
674 
675  /* Enabled the RF RX uDMA channel */
677 
678  /* Trigger the uDMA transfer */
680 
681  /* Wait for the transfer to complete. */
683  } else {
684  for(i = 0; i < len; ++i) {
685  ((unsigned char *)(buf))[i] = REG(RFCORE_SFR_RFDATA);
686  PRINTF("%02x", ((unsigned char *)(buf))[i]);
687  }
688  }
689 
690  /* Read the RSSI and CRC/Corr bytes */
691  rssi = ((int8_t)REG(RFCORE_SFR_RFDATA)) - RSSI_OFFSET;
692  crc_corr = REG(RFCORE_SFR_RFDATA);
693 
694  PRINTF("%02x%02x\n", (uint8_t)rssi, crc_corr);
695 
696  /* MS bit CRC OK/Not OK, 7 LS Bits, Correlation value */
697  if(crc_corr & CRC_BIT_MASK) {
698  packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);
699  packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_corr & LQI_BIT_MASK);
700  RIMESTATS_ADD(llrx);
701  } else {
702  RIMESTATS_ADD(badcrc);
703  PRINTF("RF: Bad CRC\n");
705  return 0;
706  }
707 
708 #if CC2538_RF_CONF_SNIFFER
709  write_byte(magic[0]);
710  write_byte(magic[1]);
711  write_byte(magic[2]);
712  write_byte(magic[3]);
713  write_byte(len + 2);
714  for(i = 0; i < len; ++i) {
715  write_byte(((unsigned char *)(buf))[i]);
716  }
717  write_byte(rssi);
718  write_byte(crc_corr);
719  flush();
720 #endif
721 
722  /* If FIFOP==1 and FIFO==0 then we had a FIFO overflow at some point. */
723  if(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP) {
725  process_poll(&cc2538_rf_process);
726  } else {
728  }
729  }
730 
731  return (len);
732 }
733 /*---------------------------------------------------------------------------*/
734 static int
735 receiving_packet(void)
736 {
737  PRINTF("RF: Receiving\n");
738 
739  /*
740  * SFD high while transmitting and receiving.
741  * TX_ACTIVE high only when transmitting
742  *
743  * FSMSTAT1 & (TX_ACTIVE | SFD) == SFD <=> receiving
744  */
745  return ((REG(RFCORE_XREG_FSMSTAT1)
746  & (RFCORE_XREG_FSMSTAT1_TX_ACTIVE | RFCORE_XREG_FSMSTAT1_SFD))
747  == RFCORE_XREG_FSMSTAT1_SFD);
748 }
749 /*---------------------------------------------------------------------------*/
750 static int
751 pending_packet(void)
752 {
753  PRINTF("RF: Pending\n");
754 
755  return (REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP);
756 }
757 /*---------------------------------------------------------------------------*/
758 static radio_result_t
759 get_value(radio_param_t param, radio_value_t *value)
760 {
761  if(!value) {
762  return RADIO_RESULT_INVALID_VALUE;
763  }
764 
765  switch(param) {
766  case RADIO_PARAM_POWER_MODE:
768  ? RADIO_POWER_MODE_OFF : RADIO_POWER_MODE_ON;
769  return RADIO_RESULT_OK;
770  case RADIO_PARAM_CHANNEL:
771  *value = (radio_value_t)get_channel();
772  return RADIO_RESULT_OK;
773  case RADIO_PARAM_PAN_ID:
774  *value = get_pan_id();
775  return RADIO_RESULT_OK;
776  case RADIO_PARAM_16BIT_ADDR:
777  *value = get_short_addr();
778  return RADIO_RESULT_OK;
779  case RADIO_PARAM_RX_MODE:
780  *value = 0;
783  }
785  *value |= RADIO_RX_MODE_AUTOACK;
786  }
787  return RADIO_RESULT_OK;
788  case RADIO_PARAM_TXPOWER:
789  *value = get_tx_power();
790  return RADIO_RESULT_OK;
791  case RADIO_PARAM_CCA_THRESHOLD:
792  *value = get_cca_threshold();
793  return RADIO_RESULT_OK;
794  case RADIO_PARAM_RSSI:
795  *value = get_rssi();
796  return RADIO_RESULT_OK;
797  case RADIO_CONST_CHANNEL_MIN:
798  *value = CC2538_RF_CHANNEL_MIN;
799  return RADIO_RESULT_OK;
800  case RADIO_CONST_CHANNEL_MAX:
801  *value = CC2538_RF_CHANNEL_MAX;
802  return RADIO_RESULT_OK;
803  case RADIO_CONST_TXPOWER_MIN:
804  *value = OUTPUT_POWER_MIN;
805  return RADIO_RESULT_OK;
806  case RADIO_CONST_TXPOWER_MAX:
807  *value = OUTPUT_POWER_MAX;
808  return RADIO_RESULT_OK;
809  default:
810  return RADIO_RESULT_NOT_SUPPORTED;
811  }
812 }
813 /*---------------------------------------------------------------------------*/
814 static radio_result_t
815 set_value(radio_param_t param, radio_value_t value)
816 {
817  switch(param) {
818  case RADIO_PARAM_POWER_MODE:
819  if(value == RADIO_POWER_MODE_ON) {
820  on();
821  return RADIO_RESULT_OK;
822  }
823  if(value == RADIO_POWER_MODE_OFF) {
824  off();
825  return RADIO_RESULT_OK;
826  }
827  return RADIO_RESULT_INVALID_VALUE;
828  case RADIO_PARAM_CHANNEL:
829  if(value < CC2538_RF_CHANNEL_MIN ||
830  value > CC2538_RF_CHANNEL_MAX) {
831  return RADIO_RESULT_INVALID_VALUE;
832  }
833  if(set_channel(value) == CC2538_RF_CHANNEL_SET_ERROR) {
834  return RADIO_RESULT_ERROR;
835  }
836  return RADIO_RESULT_OK;
837  case RADIO_PARAM_PAN_ID:
838  set_pan_id(value & 0xffff);
839  return RADIO_RESULT_OK;
840  case RADIO_PARAM_16BIT_ADDR:
841  set_short_addr(value & 0xffff);
842  return RADIO_RESULT_OK;
843  case RADIO_PARAM_RX_MODE:
844  if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER |
845  RADIO_RX_MODE_AUTOACK)) {
846  return RADIO_RESULT_INVALID_VALUE;
847  }
848 
849  set_frame_filtering((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0);
850  set_auto_ack((value & RADIO_RX_MODE_AUTOACK) != 0);
851 
852  return RADIO_RESULT_OK;
853  case RADIO_PARAM_TXPOWER:
854  if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) {
855  return RADIO_RESULT_INVALID_VALUE;
856  }
857 
858  set_tx_power(value);
859  return RADIO_RESULT_OK;
860  case RADIO_PARAM_CCA_THRESHOLD:
861  set_cca_threshold(value);
862  return RADIO_RESULT_OK;
863  default:
864  return RADIO_RESULT_NOT_SUPPORTED;
865  }
866 }
867 /*---------------------------------------------------------------------------*/
868 static radio_result_t
869 get_object(radio_param_t param, void *dest, size_t size)
870 {
871  uint8_t *target;
872  int i;
873 
874  if(param == RADIO_PARAM_64BIT_ADDR) {
875  if(size != 8 || !dest) {
876  return RADIO_RESULT_INVALID_VALUE;
877  }
878 
879  target = dest;
880  for(i = 0; i < 8; i++) {
881  target[i] = ((uint32_t *)RFCORE_FFSM_EXT_ADDR0)[7 - i] & 0xFF;
882  }
883 
884  return RADIO_RESULT_OK;
885  }
886  return RADIO_RESULT_NOT_SUPPORTED;
887 }
888 /*---------------------------------------------------------------------------*/
889 static radio_result_t
890 set_object(radio_param_t param, const void *src, size_t size)
891 {
892  int i;
893 
894  if(param == RADIO_PARAM_64BIT_ADDR) {
895  if(size != 8 || !src) {
896  return RADIO_RESULT_INVALID_VALUE;
897  }
898 
899  for(i = 0; i < 8; i++) {
900  ((uint32_t *)RFCORE_FFSM_EXT_ADDR0)[i] = ((uint8_t *)src)[7 - i];
901  }
902 
903  return RADIO_RESULT_OK;
904  }
905  return RADIO_RESULT_NOT_SUPPORTED;
906 }
907 /*---------------------------------------------------------------------------*/
909  init,
910  prepare,
911  transmit,
912  send,
913  read,
917  on,
918  off,
919  get_value,
920  set_value,
921  get_object,
922  set_object
923 };
924 /*---------------------------------------------------------------------------*/
925 /**
926  * \brief Implementation of the cc2538 RF driver process
927  *
928  * This process is started by init(). It simply sits there waiting for
929  * an event. Upon frame reception, the RX ISR will poll this process.
930  * Subsequently, the contiki core will generate an event which will
931  * call this process so that the received frame can be picked up from
932  * the RF RX FIFO
933  *
934  */
935 PROCESS_THREAD(cc2538_rf_process, ev, data)
936 {
937  int len;
938  PROCESS_BEGIN();
939 
940  while(1) {
941  PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
942 
943  packetbuf_clear();
945 
946  if(len > 0) {
948 
949  NETSTACK_RDC.input();
950  }
951 
952  /* If we were polled due to an RF error, reset the transceiver */
953  if(rf_flags & RF_MUST_RESET) {
954  rf_flags = 0;
955 
956  off();
957  init();
958  }
959  }
960 
961  PROCESS_END();
962 }
963 /*---------------------------------------------------------------------------*/
964 /**
965  * \brief The cc2538 RF RX/TX ISR
966  *
967  * This is the interrupt service routine for all RF interrupts relating
968  * to RX and TX. Error conditions are handled by cc2538_rf_err_isr().
969  * Currently, we only acknowledge the FIFOP interrupt source.
970  */
971 void
973 {
974  ENERGEST_ON(ENERGEST_TYPE_IRQ);
975 
976  process_poll(&cc2538_rf_process);
977 
978  /* We only acknowledge FIFOP so we can safely wipe out the entire SFR */
979  REG(RFCORE_SFR_RFIRQF0) = 0;
980 
981  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
982 }
983 /*---------------------------------------------------------------------------*/
984 /**
985  * \brief The cc2538 RF Error ISR
986  *
987  * This is the interrupt service routine for all RF errors. We
988  * acknowledge every error type and instead of trying to be smart and
989  * act differently depending on error condition, we simply reset the
990  * transceiver. RX FIFO overflow is an exception, we ignore this error
991  * since read() handles it anyway.
992  *
993  * However, we don't want to reset within this ISR. If the error occurs
994  * while we are reading a frame out of the FIFO, trashing the FIFO in
995  * the middle of read(), would result in further errors (RX underflows).
996  *
997  * Instead, we set a flag and poll the driver process. The process will
998  * reset the transceiver without any undesirable consequences.
999  */
1000 void
1002 {
1003  ENERGEST_ON(ENERGEST_TYPE_IRQ);
1004 
1005  PRINTF("RF Error: 0x%08lx\n", REG(RFCORE_SFR_RFERRF));
1006 
1007  /* If the error is not an RX FIFO overflow, set a flag */
1009  rf_flags |= RF_MUST_RESET;
1010  }
1011 
1012  REG(RFCORE_SFR_RFERRF) = 0;
1013 
1014  process_poll(&cc2538_rf_process);
1015 
1016  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
1017 }
1018 /*---------------------------------------------------------------------------*/
1019 void
1021 {
1022  set_frame_filtering(p);
1023 }
1024 /*---------------------------------------------------------------------------*/
1025 /** @} */
uint8_t udma_channel_get_mode(uint8_t channel)
Retrieve the current mode for a channel.
Definition: udma.c:235
#define RFCORE_XREG_RSSI_RSSI_VAL
RSSI estimate.
Definition: rfcore-xreg.h:320
#define RADIO_RX_MODE_ADDRESS_FILTER
The radio reception mode controls address filtering and automatic transmission of acknowledgements in...
Definition: radio.h:193
#define RFCORE_XREG_RSSISTAT_RSSI_VALID
RSSI value is valid.
Definition: rfcore-xreg.h:327
#define RFCORE_XREG_CCACTRL0
CCA threshold.
Definition: rfcore-xreg.h:66
void process_poll(struct process *p)
Request a process to be polled.
Definition: process.c:371
void udma_channel_sw_request(uint8_t channel)
Generate a software trigger to start a transfer.
Definition: udma.c:225
#define RFCORE_XREG_RFERRM_RFERRM
RF error interrupt mask.
Definition: rfcore-xreg.h:393
#define RFCORE_XREG_CCACTRL0_CCA_THR
Clear-channel-assessment.
Definition: rfcore-xreg.h:307
#define RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN
Enables frame filtering.
Definition: rfcore-xreg.h:149
#define RFCORE_XREG_RSSI
RSSI status register.
Definition: rfcore-xreg.h:68
#define RFCORE_XREG_RFERRM
RF error interrupt mask.
Definition: rfcore-xreg.h:81
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
void clock_delay_usec(uint16_t dt)
Delay a given number of microseconds.
Definition: clock.c:94
Header file for the radio API
#define RFCORE_SFR_RFERRF_RXOVERF
RX FIFO overflowed.
Definition: rfcore-sfr.h:140
#define CC2538_RF_CONF_RX_DMA_CHAN
RAM -&gt; RF DMA channel.
Definition: contiki-conf.h:127
#define RFCORE_SFR_RFIRQF0
RF interrupt flags.
Definition: rfcore-sfr.h:63
#define RFCORE_XREG_TXFILTCFG
TX filter configuration.
Definition: rfcore-xreg.h:141
Header file for the Rime buffer (packetbuf) management
#define RFCORE_XREG_RFIRQM0_FIFOP
RX FIFO exceeded threshold.
Definition: rfcore-xreg.h:373
void udma_set_channel_src(uint8_t channel, uint32_t src_end)
Sets the channels source address.
Definition: udma.c:70
void cc2538_rf_set_promiscous_mode(char p)
Turn promiscous mode on or off.
Definition: cc2538-rf.c:1020
#define NVIC_INT_RF_ERR
RF Core Error.
Definition: nvic.h:101
#define NULL
The null pointer.
The structure of a device driver for a radio in Contiki.
Definition: radio.h:225
#define SYS_CTRL_DCGCRFC
RF Core clocks - PM0.
Definition: sys-ctrl.h:93
#define CC2538_RF_CSP_ISTXON()
Send a TX ON command strobe to the CSP.
Definition: cc2538-rf.h:108
int(* pending_packet)(void)
Check if the radio driver has just received a packet.
Definition: radio.h:249
Header file with register, macro and function declarations for the cc2538 micro-DMA controller module...
#define RFCORE_XREG_FIFOPCTRL
FIFOP threshold.
Definition: rfcore-xreg.h:64
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio...
Definition: radio.h:88
#define RFCORE_XREG_FRMCTRL0
Frame handling.
Definition: rfcore-xreg.h:53
void nvic_interrupt_enable(uint32_t intr)
Enables interrupt intr.
Definition: nvic.c:64
struct radio_driver cc2538_rf_driver
The NETSTACK data structure for the cc2538 RF driver.
Definition: cc2538-rf.c:908
void cc2538_rf_rx_tx_isr(void)
The cc2538 RF RX/TX ISR.
Definition: cc2538-rf.c:972
int(* prepare)(const void *payload, unsigned short payload_len)
Prepare the radio with a packet to be sent.
Definition: radio.h:230
#define RFCORE_XREG_RSSISTAT
RSSI valid status register.
Definition: rfcore-xreg.h:69
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
Definition: packetbuf.c:200
void udma_channel_enable(uint8_t channel)
Enables a uDMA channel.
Definition: udma.c:120
#define SYS_CTRL_SCGCRFC
RF Core clocks - Sleep mode.
Definition: sys-ctrl.h:92
int(* send)(const void *payload, unsigned short payload_len)
Prepare &amp; transmit a packet.
Definition: radio.h:236
#define RFCORE_XREG_FRMCTRL0_AUTOACK
Transmit ACK frame enable.
Definition: rfcore-xreg.h:211
int(* receiving_packet)(void)
Check if the radio driver is currently receiving a packet.
Definition: radio.h:246
#define RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE
FIFO and FFCTRL status.
Definition: rfcore-xreg.h:275
Header file with register manipulation macro definitions.
Header file for the energy estimation mechanism
#define CC2538_RF_CSP_ISRXON()
Send an RX ON command strobe to the CSP.
Definition: cc2538-rf.h:102
#define RFCORE_XREG_RXENABLE
RX enabling.
Definition: rfcore-xreg.h:55
#define RFCORE_XREG_RFIRQM0
RF interrupt masks.
Definition: rfcore-xreg.h:79
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition: process.h:273
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
int(* channel_clear)(void)
Perform a Clear-Channel Assessment (CCA) to find out if there is a packet in the air or not...
Definition: radio.h:243
#define RFCORE_FFSM_PAN_ID1
Local address information.
Definition: rfcore-ffsm.h:63
Header file for the cc2538 System Control driver.
Header file for the real-time timer module.
#define RFCORE_XREG_FSMSTAT1_TX_ACTIVE
Status signal - TX states.
Definition: rfcore-xreg.h:287
#define RFCORE_XREG_FSMSTAT1
Radio status register.
Definition: rfcore-xreg.h:63
int(* on)(void)
Turn the radio on.
Definition: radio.h:252
#define NVIC_INT_RF_RXTX
RF Core Rx/Tx.
Definition: nvic.h:100
#define RFCORE_XREG_RXENABLE_RXENMASK
Enables the receiver.
Definition: rfcore-xreg.h:228
#define RFCORE_FFSM_PAN_ID0
Local address information.
Definition: rfcore-ffsm.h:62
void udma_set_channel_dst(uint8_t channel, uint32_t dst_end)
Definition: udma.c:80
radio_result_t(* get_value)(radio_param_t param, radio_value_t *value)
Get a radio parameter value.
Definition: radio.h:258
#define RFCORE_FFSM_SHORT_ADDR1
Local address information.
Definition: rfcore-ffsm.h:65
void udma_channel_mask_set(uint8_t channel)
Disable peripheral triggers for a uDMA channel.
Definition: udma.c:204
#define RFCORE_XREG_AGCCTRL1
AGC reference level.
Definition: rfcore-xreg.h:93
void udma_set_channel_control_word(uint8_t channel, uint32_t ctrl)
Configure the channel&#39;s control word.
Definition: udma.c:90
#define RFCORE_XREG_FRMCTRL0_AUTOCRC
Auto CRC generation / checking.
Definition: rfcore-xreg.h:210
#define RFCORE_XREG_FSMSTAT1_FIFO
FIFO status.
Definition: rfcore-xreg.h:281
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
Definition: radio.h:268
#define RFCORE_XREG_FSMSTAT1_SFD
SFD was sent/received.
Definition: rfcore-xreg.h:283
#define CC2538_RF_CSP_ISFLUSHRX()
Flush the RX FIFO.
Definition: cc2538-rf.h:120
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
int(* transmit)(unsigned short transmit_len)
Send the packet that has previously been prepared.
Definition: radio.h:233
#define CC2538_RF_CONF_RX_USE_DMA
RF RX over DMA.
Definition: contiki-conf.h:406
#define RFCORE_SFR_RFDATA
TX/RX FIFO data.
Definition: rfcore-sfr.h:60
void packetbuf_clear(void)
Clear and reset the packetbuf.
Definition: packetbuf.c:77
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
#define RFCORE_FFSM_EXT_ADDR0
Local address information.
Definition: rfcore-ffsm.h:54
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:133
Top-level header file for cc2538 RF Core registers.
#define CC2538_RF_CSP_ISFLUSHTX()
Flush the TX FIFO.
Definition: cc2538-rf.h:128
#define RFCORE_XREG_FRMFILT0
Frame filtering control.
Definition: rfcore-xreg.h:44
#define SYS_CTRL_RCGCRFC
RF Core clocks - active mode.
Definition: sys-ctrl.h:91
#define RFCORE_FFSM_SHORT_ADDR0
Local address information.
Definition: rfcore-ffsm.h:64
#define RFCORE_XREG_TXPOWER
Controls the output power.
Definition: rfcore-xreg.h:60
#define CC2538_RF_CSP_ISRFOFF()
Send a RF OFF command strobe to the CSP.
Definition: cc2538-rf.h:114
Header file for the cc2538 RF driver.
#define RFCORE_SFR_RFERRF
RF error interrupt flags.
Definition: rfcore-sfr.h:61
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
Definition: packetbuf.h:65
#define RFCORE_XREG_FREQCTRL_FREQ
Frequency control word.
Definition: rfcore-xreg.h:252
#define RFCORE_XREG_FREQCTRL
Controls the RF frequency.
Definition: rfcore-xreg.h:59
Header file for Rime statistics
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
Definition: packetbuf.c:207
void cc2538_rf_err_isr(void)
The cc2538 RF Error ISR.
Definition: cc2538-rf.c:1001
Header file for cc2538&#39;s UART-like I/O over USB.
#define udma_xfer_size(len)
Calculate the value of the xfersize field in the control structure.
Definition: udma.h:696
radio_result_t(* set_object)(radio_param_t param, const void *src, size_t size)
Set a radio parameter object.
Definition: radio.h:274
#define RFCORE_XREG_SRCMATCH
Source address matching.
Definition: rfcore-xreg.h:46
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
Definition: process.h:178
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
Definition: radio.h:261
#define CC2538_RF_CONF_TX_USE_DMA
RF TX over DMA.
Definition: contiki-conf.h:402
#define RFCORE_XREG_FSMSTAT1_FIFOP
FIFOP status.
Definition: rfcore-xreg.h:282
#define RFCORE_XREG_FSMSTAT0
Radio status register.
Definition: rfcore-xreg.h:62
int(* read)(void *buf, unsigned short buf_len)
Read a received packet into a buffer.
Definition: radio.h:239
int(* off)(void)
Turn the radio off.
Definition: radio.h:255
Include file for the Contiki low-layer network stack (NETSTACK)
#define RFCORE_XREG_FSMSTAT1_CCA
Clear channel assessment.
Definition: rfcore-xreg.h:284
Header file for the Rime address representation
#define CC2538_RF_CONF_TX_DMA_CHAN
RF -&gt; RAM DMA channel.
Definition: contiki-conf.h:126