20 #include "sys/clock.h"
27 #define CC2430_RF_TX_POWER_RECOMMENDED 0x5F
28 #ifdef CC2430_RF_CONF_TX_POWER
29 #define CC2430_RF_TX_POWER CC2430_RF_CONF_TX_POWER
31 #define CC2430_RF_TX_POWER CC2430_RF_TX_POWER_RECOMMENDED
34 #ifdef CC2430_RF_CONF_CHANNEL
35 #define CC2430_RF_CHANNEL CC2430_RF_CONF_CHANNEL
37 #define CC2430_RF_CHANNEL 18
39 #define CC2430_CHANNEL_MIN 11
40 #define CC2430_CHANNEL_MAX 26
42 #ifdef CC2430_RF_CONF_AUTOACK
43 #define CC2430_RF_AUTOACK CC2430_RF_CONF_AUTOACK
45 #define CC2430_RF_AUTOACK 1
48 #ifndef CC2430_CONF_CHECKSUM
49 #define CC2430_CONF_CHECKSUM 0
52 #if CC2430_CONF_CHECKSUM
54 #define CHECKSUM_LEN 2
56 #define CHECKSUM_LEN 2
62 #define RF_RX_LED_ON() leds_on(LEDS_RED);
63 #define RF_RX_LED_OFF() leds_off(LEDS_RED);
64 #define RF_TX_LED_ON() leds_on(LEDS_GREEN);
65 #define RF_TX_LED_OFF() leds_off(LEDS_GREEN);
67 #define RF_RX_LED_ON()
68 #define RF_RX_LED_OFF()
69 #define RF_TX_LED_ON()
70 #define RF_TX_LED_OFF()
74 #define PRINTF(...) printf(__VA_ARGS__)
76 #define PRINTF(...) do {} while (0)
80 #define RX_ACTIVE 0x80
82 #define TX_ON_AIR 0x20
84 #define INITIALISED 0x01
88 #define CRC_BIT_MASK 0x80
89 #define LQI_BIT_MASK 0x7F
92 #define ONOFF_TIME ((RTIMER_ARCH_SECOND / 3125) + 4)
94 #if CC2430_RF_CONF_HEXDUMP
96 static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 };
100 uint8_t rf_error = 0;
104 #if !NETSTACK_CONF_SHORTCUTS
105 PROCESS(cc2430_rf_process,
"CC2430 RF driver");
108 static uint8_t CC_AT_DATA rf_flags;
109 static uint8_t rf_channel;
112 static int off(
void);
124 if(command >= 0xE0) {
130 fifo_count = RXFIFOCNT;
133 if(fifo_count != RXFIFOCNT) {
142 }
else if(command == SSTART) {
143 RFIF &= ~IRQ_CSP_STOP;
146 while((RFIF & IRQ_CSP_STOP) == 0);
158 #if !NETSTACK_CONF_SHORTCUTS
161 #if CC2430_RFERR_INTERRUPT
184 if((channel < 11) || (channel > 26)) {
191 freq = (uint16_t) channel - 11;
195 FSCTRLH = (freq >> 8);
196 FSCTRLL = (uint8_t)freq;
200 rf_channel = channel;
202 return (int8_t) channel;
206 cc2430_rf_channel_get()
236 cc2430_rf_tx_enable(
void)
238 DMAARM = 0x80 + (1 << 0);
255 __xdata
unsigned char *ptr;
260 SHORTADDRH = addr >> 8;
261 SHORTADDRL = addr & 0xff;
263 if(ieee_addr !=
NULL) {
266 for(f = 0; f < 8; f++) {
267 *ptr-- = ieee_addr[f];
282 cc2430_rf_analyze_rssi(
void)
284 int8_t retval = -128;
287 retval = (int8_t)RSSIL;
313 if(rf_flags & INITIALISED) {
317 PRINTF(
"cc2430_rf_init called\n");
319 RFPWR &= ~RREG_RADIO_PD;
320 while((RFPWR & ADI_RADIO_PD) == 1);
321 while((RFIF & IRQ_RREG_ON) == 0);
323 while((
SLEEP & XOSC_STB) == 0);
331 #if CC2430_RF_AUTOACK
349 RFIF &= ~(IRQ_FIFOP);
351 S1CON &= ~(RFIF_0 | RFIF_1);
352 #if !NETSTACK_CONF_SHORTCUTS
357 #if CC2430_RFERR_INTERRUPT
364 rf_flags |= INITIALISED;
366 #if !NETSTACK_CONF_SHORTCUTS
376 prepare(
const void *payload,
unsigned short payload_len)
383 while(RFSTATUS & TX_ACTIVE);
385 if(rf_flags & TX_ACK) {
389 if((rf_flags & RX_ACTIVE) == 0) {
393 PRINTF(
"cc2430_rf: sending %u byte payload\n", payload_len);
396 PRINTF(
"cc2430_rf: data = ");
398 RFD = payload_len + CHECKSUM_LEN;
399 PRINTF(
"(%d)", payload_len + CHECKSUM_LEN);
400 for(i = 0; i < payload_len; i++) {
401 RFD = ((
unsigned char *)(payload))[i];
402 PRINTF(
"%02X", ((
unsigned char *)(payload))[i]);
414 transmit(
unsigned short transmit_len)
417 int ret = RADIO_TX_ERR;
419 if(!(rf_flags & RX_ACTIVE)) {
425 RIMESTATS_ADD(contentiondrop);
426 return RADIO_TX_COLLISION;
434 RIMESTATS_ADD(contentiondrop);
435 return RADIO_TX_COLLISION;
439 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
440 ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
444 while(!(RFSTATUS & TX_ACTIVE) && (counter++ < 3)) {
448 if(!(RFSTATUS & TX_ACTIVE)) {
449 PRINTF(
"cc2430_rf: TX never active.\n");
454 while(RFSTATUS & TX_ACTIVE);
460 ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
461 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
463 if(rf_flags & WAS_OFF) {
473 send(
void *payload,
unsigned short payload_len)
480 read(
void *buf,
unsigned short bufsize)
486 #if CC2420_CONF_CHECKSUM
491 #if !NETSTACK_CONF_SHORTCUTS
494 #if CC2430_RFERR_INTERRUPT
503 if(len > CC2430_MAX_PACKET_LEN) {
505 PRINTF(
"error: bad sync\n");
507 RIMESTATS_ADD(badsynch);
512 if(len <= CC2430_MIN_PACKET_LEN) {
513 PRINTF(
"error: too short\n");
515 RIMESTATS_ADD(tooshort);
520 if(len - CHECKSUM_LEN > bufsize) {
521 PRINTF(
"error: too long\n");
523 RIMESTATS_ADD(toolong);
528 #if CC2430_RF_CONF_HEXDUMP
530 uart1_writeb(magic[0]);
531 uart1_writeb(magic[1]);
532 uart1_writeb(magic[2]);
533 uart1_writeb(magic[3]);
537 PRINTF(
"cc2430_rf: read = ");
540 for(i = 0; i < len; ++i) {
541 ((
unsigned char *)(buf))[i] = RFD;
542 #if CC2430_RF_CONF_HEXDUMP
543 uart1_writeb(((
unsigned char *)(buf))[i]);
545 PRINTF(
"%02X", ((
unsigned char *)(buf))[i]);
549 #if CC2430_CONF_CHECKSUM
551 checksum = RFD * 256;
556 rssi = ((int8_t) RFD) - 45;
559 #if CC2430_RF_CONF_HEXDUMP
561 uart1_writeb(crc_corr);
565 if(crc_corr & CRC_BIT_MASK) {
566 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);
567 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_corr & LQI_BIT_MASK);
570 RIMESTATS_ADD(badcrc);
576 if((RFSTATUS & (FIFO | FIFOP)) == FIFOP) {
591 #if !NETSTACK_CONF_SHORTCUTS
594 #if CC2430_RFERR_INTERRUPT
606 if(!(RFSTATUS & CCA)) {
607 return CC2430_CCA_BUSY;
609 return CC2430_CCA_CLEAR;
621 return (RFSTATUS & (TX_ACTIVE | SFD) == SFD);
627 return (RFSTATUS & FIFOP);
641 PRINTF(
"cc2430_rf_rx_enable called\n");
642 if(!(rf_flags & RX_ACTIVE)) {
644 rf_flags |= RX_ACTIVE;
648 RFPWR &= ~RREG_RADIO_PD;
649 while((RFIF & IRQ_RREG_ON) == 0);
652 RFIF &= ~IRQ_RREG_ON;
656 while(RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + ONOFF_TIME));
659 PRINTF(
"cc2430_rf_rx_enable done\n");
660 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
678 RFPWR |= RREG_RADIO_PD;
681 RFIF &= ~IRQ_RREG_ON;
683 rf_flags &= ~RX_ACTIVE;
684 rf_flags &= ~WAS_OFF;
685 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
689 static radio_result_t
692 return RADIO_RESULT_NOT_SUPPORTED;
695 static radio_result_t
698 return RADIO_RESULT_NOT_SUPPORTED;
701 static radio_result_t
702 get_object(radio_param_t param,
void *dest,
size_t size)
704 return RADIO_RESULT_NOT_SUPPORTED;
707 static radio_result_t
708 set_object(radio_param_t param,
const void *src,
size_t size)
710 return RADIO_RESULT_NOT_SUPPORTED;
730 #if !NETSTACK_CONF_SHORTCUTS
743 NETSTACK_RDC.input();
CC2430 registers header file for CC2430.
#define PROCESS_BEGIN()
Define the beginning of a process.
void clock_delay_usec(uint16_t dt)
Delay a given number of microseconds.
Header file for the radio API
int8_t cc2430_rf_channel_set(uint8_t channel)
Select RF channel.
Header file for the Rime buffer (packetbuf) management
CC2430 RF driver header file
#define NULL
The null pointer.
The structure of a device driver for a radio in Contiki.
int(* pending_packet)(void)
Check if the radio driver has just received a packet.
uint8_t cc2430_rf_power_set(uint8_t new_power)
Select RF transmit power.
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio...
int(* prepare)(const void *payload, unsigned short payload_len)
Prepare the radio with a packet to be sent.
void cc2430_rf_command(uint8_t command)
Execute a single CSP command.
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
int(* send)(const void *payload, unsigned short payload_len)
Prepare & transmit a packet.
int(* receiving_packet)(void)
Check if the radio driver is currently receiving a packet.
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
#define PROCESS_END()
Define the end of a process.
int(* channel_clear)(void)
Perform a Clear-Channel Assessment (CCA) to find out if there is a packet in the air or not...
Header file for the real-time timer module.
void cc2430_rf_send_ack(uint8_t pending)
Send ACK.
int(* on)(void)
Turn the radio on.
radio_result_t(* get_value)(radio_param_t param, radio_value_t *value)
Get a radio parameter value.
void cc2430_rf_set_addr(unsigned pan, unsigned addr, const uint8_t *ieee_addr)
Set MAC addresses.
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
#define PROCESS(name, strname)
Declare a process.
#define SLEEP
Constant SLEEP for sub-register SR_TRX_STATUS.
int(* transmit)(unsigned short transmit_len)
Send the packet that has previously been prepared.
void packetbuf_clear(void)
Clear and reset the packetbuf.
void process_start(struct process *p, process_data_t data)
Start a process.
#define RTIMER_NOW()
Get the current clock time.
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
Header file for Rime statistics
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
radio_result_t(* set_object)(radio_param_t param, const void *src, size_t size)
Set a radio parameter object.
Header file for the CRC16 calculcation
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
int(* read)(void *buf, unsigned short buf_len)
Read a received packet into a buffer.
int(* off)(void)
Turn the radio off.
Include file for the Contiki low-layer network stack (NETSTACK)