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)