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);
702 #if !NETSTACK_CONF_SHORTCUTS
715 NETSTACK_RDC.input();