44 #include "dev/radio/cc2420/cc2420_const.h" 49 enum write_ram_order {
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) 78 struct output_config {
83 static 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 97 void cc2420_arch_init(
void);
99 int cc2420_authority_level_of_sender;
101 volatile uint8_t cc2420_sfd_counter;
102 volatile uint16_t cc2420_sfd_start_time;
103 volatile uint16_t cc2420_sfd_end_time;
105 static volatile uint16_t last_packet_timestamp;
112 #define MAX_PAYLOAD_LEN (127 - CHECKSUM_LEN) 114 PROCESS(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) 127 int cc2420_off(
void);
129 static int cc2420_read(
void *buf,
unsigned short bufsize);
131 static int cc2420_prepare(
const void *data,
unsigned short len);
132 static int cc2420_transmit(
unsigned short len);
133 static int cc2420_send(
const void *data,
unsigned short len);
135 static int cc2420_receiving_packet(
void);
136 static int pending_packet(
void);
137 static int get_cca_threshold(
void);
138 static int cc2420_cca(
void);
139 static uint16_t getreg(
enum cc2420_register regname);
141 static void set_frame_filtering(uint8_t enable);
142 static void set_poll_mode(uint8_t enable);
143 static void set_send_on_cca(uint8_t enable);
144 static void set_auto_ack(uint8_t enable);
146 static void set_test_mode(uint8_t enable, uint8_t modulated);
148 signed char cc2420_last_rssi;
149 uint8_t cc2420_last_correlation;
151 static uint8_t receive_on;
155 static uint8_t
volatile poll_mode = 0;
157 static 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);
305 get_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;
322 set_object(radio_param_t param,
const void *src,
size_t size)
335 cc2420_receiving_packet,
348 strobe(
enum cc2420_register regname)
352 CC2420_SPI_DISABLE();
357 getreg(
enum cc2420_register regname)
362 SPI_WRITE(regname | 0x40);
363 value = (uint8_t)SPI_RXBUF;
366 value = SPI_RXBUF << 8;
370 CC2420_SPI_DISABLE();
381 setreg(
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();
393 read_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();
409 write_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();
433 write_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();
461 getrxdata(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);
489 wait_for_status(uint8_t status_bit)
493 while(!(get_status() & status_bit)
498 wait_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) {
539 static uint8_t locked, lock_on, lock_off;
540 #define GET_LOCK() locked++ 541 static void RELEASE_LOCK(
void) {
559 setreg(CC2420_SECCTRL0, 0);
560 setreg(CC2420_SECCTRL1, 0);
564 set_key(
const uint8_t *key)
568 write_ram(key, CC2420RAM_KEY0, 16, WRITE_RAM_REVERSE);
574 encrypt(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);
597 set_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);
675 cc2420_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");
745 cc2420_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);
772 cc2420_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)) {
826 cc2420_get_channel(
void)
832 cc2420_set_channel(
int c)
843 f = 5 * (c - 11) + 357 + 0x4000;
846 wait_for_transmission();
848 setreg(CC2420_FSCTRL, f);
853 strobe(CC2420_SRXON);
861 cc2420_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");
902 packetbuf_set_attr(PACKETBUF_ATTR_TIMESTAMP, last_packet_timestamp);
907 NETSTACK_MAC.
input();
914 cc2420_read(
void *buf,
unsigned short bufsize)
916 uint8_t footer[FOOTER_LEN];
919 if(!CC2420_FIFOP_IS_1) {
927 if(len > CC2420_MAX_PACKET_LEN) {
929 }
else if(len <= FOOTER_LEN) {
931 }
else if(len - FOOTER_LEN > bufsize) {
934 getrxdata((uint8_t *) buf, len - FOOTER_LEN);
935 getrxdata(footer, FOOTER_LEN);
937 if(footer[1] & FOOTER1_CRC_OK) {
938 cc2420_last_rssi = footer[0] + RSSI_OFFSET;
939 cc2420_last_correlation = footer[1] & FOOTER1_CORRELATION;
944 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, cc2420_last_rssi);
945 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, cc2420_last_correlation);
952 if(CC2420_FIFOP_IS_1) {
953 if(!CC2420_FIFO_IS_1) {
966 return len - FOOTER_LEN;
983 cc2420_get_txpower(
void)
987 power = (int)(getreg(CC2420_TXCTRL) & 0x001f);
996 int radio_was_off = 0;
1008 wait_for_status(BV(CC2420_RSSI_VALID));
1010 rssi = (int)((
signed char) getreg(CC2420_RSSI));
1011 rssi += RSSI_OFFSET;
1024 int radio_was_off = 0;
1049 wait_for_status(BV(CC2420_RSSI_VALID));
1051 cca = CC2420_CCA_IS_1;
1061 cc2420_receiving_packet(
void)
1063 return CC2420_SFD_IS_1;
1067 pending_packet(
void)
1069 return CC2420_FIFOP_IS_1;
1073 get_cca_threshold(
void)
1078 value = (int8_t)(getreg(CC2420_RSSI) >> 8);
1084 cc2420_set_cca_threshold(
int value)
1086 uint16_t shifted = value << 8;
1088 setreg(CC2420_RSSI, shifted);
1094 set_auto_ack(uint8_t enable)
1098 uint16_t reg = getreg(CC2420_MDMCTRL0);
1105 setreg(CC2420_MDMCTRL0, reg);
1111 set_frame_filtering(uint8_t enable)
1116 uint16_t reg = getreg(CC2420_MDMCTRL0);
1120 reg &= ~(ADR_DECODE);
1123 setreg(CC2420_MDMCTRL0, reg);
1129 set_poll_mode(uint8_t enable)
1135 CC2420_CLEAR_FIFOP_INT();
1136 CC2420_DISABLE_FIFOP_INT();
1139 CC2420_FIFOP_INT_INIT();
1140 CC2420_ENABLE_FIFOP_INT();
1141 CC2420_CLEAR_FIFOP_INT();
1148 set_send_on_cca(uint8_t enable)
1150 send_on_cca = enable;
1156 static uint16_t prev_MDMCTRL1, prev_DACTST;
1157 static uint8_t was_on;
1160 set_test_mode(uint8_t enable, uint8_t modulated)
1171 prev_MDMCTRL1 = getreg(CC2420_MDMCTRL1);
1172 setreg(CC2420_MDMCTRL1, 0x050C);
1174 prev_DACTST = getreg(CC2420_DACTST);
1175 setreg(CC2420_DACTST, 0x1800);
1178 strobe(CC2420_STXON);
1183 strobe(CC2420_SRFOFF);
1185 setreg(CC2420_DACTST, prev_DACTST);
1187 setreg(CC2420_MDMCTRL1, prev_MDMCTRL1);
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
CC2420 driver header file
#define PROCESS(name, strname)
Declare a process.
The parameter is not supported.
void packetbuf_clear(void)
Clear and reset the packetbuf.
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Header file for the energy estimation mechanism
TX failed due to a collision.
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
Radio powered on and emitting unmodulated carriers.
#define PROCESS_BEGIN()
Define the beginning of a process.
The maximum transmission power in dBm.
#define PROCESS_END()
Define the end of a process.
int cc2420_interrupt(void)
Interrupt function, called from the simple-cc2420-arch driver.
Received signal strength indicator in dBm.
Structure of AES drivers.
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
int(* pending_packet)(void)
Check if a packet has been received and is available in the radio driver's buffers.
void(* encrypt)(uint8_t *plaintext_and_result)
Encrypts.
The structure of a Contiki-NG radio device driver.
Channel used for radio communication.
The value argument was incorrect.
The parameter was set/read successfully.
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio...
Radio transmission mode determines if the radio has send on CCA (RADIO_TX_MODE_SEND_ON_CCA) enabled o...
#define RTIMER_SECOND
Number of rtimer ticks for 1 second.
#define IEEE802154_DEFAULT_CHANNEL
The default channel for IEEE 802.15.4 networks.
#define RTIMER_NOW()
Get the current clock time.
The RSSI value of the last received packet.
void cc2420_set_txpower(uint8_t power)
Clear channel assessment threshold in dBm.
void(* input)(void)
Callback for getting notified of incoming packet.
void process_poll(struct process *p)
Request a process to be polled.
int(* off)(void)
Turn the radio off.
The lowest radio channel number.
Radio receiver mode determines if the radio has address filter (RADIO_RX_MODE_ADDRESS_FILTER) and aut...
The highest radio channel number.
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
void clock_delay(unsigned int i)
Obsolete delay function but we implement it here since some code still uses it.
Radio powered on, but not emitting unmodulated carriers.
#define RADIO_RX_MODE_ADDRESS_FILTER
Enable address-based frame filtering.
When getting the value of this parameter, the radio driver should indicate whether the radio is on or...
enum radio_result_e radio_result_t
Radio return values when setting or getting radio parameters.
#define RADIO_TX_MODE_SEND_ON_CCA
Radio TX mode control / retrieval.
#define RADIO_RX_MODE_AUTOACK
Enable automatic transmission of ACK frames.
#define RADIO_RX_MODE_POLL_MODE
Enable/disable/get the state of radio driver poll mode operation.
Link quality indicator of the last received packet.
The minimum transmission power in dBm.
Radio powered on and able to receive frames.
Transmission power in dBm.
Header file for the Packet buffer (packetbuf) management
Include file for the Contiki low-layer network stack (NETSTACK)
radio_result_t(* get_value)(radio_param_t param, radio_value_t *value)
Get a radio parameter value.
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
Last packet timestamp, of type rtimer_clock_t.
An error occurred during transmission.
radio_result_t(* set_object)(radio_param_t param, const void *src, size_t size)
Set a radio parameter object.
Header file for the LED HAL.
Radio powered off and in the lowest possible power consumption state.
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
TX was successful and where an ACK was requested one was received.
int(* on)(void)
Turn the radio on.
void process_start(struct process *p, process_data_t data)
Start a process.
void(* set_key)(const uint8_t *key)
Sets the current key.