Merge pull request #684 from kkrentz/cc2538-pr
Improvements to cc2538-rf.c
This commit is contained in:
commit
710019877e
@ -68,13 +68,10 @@
|
||||
*/
|
||||
#define UDMA_RX_SIZE_THRESHOLD 3
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#endif
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "cc2538-rf"
|
||||
#define LOG_LEVEL LOG_LEVEL_NONE
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Local RF Flags */
|
||||
#define RX_ACTIVE 0x80
|
||||
@ -86,6 +83,7 @@
|
||||
#define LQI_BIT_MASK 0x7F
|
||||
/* RSSI Offset */
|
||||
#define RSSI_OFFSET 73
|
||||
#define RSSI_INVALID -128
|
||||
|
||||
/* 192 usec off -> on interval (RX Callib -> SFD Wait). We wait a bit more */
|
||||
#define ONOFF_TIME RTIMER_ARCH_SECOND / 3125
|
||||
@ -156,28 +154,19 @@ PROCESS(cc2538_rf_process, "cc2538 RF driver");
|
||||
static uint8_t
|
||||
get_channel()
|
||||
{
|
||||
uint8_t chan = REG(RFCORE_XREG_FREQCTRL) & RFCORE_XREG_FREQCTRL_FREQ;
|
||||
|
||||
return (chan - CC2538_RF_CHANNEL_MIN) / CC2538_RF_CHANNEL_SPACING
|
||||
+ CC2538_RF_CHANNEL_MIN;
|
||||
return rf_channel;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Set the current operating channel
|
||||
* \param channel The desired channel as a value in [11,26]
|
||||
* \return Returns a value in [11,26] representing the current channel
|
||||
* or a negative value if \e channel was out of bounds
|
||||
*/
|
||||
static int8_t
|
||||
static void
|
||||
set_channel(uint8_t channel)
|
||||
{
|
||||
uint8_t was_on = 0;
|
||||
|
||||
PRINTF("RF: Set Channel\n");
|
||||
|
||||
if((channel < CC2538_RF_CHANNEL_MIN) || (channel > CC2538_RF_CHANNEL_MAX)) {
|
||||
return CC2538_RF_CHANNEL_SET_ERROR;
|
||||
}
|
||||
LOG_INFO("Set Channel\n");
|
||||
|
||||
/* Changes to FREQCTRL take effect after the next recalibration */
|
||||
|
||||
@ -195,8 +184,6 @@ set_channel(uint8_t channel)
|
||||
}
|
||||
|
||||
rf_channel = channel;
|
||||
|
||||
return (int8_t)channel;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_value_t
|
||||
@ -244,10 +231,11 @@ get_rssi(void)
|
||||
on();
|
||||
}
|
||||
|
||||
/* Wait on RSSI_VALID */
|
||||
while((REG(RFCORE_XREG_RSSISTAT) & RFCORE_XREG_RSSISTAT_RSSI_VALID) == 0);
|
||||
|
||||
rssi = (int8_t)(REG(RFCORE_XREG_RSSI) & RFCORE_XREG_RSSI_RSSI_VAL) - RSSI_OFFSET;
|
||||
/* Wait for a valid RSSI reading */
|
||||
do {
|
||||
rssi = REG(RFCORE_XREG_RSSI);
|
||||
} while(rssi == RSSI_INVALID);
|
||||
rssi -= RSSI_OFFSET;
|
||||
|
||||
/* If we were off, turn back off */
|
||||
if(was_off) {
|
||||
@ -322,6 +310,16 @@ set_frame_filtering(uint8_t enable)
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_shr_search(int enable)
|
||||
{
|
||||
if(enable) {
|
||||
REG(RFCORE_XREG_FRMCTRL0) &= ~RFCORE_XREG_FRMCTRL0_RX_MODE;
|
||||
} else {
|
||||
REG(RFCORE_XREG_FRMCTRL0) |= RFCORE_XREG_FRMCTRL0_RX_MODE;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
mac_timer_init(void)
|
||||
{
|
||||
CLOCK_STABLE();
|
||||
@ -403,7 +401,7 @@ channel_clear(void)
|
||||
int cca;
|
||||
uint8_t was_off = 0;
|
||||
|
||||
PRINTF("RF: CCA\n");
|
||||
LOG_INFO("CCA\n");
|
||||
|
||||
/* If we are off, turn on first */
|
||||
if((REG(RFCORE_XREG_FSMSTAT0) & RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE) == 0) {
|
||||
@ -431,7 +429,7 @@ channel_clear(void)
|
||||
static int
|
||||
on(void)
|
||||
{
|
||||
PRINTF("RF: On\n");
|
||||
LOG_INFO("On\n");
|
||||
|
||||
if(!(rf_flags & RX_ACTIVE)) {
|
||||
CC2538_RF_CSP_ISFLUSHRX();
|
||||
@ -447,7 +445,7 @@ on(void)
|
||||
static int
|
||||
off(void)
|
||||
{
|
||||
PRINTF("RF: Off\n");
|
||||
LOG_INFO("Off\n");
|
||||
|
||||
/* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */
|
||||
while(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE);
|
||||
@ -470,7 +468,7 @@ off(void)
|
||||
static int
|
||||
init(void)
|
||||
{
|
||||
PRINTF("RF: Init\n");
|
||||
LOG_INFO("Init\n");
|
||||
|
||||
if(rf_flags & RF_ON) {
|
||||
return 0;
|
||||
@ -490,6 +488,7 @@ init(void)
|
||||
REG(RFCORE_XREG_TXFILTCFG) = 0x09; /** TX anti-aliasing filter bandwidth */
|
||||
REG(RFCORE_XREG_AGCCTRL1) = 0x15; /** AGC target value */
|
||||
REG(ANA_REGS_IVCTRL) = 0x0B; /** Bias currents */
|
||||
REG(RFCORE_XREG_FSCAL1) = 0x01; /** Tune frequency calibration */
|
||||
|
||||
/*
|
||||
* Defaults:
|
||||
@ -513,6 +512,9 @@ init(void)
|
||||
|
||||
set_channel(rf_channel);
|
||||
|
||||
/* Enable SHR search */
|
||||
set_shr_search(1);
|
||||
|
||||
/* Acknowledge all RF Error interrupts */
|
||||
REG(RFCORE_XREG_RFERRM) = RFCORE_XREG_RFERRM_RFERRM;
|
||||
NVIC_EnableIRQ(RF_ERR_IRQn);
|
||||
@ -545,8 +547,6 @@ init(void)
|
||||
|
||||
rf_flags |= RF_ON;
|
||||
|
||||
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -555,7 +555,7 @@ prepare(const void *payload, unsigned short payload_len)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
PRINTF("RF: Prepare 0x%02x bytes\n", payload_len + CHECKSUM_LEN);
|
||||
LOG_INFO("Prepare 0x%02x bytes\n", payload_len + CHECKSUM_LEN);
|
||||
|
||||
/*
|
||||
* When we transmit in very quick bursts, make sure previous transmission
|
||||
@ -569,12 +569,12 @@ prepare(const void *payload, unsigned short payload_len)
|
||||
|
||||
CC2538_RF_CSP_ISFLUSHTX();
|
||||
|
||||
PRINTF("RF: data = ");
|
||||
LOG_INFO("data = ");
|
||||
/* Send the phy length byte first */
|
||||
REG(RFCORE_SFR_RFDATA) = payload_len + CHECKSUM_LEN;
|
||||
|
||||
if(CC2538_RF_CONF_TX_USE_DMA) {
|
||||
PRINTF("<uDMA payload>");
|
||||
LOG_INFO_("<uDMA payload>");
|
||||
|
||||
/* Set the transfer source's end address */
|
||||
udma_set_channel_src(CC2538_RF_CONF_TX_DMA_CHAN,
|
||||
@ -598,10 +598,10 @@ prepare(const void *payload, unsigned short payload_len)
|
||||
} else {
|
||||
for(i = 0; i < payload_len; i++) {
|
||||
REG(RFCORE_SFR_RFDATA) = ((unsigned char *)(payload))[i];
|
||||
PRINTF("%02x", ((unsigned char *)(payload))[i]);
|
||||
LOG_INFO_("%02x", ((unsigned char *)(payload))[i]);
|
||||
}
|
||||
}
|
||||
PRINTF("\n");
|
||||
LOG_INFO_("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -614,7 +614,7 @@ transmit(unsigned short transmit_len)
|
||||
rtimer_clock_t t0;
|
||||
uint8_t was_off = 0;
|
||||
|
||||
PRINTF("RF: Transmit\n");
|
||||
LOG_INFO("Transmit\n");
|
||||
|
||||
if(!(rf_flags & RX_ACTIVE)) {
|
||||
t0 = RTIMER_NOW();
|
||||
@ -649,7 +649,7 @@ transmit(unsigned short transmit_len)
|
||||
}
|
||||
|
||||
if(!(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE)) {
|
||||
PRINTF("RF: TX never active.\n");
|
||||
LOG_ERR("TX never active.\n");
|
||||
CC2538_RF_CSP_ISFLUSHTX();
|
||||
ret = RADIO_TX_ERR;
|
||||
} else {
|
||||
@ -679,7 +679,7 @@ read(void *buf, unsigned short bufsize)
|
||||
uint8_t i;
|
||||
uint8_t len;
|
||||
|
||||
PRINTF("RF: Read\n");
|
||||
LOG_INFO("Read\n");
|
||||
|
||||
if((REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP) == 0) {
|
||||
return 0;
|
||||
@ -691,33 +691,33 @@ read(void *buf, unsigned short bufsize)
|
||||
/* Check for validity */
|
||||
if(len > CC2538_RF_MAX_PACKET_LEN) {
|
||||
/* Oops, we must be out of sync. */
|
||||
PRINTF("RF: bad sync\n");
|
||||
LOG_ERR("RF: bad sync\n");
|
||||
|
||||
CC2538_RF_CSP_ISFLUSHRX();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(len <= CC2538_RF_MIN_PACKET_LEN) {
|
||||
PRINTF("RF: too short\n");
|
||||
LOG_ERR("RF: too short\n");
|
||||
|
||||
CC2538_RF_CSP_ISFLUSHRX();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(len - CHECKSUM_LEN > bufsize) {
|
||||
PRINTF("RF: too long\n");
|
||||
LOG_ERR("RF: too long\n");
|
||||
|
||||
CC2538_RF_CSP_ISFLUSHRX();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If we reach here, chances are the FIFO is holding a valid frame */
|
||||
PRINTF("RF: read (0x%02x bytes) = ", len);
|
||||
LOG_INFO("read (0x%02x bytes) = ", len);
|
||||
len -= CHECKSUM_LEN;
|
||||
|
||||
/* Don't bother with uDMA for short frames (e.g. ACKs) */
|
||||
if(CC2538_RF_CONF_RX_USE_DMA && len > UDMA_RX_SIZE_THRESHOLD) {
|
||||
PRINTF("<uDMA payload>");
|
||||
LOG_INFO_("<uDMA payload>");
|
||||
|
||||
/* Set the transfer destination's end address */
|
||||
udma_set_channel_dst(CC2538_RF_CONF_RX_DMA_CHAN,
|
||||
@ -738,7 +738,7 @@ read(void *buf, unsigned short bufsize)
|
||||
} else {
|
||||
for(i = 0; i < len; ++i) {
|
||||
((unsigned char *)(buf))[i] = REG(RFCORE_SFR_RFDATA);
|
||||
PRINTF("%02x", ((unsigned char *)(buf))[i]);
|
||||
LOG_INFO_("%02x", ((unsigned char *)(buf))[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -746,14 +746,14 @@ read(void *buf, unsigned short bufsize)
|
||||
rssi = ((int8_t)REG(RFCORE_SFR_RFDATA)) - RSSI_OFFSET;
|
||||
crc_corr = REG(RFCORE_SFR_RFDATA);
|
||||
|
||||
PRINTF("%02x%02x\n", (uint8_t)rssi, crc_corr);
|
||||
LOG_INFO_("%02x%02x\n", (uint8_t)rssi, crc_corr);
|
||||
|
||||
/* MS bit CRC OK/Not OK, 7 LS Bits, Correlation value */
|
||||
if(crc_corr & CRC_BIT_MASK) {
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_corr & LQI_BIT_MASK);
|
||||
} else {
|
||||
PRINTF("RF: Bad CRC\n");
|
||||
LOG_ERR("Bad CRC\n");
|
||||
CC2538_RF_CSP_ISFLUSHRX();
|
||||
return 0;
|
||||
}
|
||||
@ -775,7 +775,7 @@ read(void *buf, unsigned short bufsize)
|
||||
static int
|
||||
receiving_packet(void)
|
||||
{
|
||||
PRINTF("RF: Receiving\n");
|
||||
LOG_INFO("Receiving\n");
|
||||
|
||||
/*
|
||||
* SFD high while transmitting and receiving.
|
||||
@ -791,7 +791,7 @@ receiving_packet(void)
|
||||
static int
|
||||
pending_packet(void)
|
||||
{
|
||||
PRINTF("RF: Pending\n");
|
||||
LOG_INFO("Pending\n");
|
||||
|
||||
return REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP;
|
||||
}
|
||||
@ -886,9 +886,7 @@ set_value(radio_param_t param, radio_value_t value)
|
||||
value > CC2538_RF_CHANNEL_MAX) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
if(set_channel(value) == CC2538_RF_CHANNEL_SET_ERROR) {
|
||||
return RADIO_RESULT_ERROR;
|
||||
}
|
||||
set_channel(value);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_PAN_ID:
|
||||
set_pan_id(value & 0xffff);
|
||||
@ -924,6 +922,9 @@ set_value(radio_param_t param, radio_value_t value)
|
||||
case RADIO_PARAM_CCA_THRESHOLD:
|
||||
set_cca_threshold(value);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_SHR_SEARCH:
|
||||
set_shr_search(value);
|
||||
return RADIO_RESULT_OK;
|
||||
default:
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
@ -1085,7 +1086,7 @@ cc2538_rf_rx_tx_isr(void)
|
||||
void
|
||||
cc2538_rf_err_isr(void)
|
||||
{
|
||||
PRINTF("RF Error: 0x%08lx\n", REG(RFCORE_SFR_RFERRF));
|
||||
LOG_ERR("Error 0x%08lx occurred\n", REG(RFCORE_SFR_RFERRF));
|
||||
|
||||
/* If the error is not an RX FIFO overflow, set a flag */
|
||||
if(REG(RFCORE_SFR_RFERRF) != RFCORE_SFR_RFERRF_RXOVERF) {
|
||||
@ -1097,10 +1098,5 @@ cc2538_rf_err_isr(void)
|
||||
process_poll(&cc2538_rf_process);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
cc2538_rf_set_promiscous_mode(char p)
|
||||
{
|
||||
set_frame_filtering(p);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/** @} */
|
||||
|
@ -56,7 +56,6 @@
|
||||
#define CC2538_RF_CHANNEL_MIN 11
|
||||
#define CC2538_RF_CHANNEL_MAX 26
|
||||
#define CC2538_RF_CHANNEL_SPACING 5
|
||||
#define CC2538_RF_CHANNEL_SET_ERROR -1
|
||||
#define CC2538_RF_MAX_PACKET_LEN 127
|
||||
#define CC2538_RF_MIN_PACKET_LEN 4
|
||||
#define CC2538_RF_CCA_CLEAR 1
|
||||
@ -113,7 +112,6 @@
|
||||
*/
|
||||
#define CC2538_RF_CSP_ISFLUSHRX() do { \
|
||||
REG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX; \
|
||||
REG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX; \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
@ -121,7 +119,6 @@
|
||||
*/
|
||||
#define CC2538_RF_CSP_ISFLUSHTX() do { \
|
||||
REG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; \
|
||||
REG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; \
|
||||
} while(0)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** The NETSTACK data structure for the cc2538 RF driver */
|
||||
@ -138,16 +135,6 @@ extern const struct radio_driver cc2538_rf_driver;
|
||||
*/
|
||||
void cc2538_rf_set_addr(uint16_t pan);
|
||||
|
||||
/**
|
||||
* \brief Turn promiscous mode on or off
|
||||
* \param p If promiscous mode should be on (1) or off (0)
|
||||
*
|
||||
* This function turns promiscous mode on or off. In promiscous mode,
|
||||
* every received frame is returned from the RF core. In
|
||||
* non-promiscous mode, only broadcast frames or frames with our
|
||||
* address as the receive address are returned from the RF core.
|
||||
*/
|
||||
void cc2538_rf_set_promiscous_mode(char p);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* CC2538_RF_H__ */
|
||||
|
||||
|
@ -170,6 +170,9 @@ enum {
|
||||
* it needs to be used with radio.get_object()/set_object(). */
|
||||
RADIO_PARAM_LAST_PACKET_TIMESTAMP,
|
||||
|
||||
/* For enabling and disabling the SHR search */
|
||||
RADIO_PARAM_SHR_SEARCH,
|
||||
|
||||
/* Constants (read only) */
|
||||
|
||||
/* The lowest radio channel. */
|
||||
|
Loading…
Reference in New Issue
Block a user