59#define UDMA_TX_FLAGS (UDMA_CHCTL_ARBSIZE_128 | UDMA_CHCTL_XFERMODE_AUTO \
60 | UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_DSTSIZE_8 \
61 | UDMA_CHCTL_SRCINC_8 | UDMA_CHCTL_DSTINC_NONE)
63#define UDMA_RX_FLAGS (UDMA_CHCTL_ARBSIZE_128 | UDMA_CHCTL_XFERMODE_AUTO \
64 | UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_DSTSIZE_8 \
65 | UDMA_CHCTL_SRCINC_NONE | UDMA_CHCTL_DSTINC_8)
71#define UDMA_RX_SIZE_THRESHOLD 3
75#define LOG_MODULE "cc2538-rf"
76#define LOG_LEVEL LOG_LEVEL_NONE
80#define RF_MUST_RESET 0x40
84#define CRC_BIT_MASK 0x80
85#define LQI_BIT_MASK 0x7F
88#define RSSI_INVALID -128
91#define ONOFF_TIME RTIMER_ARCH_SECOND / 3125
93#ifdef CC2538_RF_CONF_AUTOACK
94#define CC2538_RF_AUTOACK CC2538_RF_CONF_AUTOACK
96#define CC2538_RF_AUTOACK 1
102#define RADIO_TO_RTIMER(X) ((uint32_t)((uint64_t)(X) * RTIMER_ARCH_SECOND / SYS_CTRL_32MHZ))
104#define CLOCK_STABLE() do { \
105 while ( !(REG(SYS_CTRL_CLOCK_STA) & (SYS_CTRL_CLOCK_STA_XOSC_STB))); \
109static uint8_t
volatile poll_mode = 0;
111static uint8_t send_on_cca = 1;
113static uint8_t crc_corr;
115static uint8_t rf_flags;
122typedef struct output_config {
127static const output_config_t output_power[] = {
146#define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t))
149#define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].power)
150#define OUTPUT_POWER_MAX (output_power[0].power)
157#define MAX_PAYLOAD_LEN (CC2538_RF_MAX_PACKET_LEN - CHECKSUM_LEN)
159PROCESS(cc2538_rf_process,
"cc2538 RF driver");
180 LOG_INFO(
"Set Channel\n");
190 (channel - CC2538_RF_CHANNEL_MIN) * CC2538_RF_CHANNEL_SPACING;
197 rf_channel = channel;
207set_pan_id(uint16_t pan)
220set_short_addr(uint16_t
addr)
248 }
while(rssi == RSSI_INVALID);
294get_cca_threshold(
void)
319 for(i = 0; i < OUTPUT_CONFIG_COUNT; i++) {
320 if(reg_val >= output_power[i].txpower_val) {
321 return output_power[i].power;
324 return OUTPUT_POWER_MIN;
338 for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) {
339 if(power <= output_power[i].power) {
347set_frame_filtering(uint8_t enable)
357set_shr_search(
int enable)
381set_poll_mode(uint8_t enable)
397set_send_on_cca(uint8_t enable)
399 send_on_cca = enable;
403set_auto_ack(uint8_t enable)
413get_sfd_timestamp(
void)
415 uint64_t sfd, timer_val, buffer;
425 timer_val |= (buffer << 32);
435 sfd |= (buffer << 32);
437 return RTIMER_NOW() - RADIO_TO_RTIMER(timer_val - sfd);
443static uint32_t prev_FRMCTRL0, prev_MDMTEST1;
444static uint8_t was_on;
447set_test_mode(uint8_t enable, uint8_t modulated)
502 cca = CC2538_RF_CCA_CLEAR;
504 cca = CC2538_RF_CCA_BUSY;
520 if(!(rf_flags & RX_ACTIVE)) {
524 rf_flags |= RX_ACTIVE;
527 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
548 rf_flags &= ~RX_ACTIVE;
550 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
559 if(rf_flags & RF_ON) {
576 REG(ANA_REGS_IVCTRL) = 0x0B;
630 set_poll_mode(poll_mode);
644prepare(
const void *payload,
unsigned short payload_len)
648 if(payload_len > MAX_PAYLOAD_LEN) {
652 LOG_INFO(
"Prepare 0x%02x bytes\n", payload_len + CHECKSUM_LEN);
660 if((rf_flags & RX_ACTIVE) == 0) {
671 LOG_INFO_(
"<uDMA payload>");
675 (uint32_t)(payload) + payload_len - 1);
693 for(i = 0; i < payload_len; i++) {
695 LOG_INFO_(
"%02x", ((
unsigned char *)(payload))[i]);
704transmit(
unsigned short transmit_len)
711 LOG_INFO(
"Transmit\n");
713 if(transmit_len > MAX_PAYLOAD_LEN) {
717 if(!(rf_flags & RX_ACTIVE)) {
721 while(RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + ONOFF_TIME));
725 if(channel_clear() == CC2538_RF_CCA_BUSY) {
739 ENERGEST_SWITCH(ENERGEST_TYPE_LISTEN, ENERGEST_TYPE_TRANSMIT);
745 && (counter++ < 3)) {
750 LOG_ERR(
"TX never active.\n");
758 ENERGEST_SWITCH(ENERGEST_TYPE_TRANSMIT, ENERGEST_TYPE_LISTEN);
768send(
const void *payload,
unsigned short payload_len)
770 prepare(payload, payload_len);
771 return transmit(payload_len);
775read(
void *buf,
unsigned short bufsize)
790 if(len > CC2538_RF_MAX_PACKET_LEN) {
792 LOG_ERR(
"RF: bad sync\n");
798 if(len <= CC2538_RF_MIN_PACKET_LEN) {
799 LOG_ERR(
"RF: too short\n");
805 if(len - CHECKSUM_LEN > bufsize) {
806 LOG_ERR(
"RF: too long\n");
813 LOG_INFO(
"read (0x%02x bytes) = ", len);
818 LOG_INFO_(
"<uDMA payload>");
822 (uint32_t)(buf) + len - 1);
837 for(i = 0; i < len; ++i) {
839 LOG_INFO_(
"%02x", ((
unsigned char *)(buf))[i]);
847 LOG_INFO_(
"%02x%02x\n", (uint8_t)rssi, crc_corr);
850 if(crc_corr & CRC_BIT_MASK) {
851 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);
852 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_corr & LQI_BIT_MASK);
854 LOG_ERR(
"Bad CRC\n");
874receiving_packet(
void)
876 LOG_INFO(
"Receiving\n");
892 LOG_INFO(
"Pending\n");
917 *value = get_pan_id();
920 *value = get_short_addr();
941 *value = get_tx_power();
944 *value = get_cca_threshold();
953 *value = crc_corr & LQI_BIT_MASK;
959 *value = CC2538_RF_CHANNEL_MIN;
962 *value = CC2538_RF_CHANNEL_MAX;
965 *value = OUTPUT_POWER_MIN;
968 *value = OUTPUT_POWER_MAX;
985 case RADIO_CONST_MAX_PAYLOAD_LEN:
1013 if(value < CC2538_RF_CHANNEL_MIN ||
1014 value > CC2538_RF_CHANNEL_MAX) {
1020 set_pan_id(value & 0xffff);
1023 set_short_addr(value & 0xffff);
1044 if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) {
1048 set_tx_power(value);
1051 set_cca_threshold(value);
1057 set_shr_search(value);
1065get_object(radio_param_t param,
void *dest,
size_t size)
1071 if(size != 8 || !dest) {
1076 for(i = 0; i < 8; i++) {
1084 if(size !=
sizeof(rtimer_clock_t) || !dest) {
1087 *(rtimer_clock_t *)dest = get_sfd_timestamp();
1091#if MAC_CONF_WITH_TSCH
1092 if(param == RADIO_CONST_TSCH_TIMING) {
1093 if(size !=
sizeof(uint16_t *) || !dest) {
1106set_object(radio_param_t param,
const void *src,
size_t size)
1111 if(size != 8 || !src) {
1115 for(i = 0; i < 8; i++) {
1166 NETSTACK_MAC.
input();
1171 if(rf_flags & RF_MUST_RESET) {
1234 rf_flags |= RF_MUST_RESET;
Header file for the cc2538 RF driver.
Header file for the energy estimation mechanism.
@ RF_ERR_IRQn
RF Error Interrupt.
@ RF_TX_RX_IRQn
RF Tx/Rx Interrupt.
void clock_delay_usec(uint16_t dt)
Delay a given number of microseconds.
void cc2538_rf_rx_tx_isr(void)
The cc2538 RF RX/TX ISR.
static radio_value_t get_rssi(void)
Reads the current signal strength (RSSI)
#define CC2538_RF_CSP_ISRFOFF()
Send a RF OFF command strobe to the CSP.
#define CC2538_RF_CSP_ISRXON()
Send an RX ON command strobe to the CSP.
static void get_iq_lsbs(radio_value_t *value)
Reads the current I/Q data of the received signal.
#define CC2538_RF_CSP_ISFLUSHTX()
Flush the TX FIFO.
static uint8_t get_channel()
Get the current operating channel.
const struct radio_driver cc2538_rf_driver
The NETSTACK data structure for the cc2538 RF driver.
static void set_channel(uint8_t channel)
Set the current operating channel.
#define CC2538_RF_CSP_ISFLUSHRX()
Flush the RX FIFO.
#define CC2538_RF_CSP_ISTXON()
Send a TX ON command strobe to the CSP.
void cc2538_rf_err_isr(void)
The cc2538 RF Error ISR.
#define RFCORE_FFSM_PAN_ID0
Local address information.
#define RFCORE_XREG_FSMSTAT1_SFD
SFD was sent/received.
#define RFCORE_SFR_MTM1
MAC Timer MUX register 1.
#define RFCORE_SFR_MTMOVF2_MTMOVF2
Register[23:16].
#define RFCORE_XREG_CCACTRL0
CCA threshold.
#define RFCORE_SFR_MTMOVF1_MTMOVF1
Register[15:8].
#define RFCORE_SFR_MTCTRL_STATE
State of MAC Timer.
#define RFCORE_XREG_FRMCTRL0
Frame handling.
#define RFCORE_XREG_FSMSTAT1
Radio status register.
#define RFCORE_XREG_SRCMATCH
Source address matching.
#define RFCORE_XREG_RXENABLE_RXENMASK
Enables the receiver.
#define RFCORE_XREG_FRMFILT0
Frame filtering control.
#define RFCORE_SFR_MTM0_MTM0
Register[7:0].
#define RFCORE_XREG_FRMCTRL0_RX_MODE
Set RX modes.
#define RFCORE_XREG_RFERRM_RFERRM
RF error interrupt mask.
#define RFCORE_XREG_FSMSTAT0
Radio status register.
#define RFCORE_SFR_MTCTRL_SYNC
Timer start/stop timing.
#define RFCORE_XREG_RFERRM
RF error interrupt mask.
#define RFCORE_XREG_RFRND_QRND
Random bit from the Q channel.
#define RFCORE_XREG_TXPOWER
Controls the output power.
#define RFCORE_SFR_MTMSEL
MAC Timer multiplex select.
#define RFCORE_SFR_MTMOVF0_MTMOVF0
Register[7:0].
#define RFCORE_XREG_FRMCTRL0_AUTOACK
Transmit ACK frame enable.
#define RFCORE_XREG_RSSISTAT
RSSI valid status register.
#define RFCORE_SFR_MTMOVF2
MAC Timer MUX overflow 2.
#define RFCORE_SFR_MTCTRL_RUN
Timer start/stop.
#define RFCORE_XREG_RFRND_IRND
Random bit from the I channel.
#define RFCORE_SFR_MTM0
MAC Timer MUX register 0.
#define RFCORE_XREG_MDMTEST1
Test Register for Modem.
#define RFCORE_SFR_RFERRF_RXOVERF
RX FIFO overflowed.
#define RFCORE_XREG_FSMSTAT1_FIFOP
FIFOP status.
#define RFCORE_FFSM_EXT_ADDR0
Local address information.
#define RFCORE_SFR_MTMOVF0
MAC Timer MUX overflow 0.
#define RFCORE_SFR_MTMOVF1
MAC Timer MUX overflow 1.
#define RFCORE_XREG_FSMSTAT1_TX_ACTIVE
Status signal - TX states.
#define RFCORE_XREG_RFIRQM0
RF interrupt masks.
#define RFCORE_XREG_FSMSTAT1_CCA
Clear channel assessment.
#define RFCORE_XREG_FRMCTRL0_AUTOCRC
Auto CRC generation / checking.
#define RFCORE_XREG_RSSI
RSSI status register.
#define RFCORE_SFR_MTCTRL_LATCH_MODE
OVF counter latch mode.
#define RFCORE_FFSM_PAN_ID1
Local address information.
#define RFCORE_XREG_AGCCTRL1
AGC reference level.
#define RFCORE_FFSM_SHORT_ADDR1
Local address information.
#define RFCORE_SFR_RFERRF
RF error interrupt flags.
#define RFCORE_XREG_FIFOPCTRL
FIFOP threshold.
#define RFCORE_SFR_RFDATA
TX/RX FIFO data.
#define RFCORE_SFR_MTM1_MTM1
Register[15:8].
#define RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE
FIFO and FFCTRL status.
#define RFCORE_XREG_FRMCTRL0_TX_MODE
Set test modes for TX.
#define RFCORE_XREG_RXENABLE
RX enabling.
#define RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN
Enables frame filtering.
#define RFCORE_FFSM_SHORT_ADDR0
Local address information.
#define RFCORE_SFR_RFIRQF0
RF interrupt flags.
#define RFCORE_XREG_CCACTRL0_CCA_THR
Clear-channel-assessment.
#define RFCORE_XREG_FREQCTRL
Controls the RF frequency.
#define RFCORE_SFR_MTCTRL
MAC Timer control register.
#define RFCORE_XREG_FSMSTAT1_FIFO
FIFO status.
#define RFCORE_XREG_RSSISTAT_RSSI_VALID
RSSI value is valid.
#define RFCORE_XREG_TXFILTCFG
TX filter configuration.
#define RFCORE_XREG_RFIRQM0_FIFOP
RX FIFO exceeded threshold.
#define RFCORE_XREG_RFRND
Random data.
#define RFCORE_XREG_FSCAL1
Tune frequency calibration.
#define SYS_CTRL_DCGCRFC
RF Core clocks - PM0.
#define SYS_CTRL_RCGCRFC
RF Core clocks - active mode.
#define SYS_CTRL_SCGCRFC
RF Core clocks - Sleep mode.
void udma_set_channel_dst(uint8_t channel, uint32_t dst_end)
Sets the channel's destination address.
void udma_channel_mask_set(uint8_t channel)
Disable peripheral triggers for a uDMA channel.
void udma_channel_enable(uint8_t channel)
Enables a uDMA channel.
uint8_t udma_channel_get_mode(uint8_t channel)
Retrieve the current mode for a channel.
void udma_channel_sw_request(uint8_t channel)
Generate a software trigger to start a transfer.
void udma_set_channel_control_word(uint8_t channel, uint32_t ctrl)
Configure the channel's control word.
#define udma_xfer_size(len)
Calculate the value of the xfersize field in the control structure.
void udma_set_channel_src(uint8_t channel, uint32_t src_end)
Sets the channels source address.
#define CC2538_RF_CONF_RX_USE_DMA
RF RX over DMA.
#define CC2538_RF_CONF_TX_USE_DMA
RF TX over DMA.
#define CC2538_RF_CONF_TX_DMA_CHAN
RF -> RAM DMA channel.
#define CC2538_RF_CONF_RX_DMA_CHAN
RAM -> RF DMA channel.
void iq_seeder_seed(void)
This function will feed the CSPRNG with a new seed.
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
void packetbuf_clear(void)
Clear and reset the packetbuf.
#define PROCESS(name, strname)
Declare a process.
#define PROCESS_BEGIN()
Define the beginning of a process.
#define PROCESS_END()
Define the end of a process.
void process_start(struct process *p, process_data_t data)
Start a process.
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
void process_poll(struct process *p)
Request a process to be polled.
#define RADIO_RX_MODE_ADDRESS_FILTER
Enable address-based frame filtering.
#define RADIO_RX_MODE_POLL_MODE
Enable/disable/get the state of radio driver poll mode operation.
#define RADIO_TX_MODE_SEND_ON_CCA
Radio TX mode control / retrieval.
enum radio_result_e radio_result_t
Radio return values when setting or getting radio parameters.
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio.
#define RADIO_RX_MODE_AUTOACK
Enable automatic transmission of ACK frames.
@ RADIO_RESULT_NOT_SUPPORTED
The parameter is not supported.
@ RADIO_RESULT_INVALID_VALUE
The value argument was incorrect.
@ RADIO_RESULT_OK
The parameter was set/read successfully.
@ RADIO_PARAM_POWER_MODE
When getting the value of this parameter, the radio driver should indicate whether the radio is on or...
@ RADIO_CONST_PHY_OVERHEAD
The physical layer header (PHR) + MAC layer footer (MFR) overhead in bytes.
@ RADIO_PARAM_RSSI
Received signal strength indicator in dBm.
@ RADIO_PARAM_LAST_PACKET_TIMESTAMP
Last packet timestamp, of type rtimer_clock_t.
@ RADIO_PARAM_IQ_LSBS
The current I/Q LSBs.
@ RADIO_PARAM_LAST_RSSI
The RSSI value of the last received packet.
@ RADIO_CONST_BYTE_AIR_TIME
The air time of one byte in usec, e.g.
@ RADIO_PARAM_RX_MODE
Radio receiver mode determines if the radio has address filter (RADIO_RX_MODE_ADDRESS_FILTER) and aut...
@ RADIO_PARAM_CHANNEL
Channel used for radio communication.
@ RADIO_PARAM_SHR_SEARCH
For enabling and disabling the SHR search.
@ RADIO_PARAM_LAST_LINK_QUALITY
Link quality indicator of the last received packet.
@ RADIO_CONST_DELAY_BEFORE_RX
The delay in usec between turning on the radio and it being actually listening (able to hear a preamb...
@ RADIO_PARAM_TXPOWER
Transmission power in dBm.
@ RADIO_PARAM_64BIT_ADDR
Long (64 bits) address for the radio, which is used by the address filter.
@ RADIO_CONST_DELAY_BEFORE_TX
The delay in usec between a call to the radio API's transmit function and the end of SFD transmission...
@ RADIO_CONST_CHANNEL_MAX
The highest radio channel number.
@ RADIO_PARAM_PAN_ID
The personal area network identifier (PAN ID), which is used by the h/w frame filtering functionality...
@ RADIO_PARAM_CCA_THRESHOLD
Clear channel assessment threshold in dBm.
@ RADIO_CONST_TXPOWER_MIN
The minimum transmission power in dBm.
@ RADIO_CONST_CHANNEL_MIN
The lowest radio channel number.
@ RADIO_CONST_TXPOWER_MAX
The maximum transmission power in dBm.
@ RADIO_CONST_DELAY_BEFORE_DETECT
The delay in usec between the end of SFD reception for an incoming frame and the radio API starting t...
@ RADIO_PARAM_16BIT_ADDR
The short address (16 bits) for the radio, which is used by the h/w filter.
@ RADIO_PARAM_TX_MODE
Radio transmission mode determines if the radio has send on CCA (RADIO_TX_MODE_SEND_ON_CCA) enabled o...
@ RADIO_SHR_SEARCH_EN
Enable SHR search or SHR search is enabled.
@ RADIO_SHR_SEARCH_DIS
Disable SHR search or SHR search is enabled.
@ RADIO_POWER_MODE_CARRIER_OFF
Radio powered on, but not emitting unmodulated carriers.
@ RADIO_POWER_MODE_OFF
Radio powered off and in the lowest possible power consumption state.
@ RADIO_POWER_MODE_ON
Radio powered on and able to receive frames.
@ RADIO_POWER_MODE_CARRIER_ON
Radio powered on and emitting unmodulated carriers.
@ RADIO_TX_COLLISION
TX failed due to a collision.
@ RADIO_TX_ERR
An error occurred during transmission.
@ RADIO_TX_OK
TX was successful and where an ACK was requested one was received.
#define RTIMER_NOW()
Get the current clock time.
const tsch_timeslot_timing_usec tsch_timeslot_timing_us_10000
TSCH timing attributes and description.
Header file for the link-layer address representation.
Header file for the logging system.
#define IEEE802154_DEFAULT_CHANNEL
The default channel for IEEE 802.15.4 networks.
Include file for the Contiki low-layer network stack (NETSTACK)
Header file for the Packet buffer (packetbuf) management.
Header file for the radio API.
Header file with register manipulation macro definitions.
Top-level header file for cc2538 RF Core registers.
Header file for the real-time timer module.
void(* input)(void)
Callback for getting notified of incoming packet.
The structure of a Contiki-NG radio device driver.
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
int(* read)(void *buf, unsigned short buf_len)
Read a received packet into a buffer.
int(* prepare)(const void *payload, unsigned short payload_len)
Prepare the radio with a packet to be sent.
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
int(* off)(void)
Turn the radio off.
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.
radio_result_t(* set_object)(radio_param_t param, const void *src, size_t size)
Set a radio parameter object.
int(* on)(void)
Turn the radio on.
int(* transmit)(unsigned short transmit_len)
Send the packet that has previously been prepared.
int(* pending_packet)(void)
Check if a packet has been received and is available in the radio driver's buffers.
radio_result_t(* get_value)(radio_param_t param, radio_value_t *value)
Get a radio parameter value.
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 cc2538 System Control driver.
Main API declarations for TSCH.
Header file with register, macro and function declarations for the cc2538 micro-DMA controller module...
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.