40 #include "sys/clock.h" 55 #define CHECKSUM_LEN 2 58 #define UDMA_TX_FLAGS (UDMA_CHCTL_ARBSIZE_128 | UDMA_CHCTL_XFERMODE_AUTO \ 59 | UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_DSTSIZE_8 \ 60 | UDMA_CHCTL_SRCINC_8 | UDMA_CHCTL_DSTINC_NONE) 62 #define UDMA_RX_FLAGS (UDMA_CHCTL_ARBSIZE_128 | UDMA_CHCTL_XFERMODE_AUTO \ 63 | UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_DSTSIZE_8 \ 64 | UDMA_CHCTL_SRCINC_NONE | UDMA_CHCTL_DSTINC_8) 70 #define UDMA_RX_SIZE_THRESHOLD 3 74 #define LOG_MODULE "cc2538-rf" 75 #define LOG_LEVEL LOG_LEVEL_NONE 78 #define RX_ACTIVE 0x80 79 #define RF_MUST_RESET 0x40 83 #define CRC_BIT_MASK 0x80 84 #define LQI_BIT_MASK 0x7F 86 #define RSSI_OFFSET 73 87 #define RSSI_INVALID -128 90 #define ONOFF_TIME RTIMER_ARCH_SECOND / 3125 92 #ifdef CC2538_RF_CONF_AUTOACK 93 #define CC2538_RF_AUTOACK CC2538_RF_CONF_AUTOACK 95 #define CC2538_RF_AUTOACK 1 101 #define RADIO_TO_RTIMER(X) ((uint32_t)((uint64_t)(X) * RTIMER_ARCH_SECOND / SYS_CTRL_32MHZ)) 103 #define CLOCK_STABLE() do { \ 104 while ( !(REG(SYS_CTRL_CLOCK_STA) & (SYS_CTRL_CLOCK_STA_XOSC_STB))); \ 108 static uint8_t
volatile poll_mode = 0;
110 static uint8_t send_on_cca = 1;
112 static uint8_t crc_corr;
114 static uint8_t rf_flags;
118 static int off(
void);
121 typedef struct output_config {
126 static const output_config_t output_power[] = {
143 #define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t)) 146 #define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].power) 147 #define OUTPUT_POWER_MAX (output_power[0].power) 149 PROCESS(cc2538_rf_process,
"cc2538 RF driver");
170 LOG_INFO(
"Set Channel\n");
180 (channel - CC2538_RF_CHANNEL_MIN) * CC2538_RF_CHANNEL_SPACING;
187 rf_channel = channel;
197 set_pan_id(uint16_t pan)
210 set_short_addr(uint16_t
addr)
238 }
while(rssi == RSSI_INVALID);
251 get_cca_threshold(
void)
276 for(i = 0; i < OUTPUT_CONFIG_COUNT; i++) {
277 if(reg_val >= output_power[i].txpower_val) {
278 return output_power[i].power;
281 return OUTPUT_POWER_MIN;
295 for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) {
296 if(power <= output_power[i].power) {
304 set_frame_filtering(uint8_t enable)
314 set_shr_search(
int enable)
338 set_poll_mode(uint8_t enable)
354 set_send_on_cca(uint8_t enable)
356 send_on_cca = enable;
360 set_auto_ack(uint8_t enable)
370 get_sfd_timestamp(
void)
372 uint64_t sfd, timer_val, buffer;
382 timer_val |= (buffer << 32);
392 sfd |= (buffer << 32);
394 return RTIMER_NOW() - RADIO_TO_RTIMER(timer_val - sfd);
417 cca = CC2538_RF_CCA_CLEAR;
419 cca = CC2538_RF_CCA_BUSY;
435 if(!(rf_flags & RX_ACTIVE)) {
439 rf_flags |= RX_ACTIVE;
442 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
463 rf_flags &= ~RX_ACTIVE;
465 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
474 if(rf_flags & RF_ON) {
491 REG(ANA_REGS_IVCTRL) = 0x0B;
501 #if CC2538_RF_AUTOACK 545 set_poll_mode(poll_mode);
555 prepare(
const void *payload,
unsigned short payload_len)
559 LOG_INFO(
"Prepare 0x%02x bytes\n", payload_len + CHECKSUM_LEN);
567 if((rf_flags & RX_ACTIVE) == 0) {
578 LOG_INFO_(
"<uDMA payload>");
582 (uint32_t)(payload) + payload_len - 1);
600 for(i = 0; i < payload_len; i++) {
602 LOG_INFO_(
"%02x", ((
unsigned char *)(payload))[i]);
611 transmit(
unsigned short transmit_len)
614 int ret = RADIO_TX_ERR;
618 LOG_INFO(
"Transmit\n");
620 if(!(rf_flags & RX_ACTIVE)) {
624 while(RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + ONOFF_TIME));
628 if(channel_clear() == CC2538_RF_CCA_BUSY) {
629 return RADIO_TX_COLLISION;
638 return RADIO_TX_COLLISION;
642 ENERGEST_SWITCH(ENERGEST_TYPE_LISTEN, ENERGEST_TYPE_TRANSMIT);
648 && (counter++ < 3)) {
653 LOG_ERR(
"TX never active.\n");
661 ENERGEST_SWITCH(ENERGEST_TYPE_TRANSMIT, ENERGEST_TYPE_LISTEN);
671 send(
const void *payload,
unsigned short payload_len)
673 prepare(payload, payload_len);
674 return transmit(payload_len);
678 read(
void *buf,
unsigned short bufsize)
693 if(len > CC2538_RF_MAX_PACKET_LEN) {
695 LOG_ERR(
"RF: bad sync\n");
701 if(len <= CC2538_RF_MIN_PACKET_LEN) {
702 LOG_ERR(
"RF: too short\n");
708 if(len - CHECKSUM_LEN > bufsize) {
709 LOG_ERR(
"RF: too long\n");
716 LOG_INFO(
"read (0x%02x bytes) = ", len);
721 LOG_INFO_(
"<uDMA payload>");
725 (uint32_t)(buf) + len - 1);
740 for(i = 0; i < len; ++i) {
742 LOG_INFO_(
"%02x", ((
unsigned char *)(buf))[i]);
750 LOG_INFO_(
"%02x%02x\n", (uint8_t)rssi, crc_corr);
753 if(crc_corr & CRC_BIT_MASK) {
754 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);
755 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_corr & LQI_BIT_MASK);
757 LOG_ERR(
"Bad CRC\n");
777 receiving_packet(
void)
779 LOG_INFO(
"Receiving\n");
795 LOG_INFO(
"Pending\n");
800 static radio_result_t
804 return RADIO_RESULT_INVALID_VALUE;
808 case RADIO_PARAM_POWER_MODE:
810 ? RADIO_POWER_MODE_OFF : RADIO_POWER_MODE_ON;
811 return RADIO_RESULT_OK;
812 case RADIO_PARAM_CHANNEL:
814 return RADIO_RESULT_OK;
815 case RADIO_PARAM_PAN_ID:
816 *value = get_pan_id();
817 return RADIO_RESULT_OK;
818 case RADIO_PARAM_16BIT_ADDR:
819 *value = get_short_addr();
820 return RADIO_RESULT_OK;
821 case RADIO_PARAM_RX_MODE:
827 *value |= RADIO_RX_MODE_AUTOACK;
830 *value |= RADIO_RX_MODE_POLL_MODE;
832 return RADIO_RESULT_OK;
833 case RADIO_PARAM_TX_MODE:
838 return RADIO_RESULT_OK;
839 case RADIO_PARAM_TXPOWER:
840 *value = get_tx_power();
841 return RADIO_RESULT_OK;
842 case RADIO_PARAM_CCA_THRESHOLD:
843 *value = get_cca_threshold();
844 return RADIO_RESULT_OK;
845 case RADIO_PARAM_RSSI:
847 return RADIO_RESULT_OK;
848 case RADIO_PARAM_LAST_RSSI:
850 return RADIO_RESULT_OK;
851 case RADIO_PARAM_LAST_LINK_QUALITY:
852 *value = crc_corr & LQI_BIT_MASK;
853 return RADIO_RESULT_OK;
854 case RADIO_CONST_CHANNEL_MIN:
855 *value = CC2538_RF_CHANNEL_MIN;
856 return RADIO_RESULT_OK;
857 case RADIO_CONST_CHANNEL_MAX:
858 *value = CC2538_RF_CHANNEL_MAX;
859 return RADIO_RESULT_OK;
860 case RADIO_CONST_TXPOWER_MIN:
861 *value = OUTPUT_POWER_MIN;
862 return RADIO_RESULT_OK;
863 case RADIO_CONST_TXPOWER_MAX:
864 *value = OUTPUT_POWER_MAX;
865 return RADIO_RESULT_OK;
866 case RADIO_CONST_PHY_OVERHEAD:
868 return RADIO_RESULT_OK;
869 case RADIO_CONST_BYTE_AIR_TIME:
871 return RADIO_RESULT_OK;
872 case RADIO_CONST_DELAY_BEFORE_TX:
874 return RADIO_RESULT_OK;
875 case RADIO_CONST_DELAY_BEFORE_RX:
877 return RADIO_RESULT_OK;
878 case RADIO_CONST_DELAY_BEFORE_DETECT:
880 return RADIO_RESULT_OK;
882 return RADIO_RESULT_NOT_SUPPORTED;
886 static radio_result_t
890 case RADIO_PARAM_POWER_MODE:
891 if(value == RADIO_POWER_MODE_ON) {
893 return RADIO_RESULT_OK;
895 if(value == RADIO_POWER_MODE_OFF) {
897 return RADIO_RESULT_OK;
899 return RADIO_RESULT_INVALID_VALUE;
900 case RADIO_PARAM_CHANNEL:
901 if(value < CC2538_RF_CHANNEL_MIN ||
902 value > CC2538_RF_CHANNEL_MAX) {
903 return RADIO_RESULT_INVALID_VALUE;
906 return RADIO_RESULT_OK;
907 case RADIO_PARAM_PAN_ID:
908 set_pan_id(value & 0xffff);
909 return RADIO_RESULT_OK;
910 case RADIO_PARAM_16BIT_ADDR:
911 set_short_addr(value & 0xffff);
912 return RADIO_RESULT_OK;
913 case RADIO_PARAM_RX_MODE:
915 RADIO_RX_MODE_AUTOACK |
916 RADIO_RX_MODE_POLL_MODE)) {
917 return RADIO_RESULT_INVALID_VALUE;
921 set_auto_ack((value & RADIO_RX_MODE_AUTOACK) != 0);
922 set_poll_mode((value & RADIO_RX_MODE_POLL_MODE) != 0);
924 return RADIO_RESULT_OK;
925 case RADIO_PARAM_TX_MODE:
927 return RADIO_RESULT_INVALID_VALUE;
930 return RADIO_RESULT_OK;
931 case RADIO_PARAM_TXPOWER:
932 if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) {
933 return RADIO_RESULT_INVALID_VALUE;
937 return RADIO_RESULT_OK;
938 case RADIO_PARAM_CCA_THRESHOLD:
939 set_cca_threshold(value);
940 return RADIO_RESULT_OK;
941 case RADIO_PARAM_SHR_SEARCH:
942 set_shr_search(value);
943 return RADIO_RESULT_OK;
945 return RADIO_RESULT_NOT_SUPPORTED;
949 static radio_result_t
950 get_object(radio_param_t param,
void *dest,
size_t size)
955 if(param == RADIO_PARAM_64BIT_ADDR) {
956 if(size != 8 || !dest) {
957 return RADIO_RESULT_INVALID_VALUE;
961 for(i = 0; i < 8; i++) {
965 return RADIO_RESULT_OK;
968 if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) {
969 if(size !=
sizeof(rtimer_clock_t) || !dest) {
970 return RADIO_RESULT_INVALID_VALUE;
972 *(rtimer_clock_t *)dest = get_sfd_timestamp();
973 return RADIO_RESULT_OK;
976 #if MAC_CONF_WITH_TSCH 977 if(param == RADIO_CONST_TSCH_TIMING) {
978 if(size !=
sizeof(uint16_t *) || !dest) {
979 return RADIO_RESULT_INVALID_VALUE;
982 return RADIO_RESULT_OK;
986 return RADIO_RESULT_NOT_SUPPORTED;
989 static radio_result_t
990 set_object(radio_param_t param,
const void *src,
size_t size)
994 if(param == RADIO_PARAM_64BIT_ADDR) {
995 if(size != 8 || !src) {
996 return RADIO_RESULT_INVALID_VALUE;
999 for(i = 0; i < 8; i++) {
1003 return RADIO_RESULT_OK;
1005 return RADIO_RESULT_NOT_SUPPORTED;
1042 PROCESS_YIELD_UNTIL((!poll_mode || (poll_mode && (rf_flags & RF_MUST_RESET))) && (ev == PROCESS_EVENT_POLL));
1051 NETSTACK_MAC.
input();
1056 if(rf_flags & RF_MUST_RESET) {
1119 rf_flags |= RF_MUST_RESET;
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
#define RFCORE_FFSM_SHORT_ADDR0
Local address information.
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
Top-level header file for cc2538 RF Core registers.
int(* prepare)(const void *payload, unsigned short payload_len)
Prepare the radio with a packet to be sent.
#define RFCORE_SFR_MTM1_MTM1
Register[15:8].
#define RFCORE_XREG_SRCMATCH
Source address matching.
#define SYS_CTRL_RCGCRFC
RF Core clocks - active mode.
#define PROCESS(name, strname)
Declare a process.
#define RFCORE_SFR_MTCTRL_SYNC
Timer start/stop timing.
#define RFCORE_SFR_MTMOVF0
MAC Timer MUX overflow 0.
#define RFCORE_XREG_FRMCTRL0_AUTOACK
Transmit ACK frame enable.
Header file for the cc2538 System Control driver.
#define RFCORE_XREG_FSMSTAT0
Radio status register.
void udma_set_channel_dst(uint8_t channel, uint32_t dst_end)
Sets the channel's destination address.
void packetbuf_clear(void)
Clear and reset the packetbuf.
#define RFCORE_SFR_MTM1
MAC Timer MUX register 1.
#define SYS_CTRL_SCGCRFC
RF Core clocks - Sleep mode.
#define RFCORE_XREG_FSMSTAT1
Radio status register.
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
#define RFCORE_SFR_MTCTRL_LATCH_MODE
OVF counter latch mode.
Header file for the cc2538 RF driver.
Header file for the energy estimation mechanism
#define CC2538_RF_CSP_ISFLUSHTX()
Flush the TX FIFO.
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
Header file for the radio API
#define PROCESS_BEGIN()
Define the beginning of a process.
#define RFCORE_SFR_MTMOVF0_MTMOVF0
Register[7:0].
Header file for the link-layer address representation
#define PROCESS_END()
Define the end of a process.
int(* receiving_packet)(void)
Check if the radio driver is currently receiving a packet.
#define RFCORE_FFSM_SHORT_ADDR1
Local address information.
#define RFCORE_SFR_MTCTRL_RUN
Timer start/stop.
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
int(* pending_packet)(void)
Check if the radio driver has just received a packet.
void clock_delay_usec(uint16_t dt)
Delay a given number of microseconds.
The structure of a device driver for a radio in Contiki.
static void set_channel(uint8_t channel)
Set the current operating channel.
#define RFCORE_XREG_FSMSTAT1_SFD
SFD was sent/received.
Header file with register manipulation macro definitions.
#define RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN
Enables frame filtering.
#define RFCORE_XREG_CCACTRL0_CCA_THR
Clear-channel-assessment.
int(* channel_clear)(void)
Perform a Clear-Channel Assessment (CCA) to find out if there is a packet in the air or not...
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio...
#define CC2538_RF_CONF_RX_DMA_CHAN
RAM -> RF DMA channel.
#define RFCORE_SFR_MTMSEL
MAC Timer multiplex select.
#define RFCORE_SFR_RFDATA
TX/RX FIFO data.
const struct radio_driver cc2538_rf_driver
The NETSTACK data structure for the cc2538 RF driver.
Header file with register, macro and function declarations for the cc2538 micro-DMA controller module...
#define CC2538_RF_CONF_TX_DMA_CHAN
RF -> RAM DMA channel.
#define RFCORE_XREG_FSMSTAT1_TX_ACTIVE
Status signal - TX states.
void udma_channel_mask_set(uint8_t channel)
Disable peripheral triggers for a uDMA channel.
#define RFCORE_XREG_RFERRM_RFERRM
RF error interrupt mask.
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
Disable External Interrupt.
#define IEEE802154_DEFAULT_CHANNEL
The default channel for IEEE 802.15.4 networks.
#define RTIMER_NOW()
Get the current clock time.
#define RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE
FIFO and FFCTRL status.
#define RFCORE_FFSM_EXT_ADDR0
Local address information.
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
Enable External Interrupt.
#define CC2538_RF_CSP_ISRXON()
Send an RX ON command strobe to the CSP.
void udma_set_channel_src(uint8_t channel, uint32_t src_end)
Sets the channels source address.
#define RFCORE_XREG_FSCAL1
Tune frequency calibration.
#define RFCORE_XREG_TXPOWER
Controls the output power.
void(* input)(void)
Callback for getting notified of incoming packet.
#define RFCORE_XREG_FSMSTAT1_FIFO
FIFO status.
#define CC2538_RF_CSP_ISRFOFF()
Send a RF OFF command strobe to the CSP.
#define RFCORE_XREG_RFIRQM0
RF interrupt masks.
int(* send)(const void *payload, unsigned short payload_len)
Prepare & transmit a packet.
int(* transmit)(unsigned short transmit_len)
Send the packet that has previously been prepared.
#define RFCORE_XREG_RSSISTAT
RSSI valid status register.
void process_poll(struct process *p)
Request a process to be polled.
int(* off)(void)
Turn the radio off.
#define RFCORE_FFSM_PAN_ID0
Local address information.
#define RFCORE_XREG_FRMCTRL0
Frame handling.
#define RFCORE_XREG_FSMSTAT1_FIFOP
FIFOP status.
#define RFCORE_XREG_RFIRQM0_FIFOP
RX FIFO exceeded threshold.
void cc2538_rf_err_isr(void)
The cc2538 RF Error ISR.
#define RFCORE_XREG_FREQCTRL
Controls the RF frequency.
void udma_channel_enable(uint8_t channel)
Enables a uDMA channel.
Header file for the real-time timer module.
#define RFCORE_SFR_MTM0
MAC Timer MUX register 0.
#define RFCORE_XREG_FRMCTRL0_RX_MODE
Set RX modes.
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
#define RFCORE_XREG_FSMSTAT1_CCA
Clear channel assessment.
#define RFCORE_XREG_TXFILTCFG
TX filter configuration.
Main API declarations for TSCH.
#define RFCORE_FFSM_PAN_ID1
Local address information.
#define RADIO_RX_MODE_ADDRESS_FILTER
The radio reception mode controls address filtering and automatic transmission of acknowledgements in...
#define RFCORE_SFR_MTMOVF2
MAC Timer MUX overflow 2.
void udma_channel_sw_request(uint8_t channel)
Generate a software trigger to start a transfer.
#define RFCORE_XREG_FIFOPCTRL
FIFOP threshold.
#define RADIO_TX_MODE_SEND_ON_CCA
The radio transmission mode controls whether transmissions should be done using clear channel assessm...
#define RFCORE_SFR_RFIRQF0_FIFOP
RX FIFO exceeded threshold.
void cc2538_rf_rx_tx_isr(void)
The cc2538 RF RX/TX ISR.
#define RFCORE_SFR_MTMOVF1_MTMOVF1
Register[15:8].
#define RFCORE_XREG_RFERRM
RF error interrupt mask.
static radio_value_t get_rssi(void)
Reads the current signal strength (RSSI)
#define RFCORE_SFR_MTCTRL_STATE
State of MAC Timer.
#define CC2538_RF_CSP_ISTXON()
Send a TX ON command strobe to the CSP.
#define RFCORE_SFR_MTMOVF2_MTMOVF2
Register[23:16].
const uint16_t tsch_timeslot_timing_us_10000[tsch_ts_elements_count]
The default timeslot timing in the standard is a guard time of 2200 us, a Tx offset of 2120 us and a ...
#define RFCORE_SFR_MTCTRL
MAC Timer control register.
int(* read)(void *buf, unsigned short buf_len)
Read a received packet into a buffer.
#define RFCORE_XREG_CCACTRL0
CCA threshold.
#define CC2538_RF_CSP_ISFLUSHRX()
Flush the RX FIFO.
#define RFCORE_XREG_RSSI
RSSI status register.
#define RFCORE_SFR_MTMOVF1
MAC Timer MUX overflow 1.
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.
#define RFCORE_XREG_FRMCTRL0_AUTOCRC
Auto CRC generation / checking.
#define RFCORE_XREG_AGCCTRL1
AGC reference level.
void udma_set_channel_control_word(uint8_t channel, uint32_t ctrl)
Configure the channel's control word.
#define RFCORE_XREG_RSSISTAT_RSSI_VALID
RSSI value is valid.
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
#define udma_xfer_size(len)
Calculate the value of the xfersize field in the control structure.
#define RFCORE_XREG_RXENABLE_RXENMASK
Enables the receiver.
#define CC2538_RF_CONF_RX_USE_DMA
RF RX over DMA.
uint8_t udma_channel_get_mode(uint8_t channel)
Retrieve the current mode for a channel.
#define RFCORE_SFR_RFERRF
RF error interrupt flags.
Header file for the logging system
#define RFCORE_SFR_MTMSEL_MTMOVFSEL
MTMOVF register select.
radio_result_t(* set_object)(radio_param_t param, const void *src, size_t size)
Set a radio parameter object.
#define RFCORE_SFR_RFERRF_RXOVERF
RX FIFO overflowed.
#define RFCORE_SFR_MTMSEL_MTMSEL
MTM register select.
#define SYS_CTRL_DCGCRFC
RF Core clocks - PM0.
#define RFCORE_XREG_RXENABLE
RX enabling.
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
int(* on)(void)
Turn the radio on.
#define CC2538_RF_CONF_TX_USE_DMA
RF TX over DMA.
#define RFCORE_SFR_MTM0_MTM0
Register[7:0].
#define RFCORE_SFR_RFIRQF0
RF interrupt flags.
void process_start(struct process *p, process_data_t data)
Start a process.
static uint8_t get_channel()
Get the current operating channel.
#define RFCORE_XREG_FRMFILT0
Frame filtering control.