44#include "dev/radio/cc2420/cc2420_const.h"
59#define PRINTF(...) printf(__VA_ARGS__)
61#define PRINTF(...) do {} while (0)
64#define DEBUG_LEDS DEBUG
68#define LEDS_ON(x) leds_on(x)
69#define LEDS_OFF(x) leds_off(x)
83static const struct output_config output_power[] = {
93#define OUTPUT_NUM (sizeof(output_power) / sizeof(struct output_config))
94#define OUTPUT_POWER_MAX 0
95#define OUTPUT_POWER_MIN -25
97void cc2420_arch_init(
void);
99int cc2420_authority_level_of_sender;
101volatile uint8_t cc2420_sfd_counter;
102volatile uint16_t cc2420_sfd_start_time;
103volatile uint16_t cc2420_sfd_end_time;
105static volatile uint16_t last_packet_timestamp;
112#define MAX_PAYLOAD_LEN (127 - CHECKSUM_LEN)
114PROCESS(cc2420_process,
"CC2420 driver");
117#define AUTOACK (1 << 4)
118#define AUTOCRC (1 << 5)
119#define ADR_DECODE (1 << 11)
120#define RXFIFO_PROTECTION (1 << 9)
121#define CORR_THR(n) (((n) & 0x1f) << 6)
122#define FIFOP_THR(n) ((n) & 0x7f)
123#define RXBPF_LOCUR (1 << 13);
124#define TX_MODE (3 << 2)
129static int cc2420_read(
void *buf,
unsigned short bufsize);
131static int cc2420_prepare(
const void *data,
unsigned short len);
132static int cc2420_transmit(
unsigned short len);
133static int cc2420_send(
const void *data,
unsigned short len);
135static int cc2420_receiving_packet(
void);
136static int pending_packet(
void);
137static int get_cca_threshold(
void);
138static int cc2420_cca(
void);
139static uint16_t getreg(
enum cc2420_register regname);
141static void set_frame_filtering(uint8_t enable);
142static void set_poll_mode(uint8_t enable);
143static void set_send_on_cca(uint8_t enable);
144static void set_auto_ack(uint8_t enable);
146static void set_test_mode(uint8_t enable, uint8_t modulated);
148signed char cc2420_last_rssi;
149uint8_t cc2420_last_correlation;
151static uint8_t receive_on;
155static uint8_t
volatile poll_mode = 0;
157static uint8_t send_on_cca = WITH_SEND_CCA;
169 if((getreg(CC2420_MDMCTRL1) & TX_MODE) & 0x08) {
176 *value = cc2420_get_channel();
180 if(getreg(CC2420_MDMCTRL0) & ADR_DECODE) {
183 if(getreg(CC2420_MDMCTRL0) & AUTOACK) {
197 v = cc2420_get_txpower();
198 *value = OUTPUT_POWER_MIN;
200 for(i = 0; i < OUTPUT_NUM; i++) {
201 if(v >= output_power[i].config) {
202 *value = output_power[i].power;
208 *value = get_cca_threshold() + RSSI_OFFSET;
212 *value = cc2420_rssi();
216 *value = cc2420_last_rssi;
220 *value = cc2420_last_correlation;
229 *value = OUTPUT_POWER_MIN;
232 *value = OUTPUT_POWER_MAX;
234 case RADIO_CONST_MAX_PAYLOAD_LEN:
264 if(value < 11 || value > 26) {
267 cc2420_set_channel(value);
285 if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) {
289 for(i = 1; i < OUTPUT_NUM; i++) {
290 if(value > output_power[i].power) {
297 cc2420_set_cca_threshold(value - RSSI_OFFSET);
305get_object(radio_param_t param,
void *dest,
size_t size)
308#if CC2420_CONF_SFD_TIMESTAMPS
309 if(size !=
sizeof(rtimer_clock_t) || !dest) {
312 *(rtimer_clock_t*)dest = cc2420_sfd_start_time;
322set_object(radio_param_t param,
const void *src,
size_t size)
335 cc2420_receiving_packet,
348strobe(
enum cc2420_register regname)
352 CC2420_SPI_DISABLE();
357getreg(
enum cc2420_register regname)
362 SPI_WRITE(regname | 0x40);
363 value = (uint8_t)SPI_RXBUF;
366 value = SPI_RXBUF << 8;
370 CC2420_SPI_DISABLE();
381setreg(
enum cc2420_register regname, uint16_t value)
384 SPI_WRITE_FAST(regname);
385 SPI_WRITE_FAST((uint8_t) (value >> 8));
386 SPI_WRITE_FAST((uint8_t) (value & 0xff));
387 SPI_WAITFORTx_ENDED();
389 CC2420_SPI_DISABLE();
393read_ram(uint8_t *buffer, uint16_t adr, uint16_t
count)
398 SPI_WRITE(0x80 | ((adr) & 0x7f));
399 SPI_WRITE((((adr) >> 1) & 0xc0) | 0x20);
401 for(i = 0; i <
count; i++) {
402 SPI_READ(((uint8_t*) buffer)[i]);
404 CC2420_SPI_DISABLE();
409write_ram(
const uint8_t *buffer,
412 enum write_ram_order order)
417 SPI_WRITE_FAST(0x80 | (adr & 0x7f));
418 SPI_WRITE_FAST((adr >> 1) & 0xc0);
419 if(order == WRITE_RAM_IN_ORDER) {
420 for(i = 0; i <
count; i++) {
421 SPI_WRITE_FAST((buffer)[i]);
424 for(i =
count; i > 0; i--) {
425 SPI_WRITE_FAST((buffer)[i - 1]);
428 SPI_WAITFORTx_ENDED();
429 CC2420_SPI_DISABLE();
433write_fifo_buf(
const uint8_t *buffer, uint16_t
count)
438 SPI_WRITE_FAST(CC2420_TXFIFO);
439 for(i = 0; i <
count; i++) {
440 SPI_WRITE_FAST((buffer)[i]);
442 SPI_WAITFORTx_ENDED();
443 CC2420_SPI_DISABLE();
453 SPI_WRITE(CC2420_SNOP);
455 CC2420_SPI_DISABLE();
461getrxdata(uint8_t *buffer,
int count)
466 SPI_WRITE(CC2420_RXFIFO | 0x40);
468 for(i = 0; i <
count; i++) {
472 CC2420_SPI_DISABLE();
480 getrxdata(&dummy, 1);
481 strobe(CC2420_SFLUSHRX);
482 strobe(CC2420_SFLUSHRX);
489wait_for_status(uint8_t status_bit)
493 while(!(get_status() & status_bit)
498wait_for_transmission(
void)
502 while((get_status() & BV(CC2420_TX_ACTIVE))
510 CC2420_ENABLE_FIFOP_INT();
513 strobe(CC2420_SRXON);
515 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
526 wait_for_transmission();
528 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
529 strobe(CC2420_SRFOFF);
531 CC2420_DISABLE_FIFOP_INT();
534 if(!CC2420_FIFOP_IS_1) {
539static uint8_t locked, lock_on, lock_off;
540#define GET_LOCK() locked++
541static void RELEASE_LOCK(
void) {
559 setreg(CC2420_SECCTRL0, 0);
560 setreg(CC2420_SECCTRL1, 0);
564set_key(
const uint8_t *key)
568 write_ram(key, CC2420RAM_KEY0, 16, WRITE_RAM_REVERSE);
574encrypt(uint8_t *plaintext_and_result)
578 write_ram(plaintext_and_result,
584 while(get_status() & BV(CC2420_ENC_BUSY));
586 read_ram(plaintext_and_result, CC2420RAM_SABUF, 16);
597set_txpower(uint8_t power)
601 reg = getreg(CC2420_TXCTRL);
602 reg = (reg & 0xffe0) | (power & 0x1f);
603 setreg(CC2420_TXCTRL, reg);
613 CC2420_DISABLE_FIFOP_INT();
614 CC2420_FIFOP_INT_INIT();
623 SET_RESET_INACTIVE();
628 strobe(CC2420_SXOSCON);
630 wait_for_status(BV(CC2420_XOSC16M_STABLE));
633 set_auto_ack(CC2420_CONF_AUTOACK);
634 set_frame_filtering(CC2420_CONF_AUTOACK);
639 reg = getreg(CC2420_MDMCTRL0);
641 setreg(CC2420_MDMCTRL0, reg);
652 setreg(CC2420_MDMCTRL1, CORR_THR(20));
653 reg = getreg(CC2420_RXCTRL1);
655 setreg(CC2420_RXCTRL1, reg);
658 setreg(CC2420_IOCFG0, FIFOP_THR(127));
662 cc2420_set_pan_addr(0xffff, 0x0000, NULL);
664 cc2420_set_cca_threshold(CC2420_CONF_CCA_THRESH);
675cc2420_transmit(
unsigned short payload_len)
679 if(payload_len > MAX_PAYLOAD_LEN) {
692#ifndef CC2420_CONF_SYMBOL_LOOP_COUNT
693#error CC2420_CONF_SYMBOL_LOOP_COUNT needs to be set!!!
695#define LOOP_20_SYMBOLS CC2420_CONF_SYMBOL_LOOP_COUNT
699 strobe(CC2420_SRXON);
700 wait_for_status(BV(CC2420_RSSI_VALID));
701 strobe(CC2420_STXONCCA);
703 strobe(CC2420_STXON);
705 for(i = LOOP_20_SYMBOLS; i > 0; i--) {
706 if(CC2420_SFD_IS_1) {
707 if(!(get_status() & BV(CC2420_TX_ACTIVE))) {
715 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
717 ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
720 wait_for_transmission();
722 ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
724 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
738 PRINTF(
"cc2420: do_send() transmission never started\n");
745cc2420_prepare(
const void *payload,
unsigned short payload_len)
749 if(payload_len > MAX_PAYLOAD_LEN) {
755 PRINTF(
"cc2420: sending %d bytes\n", payload_len);
761 strobe(CC2420_SFLUSHTX);
763 total_len = payload_len + CHECKSUM_LEN;
764 write_fifo_buf(&total_len, 1);
765 write_fifo_buf(payload, payload_len);
772cc2420_send(
const void *payload,
unsigned short payload_len)
774 cc2420_prepare(payload, payload_len);
775 return cc2420_transmit(payload_len);
782 if(receive_on == 0) {
799 if(get_status() & BV(CC2420_TX_ACTIVE)) {
826cc2420_get_channel(
void)
832cc2420_set_channel(
int c)
843 f = 5 * (c - 11) + 357 + 0x4000;
846 wait_for_transmission();
848 setreg(CC2420_FSCTRL, f);
853 strobe(CC2420_SRXON);
861cc2420_set_pan_addr(
unsigned pan,
863 const uint8_t *ieee_addr)
867 write_ram((uint8_t *) &pan, CC2420RAM_PANID, 2, WRITE_RAM_IN_ORDER);
868 write_ram((uint8_t *) &
addr, CC2420RAM_SHORTADDR, 2, WRITE_RAM_IN_ORDER);
870 if(ieee_addr != NULL) {
871 write_ram(ieee_addr, CC2420RAM_IEEEADDR, 8, WRITE_RAM_REVERSE);
882 CC2420_CLEAR_FIFOP_INT();
885 last_packet_timestamp = cc2420_sfd_start_time;
894 PRINTF(
"cc2420_process: started\n");
899 PRINTF(
"cc2420_process: calling receiver callback\n");
906 NETSTACK_MAC.
input();
913cc2420_read(
void *buf,
unsigned short bufsize)
915 uint8_t footer[FOOTER_LEN];
918 if(!CC2420_FIFOP_IS_1) {
926 if(len > CC2420_MAX_PACKET_LEN) {
928 }
else if(len <= FOOTER_LEN) {
930 }
else if(len - FOOTER_LEN > bufsize) {
933 getrxdata((uint8_t *) buf, len - FOOTER_LEN);
934 getrxdata(footer, FOOTER_LEN);
936 if(footer[1] & FOOTER1_CRC_OK) {
937 cc2420_last_rssi = footer[0] + RSSI_OFFSET;
938 cc2420_last_correlation = footer[1] & FOOTER1_CORRELATION;
943 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, cc2420_last_rssi);
944 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, cc2420_last_correlation);
951 if(CC2420_FIFOP_IS_1) {
952 if(!CC2420_FIFO_IS_1) {
965 return len - FOOTER_LEN;
982cc2420_get_txpower(
void)
986 power = (int)(getreg(CC2420_TXCTRL) & 0x001f);
995 int radio_was_off = 0;
1007 wait_for_status(BV(CC2420_RSSI_VALID));
1009 rssi = (int)((
signed char) getreg(CC2420_RSSI));
1010 rssi += RSSI_OFFSET;
1023 int radio_was_off = 0;
1048 wait_for_status(BV(CC2420_RSSI_VALID));
1050 cca = CC2420_CCA_IS_1;
1060cc2420_receiving_packet(
void)
1062 return CC2420_SFD_IS_1;
1068 return CC2420_FIFOP_IS_1;
1072get_cca_threshold(
void)
1077 value = (int8_t)(getreg(CC2420_RSSI) >> 8);
1083cc2420_set_cca_threshold(
int value)
1085 uint16_t shifted = value << 8;
1087 setreg(CC2420_RSSI, shifted);
1093set_auto_ack(uint8_t enable)
1097 uint16_t reg = getreg(CC2420_MDMCTRL0);
1104 setreg(CC2420_MDMCTRL0, reg);
1110set_frame_filtering(uint8_t enable)
1115 uint16_t reg = getreg(CC2420_MDMCTRL0);
1119 reg &= ~(ADR_DECODE);
1122 setreg(CC2420_MDMCTRL0, reg);
1128set_poll_mode(uint8_t enable)
1134 CC2420_CLEAR_FIFOP_INT();
1135 CC2420_DISABLE_FIFOP_INT();
1138 CC2420_FIFOP_INT_INIT();
1139 CC2420_ENABLE_FIFOP_INT();
1140 CC2420_CLEAR_FIFOP_INT();
1147set_send_on_cca(uint8_t enable)
1149 send_on_cca = enable;
1155static uint16_t prev_MDMCTRL1, prev_DACTST;
1156static uint8_t was_on;
1159set_test_mode(uint8_t enable, uint8_t modulated)
1170 prev_MDMCTRL1 = getreg(CC2420_MDMCTRL1);
1171 setreg(CC2420_MDMCTRL1, 0x050C);
1173 prev_DACTST = getreg(CC2420_DACTST);
1174 setreg(CC2420_DACTST, 0x1800);
1177 strobe(CC2420_STXON);
1182 strobe(CC2420_SRFOFF);
1184 setreg(CC2420_DACTST, prev_DACTST);
1186 setreg(CC2420_MDMCTRL1, prev_MDMCTRL1);
CC2420 driver header file.
void cc2420_set_txpower(uint8_t power)
int cc2420_interrupt(void)
Interrupt function, called from the simple-cc2420-arch driver.
Header file for the energy estimation mechanism.
void clock_delay(unsigned int i)
Obsolete delay function but we implement it here since some code still uses it.
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
static volatile uint64_t count
Num.
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
void packetbuf_clear(void)
Clear and reset the packetbuf.
#define PROCESS(name, strname)
Declare a process.
#define PROCESS_BEGIN()
Define the beginning of a process.
#define PROCESS_END()
Define the end of a process.
void process_start(struct process *p, process_data_t data)
Start a process.
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
void process_poll(struct process *p)
Request a process to be polled.
#define RADIO_RX_MODE_ADDRESS_FILTER
Enable address-based frame filtering.
#define RADIO_RX_MODE_POLL_MODE
Enable/disable/get the state of radio driver poll mode operation.
#define RADIO_TX_MODE_SEND_ON_CCA
Radio TX mode control / retrieval.
enum radio_result_e radio_result_t
Radio return values when setting or getting radio parameters.
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio.
#define RADIO_RX_MODE_AUTOACK
Enable automatic transmission of ACK frames.
@ RADIO_RESULT_NOT_SUPPORTED
The parameter is not supported.
@ RADIO_RESULT_INVALID_VALUE
The value argument was incorrect.
@ RADIO_RESULT_OK
The parameter was set/read successfully.
@ RADIO_PARAM_POWER_MODE
When getting the value of this parameter, the radio driver should indicate whether the radio is on or...
@ RADIO_PARAM_RSSI
Received signal strength indicator in dBm.
@ RADIO_PARAM_LAST_PACKET_TIMESTAMP
Last packet timestamp, of type rtimer_clock_t.
@ RADIO_PARAM_LAST_RSSI
The RSSI value of the last received packet.
@ RADIO_PARAM_RX_MODE
Radio receiver mode determines if the radio has address filter (RADIO_RX_MODE_ADDRESS_FILTER) and aut...
@ RADIO_PARAM_CHANNEL
Channel used for radio communication.
@ RADIO_PARAM_LAST_LINK_QUALITY
Link quality indicator of the last received packet.
@ RADIO_PARAM_TXPOWER
Transmission power in dBm.
@ RADIO_CONST_CHANNEL_MAX
The highest radio channel number.
@ RADIO_PARAM_CCA_THRESHOLD
Clear channel assessment threshold in dBm.
@ RADIO_CONST_TXPOWER_MIN
The minimum transmission power in dBm.
@ RADIO_CONST_CHANNEL_MIN
The lowest radio channel number.
@ RADIO_CONST_TXPOWER_MAX
The maximum transmission power in dBm.
@ RADIO_PARAM_TX_MODE
Radio transmission mode determines if the radio has send on CCA (RADIO_TX_MODE_SEND_ON_CCA) enabled o...
@ RADIO_POWER_MODE_CARRIER_OFF
Radio powered on, but not emitting unmodulated carriers.
@ RADIO_POWER_MODE_OFF
Radio powered off and in the lowest possible power consumption state.
@ RADIO_POWER_MODE_ON
Radio powered on and able to receive frames.
@ RADIO_POWER_MODE_CARRIER_ON
Radio powered on and emitting unmodulated carriers.
@ RADIO_TX_COLLISION
TX failed due to a collision.
@ RADIO_TX_ERR
An error occurred during transmission.
@ RADIO_TX_OK
TX was successful and where an ACK was requested one was received.
#define RTIMER_SECOND
Number of rtimer ticks for 1 second.
#define RTIMER_NOW()
Get the current clock time.
Header file for the LED HAL.
#define IEEE802154_DEFAULT_CHANNEL
The default channel for IEEE 802.15.4 networks.
Include file for the Contiki low-layer network stack (NETSTACK)
Header file for the Packet buffer (packetbuf) management.
Structure of AES drivers.
void(* set_key)(const uint8_t *key)
Sets the current key.
void(* encrypt)(uint8_t *plaintext_and_result)
Encrypts.
void(* input)(void)
Callback for getting notified of incoming packet.
The structure of a Contiki-NG radio device driver.
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
int(* off)(void)
Turn the radio off.
radio_result_t(* set_object)(radio_param_t param, const void *src, size_t size)
Set a radio parameter object.
int(* on)(void)
Turn the radio on.
int(* pending_packet)(void)
Check if a packet has been received and is available in the radio driver's buffers.
radio_result_t(* get_value)(radio_param_t param, radio_value_t *value)
Get a radio parameter value.
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.