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 RF_ON 0x01
84 
85 /* Bit Masks for the last byte in the RX FIFO */
86 #define CRC_BIT_MASK 0x80
87 #define LQI_BIT_MASK 0x7F
88 /* RSSI Offset */
89 #define RSSI_OFFSET 73
90 
91 /* 192 usec off -> on interval (RX Callib -> SFD Wait). We wait a bit more */
92 #define ONOFF_TIME RTIMER_ARCH_SECOND / 3125
93 /*---------------------------------------------------------------------------*/
94 /* Sniffer configuration */
95 #ifndef CC2538_RF_CONF_SNIFFER_USB
96 #define CC2538_RF_CONF_SNIFFER_USB 0
97 #endif
98 
99 #if CC2538_RF_CONF_SNIFFER
100 static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /** Snif */
101 
102 #if CC2538_RF_CONF_SNIFFER_USB
103 #include "usb/usb-serial.h"
104 #define write_byte(b) usb_serial_writeb(b)
105 #define flush() usb_serial_flush()
106 #else
107 #include "dev/uart.h"
108 #define write_byte(b) uart_write_byte(CC2538_RF_CONF_SNIFFER_UART, b)
109 #define flush()
110 #endif
111 
112 #else /* CC2538_RF_CONF_SNIFFER */
113 #define write_byte(b)
114 #define flush()
115 #endif /* CC2538_RF_CONF_SNIFFER */
116 /*---------------------------------------------------------------------------*/
117 #ifdef CC2538_RF_CONF_AUTOACK
118 #define CC2538_RF_AUTOACK CC2538_RF_CONF_AUTOACK
119 #else
120 #define CC2538_RF_AUTOACK 1
121 #endif
122 /*---------------------------------------------------------------------------
123  * MAC timer
124  *---------------------------------------------------------------------------*/
125 /* Timer conversion */
126 #define RADIO_TO_RTIMER(X) ((uint32_t)((uint64_t)(X) * RTIMER_ARCH_SECOND / SYS_CTRL_32MHZ))
127 
128 #define CLOCK_STABLE() do { \
129  while ( !(REG(SYS_CTRL_CLOCK_STA) & (SYS_CTRL_CLOCK_STA_XOSC_STB))); \
130  } while(0)
131 /*---------------------------------------------------------------------------*/
132 /* Are we currently in poll mode? Disabled by default */
133 static uint8_t volatile poll_mode = 0;
134 /* Do we perform a CCA before sending? Enabled by default. */
135 static uint8_t send_on_cca = 1;
136 static int8_t rssi;
137 static uint8_t crc_corr;
138 
139 void mac_timer_init(void);
140 uint32_t get_sfd_timestamp(void);
141 /*---------------------------------------------------------------------------*/
142 static uint8_t rf_flags;
143 static uint8_t rf_channel = CC2538_RF_CHANNEL;
144 
145 static int on(void);
146 static int off(void);
147 /*---------------------------------------------------------------------------*/
148 /* TX Power dBm lookup table. Values from SmartRF Studio v1.16.0 */
149 typedef struct output_config {
150  radio_value_t power;
151  uint8_t txpower_val;
152 } output_config_t;
153 
154 static const output_config_t output_power[] = {
155  { 7, 0xFF },
156  { 5, 0xED },
157  { 3, 0xD5 },
158  { 1, 0xC5 },
159  { 0, 0xB6 },
160  { -1, 0xB0 },
161  { -3, 0xA1 },
162  { -5, 0x91 },
163  { -7, 0x88 },
164  { -9, 0x72 },
165  {-11, 0x62 },
166  {-13, 0x58 },
167  {-15, 0x42 },
168  {-24, 0x00 },
169 };
170 
171 #define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t))
172 
173 /* Max and Min Output Power in dBm */
174 #define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].power)
175 #define OUTPUT_POWER_MAX (output_power[0].power)
176 /*---------------------------------------------------------------------------*/
177 PROCESS(cc2538_rf_process, "cc2538 RF driver");
178 /*---------------------------------------------------------------------------*/
179 /**
180  * \brief Get the current operating channel
181  * \return Returns a value in [11,26] representing the current channel
182  */
183 static uint8_t
185 {
186  uint8_t chan = REG(RFCORE_XREG_FREQCTRL) & RFCORE_XREG_FREQCTRL_FREQ;
187 
188  return ((chan - CC2538_RF_CHANNEL_MIN) / CC2538_RF_CHANNEL_SPACING
189  + CC2538_RF_CHANNEL_MIN);
190 }
191 /*---------------------------------------------------------------------------*/
192 /**
193  * \brief Set the current operating channel
194  * \param channel The desired channel as a value in [11,26]
195  * \return Returns a value in [11,26] representing the current channel
196  * or a negative value if \e channel was out of bounds
197  */
198 static int8_t
199 set_channel(uint8_t channel)
200 {
201  uint8_t was_on = 0;
202 
203  PRINTF("RF: Set Channel\n");
204 
205  if((channel < CC2538_RF_CHANNEL_MIN) || (channel > CC2538_RF_CHANNEL_MAX)) {
206  return CC2538_RF_CHANNEL_SET_ERROR;
207  }
208 
209  /* Changes to FREQCTRL take effect after the next recalibration */
210 
211  /* If we are off, save state, otherwise switch off and save state */
213  was_on = 1;
214  off();
215  }
216  REG(RFCORE_XREG_FREQCTRL) = (CC2538_RF_CHANNEL_MIN
217  + (channel - CC2538_RF_CHANNEL_MIN) * CC2538_RF_CHANNEL_SPACING);
218  /* switch radio back on only if radio was on before - otherwise will turn on radio foor sleepy nodes */
219  if(was_on) {
220  on();
221  }
222 
223  rf_channel = channel;
224 
225  return (int8_t) channel;
226 }
227 /*---------------------------------------------------------------------------*/
228 static radio_value_t
229 get_pan_id(void)
230 {
231  return (radio_value_t)(REG(RFCORE_FFSM_PAN_ID1) << 8 | REG(RFCORE_FFSM_PAN_ID0));
232 }
233 /*---------------------------------------------------------------------------*/
234 static void
235 set_pan_id(uint16_t pan)
236 {
237  REG(RFCORE_FFSM_PAN_ID0) = pan & 0xFF;
238  REG(RFCORE_FFSM_PAN_ID1) = pan >> 8;
239 }
240 /*---------------------------------------------------------------------------*/
241 static radio_value_t
242 get_short_addr(void)
243 {
245 }
246 /*---------------------------------------------------------------------------*/
247 static void
248 set_short_addr(uint16_t addr)
249 {
250  REG(RFCORE_FFSM_SHORT_ADDR0) = addr & 0xFF;
251  REG(RFCORE_FFSM_SHORT_ADDR1) = addr >> 8;
252 }
253 /*---------------------------------------------------------------------------*/
254 /**
255  * \brief Reads the current signal strength (RSSI)
256  * \return The current RSSI in dBm
257  *
258  * This function reads the current RSSI on the currently configured
259  * channel.
260  */
261 static radio_value_t
262 get_rssi(void)
263 {
264  int8_t rssi;
265  uint8_t was_off = 0;
266 
267  /* If we are off, turn on first */
269  was_off = 1;
270  on();
271  }
272 
273  /* Wait on RSSI_VALID */
275 
276  rssi = (int8_t)(REG(RFCORE_XREG_RSSI) & RFCORE_XREG_RSSI_RSSI_VAL) - RSSI_OFFSET;
277 
278  /* If we were off, turn back off */
279  if(was_off) {
280  off();
281  }
282 
283  return rssi;
284 }
285 /*---------------------------------------------------------------------------*/
286 /* Returns the current CCA threshold in dBm */
287 static radio_value_t
288 get_cca_threshold(void)
289 {
290  return (int8_t)(REG(RFCORE_XREG_CCACTRL0) & RFCORE_XREG_CCACTRL0_CCA_THR) - RSSI_OFFSET;
291 }
292 /*---------------------------------------------------------------------------*/
293 /* Sets the CCA threshold in dBm */
294 static void
295 set_cca_threshold(radio_value_t value)
296 {
297  REG(RFCORE_XREG_CCACTRL0) = (value & 0xFF) + RSSI_OFFSET;
298 }
299 /*---------------------------------------------------------------------------*/
300 /* Returns the current TX power in dBm */
301 static radio_value_t
302 get_tx_power(void)
303 {
304  int i;
305  uint8_t reg_val = REG(RFCORE_XREG_TXPOWER) & 0xFF;
306 
307  /*
308  * Find the TXPOWER value in the lookup table
309  * If the value has been written with set_tx_power, we should be able to
310  * find the exact value. However, in case the register has been written in
311  * a different fashion, we return the immediately lower value of the lookup
312  */
313  for(i = 0; i < OUTPUT_CONFIG_COUNT; i++) {
314  if(reg_val >= output_power[i].txpower_val) {
315  return output_power[i].power;
316  }
317  }
318  return OUTPUT_POWER_MIN;
319 }
320 /*---------------------------------------------------------------------------*/
321 /*
322  * Set TX power to 'at least' power dBm
323  * This works with a lookup table. If the value of 'power' does not exist in
324  * the lookup table, TXPOWER will be set to the immediately higher available
325  * value
326  */
327 static void
328 set_tx_power(radio_value_t power)
329 {
330  int i;
331 
332  for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) {
333  if(power <= output_power[i].power) {
334  REG(RFCORE_XREG_TXPOWER) = output_power[i].txpower_val;
335  return;
336  }
337  }
338 }
339 /*---------------------------------------------------------------------------*/
340 static void
341 set_frame_filtering(uint8_t enable)
342 {
343  if(enable) {
345  } else {
347  }
348 }
349 /*---------------------------------------------------------------------------*/
350 static void
351 set_poll_mode(uint8_t enable)
352 {
353  poll_mode = enable;
354 
355  if(enable) {
356  mac_timer_init();
357  REG(RFCORE_XREG_RFIRQM0) &= ~RFCORE_XREG_RFIRQM0_FIFOP; // mask out FIFOP interrupt source
358  REG(RFCORE_SFR_RFIRQF0) &= ~RFCORE_SFR_RFIRQF0_FIFOP; // clear pending FIFOP interrupt
359  nvic_interrupt_disable(NVIC_INT_RF_RXTX); // disable RF interrupts
360  } else {
361  REG(RFCORE_XREG_RFIRQM0) |= RFCORE_XREG_RFIRQM0_FIFOP; // enable FIFOP interrupt source
362  nvic_interrupt_enable(NVIC_INT_RF_RXTX); // enable RF interrupts
363  }
364 }
365 /*---------------------------------------------------------------------------*/
366 static void
367 set_send_on_cca(uint8_t enable)
368 {
369  send_on_cca = enable;
370 }
371 /*---------------------------------------------------------------------------*/
372 static void
373 set_auto_ack(uint8_t enable)
374 {
375  if(enable) {
377  } else {
379  }
380 }
381 /*---------------------------------------------------------------------------*/
382 /* Netstack API radio driver functions */
383 /*---------------------------------------------------------------------------*/
384 static int
385 channel_clear(void)
386 {
387  int cca;
388  uint8_t was_off = 0;
389 
390  PRINTF("RF: CCA\n");
391 
392  /* If we are off, turn on first */
394  was_off = 1;
395  on();
396  }
397 
398  /* Wait on RSSI_VALID */
400 
402  cca = CC2538_RF_CCA_CLEAR;
403  } else {
404  cca = CC2538_RF_CCA_BUSY;
405  }
406 
407  /* If we were off, turn back off */
408  if(was_off) {
409  off();
410  }
411 
412  return cca;
413 }
414 /*---------------------------------------------------------------------------*/
415 static int
416 on(void)
417 {
418  PRINTF("RF: On\n");
419 
420  if(!(rf_flags & RX_ACTIVE)) {
423 
424  rf_flags |= RX_ACTIVE;
425  }
426 
427  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
428  return 1;
429 }
430 /*---------------------------------------------------------------------------*/
431 static int
432 off(void)
433 {
434  PRINTF("RF: Off\n");
435 
436  /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */
438 
441  }
442 
443  /* Don't turn off if we are off as this will trigger a Strobe Error */
444  if(REG(RFCORE_XREG_RXENABLE) != 0) {
446  }
447 
448  rf_flags &= ~RX_ACTIVE;
449 
450  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
451  return 1;
452 }
453 /*---------------------------------------------------------------------------*/
454 static int
455 init(void)
456 {
457  PRINTF("RF: Init\n");
458 
459  if(rf_flags & RF_ON) {
460  return 0;
461  }
462 
463  /* Enable clock for the RF Core while Running, in Sleep and Deep Sleep */
464  REG(SYS_CTRL_RCGCRFC) = 1;
465  REG(SYS_CTRL_SCGCRFC) = 1;
466  REG(SYS_CTRL_DCGCRFC) = 1;
467 
468  REG(RFCORE_XREG_CCACTRL0) = CC2538_RF_CCA_THRES_USER_GUIDE;
469 
470  /*
471  * Changes from default values
472  * See User Guide, section "Register Settings Update"
473  */
474  REG(RFCORE_XREG_TXFILTCFG) = 0x09; /** TX anti-aliasing filter bandwidth */
475  REG(RFCORE_XREG_AGCCTRL1) = 0x15; /** AGC target value */
476  REG(ANA_REGS_IVCTRL) = 0x0B; /** Bias currents */
477 
478  /*
479  * Defaults:
480  * Auto CRC; Append RSSI, CRC-OK and Corr. Val.; CRC calculation;
481  * RX and TX modes with FIFOs
482  */
484 
485 #if CC2538_RF_AUTOACK
487 #endif
488 
489  /* If we are a sniffer, turn off frame filtering */
490 #if CC2538_RF_CONF_SNIFFER
492 #endif
493 
494  /* Disable source address matching and autopend */
495  REG(RFCORE_XREG_SRCMATCH) = 0;
496 
497  /* MAX FIFOP threshold */
498  REG(RFCORE_XREG_FIFOPCTRL) = CC2538_RF_MAX_PACKET_LEN;
499 
500  /* Set TX Power */
501  REG(RFCORE_XREG_TXPOWER) = CC2538_RF_TX_POWER;
502 
503  set_channel(rf_channel);
504 
505  /* Acknowledge all RF Error interrupts */
508 
510  /* Disable peripheral triggers for the channel */
512 
513  /*
514  * Set the channel's DST. SRC can not be set yet since it will change for
515  * each transfer
516  */
518  }
519 
521  /* Disable peripheral triggers for the channel */
523 
524  /*
525  * Set the channel's SRC. DST can not be set yet since it will change for
526  * each transfer
527  */
529  }
530 
531  set_poll_mode(poll_mode);
532 
533  process_start(&cc2538_rf_process, NULL);
534 
535  rf_flags |= RF_ON;
536 
537  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
538 
539  return 1;
540 }
541 /*---------------------------------------------------------------------------*/
542 static int
543 prepare(const void *payload, unsigned short payload_len)
544 {
545  uint8_t i;
546 
547  PRINTF("RF: Prepare 0x%02x bytes\n", payload_len + CHECKSUM_LEN);
548 
549  /*
550  * When we transmit in very quick bursts, make sure previous transmission
551  * is not still in progress before re-writing to the TX FIFO
552  */
553  while(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE);
554 
555  if((rf_flags & RX_ACTIVE) == 0) {
556  on();
557  }
558 
560 
561  PRINTF("RF: data = ");
562  /* Send the phy length byte first */
563  REG(RFCORE_SFR_RFDATA) = payload_len + CHECKSUM_LEN;
564 
566  PRINTF("<uDMA payload>");
567 
568  /* Set the transfer source's end address */
570  (uint32_t)(payload) + payload_len - 1);
571 
572  /* Configure the control word */
574  UDMA_TX_FLAGS | udma_xfer_size(payload_len));
575 
576  /* Enabled the RF TX uDMA channel */
578 
579  /* Trigger the uDMA transfer */
581 
582  /*
583  * No need to wait for this to end. Even if transmit() gets called
584  * immediately, the uDMA controller will stream the frame to the TX FIFO
585  * faster than transmit() can empty it
586  */
587  } else {
588  for(i = 0; i < payload_len; i++) {
589  REG(RFCORE_SFR_RFDATA) = ((unsigned char *)(payload))[i];
590  PRINTF("%02x", ((unsigned char *)(payload))[i]);
591  }
592  }
593  PRINTF("\n");
594 
595  return 0;
596 }
597 /*---------------------------------------------------------------------------*/
598 static int
599 transmit(unsigned short transmit_len)
600 {
601  uint8_t counter;
602  int ret = RADIO_TX_ERR;
603  rtimer_clock_t t0;
604  uint8_t was_off = 0;
605 
606  PRINTF("RF: Transmit\n");
607 
608  if(!(rf_flags & RX_ACTIVE)) {
609  t0 = RTIMER_NOW();
610  on();
611  was_off = 1;
612  while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ONOFF_TIME));
613  }
614 
615  if(send_on_cca) {
616  if(channel_clear() == CC2538_RF_CCA_BUSY) {
617  RIMESTATS_ADD(contentiondrop);
618  return RADIO_TX_COLLISION;
619  }
620  }
621 
622  /*
623  * prepare() double checked that TX_ACTIVE is low. If SFD is high we are
624  * receiving. Abort transmission and bail out with RADIO_TX_COLLISION
625  */
627  RIMESTATS_ADD(contentiondrop);
628  return RADIO_TX_COLLISION;
629  }
630 
631  /* Start the transmission */
632  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
633  ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
634 
636 
637  counter = 0;
638  while(!((REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE))
639  && (counter++ < 3)) {
640  clock_delay_usec(6);
641  }
642 
643  if(!(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE)) {
644  PRINTF("RF: TX never active.\n");
646  ret = RADIO_TX_ERR;
647  } else {
648  /* Wait for the transmission to finish */
649  while(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE);
650  ret = RADIO_TX_OK;
651  }
652  ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
653  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
654 
655  if(was_off) {
656  off();
657  }
658 
659  RIMESTATS_ADD(lltx);
660 
661  return ret;
662 }
663 /*---------------------------------------------------------------------------*/
664 static int
665 send(const void *payload, unsigned short payload_len)
666 {
667  prepare(payload, payload_len);
668  return transmit(payload_len);
669 }
670 /*---------------------------------------------------------------------------*/
671 static int
672 read(void *buf, unsigned short bufsize)
673 {
674  uint8_t i;
675  uint8_t len;
676 
677  PRINTF("RF: Read\n");
678 
679  if((REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP) == 0) {
680  return 0;
681  }
682 
683  /* Check the length */
684  len = REG(RFCORE_SFR_RFDATA);
685 
686  /* Check for validity */
687  if(len > CC2538_RF_MAX_PACKET_LEN) {
688  /* Oops, we must be out of sync. */
689  PRINTF("RF: bad sync\n");
690 
691  RIMESTATS_ADD(badsynch);
693  return 0;
694  }
695 
696  if(len <= CC2538_RF_MIN_PACKET_LEN) {
697  PRINTF("RF: too short\n");
698 
699  RIMESTATS_ADD(tooshort);
701  return 0;
702  }
703 
704  if(len - CHECKSUM_LEN > bufsize) {
705  PRINTF("RF: too long\n");
706 
707  RIMESTATS_ADD(toolong);
709  return 0;
710  }
711 
712  /* If we reach here, chances are the FIFO is holding a valid frame */
713  PRINTF("RF: read (0x%02x bytes) = ", len);
714  len -= CHECKSUM_LEN;
715 
716  /* Don't bother with uDMA for short frames (e.g. ACKs) */
717  if(CC2538_RF_CONF_RX_USE_DMA && len > UDMA_RX_SIZE_THRESHOLD) {
718  PRINTF("<uDMA payload>");
719 
720  /* Set the transfer destination's end address */
722  (uint32_t)(buf) + len - 1);
723 
724  /* Configure the control word */
726  UDMA_RX_FLAGS | udma_xfer_size(len));
727 
728  /* Enabled the RF RX uDMA channel */
730 
731  /* Trigger the uDMA transfer */
733 
734  /* Wait for the transfer to complete. */
736  } else {
737  for(i = 0; i < len; ++i) {
738  ((unsigned char *)(buf))[i] = REG(RFCORE_SFR_RFDATA);
739  PRINTF("%02x", ((unsigned char *)(buf))[i]);
740  }
741  }
742 
743  /* Read the RSSI and CRC/Corr bytes */
744  rssi = ((int8_t)REG(RFCORE_SFR_RFDATA)) - RSSI_OFFSET;
745  crc_corr = REG(RFCORE_SFR_RFDATA);
746 
747  PRINTF("%02x%02x\n", (uint8_t)rssi, crc_corr);
748 
749  /* MS bit CRC OK/Not OK, 7 LS Bits, Correlation value */
750  if(crc_corr & CRC_BIT_MASK) {
751  packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);
752  packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_corr & LQI_BIT_MASK);
753  RIMESTATS_ADD(llrx);
754  } else {
755  RIMESTATS_ADD(badcrc);
756  PRINTF("RF: Bad CRC\n");
758  return 0;
759  }
760 
761 #if CC2538_RF_CONF_SNIFFER
762  write_byte(magic[0]);
763  write_byte(magic[1]);
764  write_byte(magic[2]);
765  write_byte(magic[3]);
766  write_byte(len + 2);
767  for(i = 0; i < len; ++i) {
768  write_byte(((unsigned char *)(buf))[i]);
769  }
770  write_byte(rssi);
771  write_byte(crc_corr);
772  flush();
773 #endif
774 
775  if(!poll_mode) {
776  /* If FIFOP==1 and FIFO==0 then we had a FIFO overflow at some point. */
777  if(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP) {
779  process_poll(&cc2538_rf_process);
780  } else {
782  }
783  }
784  }
785 
787 
788  return (len);
789 }
790 /*---------------------------------------------------------------------------*/
791 static int
792 receiving_packet(void)
793 {
794  PRINTF("RF: Receiving\n");
795 
796  /*
797  * SFD high while transmitting and receiving.
798  * TX_ACTIVE high only when transmitting
799  *
800  * FSMSTAT1 & (TX_ACTIVE | SFD) == SFD <=> receiving
801  */
802  return ((REG(RFCORE_XREG_FSMSTAT1)
803  & (RFCORE_XREG_FSMSTAT1_TX_ACTIVE | RFCORE_XREG_FSMSTAT1_SFD))
804  == RFCORE_XREG_FSMSTAT1_SFD);
805 }
806 /*---------------------------------------------------------------------------*/
807 static int
808 pending_packet(void)
809 {
810  PRINTF("RF: Pending\n");
811 
812  return (REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP);
813 }
814 /*---------------------------------------------------------------------------*/
815 static radio_result_t
816 get_value(radio_param_t param, radio_value_t *value)
817 {
818  if(!value) {
819  return RADIO_RESULT_INVALID_VALUE;
820  }
821 
822  switch(param) {
823  case RADIO_PARAM_POWER_MODE:
825  ? RADIO_POWER_MODE_OFF : RADIO_POWER_MODE_ON;
826  return RADIO_RESULT_OK;
827  case RADIO_PARAM_CHANNEL:
828  *value = (radio_value_t)get_channel();
829  return RADIO_RESULT_OK;
830  case RADIO_PARAM_PAN_ID:
831  *value = get_pan_id();
832  return RADIO_RESULT_OK;
833  case RADIO_PARAM_16BIT_ADDR:
834  *value = get_short_addr();
835  return RADIO_RESULT_OK;
836  case RADIO_PARAM_RX_MODE:
837  *value = 0;
840  }
842  *value |= RADIO_RX_MODE_AUTOACK;
843  }
844  if(poll_mode) {
845  *value |= RADIO_RX_MODE_POLL_MODE;
846  }
847  return RADIO_RESULT_OK;
848  case RADIO_PARAM_TX_MODE:
849  *value = 0;
850  if(send_on_cca) {
851  *value |= RADIO_TX_MODE_SEND_ON_CCA;
852  }
853  return RADIO_RESULT_OK;
854  case RADIO_PARAM_TXPOWER:
855  *value = get_tx_power();
856  return RADIO_RESULT_OK;
857  case RADIO_PARAM_CCA_THRESHOLD:
858  *value = get_cca_threshold();
859  return RADIO_RESULT_OK;
860  case RADIO_PARAM_RSSI:
861  *value = get_rssi();
862  return RADIO_RESULT_OK;
863  case RADIO_PARAM_LAST_RSSI:
864  *value = rssi;
865  return RADIO_RESULT_OK;
866  case RADIO_PARAM_LAST_LINK_QUALITY:
867  *value = crc_corr & LQI_BIT_MASK;
868  return RADIO_RESULT_OK;
869  case RADIO_CONST_CHANNEL_MIN:
870  *value = CC2538_RF_CHANNEL_MIN;
871  return RADIO_RESULT_OK;
872  case RADIO_CONST_CHANNEL_MAX:
873  *value = CC2538_RF_CHANNEL_MAX;
874  return RADIO_RESULT_OK;
875  case RADIO_CONST_TXPOWER_MIN:
876  *value = OUTPUT_POWER_MIN;
877  return RADIO_RESULT_OK;
878  case RADIO_CONST_TXPOWER_MAX:
879  *value = OUTPUT_POWER_MAX;
880  return RADIO_RESULT_OK;
881  default:
882  return RADIO_RESULT_NOT_SUPPORTED;
883  }
884 }
885 /*---------------------------------------------------------------------------*/
886 static radio_result_t
887 set_value(radio_param_t param, radio_value_t value)
888 {
889  switch(param) {
890  case RADIO_PARAM_POWER_MODE:
891  if(value == RADIO_POWER_MODE_ON) {
892  on();
893  return RADIO_RESULT_OK;
894  }
895  if(value == RADIO_POWER_MODE_OFF) {
896  off();
897  return RADIO_RESULT_OK;
898  }
899  return RADIO_RESULT_INVALID_VALUE;
900  case RADIO_PARAM_CHANNEL:
901  if(value < CC2538_RF_CHANNEL_MIN ||
902  value > CC2538_RF_CHANNEL_MAX) {
903  return RADIO_RESULT_INVALID_VALUE;
904  }
905  if(set_channel(value) == CC2538_RF_CHANNEL_SET_ERROR) {
906  return RADIO_RESULT_ERROR;
907  }
908  return RADIO_RESULT_OK;
909  case RADIO_PARAM_PAN_ID:
910  set_pan_id(value & 0xffff);
911  return RADIO_RESULT_OK;
912  case RADIO_PARAM_16BIT_ADDR:
913  set_short_addr(value & 0xffff);
914  return RADIO_RESULT_OK;
915  case RADIO_PARAM_RX_MODE:
916  if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER |
917  RADIO_RX_MODE_AUTOACK |
918  RADIO_RX_MODE_POLL_MODE)) {
919  return RADIO_RESULT_INVALID_VALUE;
920  }
921 
922  set_frame_filtering((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0);
923  set_auto_ack((value & RADIO_RX_MODE_AUTOACK) != 0);
924  set_poll_mode((value & RADIO_RX_MODE_POLL_MODE) != 0);
925 
926  return RADIO_RESULT_OK;
927  case RADIO_PARAM_TX_MODE:
928  if(value & ~(RADIO_TX_MODE_SEND_ON_CCA)) {
929  return RADIO_RESULT_INVALID_VALUE;
930  }
931  set_send_on_cca((value & RADIO_TX_MODE_SEND_ON_CCA) != 0);
932  return RADIO_RESULT_OK;
933  case RADIO_PARAM_TXPOWER:
934  if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) {
935  return RADIO_RESULT_INVALID_VALUE;
936  }
937 
938  set_tx_power(value);
939  return RADIO_RESULT_OK;
940  case RADIO_PARAM_CCA_THRESHOLD:
941  set_cca_threshold(value);
942  return RADIO_RESULT_OK;
943  default:
944  return RADIO_RESULT_NOT_SUPPORTED;
945  }
946 }
947 /*---------------------------------------------------------------------------*/
948 static radio_result_t
949 get_object(radio_param_t param, void *dest, size_t size)
950 {
951  uint8_t *target;
952  int i;
953 
954  if(param == RADIO_PARAM_64BIT_ADDR) {
955  if(size != 8 || !dest) {
956  return RADIO_RESULT_INVALID_VALUE;
957  }
958 
959  target = dest;
960  for(i = 0; i < 8; i++) {
961  target[i] = ((uint32_t *)RFCORE_FFSM_EXT_ADDR0)[7 - i] & 0xFF;
962  }
963 
964  return RADIO_RESULT_OK;
965  }
966 
967  if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) {
968  if(size != sizeof(rtimer_clock_t) || !dest) {
969  return RADIO_RESULT_INVALID_VALUE;
970  }
971  *(rtimer_clock_t*)dest = get_sfd_timestamp();
972  return RADIO_RESULT_OK;
973  }
974 
975  return RADIO_RESULT_NOT_SUPPORTED;
976 }
977 /*---------------------------------------------------------------------------*/
978 static radio_result_t
979 set_object(radio_param_t param, const void *src, size_t size)
980 {
981  int i;
982 
983  if(param == RADIO_PARAM_64BIT_ADDR) {
984  if(size != 8 || !src) {
985  return RADIO_RESULT_INVALID_VALUE;
986  }
987 
988  for(i = 0; i < 8; i++) {
989  ((uint32_t *)RFCORE_FFSM_EXT_ADDR0)[i] = ((uint8_t *)src)[7 - i];
990  }
991 
992  return RADIO_RESULT_OK;
993  }
994  return RADIO_RESULT_NOT_SUPPORTED;
995 }
996 /*---------------------------------------------------------------------------*/
998  init,
999  prepare,
1000  transmit,
1001  send,
1002  read,
1003  channel_clear,
1006  on,
1007  off,
1008  get_value,
1009  set_value,
1010  get_object,
1011  set_object
1012 };
1013 /*---------------------------------------------------------------------------*/
1014 /**
1015  * \brief Implementation of the cc2538 RF driver process
1016  *
1017  * This process is started by init(). It simply sits there waiting for
1018  * an event. Upon frame reception, the RX ISR will poll this process.
1019  * Subsequently, the contiki core will generate an event which will
1020  * call this process so that the received frame can be picked up from
1021  * the RF RX FIFO
1022  *
1023  */
1024 PROCESS_THREAD(cc2538_rf_process, ev, data)
1025 {
1026  int len;
1027  PROCESS_BEGIN();
1028 
1029  while(1) {
1030  /* Only if we are not in poll mode oder we are in poll mode and transceiver has to be reset */
1031  PROCESS_YIELD_UNTIL((!poll_mode || (poll_mode && (rf_flags & RF_MUST_RESET))) && (ev == PROCESS_EVENT_POLL));
1032 
1033  if(!poll_mode) {
1034  packetbuf_clear();
1036 
1037  if(len > 0) {
1038  packetbuf_set_datalen(len);
1039 
1040  NETSTACK_RDC.input();
1041  }
1042  }
1043 
1044  /* If we were polled due to an RF error, reset the transceiver */
1045  if(rf_flags & RF_MUST_RESET) {
1046  uint8_t was_on;
1047  rf_flags = 0;
1048 
1049  /* save state so we know if to switch on again after re-init */
1050  if((REG(RFCORE_XREG_FSMSTAT0) & RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE) == 0) {
1051  was_on = 0;
1052  } else {
1053  was_on = 1;
1054  }
1055  off();
1056  init();
1057  if(was_on) {
1058  /* switch back on */
1059  on();
1060  }
1061  }
1062  }
1063 
1064  PROCESS_END();
1065 }
1066 /*---------------------------------------------------------------------------*/
1067 /**
1068  * \brief The cc2538 RF RX/TX ISR
1069  *
1070  * This is the interrupt service routine for all RF interrupts relating
1071  * to RX and TX. Error conditions are handled by cc2538_rf_err_isr().
1072  * Currently, we only acknowledge the FIFOP interrupt source.
1073  */
1074 void
1076 {
1077  ENERGEST_ON(ENERGEST_TYPE_IRQ);
1078 
1079  if(!poll_mode) {
1080  process_poll(&cc2538_rf_process);
1081  }
1082 
1083  /* We only acknowledge FIFOP so we can safely wipe out the entire SFR */
1084  REG(RFCORE_SFR_RFIRQF0) = 0;
1085 
1086  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
1087 }
1088 /*---------------------------------------------------------------------------*/
1089 /**
1090  * \brief The cc2538 RF Error ISR
1091  *
1092  * This is the interrupt service routine for all RF errors. We
1093  * acknowledge every error type and instead of trying to be smart and
1094  * act differently depending on error condition, we simply reset the
1095  * transceiver. RX FIFO overflow is an exception, we ignore this error
1096  * since read() handles it anyway.
1097  *
1098  * However, we don't want to reset within this ISR. If the error occurs
1099  * while we are reading a frame out of the FIFO, trashing the FIFO in
1100  * the middle of read(), would result in further errors (RX underflows).
1101  *
1102  * Instead, we set a flag and poll the driver process. The process will
1103  * reset the transceiver without any undesirable consequences.
1104  */
1105 void
1107 {
1108  ENERGEST_ON(ENERGEST_TYPE_IRQ);
1109 
1110  PRINTF("RF Error: 0x%08lx\n", REG(RFCORE_SFR_RFERRF));
1111 
1112  /* If the error is not an RX FIFO overflow, set a flag */
1114  rf_flags |= RF_MUST_RESET;
1115  }
1116 
1117  REG(RFCORE_SFR_RFERRF) = 0;
1118 
1119  process_poll(&cc2538_rf_process);
1120 
1121  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
1122 }
1123 /*---------------------------------------------------------------------------*/
1124 void
1126 {
1127  set_frame_filtering(p);
1128 }
1129 /*---------------------------------------------------------------------------*/
1130 uint32_t get_sfd_timestamp(void)
1131 {
1132  uint64_t sfd, timer_val, buffer;
1133 
1134  REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMSEL) | 0x00000000;
1136  timer_val = REG(RFCORE_SFR_MTM0) & RFCORE_SFR_MTM0_MTM0;
1137  timer_val |= ((REG(RFCORE_SFR_MTM1) & RFCORE_SFR_MTM1_MTM1) << 8);
1138  REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMOVFSEL) | 0x00000000;
1139  timer_val |= ((REG(RFCORE_SFR_MTMOVF0) & RFCORE_SFR_MTMOVF0_MTMOVF0) << 16);
1140  timer_val |= ((REG(RFCORE_SFR_MTMOVF1) & RFCORE_SFR_MTMOVF1_MTMOVF1) << 24);
1142  timer_val |= (buffer << 32);
1143 
1144  REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMSEL) | 0x00000001;
1147  sfd |= ((REG(RFCORE_SFR_MTM1) & RFCORE_SFR_MTM1_MTM1) << 8);
1148  REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMOVFSEL) | 0x00000010;
1149  sfd |= ((REG(RFCORE_SFR_MTMOVF0) & RFCORE_SFR_MTMOVF0_MTMOVF0) << 16);
1150  sfd |= ((REG(RFCORE_SFR_MTMOVF1) & RFCORE_SFR_MTMOVF1_MTMOVF1) << 24);
1152  sfd |= (buffer << 32);
1153 
1154  return (RTIMER_NOW() - RADIO_TO_RTIMER(timer_val - sfd));
1155 }
1156 /*---------------------------------------------------------------------------*/
1157 void mac_timer_init(void)
1158 {
1159  CLOCK_STABLE();
1162  while(!(REG(RFCORE_SFR_MTCTRL) & RFCORE_SFR_MTCTRL_STATE));
1164  while(REG(RFCORE_SFR_MTCTRL) & RFCORE_SFR_MTCTRL_STATE);
1167  while(!(REG(RFCORE_SFR_MTCTRL) & RFCORE_SFR_MTCTRL_STATE));
1168 }
1169 /*---------------------------------------------------------------------------*/
1170 /** @} */
#define RFCORE_XREG_TXFILTCFG
TX filter configuration.
Definition: rfcore-xreg.h:141
#define RFCORE_XREG_CCACTRL0
CCA threshold.
Definition: rfcore-xreg.h:66
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
Definition: packetbuf.c:158
#define RFCORE_SFR_MTMOVF0
MAC Timer MUX overflow 0.
Definition: rfcore-sfr.h:54
static radio_value_t get_rssi(void)
Reads the current signal strength (RSSI)
Definition: cc2538-rf.c:262
#define RFCORE_SFR_MTCTRL_RUN
Timer start/stop.
Definition: rfcore-sfr.h:80
#define RFCORE_XREG_RFERRM
RF error interrupt mask.
Definition: rfcore-xreg.h:81
#define RFCORE_SFR_RFERRF_RXOVERF
RX FIFO overflowed.
Definition: rfcore-sfr.h:140
void process_poll(struct process *p)
Request a process to be polled.
Definition: process.c:371
#define RFCORE_SFR_MTMOVF1_MTMOVF1
Register[15:8].
Definition: rfcore-sfr.h:123
Header file for the real-time timer module.
static uint8_t get_channel()
Get the current operating channel.
Definition: cc2538-rf.c:184
#define RFCORE_XREG_FRMCTRL0_AUTOCRC
Auto CRC generation / checking.
Definition: rfcore-xreg.h:210
#define NVIC_INT_RF_RXTX
RF Core Rx/Tx.
Definition: nvic.h:96
#define NVIC_INT_RF_ERR
RF Core Error.
Definition: nvic.h:97
#define CC2538_RF_CONF_RX_USE_DMA
RF RX over DMA.
Definition: contiki-conf.h:403
#define RFCORE_SFR_RFIRQF0
RF interrupt flags.
Definition: rfcore-sfr.h:63
#define RFCORE_XREG_TXPOWER
Controls the output power.
Definition: rfcore-xreg.h:60
#define RFCORE_SFR_MTCTRL_STATE
State of MAC Timer.
Definition: rfcore-sfr.h:78
Header file with register manipulation macro definitions.
#define CC2538_RF_CONF_TX_USE_DMA
RF TX over DMA.
Definition: contiki-conf.h:399
#define RFCORE_XREG_RXENABLE_RXENMASK
Enables the receiver.
Definition: rfcore-xreg.h:228
Header file for the radio API
#define RFCORE_XREG_RSSISTAT_RSSI_VALID
RSSI value is valid.
Definition: rfcore-xreg.h:327
static uip_ds6_addr_t * addr
Pointer to a router list entry.
Definition: uip-nd6.c:124
#define RFCORE_SFR_MTCTRL
MAC Timer control register.
Definition: rfcore-sfr.h:46
const struct radio_driver cc2538_rf_driver
The NETSTACK data structure for the cc2538 RF driver.
Definition: cc2538-rf.c:997
#define RFCORE_XREG_FRMFILT0
Frame filtering control.
Definition: rfcore-xreg.h:44
uint8_t udma_channel_get_mode(uint8_t channel)
Retrieve the current mode for a channel.
Definition: udma.c:235
Header file for the cc2538 RF driver.
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:135
void udma_set_channel_src(uint8_t channel, uint32_t src_end)
Sets the channels source address.
Definition: udma.c:70
void udma_channel_mask_set(uint8_t channel)
Disable peripheral triggers for a uDMA channel.
Definition: udma.c:204
#define RFCORE_SFR_MTMOVF0_MTMOVF0
Register[7:0].
Definition: rfcore-sfr.h:124
void packetbuf_clear(void)
Clear and reset the packetbuf.
Definition: packetbuf.c:76
#define udma_xfer_size(len)
Calculate the value of the xfersize field in the control structure.
Definition: udma.h:697
#define RFCORE_XREG_FSMSTAT0
Radio status register.
Definition: rfcore-xreg.h:62
#define RFCORE_SFR_MTM0_MTM0
Register[7:0].
Definition: rfcore-sfr.h:115
int(* read)(void *buf, unsigned short buf_len)
Read a received packet into a buffer.
Definition: radio.h:251
#define RFCORE_SFR_MTMSEL
MAC Timer multiplex select.
Definition: rfcore-sfr.h:49
#define RFCORE_XREG_RFIRQM0_FIFOP
RX FIFO exceeded threshold.
Definition: rfcore-xreg.h:373
void cc2538_rf_set_promiscous_mode(char p)
Turn promiscous mode on or off.
Definition: cc2538-rf.c:1125
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:255
#define RFCORE_XREG_FRMCTRL0
Frame handling.
Definition: rfcore-xreg.h:53
#define RFCORE_XREG_FSMSTAT1_CCA
Clear channel assessment.
Definition: rfcore-xreg.h:284
int(* prepare)(const void *payload, unsigned short payload_len)
Prepare the radio with a packet to be sent.
Definition: radio.h:242
void cc2538_rf_err_isr(void)
The cc2538 RF Error ISR.
Definition: cc2538-rf.c:1106
#define RFCORE_XREG_RXENABLE
RX enabling.
Definition: rfcore-xreg.h:55
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
#define RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN
Enables frame filtering.
Definition: rfcore-xreg.h:149
#define CC2538_RF_CSP_ISRXON()
Send an RX ON command strobe to the CSP.
Definition: cc2538-rf.h:102
#define RFCORE_SFR_MTMOVF2_MTMOVF2
Register[23:16].
Definition: rfcore-sfr.h:117
#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
#define RFCORE_SFR_MTMOVF2
MAC Timer MUX overflow 2.
Definition: rfcore-sfr.h:52
#define RFCORE_SFR_RFDATA
TX/RX FIFO data.
Definition: rfcore-sfr.h:60
#define RFCORE_FFSM_SHORT_ADDR1
Local address information.
Definition: rfcore-ffsm.h:65
void udma_channel_enable(uint8_t channel)
Enables a uDMA channel.
Definition: udma.c:120
Header file for the energy estimation mechanism
The structure of a device driver for a radio in Contiki.
Definition: radio.h:237
#define RFCORE_XREG_AGCCTRL1
AGC reference level.
Definition: rfcore-xreg.h:93
#define RFCORE_XREG_FSMSTAT1_SFD
SFD was sent/received.
Definition: rfcore-xreg.h:283
#define RFCORE_SFR_MTCTRL_SYNC
Timer start/stop timing.
Definition: rfcore-sfr.h:79
#define RFCORE_SFR_MTMSEL_MTMOVFSEL
MTMOVF register select.
Definition: rfcore-sfr.h:108
#define RFCORE_XREG_SRCMATCH
Source address matching.
Definition: rfcore-xreg.h:46
int(* pending_packet)(void)
Check if the radio driver has just received a packet.
Definition: radio.h:261
void udma_set_channel_control_word(uint8_t channel, uint32_t ctrl)
Configure the channel's control word.
Definition: udma.c:90
void cc2538_rf_rx_tx_isr(void)
The cc2538 RF RX/TX ISR.
Definition: cc2538-rf.c:1075
Header file for the Rime buffer (packetbuf) management
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
Definition: radio.h:273
#define CC2538_RF_CSP_ISFLUSHRX()
Flush the RX FIFO.
Definition: cc2538-rf.h:120
#define RFCORE_XREG_FIFOPCTRL
FIFOP threshold.
Definition: rfcore-xreg.h:64
#define RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE
FIFO and FFCTRL status.
Definition: rfcore-xreg.h:275
#define CC2538_RF_CSP_ISRFOFF()
Send a RF OFF command strobe to the CSP.
Definition: cc2538-rf.h:114
static int init(void)
Definition: cc2538-rf.c:455
#define RFCORE_FFSM_PAN_ID1
Local address information.
Definition: rfcore-ffsm.h:63
static int8_t set_channel(uint8_t channel)
Set the current operating channel.
Definition: cc2538-rf.c:199
Header file for the Rime address representation
#define SYS_CTRL_RCGCRFC
RF Core clocks - active mode.
Definition: sys-ctrl.h:93
int(* off)(void)
Turn the radio off.
Definition: radio.h:267
#define CC2538_RF_CONF_TX_DMA_CHAN
RF -> RAM DMA channel.
Definition: contiki-conf.h:119
#define RFCORE_XREG_RFIRQM0
RF interrupt masks.
Definition: rfcore-xreg.h:79
#define RFCORE_XREG_FSMSTAT1_TX_ACTIVE
Status signal - TX states.
Definition: rfcore-xreg.h:287
#define RFCORE_SFR_MTCTRL_LATCH_MODE
OVF counter latch mode.
Definition: rfcore-sfr.h:77
#define RFCORE_XREG_FSMSTAT1
Radio status register.
Definition: rfcore-xreg.h:63
#define RFCORE_SFR_MTMSEL_MTMSEL
MTM register select.
Definition: rfcore-sfr.h:109
#define NULL
The null pointer.
#define RFCORE_XREG_CCACTRL0_CCA_THR
Clear-channel-assessment.
Definition: rfcore-xreg.h:307
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 CC2538_RF_CSP_ISFLUSHTX()
Flush the TX FIFO.
Definition: cc2538-rf.h:128
#define RADIO_RX_MODE_ADDRESS_FILTER
The radio reception mode controls address filtering and automatic transmission of acknowledgements in...
Definition: radio.h:204
#define RFCORE_FFSM_PAN_ID0
Local address information.
Definition: rfcore-ffsm.h:62
#define RFCORE_XREG_FREQCTRL_FREQ
Frequency control word.
Definition: rfcore-xreg.h:252
#define RFCORE_SFR_MTMOVF1
MAC Timer MUX overflow 1.
Definition: rfcore-sfr.h:53
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
Definition: radio.h:280
Header file for the cc2538 System Control driver.
#define RFCORE_XREG_FRMCTRL0_AUTOACK
Transmit ACK frame enable.
Definition: rfcore-xreg.h:211
int(* on)(void)
Turn the radio on.
Definition: radio.h:264
#define SYS_CTRL_DCGCRFC
RF Core clocks - PM0.
Definition: sys-ctrl.h:95
#define SYS_CTRL_SCGCRFC
RF Core clocks - Sleep mode.
Definition: sys-ctrl.h:94
#define RADIO_TX_MODE_SEND_ON_CCA
The radio transmission mode controls whether transmissions should be done using clear channel assessm...
Definition: radio.h:216
#define RFCORE_SFR_MTM1
MAC Timer MUX register 1.
Definition: rfcore-sfr.h:51
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
radio_result_t(* get_value)(radio_param_t param, radio_value_t *value)
Get a radio parameter value.
Definition: radio.h:270
#define RFCORE_SFR_MTM1_MTM1
Register[15:8].
Definition: rfcore-sfr.h:116
int(* send)(const void *payload, unsigned short payload_len)
Prepare & transmit a packet.
Definition: radio.h:248
#define RFCORE_XREG_RFERRM_RFERRM
RF error interrupt mask.
Definition: rfcore-xreg.h:393
#define RFCORE_XREG_RSSISTAT
RSSI valid status register.
Definition: rfcore-xreg.h:69
void nvic_interrupt_enable(uint32_t intr)
Enables interrupt intr.
Definition: nvic.c:64
#define RFCORE_XREG_FSMSTAT1_FIFO
FIFO status.
Definition: rfcore-xreg.h:281
void nvic_interrupt_disable(uint32_t intr)
Disables interrupt intr.
Definition: nvic.c:71
#define RFCORE_XREG_FREQCTRL
Controls the RF frequency.
Definition: rfcore-xreg.h:59
#define CC2538_RF_CONF_RX_DMA_CHAN
RAM -> RF DMA channel.
Definition: contiki-conf.h:120
#define RFCORE_SFR_RFIRQF0_FIFOP
RX FIFO exceeded threshold.
Definition: rfcore-sfr.h:164
Header file for Rime statistics
Header file for cc2538's UART-like I/O over USB.
#define RFCORE_FFSM_SHORT_ADDR0
Local address information.
Definition: rfcore-ffsm.h:64
#define RFCORE_XREG_RSSI
RSSI status register.
Definition: rfcore-xreg.h:68
Header file with register, macro and function declarations for the cc2538 micro-DMA controller module...
Top-level header file for cc2538 RF Core registers.
#define RFCORE_FFSM_EXT_ADDR0
Local address information.
Definition: rfcore-ffsm.h:54
#define RFCORE_XREG_RSSI_RSSI_VAL
RSSI estimate.
Definition: rfcore-xreg.h:320
void clock_delay_usec(uint16_t dt)
Delay a given number of microseconds.
Definition: clock.c:94
#define RFCORE_XREG_FSMSTAT1_FIFOP
FIFOP status.
Definition: rfcore-xreg.h:282
int(* transmit)(unsigned short transmit_len)
Send the packet that has previously been prepared.
Definition: radio.h:245
void udma_set_channel_dst(uint8_t channel, uint32_t dst_end)
Sets the channel's destination address.
Definition: udma.c:80
#define RFCORE_SFR_MTM0
MAC Timer MUX register 0.
Definition: rfcore-sfr.h:50
#define CC2538_RF_CSP_ISTXON()
Send a TX ON command strobe to the CSP.
Definition: cc2538-rf.h:108
Include file for the Contiki low-layer network stack (NETSTACK)
radio_result_t(* set_object)(radio_param_t param, const void *src, size_t size)
Set a radio parameter object.
Definition: radio.h:286
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
Definition: cc2538-rf.c:1024
void udma_channel_sw_request(uint8_t channel)
Generate a software trigger to start a transfer.
Definition: udma.c:225
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
#define RFCORE_SFR_RFERRF
RF error interrupt flags.
Definition: rfcore-sfr.h:61