Merge pull request #617 from nfi/extended-radio-api
Extended radio API with support for setting channel, pan id, addressing modes, etc
This commit is contained in:
commit
64f65b4e45
24 changed files with 2055 additions and 177 deletions
|
@ -28,7 +28,7 @@ send(const void *payload, unsigned short payload_len)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
read(void *buf, unsigned short buf_len)
|
||||
radio_read(void *buf, unsigned short buf_len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -63,17 +63,45 @@ off(void)
|
|||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_value(radio_param_t param, radio_value_t *value)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_value(radio_param_t param, radio_value_t value)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_object(radio_param_t param, void *dest, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_object(radio_param_t param, const void *src, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct radio_driver nullradio_driver =
|
||||
{
|
||||
init,
|
||||
prepare,
|
||||
transmit,
|
||||
send,
|
||||
read,
|
||||
radio_read,
|
||||
channel_clear,
|
||||
receiving_packet,
|
||||
pending_packet,
|
||||
on,
|
||||
off,
|
||||
get_value,
|
||||
set_value,
|
||||
get_object,
|
||||
set_object
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
195
core/dev/radio.h
195
core/dev/radio.h
|
@ -49,18 +49,183 @@
|
|||
* Header file for the radio API
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
* Joakim Eriksson <joakime@sics.se>
|
||||
* Niclas Finne <nfi@sics.se>
|
||||
* Nicolas Tsiftes <nvt@sics.se>
|
||||
*/
|
||||
|
||||
#ifndef RADIO_H_
|
||||
#define RADIO_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* Each radio has a set of parameters that designate the current
|
||||
* configuration and state of the radio. Parameters can either have
|
||||
* values of type radio_value_t, or, when this type is insufficient, a
|
||||
* generic object that is specified by a memory pointer and the size
|
||||
* of the object.
|
||||
*
|
||||
* The radio_value_t type is set to an integer type that can hold most
|
||||
* values used to configure the radio, and is therefore the most
|
||||
* common type used for a parameter. Certain parameters require
|
||||
* objects of a considerably larger size than radio_value_t, however,
|
||||
* and in these cases the documentation below for the parameter will
|
||||
* indicate this.
|
||||
*
|
||||
* All radio parameters that can vary during runtime are prefixed by
|
||||
* "RADIO_PARAM", whereas those "parameters" that are guaranteed to
|
||||
* remain immutable are prefixed by "RADIO_CONST". Each mutable
|
||||
* parameter has a set of valid parameter values. When attempting to
|
||||
* set a parameter to an invalid value, the radio will return
|
||||
* RADIO_RESULT_INVALID_VALUE.
|
||||
*
|
||||
* Some radios support only a subset of the defined radio parameters.
|
||||
* When trying to set or get such an unsupported parameter, the radio
|
||||
* will return RADIO_RESULT_NOT_SUPPORTED.
|
||||
*/
|
||||
|
||||
typedef int radio_value_t;
|
||||
typedef unsigned radio_param_t;
|
||||
|
||||
enum {
|
||||
|
||||
/* Radio power mode determines if the radio is on
|
||||
(RADIO_POWER_MODE_ON) or off (RADIO_POWER_MODE_OFF). */
|
||||
RADIO_PARAM_POWER_MODE,
|
||||
|
||||
/*
|
||||
* Channel used for radio communication. The channel depends on the
|
||||
* communication standard used by the radio. The values can range
|
||||
* from RADIO_CONST_CHANNEL_MIN to RADIO_CONST_CHANNEL_MAX.
|
||||
*/
|
||||
RADIO_PARAM_CHANNEL,
|
||||
|
||||
/* Personal area network identifier, which is used by the address filter. */
|
||||
RADIO_PARAM_PAN_ID,
|
||||
|
||||
/* Short address (16 bits) for the radio, which is used by the address
|
||||
filter. */
|
||||
RADIO_PARAM_16BIT_ADDR,
|
||||
|
||||
/*
|
||||
* Radio receiver mode determines if the radio has address filter
|
||||
* (RADIO_RX_MODE_ADDRESS_FILTER) and auto-ACK (RADIO_RX_MODE_AUTOACK)
|
||||
* enabled. This parameter is set as a bit mask.
|
||||
*/
|
||||
RADIO_PARAM_RX_MODE,
|
||||
|
||||
/*
|
||||
* Radio transmission mode determines if the radio has send on CCA
|
||||
* (RADIO_TX_MODE_SEND_ON_CCA) enabled or not. This parameter is set
|
||||
* as a bit mask.
|
||||
*/
|
||||
RADIO_PARAM_TX_MODE,
|
||||
|
||||
/*
|
||||
* Transmission power in dBm. The values can range from
|
||||
* RADIO_CONST_TXPOWER_MIN to RADIO_CONST_TXPOWER_MAX.
|
||||
*
|
||||
* Some radios restrict the available values to a subset of this
|
||||
* range. If an unavailable TXPOWER value is requested to be set,
|
||||
* the radio may select another TXPOWER close to the requested
|
||||
* one. When getting the value of this parameter, the actual value
|
||||
* used by the radio will be returned.
|
||||
*/
|
||||
RADIO_PARAM_TXPOWER,
|
||||
|
||||
/*
|
||||
* Clear channel assessment threshold in dBm. This threshold
|
||||
* determines the minimum RSSI level at which the radio will assume
|
||||
* that there is a packet in the air.
|
||||
*
|
||||
* The CCA threshold must be set to a level above the noise floor of
|
||||
* the deployment. Otherwise mechanisms such as send-on-CCA and
|
||||
* low-power-listening duty cycling protocols may not work
|
||||
* correctly. Hence, the default value of the system may not be
|
||||
* optimal for any given deployment.
|
||||
*/
|
||||
RADIO_PARAM_CCA_THRESHOLD,
|
||||
|
||||
/* Received signal strength indicator in dBm. */
|
||||
RADIO_PARAM_RSSI,
|
||||
|
||||
/*
|
||||
* Long (64 bits) address for the radio, which is used by the address filter.
|
||||
* The address is specified in network byte order.
|
||||
*
|
||||
* Because this parameter value is larger than what fits in radio_value_t,
|
||||
* it needs to be used with radio.get_object()/set_object().
|
||||
*/
|
||||
RADIO_PARAM_64BIT_ADDR,
|
||||
|
||||
/* Constants (read only) */
|
||||
|
||||
/* The lowest radio channel. */
|
||||
RADIO_CONST_CHANNEL_MIN,
|
||||
/* The highest radio channel. */
|
||||
RADIO_CONST_CHANNEL_MAX,
|
||||
|
||||
/* The minimum transmission power in dBm. */
|
||||
RADIO_CONST_TXPOWER_MIN,
|
||||
/* The maximum transmission power in dBm. */
|
||||
RADIO_CONST_TXPOWER_MAX
|
||||
};
|
||||
|
||||
/* Radio power modes */
|
||||
enum {
|
||||
RADIO_POWER_MODE_OFF,
|
||||
RADIO_POWER_MODE_ON
|
||||
};
|
||||
|
||||
/**
|
||||
* The radio reception mode controls address filtering and automatic
|
||||
* transmission of acknowledgements in the radio (if such operations
|
||||
* are supported by the radio). A single parameter is used to allow
|
||||
* setting these features simultaneously as an atomic operation.
|
||||
*
|
||||
* To enable both address filter and transmissions of automatic
|
||||
* acknowledgments:
|
||||
*
|
||||
* NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE,
|
||||
* RADIO_RX_MODE_ADDRESS_FILTER | RADIO_RX_MODE_AUTOACK);
|
||||
*/
|
||||
#define RADIO_RX_MODE_ADDRESS_FILTER (1 << 0)
|
||||
#define RADIO_RX_MODE_AUTOACK (1 << 1)
|
||||
|
||||
/**
|
||||
* The radio transmission mode controls whether transmissions should
|
||||
* be done using clear channel assessment (if supported by the
|
||||
* radio). If send-on-CCA is enabled, the radio's send function will
|
||||
* wait for a radio-specific time window for the channel to become
|
||||
* clear. If this does not happen, the send function will return
|
||||
* RADIO_TX_COLLISION.
|
||||
*/
|
||||
#define RADIO_TX_MODE_SEND_ON_CCA (1 << 0)
|
||||
|
||||
/* Radio return values when setting or getting radio parameters. */
|
||||
typedef enum {
|
||||
RADIO_RESULT_OK,
|
||||
RADIO_RESULT_NOT_SUPPORTED,
|
||||
RADIO_RESULT_INVALID_VALUE,
|
||||
RADIO_RESULT_ERROR
|
||||
} radio_result_t;
|
||||
|
||||
/* Radio return values for transmissions. */
|
||||
enum {
|
||||
RADIO_TX_OK,
|
||||
RADIO_TX_ERR,
|
||||
RADIO_TX_COLLISION,
|
||||
RADIO_TX_NOACK,
|
||||
};
|
||||
|
||||
/**
|
||||
* The structure of a device driver for a radio in Contiki.
|
||||
*/
|
||||
struct radio_driver {
|
||||
|
||||
int (* init)(void);
|
||||
|
||||
|
||||
/** Prepare the radio with a packet to be sent. */
|
||||
int (* prepare)(const void *payload, unsigned short payload_len);
|
||||
|
||||
|
@ -88,18 +253,30 @@ struct radio_driver {
|
|||
|
||||
/** Turn the radio off. */
|
||||
int (* off)(void);
|
||||
};
|
||||
|
||||
/* Generic radio return values. */
|
||||
enum {
|
||||
RADIO_TX_OK,
|
||||
RADIO_TX_ERR,
|
||||
RADIO_TX_COLLISION,
|
||||
RADIO_TX_NOACK,
|
||||
/** Get a radio parameter value. */
|
||||
radio_result_t (* get_value)(radio_param_t param, radio_value_t *value);
|
||||
|
||||
/** Set a radio parameter value. */
|
||||
radio_result_t (* set_value)(radio_param_t param, radio_value_t value);
|
||||
|
||||
/**
|
||||
* Get a radio parameter object. The argument 'dest' must point to a
|
||||
* memory area of at least 'size' bytes, and this memory area will
|
||||
* contain the parameter object if the function succeeds.
|
||||
*/
|
||||
radio_result_t (* get_object)(radio_param_t param, void *dest, size_t size);
|
||||
|
||||
/**
|
||||
* Set a radio parameter object. The memory area referred to by the
|
||||
* argument 'src' will not be accessed after the function returns.
|
||||
*/
|
||||
radio_result_t (* set_object)(radio_param_t param, const void *src,
|
||||
size_t size);
|
||||
|
||||
};
|
||||
|
||||
#endif /* RADIO_H_ */
|
||||
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
|
|
@ -252,6 +252,31 @@ static int rf230_cca(void);
|
|||
|
||||
uint8_t rf230_last_correlation,rf230_last_rssi,rf230_smallest_rssi;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_value(radio_param_t param, radio_value_t *value)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_value(radio_param_t param, radio_value_t value)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_object(radio_param_t param, void *dest, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_object(radio_param_t param, const void *src, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct radio_driver rf230_driver =
|
||||
{
|
||||
rf230_init,
|
||||
|
@ -263,7 +288,11 @@ const struct radio_driver rf230_driver =
|
|||
rf230_receiving_packet,
|
||||
rf230_pending_packet,
|
||||
rf230_on,
|
||||
rf230_off
|
||||
rf230_off,
|
||||
get_value,
|
||||
set_value,
|
||||
get_object,
|
||||
set_object
|
||||
};
|
||||
|
||||
uint8_t RF230_receive_on;
|
||||
|
|
|
@ -686,6 +686,30 @@ off(void)
|
|||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_value(radio_param_t param, radio_value_t *value)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_value(radio_param_t param, radio_value_t value)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_object(radio_param_t param, void *dest, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_object(radio_param_t param, const void *src, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct radio_driver cc2430_rf_driver = {
|
||||
init,
|
||||
prepare,
|
||||
|
@ -697,6 +721,10 @@ const struct radio_driver cc2430_rf_driver = {
|
|||
pending_packet,
|
||||
on,
|
||||
off,
|
||||
get_value,
|
||||
set_value,
|
||||
get_object,
|
||||
set_object
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if !NETSTACK_CONF_SHORTCUTS
|
||||
|
|
|
@ -126,10 +126,43 @@ static uint8_t rf_flags;
|
|||
static int on(void);
|
||||
static int off(void);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* TX Power dBm lookup table. Values from SmartRF Studio v1.16.0 */
|
||||
typedef struct output_config {
|
||||
radio_value_t power;
|
||||
uint8_t txpower_val;
|
||||
} output_config_t;
|
||||
|
||||
static const output_config_t output_power[] = {
|
||||
{ 7, 0xFF },
|
||||
{ 5, 0xED },
|
||||
{ 3, 0xD5 },
|
||||
{ 1, 0xC5 },
|
||||
{ 0, 0xB6 },
|
||||
{ -1, 0xB0 },
|
||||
{ -3, 0xA1 },
|
||||
{ -5, 0x91 },
|
||||
{ -7, 0x88 },
|
||||
{ -9, 0x72 },
|
||||
{-11, 0x62 },
|
||||
{-13, 0x58 },
|
||||
{-15, 0x42 },
|
||||
{-24, 0x00 },
|
||||
};
|
||||
|
||||
#define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t))
|
||||
|
||||
/* Max and Min Output Power in dBm */
|
||||
#define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].power)
|
||||
#define OUTPUT_POWER_MAX (output_power[0].power)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(cc2538_rf_process, "cc2538 RF driver");
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
cc2538_rf_channel_get()
|
||||
/**
|
||||
* \brief Get the current operating channel
|
||||
* \return Returns a value in [11,26] representing the current channel
|
||||
*/
|
||||
static uint8_t
|
||||
get_channel()
|
||||
{
|
||||
uint8_t chan = REG(RFCORE_XREG_FREQCTRL) & RFCORE_XREG_FREQCTRL_FREQ;
|
||||
|
||||
|
@ -137,13 +170,19 @@ cc2538_rf_channel_get()
|
|||
+ CC2538_RF_CHANNEL_MIN);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int8_t
|
||||
cc2538_rf_channel_set(uint8_t 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
|
||||
set_channel(uint8_t channel)
|
||||
{
|
||||
PRINTF("RF: Set Channel\n");
|
||||
|
||||
if((channel < CC2538_RF_CHANNEL_MIN) || (channel > CC2538_RF_CHANNEL_MAX)) {
|
||||
return -1;
|
||||
return CC2538_RF_CHANNEL_SET_ERROR;
|
||||
}
|
||||
|
||||
/* Changes to FREQCTRL take effect after the next recalibration */
|
||||
|
@ -155,41 +194,43 @@ cc2538_rf_channel_set(uint8_t channel)
|
|||
return (int8_t) channel;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
cc2538_rf_power_set(uint8_t new_power)
|
||||
static radio_value_t
|
||||
get_pan_id(void)
|
||||
{
|
||||
PRINTF("RF: Set Power\n");
|
||||
|
||||
REG(RFCORE_XREG_TXPOWER) = new_power;
|
||||
|
||||
return (REG(RFCORE_XREG_TXPOWER) & 0xFF);
|
||||
return (radio_value_t)(REG(RFCORE_FFSM_PAN_ID1) << 8 | REG(RFCORE_FFSM_PAN_ID0));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* ToDo: Check once we have info on the... infopage */
|
||||
void
|
||||
cc2538_rf_set_addr(uint16_t pan)
|
||||
static void
|
||||
set_pan_id(uint16_t pan)
|
||||
{
|
||||
#if LINKADDR_SIZE==8
|
||||
/* EXT_ADDR[7:0] is ignored when using short addresses */
|
||||
int i;
|
||||
|
||||
for(i = (LINKADDR_SIZE - 1); i >= 0; --i) {
|
||||
((uint32_t *)RFCORE_FFSM_EXT_ADDR0)[i] =
|
||||
linkaddr_node_addr.u8[LINKADDR_SIZE - 1 - i];
|
||||
}
|
||||
#endif
|
||||
|
||||
REG(RFCORE_FFSM_PAN_ID0) = pan & 0xFF;
|
||||
REG(RFCORE_FFSM_PAN_ID1) = pan >> 8;
|
||||
|
||||
REG(RFCORE_FFSM_SHORT_ADDR0) = linkaddr_node_addr.u8[LINKADDR_SIZE - 1];
|
||||
REG(RFCORE_FFSM_SHORT_ADDR1) = linkaddr_node_addr.u8[LINKADDR_SIZE - 2];
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
cc2538_rf_read_rssi(void)
|
||||
static radio_value_t
|
||||
get_short_addr(void)
|
||||
{
|
||||
int rssi;
|
||||
return (radio_value_t)(REG(RFCORE_FFSM_SHORT_ADDR1) << 8 | REG(RFCORE_FFSM_SHORT_ADDR0));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_short_addr(uint16_t addr)
|
||||
{
|
||||
REG(RFCORE_FFSM_SHORT_ADDR0) = addr & 0xFF;
|
||||
REG(RFCORE_FFSM_SHORT_ADDR1) = addr >> 8;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Reads the current signal strength (RSSI)
|
||||
* \return The current RSSI in dBm
|
||||
*
|
||||
* This function reads the current RSSI on the currently configured
|
||||
* channel.
|
||||
*/
|
||||
static radio_value_t
|
||||
get_rssi(void)
|
||||
{
|
||||
int8_t rssi;
|
||||
|
||||
/* If we are off, turn on first */
|
||||
if((REG(RFCORE_XREG_FSMSTAT0) & RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE) == 0) {
|
||||
|
@ -200,7 +241,7 @@ cc2538_rf_read_rssi(void)
|
|||
/* Wait on RSSI_VALID */
|
||||
while((REG(RFCORE_XREG_RSSISTAT) & RFCORE_XREG_RSSISTAT_RSSI_VALID) == 0);
|
||||
|
||||
rssi = ((int8_t)REG(RFCORE_XREG_RSSI)) - RSSI_OFFSET;
|
||||
rssi = (int8_t)(REG(RFCORE_XREG_RSSI) & RFCORE_XREG_RSSI_RSSI_VAL) - RSSI_OFFSET;
|
||||
|
||||
/* If we were off, turn back off */
|
||||
if((rf_flags & WAS_OFF) == WAS_OFF) {
|
||||
|
@ -211,6 +252,80 @@ cc2538_rf_read_rssi(void)
|
|||
return rssi;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Returns the current CCA threshold in dBm */
|
||||
static radio_value_t
|
||||
get_cca_threshold(void)
|
||||
{
|
||||
return (int8_t)(REG(RFCORE_XREG_CCACTRL0) & RFCORE_XREG_CCACTRL0_CCA_THR) - RSSI_OFFSET;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Sets the CCA threshold in dBm */
|
||||
static void
|
||||
set_cca_threshold(radio_value_t value)
|
||||
{
|
||||
REG(RFCORE_XREG_CCACTRL0) = (value & 0xFF) + RSSI_OFFSET;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Returns the current TX power in dBm */
|
||||
static radio_value_t
|
||||
get_tx_power(void)
|
||||
{
|
||||
int i;
|
||||
uint8_t reg_val = REG(RFCORE_XREG_TXPOWER) & 0xFF;
|
||||
|
||||
/*
|
||||
* Find the TXPOWER value in the lookup table
|
||||
* If the value has been written with set_tx_power, we should be able to
|
||||
* find the exact value. However, in case the register has been written in
|
||||
* a different fashion, we return the immediately lower value of the lookup
|
||||
*/
|
||||
for(i = 0; i < OUTPUT_CONFIG_COUNT; i++) {
|
||||
if(reg_val >= output_power[i].txpower_val) {
|
||||
return output_power[i].power;
|
||||
}
|
||||
}
|
||||
return OUTPUT_POWER_MIN;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Set TX power to 'at least' power dBm
|
||||
* This works with a lookup table. If the value of 'power' does not exist in
|
||||
* the lookup table, TXPOWER will be set to the immediately higher available
|
||||
* value
|
||||
*/
|
||||
static void
|
||||
set_tx_power(radio_value_t power)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) {
|
||||
if(power <= output_power[i].power) {
|
||||
REG(RFCORE_XREG_TXPOWER) = output_power[i].txpower_val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_frame_filtering(uint8_t enable)
|
||||
{
|
||||
if(enable) {
|
||||
REG(RFCORE_XREG_FRMFILT0) |= RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN;
|
||||
} else {
|
||||
REG(RFCORE_XREG_FRMFILT0) &= ~RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_auto_ack(uint8_t enable)
|
||||
{
|
||||
if(enable) {
|
||||
REG(RFCORE_XREG_FRMCTRL0) |= RFCORE_XREG_FRMCTRL0_AUTOACK;
|
||||
} else {
|
||||
REG(RFCORE_XREG_FRMCTRL0) &= ~RFCORE_XREG_FRMCTRL0_AUTOACK;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Netstack API radio driver functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
|
@ -327,8 +442,10 @@ init(void)
|
|||
/* MAX FIFOP threshold */
|
||||
REG(RFCORE_XREG_FIFOPCTRL) = CC2538_RF_MAX_PACKET_LEN;
|
||||
|
||||
cc2538_rf_power_set(CC2538_RF_TX_POWER);
|
||||
cc2538_rf_channel_set(CC2538_RF_CHANNEL);
|
||||
/* Set TX Power */
|
||||
REG(RFCORE_XREG_TXPOWER) = CC2538_RF_TX_POWER;
|
||||
|
||||
set_channel(CC2538_RF_CHANNEL);
|
||||
|
||||
/* Acknowledge RF interrupts, FIFOP only */
|
||||
REG(RFCORE_XREG_RFIRQM0) |= RFCORE_XREG_RFIRQM0_FIFOP;
|
||||
|
@ -638,6 +755,156 @@ pending_packet(void)
|
|||
return (REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_value(radio_param_t param, radio_value_t *value)
|
||||
{
|
||||
if(!value) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
|
||||
switch(param) {
|
||||
case RADIO_PARAM_POWER_MODE:
|
||||
*value = (REG(RFCORE_XREG_RXENABLE) && RFCORE_XREG_RXENABLE_RXENMASK) == 0
|
||||
? RADIO_POWER_MODE_OFF : RADIO_POWER_MODE_ON;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_CHANNEL:
|
||||
*value = (radio_value_t)get_channel();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_PAN_ID:
|
||||
*value = get_pan_id();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_16BIT_ADDR:
|
||||
*value = get_short_addr();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_RX_MODE:
|
||||
*value = 0;
|
||||
if(REG(RFCORE_XREG_FRMFILT0) & RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN) {
|
||||
*value |= RADIO_RX_MODE_ADDRESS_FILTER;
|
||||
}
|
||||
if(REG(RFCORE_XREG_FRMCTRL0) & RFCORE_XREG_FRMCTRL0_AUTOACK) {
|
||||
*value |= RADIO_RX_MODE_AUTOACK;
|
||||
}
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_TXPOWER:
|
||||
*value = get_tx_power();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_CCA_THRESHOLD:
|
||||
*value = get_cca_threshold();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_RSSI:
|
||||
*value = get_rssi();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_CHANNEL_MIN:
|
||||
*value = CC2538_RF_CHANNEL_MIN;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_CHANNEL_MAX:
|
||||
*value = CC2538_RF_CHANNEL_MAX;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_TXPOWER_MIN:
|
||||
*value = OUTPUT_POWER_MIN;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_TXPOWER_MAX:
|
||||
*value = OUTPUT_POWER_MAX;
|
||||
return RADIO_RESULT_OK;
|
||||
default:
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_value(radio_param_t param, radio_value_t value)
|
||||
{
|
||||
switch(param) {
|
||||
case RADIO_PARAM_POWER_MODE:
|
||||
if(value == RADIO_POWER_MODE_ON) {
|
||||
on();
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
if(value == RADIO_POWER_MODE_OFF) {
|
||||
off();
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
case RADIO_PARAM_CHANNEL:
|
||||
if(value < CC2538_RF_CHANNEL_MIN ||
|
||||
value > CC2538_RF_CHANNEL_MAX) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
if(set_channel(value) == CC2538_RF_CHANNEL_SET_ERROR) {
|
||||
return RADIO_RESULT_ERROR;
|
||||
}
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_PAN_ID:
|
||||
set_pan_id(value & 0xffff);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_16BIT_ADDR:
|
||||
set_short_addr(value & 0xffff);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_RX_MODE:
|
||||
if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER |
|
||||
RADIO_RX_MODE_AUTOACK)) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
|
||||
set_frame_filtering((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0);
|
||||
set_auto_ack((value & RADIO_RX_MODE_AUTOACK) != 0);
|
||||
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_TXPOWER:
|
||||
if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
|
||||
set_tx_power(value);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_CCA_THRESHOLD:
|
||||
set_cca_threshold(value);
|
||||
return RADIO_RESULT_OK;
|
||||
default:
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_object(radio_param_t param, void *dest, size_t size)
|
||||
{
|
||||
uint8_t *target;
|
||||
int i;
|
||||
|
||||
if(param == RADIO_PARAM_64BIT_ADDR) {
|
||||
if(size != 8 || !dest) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
|
||||
target = dest;
|
||||
for(i = 0; i < 8; i++) {
|
||||
target[i] = ((uint32_t *)RFCORE_FFSM_EXT_ADDR0)[7 - i] & 0xFF;
|
||||
}
|
||||
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_object(radio_param_t param, const void *src, size_t size)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(param == RADIO_PARAM_64BIT_ADDR) {
|
||||
if(size != 8 || !src) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
|
||||
for(i = 0; i < 8; i++) {
|
||||
((uint32_t *)RFCORE_FFSM_EXT_ADDR0)[i] = ((uint8_t *)src)[7 - i];
|
||||
}
|
||||
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct radio_driver cc2538_rf_driver = {
|
||||
init,
|
||||
prepare,
|
||||
|
@ -649,6 +916,10 @@ const struct radio_driver cc2538_rf_driver = {
|
|||
pending_packet,
|
||||
on,
|
||||
off,
|
||||
get_value,
|
||||
set_value,
|
||||
get_object,
|
||||
set_object
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -748,11 +1019,7 @@ cc2538_rf_err_isr(void)
|
|||
void
|
||||
cc2538_rf_set_promiscous_mode(char p)
|
||||
{
|
||||
if(p) {
|
||||
REG(RFCORE_XREG_FRMFILT0) &= ~RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN;
|
||||
} else {
|
||||
REG(RFCORE_XREG_FRMFILT0) |= RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN;
|
||||
}
|
||||
set_frame_filtering(p);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#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
|
||||
|
@ -132,31 +133,6 @@
|
|||
/** The NETSTACK data structure for the cc2538 RF driver */
|
||||
extern const struct radio_driver cc2538_rf_driver;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \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
|
||||
*/
|
||||
int8_t cc2538_rf_channel_set(uint8_t channel);
|
||||
|
||||
/**
|
||||
* \brief Get the current operating channel
|
||||
* \return Returns a value in [11,26] representing the current channel
|
||||
*/
|
||||
uint8_t cc2538_rf_channel_get(void);
|
||||
|
||||
/**
|
||||
* \brief Sets RF TX power
|
||||
* \param new_power The desired power level
|
||||
* \return The power level in use after the adjustment
|
||||
*
|
||||
* The value specified in \e new_power will be written directly to the
|
||||
* RFCORE_XREG_TXPOWER register. See the datasheet for more details on
|
||||
* possible values.
|
||||
*/
|
||||
uint8_t cc2538_rf_power_set(uint8_t new_power);
|
||||
|
||||
/**
|
||||
* \brief Sets addresses and PAN identifier to the relevant RF hardware
|
||||
* registers
|
||||
|
@ -168,15 +144,6 @@ uint8_t cc2538_rf_power_set(uint8_t new_power);
|
|||
*/
|
||||
void cc2538_rf_set_addr(uint16_t pan);
|
||||
|
||||
/**
|
||||
* \brief Reads the current signal strength (RSSI)
|
||||
* \return The current RSSI
|
||||
*
|
||||
* This function reads the current RSSI on the currently configured
|
||||
* channel.
|
||||
*/
|
||||
int cc2538_rf_read_rssi(void);
|
||||
|
||||
/**
|
||||
* \brief Turn promiscous mode on or off
|
||||
* \param p If promiscous mode should be on (1) or off (0)
|
||||
|
@ -187,7 +154,6 @@ int cc2538_rf_read_rssi(void);
|
|||
* address as the receive address are returned from the RF core.
|
||||
*/
|
||||
void cc2538_rf_set_promiscous_mode(char p);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* CC2538_RF_H__ */
|
||||
|
||||
|
|
|
@ -96,6 +96,10 @@
|
|||
/* 192 ms, radio off -> on interval */
|
||||
#define ONOFF_TIME RTIMER_ARCH_SECOND / 3125
|
||||
|
||||
#define CC2530_RF_CHANNEL_SET_ERROR -1
|
||||
|
||||
#define CC2530_RF_TX_POWER_TXCTRL_MIN_VAL 0x09 /* Value for min TX Power */
|
||||
#define CC2530_RF_TX_POWER_TXCTRL_DEF_VAL 0x69 /* Reset Value */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if CC2530_RF_CONF_HEXDUMP
|
||||
#include "dev/io-arch.h"
|
||||
|
@ -114,50 +118,215 @@ static int on(void); /* prepare() needs our prototype */
|
|||
static int off(void); /* transmit() needs our prototype */
|
||||
static int channel_clear(void); /* transmit() needs our prototype */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int8_t
|
||||
cc2530_rf_channel_set(uint8_t channel)
|
||||
/* TX Power dBm lookup table. Values from SmartRF Studio v1.16.0 */
|
||||
typedef struct output_config {
|
||||
radio_value_t power;
|
||||
uint8_t txpower_val;
|
||||
} output_config_t;
|
||||
|
||||
static const output_config_t output_power[] = {
|
||||
{ 5, 0xF5 }, /* 4.5 */
|
||||
{ 3, 0xE5 }, /* 2.5 */
|
||||
{ 1, 0xD5 },
|
||||
{ 0, 0xC5 }, /* -0.5 */
|
||||
{ -1, 0xB5 }, /* -1.5 */
|
||||
{ -3, 0xA5 },
|
||||
{ -4, 0x95 },
|
||||
{ -6, 0x85 },
|
||||
{ -8, 0x75 },
|
||||
{-10, 0x65 },
|
||||
{-12, 0x55 },
|
||||
{-14, 0x45 },
|
||||
{-16, 0x35 },
|
||||
{-18, 0x25 },
|
||||
{-20, 0x15 },
|
||||
{-22, 0x05 },
|
||||
{-28, 0x05 }, /* TXCTRL must be set to 0x09 */
|
||||
};
|
||||
|
||||
#define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t))
|
||||
|
||||
/* Max and Min Output Power in dBm */
|
||||
#define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].power)
|
||||
#define OUTPUT_POWER_MAX (output_power[0].power)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Get the current operating channel
|
||||
* \return Returns a value in [11,26] representing the current channel
|
||||
*/
|
||||
static uint8_t
|
||||
get_channel()
|
||||
{
|
||||
return (uint8_t)((FREQCTRL + 44) / 5);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \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
|
||||
set_channel(uint8_t channel)
|
||||
{
|
||||
PUTSTRING("RF: Set Chan\n");
|
||||
|
||||
if((channel < CC2530_RF_CHANNEL_MIN) || (channel > CC2530_RF_CHANNEL_MAX)) {
|
||||
return -1;
|
||||
return CC2530_RF_CHANNEL_SET_ERROR;
|
||||
}
|
||||
|
||||
/* Changes to FREQCTRL take effect after the next recalibration */
|
||||
/* Changes to FREQCTRL take effect after the next recalibration */
|
||||
off();
|
||||
FREQCTRL = (CC2530_RF_CHANNEL_MIN
|
||||
+ (channel - CC2530_RF_CHANNEL_MIN) * CC2530_RF_CHANNEL_SPACING);
|
||||
on();
|
||||
|
||||
return (int8_t) channel;
|
||||
return (int8_t)channel;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
cc2530_rf_power_set(uint8_t new_power)
|
||||
static radio_value_t
|
||||
get_pan_id(void)
|
||||
{
|
||||
PUTSTRING("RF: Set Power\n");
|
||||
/* off() */
|
||||
TXPOWER = new_power;
|
||||
/* on() */
|
||||
|
||||
return TXPOWER;
|
||||
return (radio_value_t)(PAN_ID1 << 8 | PAN_ID0);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
cc2530_rf_set_addr(uint16_t pan)
|
||||
static void
|
||||
set_pan_id(uint16_t pan)
|
||||
{
|
||||
#if LINKADDR_SIZE==8 /* EXT_ADDR[7:0] is ignored when using short addresses */
|
||||
int i;
|
||||
for(i = (LINKADDR_SIZE - 1); i >= 0; --i) {
|
||||
((uint8_t *)&EXT_ADDR0)[i] = linkaddr_node_addr.u8[LINKADDR_SIZE - 1 - i];
|
||||
}
|
||||
#endif
|
||||
|
||||
PAN_ID0 = pan & 0xFF;
|
||||
PAN_ID1 = pan >> 8;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_value_t
|
||||
get_short_addr(void)
|
||||
{
|
||||
return (radio_value_t)(SHORT_ADDR1 << 8 | SHORT_ADDR0);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_short_addr(uint16_t addr)
|
||||
{
|
||||
SHORT_ADDR0 = addr & 0xFF;
|
||||
SHORT_ADDR1 = addr >> 8;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Reads the current signal strength (RSSI)
|
||||
* \return The current RSSI in dBm
|
||||
*
|
||||
* This function reads the current RSSI on the currently configured
|
||||
* channel.
|
||||
*/
|
||||
static radio_value_t
|
||||
get_rssi(void)
|
||||
{
|
||||
int8_t rssi;
|
||||
|
||||
SHORT_ADDR0 = linkaddr_node_addr.u8[LINKADDR_SIZE - 1];
|
||||
SHORT_ADDR1 = linkaddr_node_addr.u8[LINKADDR_SIZE - 2];
|
||||
/* If we are off, turn on first */
|
||||
if(RXENABLE == 0) {
|
||||
rf_flags |= WAS_OFF;
|
||||
on();
|
||||
}
|
||||
|
||||
/* Wait on RSSI_VALID */
|
||||
while((RSSISTAT & RSSISTAT_RSSI_VALID) == 0);
|
||||
|
||||
rssi = (radio_value_t)RSSI - RSSI_OFFSET;
|
||||
|
||||
/* If we were off, turn back off */
|
||||
if((rf_flags & WAS_OFF) == WAS_OFF) {
|
||||
rf_flags &= ~WAS_OFF;
|
||||
off();
|
||||
}
|
||||
|
||||
return rssi;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Returns the current CCA threshold in dBm */
|
||||
static radio_value_t
|
||||
get_cca_threshold(void)
|
||||
{
|
||||
return (int8_t)CCACTRL0 - RSSI_OFFSET;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Sets the CCA threshold in dBm */
|
||||
static void
|
||||
set_cca_threshold(radio_value_t value)
|
||||
{
|
||||
CCACTRL0 = (value + RSSI_OFFSET) & 0xFF;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Returns the current TX power in dBm */
|
||||
static radio_value_t
|
||||
get_tx_power(void)
|
||||
{
|
||||
int i;
|
||||
uint8_t reg_val = TXPOWER;
|
||||
|
||||
if(TXCTRL == CC2530_RF_TX_POWER_TXCTRL_MIN_VAL) {
|
||||
return OUTPUT_POWER_MIN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the TXPOWER value in the lookup table
|
||||
* If the value has been written with set_tx_power, we should be able to
|
||||
* find the exact value. However, in case the register has been written in
|
||||
* a different fashion, we return the immediately lower value of the lookup
|
||||
*/
|
||||
for(i = 0; i < OUTPUT_CONFIG_COUNT; i++) {
|
||||
if(reg_val >= output_power[i].txpower_val) {
|
||||
return output_power[i].power;
|
||||
}
|
||||
}
|
||||
return OUTPUT_POWER_MIN;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Set TX power to 'at least' power dBm
|
||||
* This works with a lookup table. If the value of 'power' does not exist in
|
||||
* the lookup table, TXPOWER will be set to the immediately higher available
|
||||
* value
|
||||
*/
|
||||
static void
|
||||
set_tx_power(radio_value_t power)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(power <= output_power[OUTPUT_CONFIG_COUNT - 1].power) {
|
||||
TXCTRL = CC2530_RF_TX_POWER_TXCTRL_MIN_VAL;
|
||||
TXPOWER = output_power[OUTPUT_CONFIG_COUNT - 1].txpower_val;
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = OUTPUT_CONFIG_COUNT - 2; i >= 0; --i) {
|
||||
if(power <= output_power[i].power) {
|
||||
/* Perhaps an earlier call set TXCTRL to 0x09. Restore */
|
||||
TXCTRL = CC2530_RF_TX_POWER_TXCTRL_DEF_VAL;
|
||||
TXPOWER = output_power[i].txpower_val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_frame_filtering(uint8_t enable)
|
||||
{
|
||||
if(enable) {
|
||||
FRMFILT0 |= FRMFILT0_FRAME_FILTER_EN;
|
||||
} else {
|
||||
FRMFILT0 &= ~FRMFILT0_FRAME_FILTER_EN;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_auto_ack(uint8_t enable)
|
||||
{
|
||||
if(enable) {
|
||||
FRMCTRL0 |= FRMCTRL0_AUTOACK;
|
||||
} else {
|
||||
FRMCTRL0 &= ~FRMCTRL0_AUTOACK;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Netstack API radio driver functions */
|
||||
|
@ -204,8 +373,7 @@ init(void)
|
|||
/* MAX FIFOP threshold */
|
||||
FIFOPCTRL = CC2530_RF_MAX_PACKET_LEN;
|
||||
|
||||
cc2530_rf_power_set(CC2530_RF_TX_POWER);
|
||||
cc2530_rf_channel_set(CC2530_RF_CHANNEL);
|
||||
TXPOWER = CC2530_RF_TX_POWER;
|
||||
|
||||
RF_TX_LED_OFF();
|
||||
RF_RX_LED_OFF();
|
||||
|
@ -483,6 +651,154 @@ off(void)
|
|||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_value(radio_param_t param, radio_value_t *value)
|
||||
{
|
||||
if(!value) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
|
||||
switch(param) {
|
||||
case RADIO_PARAM_POWER_MODE:
|
||||
*value = RXENABLE == 0 ? RADIO_POWER_MODE_OFF : RADIO_POWER_MODE_ON;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_CHANNEL:
|
||||
*value = (radio_value_t)get_channel();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_PAN_ID:
|
||||
*value = get_pan_id();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_16BIT_ADDR:
|
||||
*value = get_short_addr();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_RX_MODE:
|
||||
*value = 0;
|
||||
if(FRMFILT0 & FRMFILT0_FRAME_FILTER_EN) {
|
||||
*value |= RADIO_RX_MODE_ADDRESS_FILTER;
|
||||
}
|
||||
if(FRMCTRL0 & FRMCTRL0_AUTOACK) {
|
||||
*value |= RADIO_RX_MODE_AUTOACK;
|
||||
}
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_TXPOWER:
|
||||
*value = get_tx_power();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_CCA_THRESHOLD:
|
||||
*value = get_cca_threshold();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_RSSI:
|
||||
*value = get_rssi();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_CHANNEL_MIN:
|
||||
*value = CC2530_RF_CHANNEL_MIN;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_CHANNEL_MAX:
|
||||
*value = CC2530_RF_CHANNEL_MAX;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_TXPOWER_MIN:
|
||||
*value = OUTPUT_POWER_MIN;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_TXPOWER_MAX:
|
||||
*value = OUTPUT_POWER_MAX;
|
||||
return RADIO_RESULT_OK;
|
||||
default:
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_value(radio_param_t param, radio_value_t value)
|
||||
{
|
||||
switch(param) {
|
||||
case RADIO_PARAM_POWER_MODE:
|
||||
if(value == RADIO_POWER_MODE_ON) {
|
||||
on();
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
if(value == RADIO_POWER_MODE_OFF) {
|
||||
off();
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
case RADIO_PARAM_CHANNEL:
|
||||
if(value < CC2530_RF_CHANNEL_MIN || value > CC2530_RF_CHANNEL_MAX) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
if(set_channel(value) == CC2530_RF_CHANNEL_SET_ERROR) {
|
||||
return RADIO_RESULT_ERROR;
|
||||
}
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_PAN_ID:
|
||||
set_pan_id(value & 0xffff);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_16BIT_ADDR:
|
||||
set_short_addr(value & 0xffff);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_RX_MODE:
|
||||
if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER |
|
||||
RADIO_RX_MODE_AUTOACK)) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
|
||||
set_frame_filtering((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0);
|
||||
set_auto_ack((value & RADIO_RX_MODE_AUTOACK) != 0);
|
||||
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_TXPOWER:
|
||||
if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
|
||||
set_tx_power(value);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_CCA_THRESHOLD:
|
||||
set_cca_threshold(value);
|
||||
return RADIO_RESULT_OK;
|
||||
default:
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_object(radio_param_t param, void *dest, size_t size)
|
||||
{
|
||||
uint8_t *target;
|
||||
int i;
|
||||
|
||||
if(param == RADIO_PARAM_64BIT_ADDR) {
|
||||
if(size != 8 || !dest) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
|
||||
target = dest;
|
||||
for(i = 0; i < 8; i++) {
|
||||
target[i] = ((uint8_t *)&EXT_ADDR0)[7 - i] & 0xFF;
|
||||
}
|
||||
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_object(radio_param_t param, const void *src, size_t size)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(param == RADIO_PARAM_64BIT_ADDR) {
|
||||
if(size != 8 || !src) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
|
||||
for(i = 0; i < 8; i++) {
|
||||
((uint8_t *)&EXT_ADDR0)[i] = ((uint8_t *)src)[7 - i];
|
||||
}
|
||||
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct radio_driver cc2530_rf_driver = {
|
||||
init,
|
||||
prepare,
|
||||
|
@ -494,5 +810,9 @@ const struct radio_driver cc2530_rf_driver = {
|
|||
pending_packet,
|
||||
on,
|
||||
off,
|
||||
get_value,
|
||||
set_value,
|
||||
get_object,
|
||||
set_object
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -120,9 +120,6 @@
|
|||
/*---------------------------------------------------------------------------*/
|
||||
extern const struct radio_driver cc2530_rf_driver;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int8_t cc2530_rf_channel_set(uint8_t channel);
|
||||
#define cc2530_rf_channel_get() ((uint8_t)((FREQCTRL + 44) / 5))
|
||||
uint8_t cc2530_rf_power_set(uint8_t new_power);
|
||||
void cc2530_rf_set_addr(uint16_t pan);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* CC2530_RF_H_ */
|
||||
|
|
|
@ -184,6 +184,9 @@
|
|||
/*---------------------------------------------------------------------------
|
||||
* Radio Register Bits
|
||||
*---------------------------------------------------------------------------*/
|
||||
/* FRMFILT0 */
|
||||
#define FRMFILT0_FRAME_FILTER_EN 0x01
|
||||
|
||||
/* FRMCTRL0 */
|
||||
#define FRMCTRL0_APPEND_DATA_MODE 0x80
|
||||
#define FRMCTRL0_AUTOCRC 0x40
|
||||
|
|
|
@ -79,6 +79,31 @@ int contiki_maca_channel_clear(void);
|
|||
int contiki_maca_receiving_packet(void);
|
||||
int contiki_maca_pending_packet(void);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_value(radio_param_t param, radio_value_t *value)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_value(radio_param_t param, radio_value_t value)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_object(radio_param_t param, void *dest, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_object(radio_param_t param, const void *src, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct radio_driver contiki_maca_driver =
|
||||
{
|
||||
.init = contiki_maca_init,
|
||||
|
@ -91,6 +116,10 @@ const struct radio_driver contiki_maca_driver =
|
|||
.channel_clear = contiki_maca_channel_clear,
|
||||
.on = contiki_maca_on_request,
|
||||
.off = contiki_maca_off_request,
|
||||
.get_value = get_value,
|
||||
.set_value = set_value,
|
||||
.get_object = get_object,
|
||||
.set_object = set_object
|
||||
};
|
||||
|
||||
static volatile uint8_t contiki_maca_request_on = 0;
|
||||
|
|
|
@ -45,6 +45,31 @@
|
|||
static unsigned char tx_buf[ADF7023_MAX_PACKET_SIZE];
|
||||
static unsigned char rx_buf[ADF7023_MAX_PACKET_SIZE];
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_value(radio_param_t param, radio_value_t *value)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_value(radio_param_t param, radio_value_t value)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_object(radio_param_t param, void *dest, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_object(radio_param_t param, const void *src, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct radio_driver adf7023_driver = {
|
||||
|
||||
.init = adf7023_init,
|
||||
|
@ -76,6 +101,11 @@ const struct radio_driver adf7023_driver = {
|
|||
|
||||
/** Turn the radio off. */
|
||||
.off = adf7023_off,
|
||||
|
||||
.get_value = get_value,
|
||||
.set_value = set_value,
|
||||
.get_object = get_object,
|
||||
.set_object = set_object
|
||||
};
|
||||
|
||||
int
|
||||
|
|
|
@ -264,6 +264,147 @@ static int stm32w_radio_off(void);
|
|||
static int add_to_rxbuf(uint8_t * src);
|
||||
|
||||
static int read_from_rxbuf(void *dest, unsigned short len);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_value(radio_param_t param, radio_value_t *value)
|
||||
{
|
||||
if(!value) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
switch(param) {
|
||||
case RADIO_PARAM_POWER_MODE:
|
||||
*value = onoroff == ON ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_CHANNEL:
|
||||
*value = ST_RadioGetChannel();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_PAN_ID:
|
||||
*value = ST_RadioGetPanId();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_16BIT_ADDR:
|
||||
*value = ST_RadioGetNodeId();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_RX_MODE:
|
||||
*value = 0;
|
||||
if(ST_RadioAddressFilteringEnabled()) {
|
||||
*value |= RADIO_RX_MODE_ADDRESS_FILTER;
|
||||
}
|
||||
if(ST_RadioAutoAckEnabled()) {
|
||||
*value |= RADIO_RX_MODE_AUTOACK;
|
||||
}
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_TXPOWER:
|
||||
*value = ST_RadioGetPower();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_CCA_THRESHOLD:
|
||||
*value = ST_RadioGetEdCcaThreshold();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_RSSI:
|
||||
*value = ST_RadioEnergyDetection();
|
||||
return RADIO_RESULT_OK;
|
||||
|
||||
case RADIO_CONST_CHANNEL_MIN:
|
||||
*value = ST_MIN_802_15_4_CHANNEL_NUMBER;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_CHANNEL_MAX:
|
||||
*value = ST_MAX_802_15_4_CHANNEL_NUMBER;
|
||||
return RADIO_RESULT_OK;
|
||||
|
||||
case RADIO_CONST_TXPOWER_MIN:
|
||||
*value = MIN_RADIO_POWER;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_TXPOWER_MAX:
|
||||
*value = MAX_RADIO_POWER;
|
||||
return RADIO_RESULT_OK;
|
||||
|
||||
default:
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_value(radio_param_t param, radio_value_t value)
|
||||
{
|
||||
switch(param) {
|
||||
case RADIO_PARAM_POWER_MODE:
|
||||
if(value == RADIO_POWER_MODE_ON) {
|
||||
stm32w_radio_on();
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
if(value == RADIO_POWER_MODE_OFF) {
|
||||
stm32w_radio_off();
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
case RADIO_PARAM_CHANNEL:
|
||||
if(value < ST_MIN_802_15_4_CHANNEL_NUMBER ||
|
||||
value > ST_MAX_802_15_4_CHANNEL_NUMBER) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
if(ST_RadioSetChannel(value) != ST_SUCCESS) {
|
||||
return RADIO_RESULT_ERROR;
|
||||
}
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_PAN_ID:
|
||||
ST_RadioSetPanId(value & 0xffff);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_16BIT_ADDR:
|
||||
ST_RadioSetNodeId(value & 0xffff);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_RX_MODE:
|
||||
if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER |
|
||||
RADIO_RX_MODE_AUTOACK)) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
ST_RadioEnableAddressFiltering((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0);
|
||||
ST_RadioEnableAutoAck((value & RADIO_RX_MODE_AUTOACK) != 0);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_TXPOWER:
|
||||
if(value < MIN_RADIO_POWER || value > MAX_RADIO_POWER) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
if(ST_RadioSetPower((int8_t)value) != ST_SUCCESS) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_CCA_THRESHOLD:
|
||||
ST_RadioSetEdCcaThreshold((int8_t)value);
|
||||
return RADIO_RESULT_OK;
|
||||
default:
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_object(radio_param_t param, void *dest, size_t size)
|
||||
{
|
||||
const uint8_t *eui64;
|
||||
uint8_t *target;
|
||||
int i;
|
||||
|
||||
if(param == RADIO_PARAM_64BIT_ADDR) {
|
||||
if(size < 8 || !dest) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
eui64 = ST_RadioGetEui64();
|
||||
if(!eui64) {
|
||||
return RADIO_RESULT_ERROR;
|
||||
}
|
||||
target = dest;
|
||||
for(i = 0; i < 8; i++) {
|
||||
target[i] = eui64[7 - i];
|
||||
}
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_object(radio_param_t param, const void *src, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const struct radio_driver stm32w_radio_driver = {
|
||||
stm32w_radio_init,
|
||||
|
@ -276,6 +417,10 @@ const struct radio_driver stm32w_radio_driver = {
|
|||
stm32w_radio_pending_packet,
|
||||
stm32w_radio_on,
|
||||
stm32w_radio_off,
|
||||
get_value,
|
||||
set_value,
|
||||
get_object,
|
||||
set_object
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
|
|
|
@ -84,6 +84,9 @@
|
|||
#define FOOTER1_CRC_OK 0x80
|
||||
#define FOOTER1_CORRELATION 0x7f
|
||||
|
||||
/* The RSSI_OFFSET is approximate -45 (see CC2420 specification) */
|
||||
#define RSSI_OFFSET -45
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
|
@ -103,6 +106,28 @@
|
|||
#define LEDS_OFF(x)
|
||||
#endif
|
||||
|
||||
/* Conversion map between PA_LEVEL and output power in dBm
|
||||
(from table 9 in CC2420 specification).
|
||||
*/
|
||||
struct output_config {
|
||||
int8_t power;
|
||||
uint8_t config;
|
||||
};
|
||||
|
||||
static const struct output_config output_power[] = {
|
||||
{ 0, 31 }, /* 0xff */
|
||||
{ -1, 27 }, /* 0xfb */
|
||||
{ -3, 23 }, /* 0xf7 */
|
||||
{ -5, 19 }, /* 0xf3 */
|
||||
{ -7, 15 }, /* 0xef */
|
||||
{-10, 11 }, /* 0xeb */
|
||||
{-15, 7 }, /* 0xe7 */
|
||||
{-25, 3 }, /* 0xe3 */
|
||||
};
|
||||
#define OUTPUT_NUM (sizeof(output_power) / sizeof(struct output_config))
|
||||
#define OUTPUT_POWER_MAX 0
|
||||
#define OUTPUT_POWER_MIN -25
|
||||
|
||||
void cc2420_arch_init(void);
|
||||
|
||||
/* XXX hack: these will be made as Chameleon packet attributes */
|
||||
|
@ -112,7 +137,7 @@ int cc2420_authority_level_of_sender;
|
|||
|
||||
int cc2420_packets_seen, cc2420_packets_read;
|
||||
|
||||
static uint8_t volatile pending;
|
||||
/* static uint8_t volatile pending; */
|
||||
|
||||
#define BUSYWAIT_UNTIL(cond, max_time) \
|
||||
do { \
|
||||
|
@ -148,6 +173,107 @@ static int cc2420_cca(void);
|
|||
signed char cc2420_last_rssi;
|
||||
uint8_t cc2420_last_correlation;
|
||||
|
||||
static uint8_t receive_on;
|
||||
static int channel;
|
||||
|
||||
static radio_result_t
|
||||
get_value(radio_param_t param, radio_value_t *value)
|
||||
{
|
||||
int i, v;
|
||||
|
||||
if(!value) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
switch(param) {
|
||||
case RADIO_PARAM_POWER_MODE:
|
||||
*value = receive_on ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_CHANNEL:
|
||||
*value = cc2420_get_channel();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_TXPOWER:
|
||||
v = cc2420_get_txpower();
|
||||
*value = OUTPUT_POWER_MIN;
|
||||
/* Find the actual estimated output power in conversion table */
|
||||
for(i = 0; i < OUTPUT_NUM; i++) {
|
||||
if(v >= output_power[i].config) {
|
||||
*value = output_power[i].power;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_RSSI:
|
||||
/* Return the RSSI value in dBm */
|
||||
*value = cc2420_rssi() + RSSI_OFFSET;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_CHANNEL_MIN:
|
||||
*value = 11;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_CHANNEL_MAX:
|
||||
*value = 26;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_TXPOWER_MIN:
|
||||
*value = OUTPUT_POWER_MIN;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_TXPOWER_MAX:
|
||||
*value = OUTPUT_POWER_MAX;
|
||||
return RADIO_RESULT_OK;
|
||||
default:
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
static radio_result_t
|
||||
set_value(radio_param_t param, radio_value_t value)
|
||||
{
|
||||
int i;
|
||||
|
||||
switch(param) {
|
||||
case RADIO_PARAM_POWER_MODE:
|
||||
if(value == RADIO_POWER_MODE_ON) {
|
||||
cc2420_on();
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
if(value == RADIO_POWER_MODE_OFF) {
|
||||
cc2420_off();
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
case RADIO_PARAM_CHANNEL:
|
||||
if(value < 11 || value > 26) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
cc2420_set_channel(value);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_TXPOWER:
|
||||
if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
/* Find the closest higher PA_LEVEL for the desired output power */
|
||||
for(i = 1; i < OUTPUT_NUM; i++) {
|
||||
if(value > output_power[i].power) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
cc2420_set_txpower(output_power[i - 1].config);
|
||||
return RADIO_RESULT_OK;
|
||||
default:
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
static radio_result_t
|
||||
get_object(radio_param_t param, void *dest, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static radio_result_t
|
||||
set_object(radio_param_t param, const void *src, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
const struct radio_driver cc2420_driver =
|
||||
{
|
||||
cc2420_init,
|
||||
|
@ -162,12 +288,18 @@ const struct radio_driver cc2420_driver =
|
|||
pending_packet,
|
||||
cc2420_on,
|
||||
cc2420_off,
|
||||
get_value,
|
||||
set_value,
|
||||
get_object,
|
||||
set_object
|
||||
};
|
||||
|
||||
static uint8_t receive_on;
|
||||
|
||||
static int channel;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
strobe(enum cc2420_register regname)
|
||||
{
|
||||
CC2420_STROBE(regname);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
|
@ -185,15 +317,12 @@ flushrx(void)
|
|||
{
|
||||
uint8_t dummy;
|
||||
|
||||
CC2420_READ_FIFO_BYTE(dummy);
|
||||
CC2420_STROBE(CC2420_SFLUSHRX);
|
||||
CC2420_STROBE(CC2420_SFLUSHRX);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
strobe(enum cc2420_register regname)
|
||||
{
|
||||
CC2420_STROBE(regname);
|
||||
getrxbyte(&dummy);
|
||||
strobe(CC2420_SFLUSHRX);
|
||||
strobe(CC2420_SFLUSHRX);
|
||||
if(dummy) {
|
||||
/* avoid unused variable compiler warning */
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static unsigned int
|
||||
|
@ -204,6 +333,18 @@ status(void)
|
|||
return status;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
wait_for_status(unsigned int mask)
|
||||
{
|
||||
BUSYWAIT_UNTIL((status() & mask), RTIMER_SECOND / 10);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
wait_for_not_status(unsigned int mask)
|
||||
{
|
||||
BUSYWAIT_UNTIL(!(status() & mask), RTIMER_SECOND / 10);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t locked, lock_on, lock_off;
|
||||
|
||||
static void
|
||||
|
@ -212,7 +353,7 @@ on(void)
|
|||
CC2420_ENABLE_FIFOP_INT();
|
||||
strobe(CC2420_SRXON);
|
||||
|
||||
BUSYWAIT_UNTIL(status() & (BV(CC2420_XOSC16M_STABLE)), RTIMER_SECOND / 100);
|
||||
wait_for_status(BV(CC2420_XOSC16M_STABLE));
|
||||
|
||||
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
|
||||
receive_on = 1;
|
||||
|
@ -224,7 +365,7 @@ off(void)
|
|||
receive_on = 0;
|
||||
|
||||
/* Wait for transmission to end before turning radio off. */
|
||||
BUSYWAIT_UNTIL(!(status() & BV(CC2420_TX_ACTIVE)), RTIMER_SECOND / 10);
|
||||
wait_for_not_status(BV(CC2420_TX_ACTIVE));
|
||||
|
||||
ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
|
||||
strobe(CC2420_SRFOFF);
|
||||
|
@ -265,6 +406,12 @@ setreg(enum cc2420_register regname, unsigned value)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
write_ram(const void *buf, uint16_t addr, int count)
|
||||
{
|
||||
CC2420_WRITE_RAM(buf, addr, count);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_txpower(uint8_t power)
|
||||
{
|
||||
uint16_t reg;
|
||||
|
@ -351,7 +498,6 @@ static int
|
|||
cc2420_transmit(unsigned short payload_len)
|
||||
{
|
||||
int i, txpower;
|
||||
uint8_t total_len;
|
||||
#if CC2420_CONF_CHECKSUM
|
||||
uint16_t checksum;
|
||||
#endif /* CC2420_CONF_CHECKSUM */
|
||||
|
@ -366,8 +512,6 @@ cc2420_transmit(unsigned short payload_len)
|
|||
set_txpower(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) - 1);
|
||||
}
|
||||
|
||||
total_len = payload_len + AUX_LEN;
|
||||
|
||||
/* The TX FIFO can only hold one packet. Make sure to not overrun
|
||||
* FIFO by waiting for transmission to start here and synchronizing
|
||||
* with the CC2420_TX_ACTIVE check in cc2420_send.
|
||||
|
@ -383,7 +527,7 @@ cc2420_transmit(unsigned short payload_len)
|
|||
|
||||
#if WITH_SEND_CCA
|
||||
strobe(CC2420_SRXON);
|
||||
BUSYWAIT_UNTIL(status() & BV(CC2420_RSSI_VALID), RTIMER_SECOND / 10);
|
||||
wait_for_status(BV(CC2420_RSSI_VALID));
|
||||
strobe(CC2420_STXONCCA);
|
||||
#else /* WITH_SEND_CCA */
|
||||
strobe(CC2420_STXON);
|
||||
|
@ -396,7 +540,7 @@ cc2420_transmit(unsigned short payload_len)
|
|||
if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
|
||||
PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP) {
|
||||
/* Write timestamp to last two bytes of packet in TXFIFO. */
|
||||
CC2420_WRITE_RAM(&sfd_timestamp, CC2420RAM_TXFIFO + payload_len - 1, 2);
|
||||
write_ram(&sfd_timestamp, CC2420RAM_TXFIFO + payload_len - 1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -413,7 +557,7 @@ cc2420_transmit(unsigned short payload_len)
|
|||
ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
|
||||
/* We wait until transmission has ended so that we get an
|
||||
accurate measurement of the transmission time.*/
|
||||
BUSYWAIT_UNTIL(!(status() & BV(CC2420_TX_ACTIVE)), RTIMER_SECOND / 10);
|
||||
wait_for_not_status(BV(CC2420_TX_ACTIVE));
|
||||
|
||||
#ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS
|
||||
ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT,cc2420_get_txpower());
|
||||
|
@ -560,10 +704,10 @@ cc2420_set_channel(int c)
|
|||
/*
|
||||
* Writing RAM requires crystal oscillator to be stable.
|
||||
*/
|
||||
BUSYWAIT_UNTIL((status() & (BV(CC2420_XOSC16M_STABLE))), RTIMER_SECOND / 10);
|
||||
wait_for_status(BV(CC2420_XOSC16M_STABLE));
|
||||
|
||||
/* Wait for any transmission to end. */
|
||||
BUSYWAIT_UNTIL(!(status() & BV(CC2420_TX_ACTIVE)), RTIMER_SECOND / 10);
|
||||
wait_for_not_status(BV(CC2420_TX_ACTIVE));
|
||||
|
||||
setreg(CC2420_FSCTRL, f);
|
||||
|
||||
|
@ -590,22 +734,22 @@ cc2420_set_pan_addr(unsigned pan,
|
|||
/*
|
||||
* Writing RAM requires crystal oscillator to be stable.
|
||||
*/
|
||||
BUSYWAIT_UNTIL(status() & (BV(CC2420_XOSC16M_STABLE)), RTIMER_SECOND / 10);
|
||||
wait_for_status(BV(CC2420_XOSC16M_STABLE));
|
||||
|
||||
tmp[0] = pan & 0xff;
|
||||
tmp[1] = pan >> 8;
|
||||
CC2420_WRITE_RAM(&tmp, CC2420RAM_PANID, 2);
|
||||
write_ram(&tmp, CC2420RAM_PANID, 2);
|
||||
|
||||
tmp[0] = addr & 0xff;
|
||||
tmp[1] = addr >> 8;
|
||||
CC2420_WRITE_RAM(&tmp, CC2420RAM_SHORTADDR, 2);
|
||||
write_ram(&tmp, CC2420RAM_SHORTADDR, 2);
|
||||
if(ieee_addr != NULL) {
|
||||
uint8_t tmp_addr[8];
|
||||
/* LSB first, MSB last for 802.15.4 addresses in CC2420 */
|
||||
for (f = 0; f < 8; f++) {
|
||||
tmp_addr[7 - f] = ieee_addr[f];
|
||||
}
|
||||
CC2420_WRITE_RAM(tmp_addr, CC2420RAM_IEEEADDR, 8);
|
||||
write_ram(tmp_addr, CC2420RAM_IEEEADDR, 8);
|
||||
}
|
||||
RELEASE_LOCK();
|
||||
}
|
||||
|
@ -620,7 +764,7 @@ cc2420_interrupt(void)
|
|||
process_poll(&cc2420_process);
|
||||
|
||||
last_packet_timestamp = cc2420_sfd_start_time;
|
||||
pending++;
|
||||
/* pending++; */
|
||||
cc2420_packets_seen++;
|
||||
return 1;
|
||||
}
|
||||
|
@ -665,7 +809,7 @@ cc2420_read(void *buf, unsigned short bufsize)
|
|||
return 0;
|
||||
}*/
|
||||
|
||||
pending = 0;
|
||||
/* pending = 0; */
|
||||
|
||||
GET_LOCK();
|
||||
|
||||
|
@ -781,7 +925,7 @@ cc2420_rssi(void)
|
|||
radio_was_off = 1;
|
||||
cc2420_on();
|
||||
}
|
||||
BUSYWAIT_UNTIL(status() & BV(CC2420_RSSI_VALID), RTIMER_SECOND / 100);
|
||||
wait_for_status(BV(CC2420_RSSI_VALID));
|
||||
|
||||
rssi = (int)((signed char)getreg(CC2420_RSSI));
|
||||
|
||||
|
@ -800,19 +944,6 @@ detected_energy(void)
|
|||
}
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
cc2420_cca_valid(void)
|
||||
{
|
||||
int valid;
|
||||
if(locked) {
|
||||
return 1;
|
||||
}
|
||||
GET_LOCK();
|
||||
valid = !!(status() & BV(CC2420_RSSI_VALID));
|
||||
RELEASE_LOCK();
|
||||
return valid;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
cc2420_cca(void)
|
||||
{
|
||||
|
@ -842,7 +973,7 @@ cc2420_cca(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
BUSYWAIT_UNTIL(status() & BV(CC2420_RSSI_VALID), RTIMER_SECOND / 100);
|
||||
wait_for_status(BV(CC2420_RSSI_VALID));
|
||||
|
||||
cca = CC2420_CCA_IS_1;
|
||||
|
||||
|
|
|
@ -115,6 +115,70 @@ static int cc2520_cca(void);
|
|||
signed char cc2520_last_rssi;
|
||||
uint8_t cc2520_last_correlation;
|
||||
|
||||
static uint8_t receive_on;
|
||||
static int channel;
|
||||
|
||||
static radio_result_t
|
||||
get_value(radio_param_t param, radio_value_t *value)
|
||||
{
|
||||
if(!value) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
switch(param) {
|
||||
case RADIO_PARAM_POWER_MODE:
|
||||
*value = receive_on ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_CHANNEL:
|
||||
*value = cc2520_get_channel();
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_CHANNEL_MIN:
|
||||
*value = 11;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_CHANNEL_MAX:
|
||||
*value = 26;
|
||||
return RADIO_RESULT_OK;
|
||||
default:
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
static radio_result_t
|
||||
set_value(radio_param_t param, radio_value_t value)
|
||||
{
|
||||
switch(param) {
|
||||
case RADIO_PARAM_POWER_MODE:
|
||||
if(value == RADIO_POWER_MODE_ON) {
|
||||
cc2520_on();
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
if(value == RADIO_POWER_MODE_OFF) {
|
||||
cc2520_off();
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
case RADIO_PARAM_CHANNEL:
|
||||
if(value < 11 || value > 26) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
cc2520_set_channel(value);
|
||||
return RADIO_RESULT_OK;
|
||||
default:
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
static radio_result_t
|
||||
get_object(radio_param_t param, void *dest, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static radio_result_t
|
||||
set_object(radio_param_t param, const void *src, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
const struct radio_driver cc2520_driver =
|
||||
{
|
||||
cc2520_init,
|
||||
|
@ -129,12 +193,12 @@ const struct radio_driver cc2520_driver =
|
|||
pending_packet,
|
||||
cc2520_on,
|
||||
cc2520_off,
|
||||
get_value,
|
||||
set_value,
|
||||
get_object,
|
||||
set_object
|
||||
};
|
||||
|
||||
static uint8_t receive_on;
|
||||
|
||||
static int channel;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include "dev/watchdog.h"
|
||||
#include "dev/slip.h"
|
||||
#include "dev/leds.h"
|
||||
#include "dev/cc2530-rf.h"
|
||||
#include "dev/radio.h"
|
||||
#include "debug.h"
|
||||
|
||||
static uint8_t prefix_set;
|
||||
|
@ -114,6 +114,16 @@ set_prefix_64(uip_ipaddr_t *prefix_64)
|
|||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
get_rf_channel(void)
|
||||
{
|
||||
radio_value_t chan;
|
||||
|
||||
NETSTACK_RADIO.get_value(RADIO_PARAM_CHANNEL, &chan);
|
||||
|
||||
return (uint8_t)chan;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(border_router_process, ev, data)
|
||||
{
|
||||
static struct etimer et;
|
||||
|
@ -135,7 +145,7 @@ PROCESS_THREAD(border_router_process, ev, data)
|
|||
}
|
||||
/* We have created a new DODAG when we reach here */
|
||||
PUTSTRING("On Channel ");
|
||||
PUTDEC(cc2530_rf_channel_get());
|
||||
PUTDEC(get_rf_channel());
|
||||
PUTCHAR('\n');
|
||||
|
||||
print_local_addresses();
|
||||
|
|
|
@ -54,8 +54,9 @@
|
|||
#define UIP_CONF_BUFFER_SIZE 256
|
||||
*/
|
||||
|
||||
/* Disabling RDC for demo purposes. Core updates often require more memory. */
|
||||
/* For projects, optimize memory and enable RDC again. */
|
||||
/* Disabling RDC and CSMA for demo purposes. Core updates often
|
||||
require more memory. */
|
||||
/* For projects, optimize memory and enable RDC and CSMA again. */
|
||||
#undef NETSTACK_CONF_RDC
|
||||
#define NETSTACK_CONF_RDC nullrdc_driver
|
||||
|
||||
|
@ -63,6 +64,9 @@
|
|||
#undef UIP_CONF_TCP
|
||||
#define UIP_CONF_TCP 0
|
||||
|
||||
#undef NETSTACK_CONF_MAC
|
||||
#define NETSTACK_CONF_MAC nullmac_driver
|
||||
|
||||
/* Increase rpl-border-router IP-buffer when using more than 64. */
|
||||
#undef REST_MAX_CHUNK_SIZE
|
||||
#define REST_MAX_CHUNK_SIZE 48
|
||||
|
|
8
examples/extended-rf-api/Makefile
Normal file
8
examples/extended-rf-api/Makefile
Normal file
|
@ -0,0 +1,8 @@
|
|||
DEFINES+=PROJECT_CONF_H=\"project-conf.h\"
|
||||
|
||||
CONTIKI_PROJECT = extended-rf-api
|
||||
|
||||
all: $(CONTIKI_PROJECT)
|
||||
|
||||
CONTIKI = ../..
|
||||
include $(CONTIKI)/Makefile.include
|
510
examples/extended-rf-api/extended-rf-api.c
Normal file
510
examples/extended-rf-api/extended-rf-api.c
Normal file
|
@ -0,0 +1,510 @@
|
|||
/*
|
||||
* Copyright (c) 2014, George Oikonomou (george@contiki-os.org)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* Example project demonstrating the extended RF API functionality
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "net/netstack.h"
|
||||
#include "dev/radio.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
struct rf_consts {
|
||||
radio_value_t channel_min;
|
||||
radio_value_t channel_max;
|
||||
radio_value_t txpower_min;
|
||||
radio_value_t txpower_max;
|
||||
};
|
||||
|
||||
static struct rf_consts consts;
|
||||
|
||||
static radio_value_t value;
|
||||
static uint8_t ext_addr[8];
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(extended_rf_api_process, "Extended RF API demo process");
|
||||
AUTOSTART_PROCESSES(&extended_rf_api_process);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
print_64bit_addr(const uint8_t *addr)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; i < 7; i++) {
|
||||
printf("%02x:", addr[i]);
|
||||
}
|
||||
printf("%02x (network order)\n", addr[7]);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_object(radio_param_t param, void *dest, size_t size)
|
||||
{
|
||||
radio_result_t rv;
|
||||
|
||||
rv = NETSTACK_RADIO.get_object(param, dest, size);
|
||||
|
||||
switch(rv) {
|
||||
case RADIO_RESULT_ERROR:
|
||||
printf("Radio returned an error\n");
|
||||
break;
|
||||
case RADIO_RESULT_INVALID_VALUE:
|
||||
printf("Value is invalid\n");
|
||||
break;
|
||||
case RADIO_RESULT_NOT_SUPPORTED:
|
||||
printf("Param %u not supported\n", param);
|
||||
break;
|
||||
case RADIO_RESULT_OK:
|
||||
break;
|
||||
default:
|
||||
printf("Unknown return value\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_object(radio_param_t param, void *src, size_t size)
|
||||
{
|
||||
radio_result_t rv;
|
||||
|
||||
rv = NETSTACK_RADIO.set_object(param, src, size);
|
||||
|
||||
switch(rv) {
|
||||
case RADIO_RESULT_ERROR:
|
||||
printf("Radio returned an error\n");
|
||||
break;
|
||||
case RADIO_RESULT_INVALID_VALUE:
|
||||
printf("Value is invalid\n");
|
||||
break;
|
||||
case RADIO_RESULT_NOT_SUPPORTED:
|
||||
printf("Param %u not supported\n", param);
|
||||
break;
|
||||
case RADIO_RESULT_OK:
|
||||
break;
|
||||
default:
|
||||
printf("Unknown return value\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_param(radio_param_t param, radio_value_t *value)
|
||||
{
|
||||
radio_result_t rv;
|
||||
|
||||
rv = NETSTACK_RADIO.get_value(param, value);
|
||||
|
||||
switch(rv) {
|
||||
case RADIO_RESULT_ERROR:
|
||||
printf("Radio returned an error\n");
|
||||
break;
|
||||
case RADIO_RESULT_INVALID_VALUE:
|
||||
printf("Value %d is invalid\n", *value);
|
||||
break;
|
||||
case RADIO_RESULT_NOT_SUPPORTED:
|
||||
printf("Param %u not supported\n", param);
|
||||
break;
|
||||
case RADIO_RESULT_OK:
|
||||
break;
|
||||
default:
|
||||
printf("Unknown return value\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_param(radio_param_t param, radio_value_t value)
|
||||
{
|
||||
radio_result_t rv;
|
||||
|
||||
rv = NETSTACK_RADIO.set_value(param, value);
|
||||
|
||||
switch(rv) {
|
||||
case RADIO_RESULT_ERROR:
|
||||
printf("Radio returned an error\n");
|
||||
break;
|
||||
case RADIO_RESULT_INVALID_VALUE:
|
||||
printf("Value %d is invalid\n", value);
|
||||
break;
|
||||
case RADIO_RESULT_NOT_SUPPORTED:
|
||||
printf("Param %u not supported\n", param);
|
||||
break;
|
||||
case RADIO_RESULT_OK:
|
||||
break;
|
||||
default:
|
||||
printf("Unknown return value\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
get_rf_consts(void)
|
||||
{
|
||||
printf("====================================\n");
|
||||
printf("RF Constants\n");
|
||||
printf("Min Channel : ");
|
||||
if(get_param(RADIO_CONST_CHANNEL_MIN, &consts.channel_min) == RADIO_RESULT_OK) {
|
||||
printf("%3d\n", consts.channel_min);
|
||||
}
|
||||
|
||||
printf("Max Channel : ");
|
||||
if(get_param(RADIO_CONST_CHANNEL_MAX, &consts.channel_max) == RADIO_RESULT_OK) {
|
||||
printf("%3d\n", consts.channel_max);
|
||||
}
|
||||
|
||||
printf("Min TX Power: ");
|
||||
if(get_param(RADIO_CONST_TXPOWER_MIN, &consts.txpower_min) == RADIO_RESULT_OK) {
|
||||
printf("%3d dBm\n", consts.txpower_min);
|
||||
}
|
||||
|
||||
printf("Max TX Power: ");
|
||||
if(get_param(RADIO_CONST_TXPOWER_MAX, &consts.txpower_max) == RADIO_RESULT_OK) {
|
||||
printf("%3d dBm\n", consts.txpower_max);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
test_off_on(void)
|
||||
{
|
||||
printf("====================================\n");
|
||||
printf("Power mode Test: Off, then On\n");
|
||||
|
||||
printf("Power mode is : ");
|
||||
if(get_param(RADIO_PARAM_POWER_MODE, &value) == RADIO_RESULT_OK) {
|
||||
if(value == RADIO_POWER_MODE_ON) {
|
||||
printf("On\n");
|
||||
} else if(value == RADIO_POWER_MODE_OFF) {
|
||||
printf("Off\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("Turning Off : ");
|
||||
value = RADIO_POWER_MODE_OFF;
|
||||
set_param(RADIO_PARAM_POWER_MODE, value);
|
||||
if(get_param(RADIO_PARAM_POWER_MODE, &value) == RADIO_RESULT_OK) {
|
||||
if(value == RADIO_POWER_MODE_ON) {
|
||||
printf("On\n");
|
||||
} else if(value == RADIO_POWER_MODE_OFF) {
|
||||
printf("Off\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("Turning On : ");
|
||||
value = RADIO_POWER_MODE_ON;
|
||||
set_param(RADIO_PARAM_POWER_MODE, value);
|
||||
if(get_param(RADIO_PARAM_POWER_MODE, &value) == RADIO_RESULT_OK) {
|
||||
if(value == RADIO_POWER_MODE_ON) {
|
||||
printf("On\n");
|
||||
} else if(value == RADIO_POWER_MODE_OFF) {
|
||||
printf("Off\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
test_channels(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("====================================\n");
|
||||
printf("Channel Test: [%u , %u]\n", consts.channel_min, consts.channel_max);
|
||||
|
||||
for(i = consts.channel_min; i <= consts.channel_max; i++) {
|
||||
value = i;
|
||||
printf("Switch to: %d, Now: ", value);
|
||||
set_param(RADIO_PARAM_CHANNEL, value);
|
||||
if(get_param(RADIO_PARAM_CHANNEL, &value) == RADIO_RESULT_OK) {
|
||||
printf("%d\n", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
test_rx_modes(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("====================================\n");
|
||||
printf("RX Modes Test: [0 , 3]\n");
|
||||
|
||||
for(i = 0; i <= 3; i++) {
|
||||
value = i;
|
||||
printf("Switch to: %d, Now: ", value);
|
||||
set_param(RADIO_PARAM_RX_MODE, value);
|
||||
if(get_param(RADIO_PARAM_RX_MODE, &value) == RADIO_RESULT_OK) {
|
||||
printf("Address Filtering is ");
|
||||
if(value & RADIO_RX_MODE_ADDRESS_FILTER) {
|
||||
printf("On, ");
|
||||
} else {
|
||||
printf("Off, ");
|
||||
}
|
||||
printf("Auto ACK is ");
|
||||
if(value & RADIO_RX_MODE_AUTOACK) {
|
||||
printf("On, ");
|
||||
} else {
|
||||
printf("Off, ");
|
||||
}
|
||||
|
||||
printf("(value=%d)\n", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
test_tx_powers(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("====================================\n");
|
||||
printf("TX Power Test: [%d , %d]\n", consts.txpower_min, consts.txpower_max);
|
||||
|
||||
for(i = consts.txpower_min; i <= consts.txpower_max; i += 5) {
|
||||
value = i;
|
||||
printf("Switch to: %3d dBm, Now: ", value);
|
||||
set_param(RADIO_PARAM_TXPOWER, value);
|
||||
if(get_param(RADIO_PARAM_TXPOWER, &value) == RADIO_RESULT_OK) {
|
||||
printf("%3d dBm\n", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
test_cca_thresholds(void)
|
||||
{
|
||||
printf("====================================\n");
|
||||
printf("CCA Thres. Test: -105, then -81\n");
|
||||
|
||||
value = -105;
|
||||
printf("Switch to: %4d dBm, Now: ", value);
|
||||
set_param(RADIO_PARAM_CCA_THRESHOLD, value);
|
||||
if(get_param(RADIO_PARAM_CCA_THRESHOLD, &value) == RADIO_RESULT_OK) {
|
||||
printf("%4d dBm [0x%04x]\n", value, (uint16_t)value);
|
||||
}
|
||||
|
||||
value = -81;
|
||||
printf("Switch to: %4d dBm, Now: ", value);
|
||||
set_param(RADIO_PARAM_CCA_THRESHOLD, value);
|
||||
if(get_param(RADIO_PARAM_CCA_THRESHOLD, &value) == RADIO_RESULT_OK) {
|
||||
printf("%4d dBm [0x%04x]\n", value, (uint16_t)value);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
test_pan_id(void)
|
||||
{
|
||||
radio_value_t new_val;
|
||||
|
||||
printf("====================================\n");
|
||||
printf("PAN ID Test: Flip bytes and back\n");
|
||||
|
||||
printf("PAN ID is: ");
|
||||
if(get_param(RADIO_PARAM_PAN_ID, &value) == RADIO_RESULT_OK) {
|
||||
printf("0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF);
|
||||
}
|
||||
|
||||
new_val = (value >> 8) & 0xFF;
|
||||
new_val |= (value & 0xFF) << 8;
|
||||
printf("Switch to: 0x%02x%02x, Now: ", (new_val >> 8) & 0xFF, new_val & 0xFF);
|
||||
set_param(RADIO_PARAM_PAN_ID, new_val);
|
||||
if(get_param(RADIO_PARAM_PAN_ID, &value) == RADIO_RESULT_OK) {
|
||||
printf("0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF);
|
||||
}
|
||||
|
||||
new_val = (value >> 8) & 0xFF;
|
||||
new_val |= (value & 0xFF) << 8;
|
||||
printf("Switch to: 0x%02x%02x, Now: ", (new_val >> 8) & 0xFF, new_val & 0xFF);
|
||||
set_param(RADIO_PARAM_PAN_ID, new_val);
|
||||
if(get_param(RADIO_PARAM_PAN_ID, &value) == RADIO_RESULT_OK) {
|
||||
printf("0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
test_16bit_addr(void)
|
||||
{
|
||||
radio_value_t new_val;
|
||||
|
||||
printf("====================================\n");
|
||||
printf("16-bit Address Test: Flip bytes and back\n");
|
||||
|
||||
printf("16-bit Address is: ");
|
||||
if(get_param(RADIO_PARAM_16BIT_ADDR, &value) == RADIO_RESULT_OK) {
|
||||
printf("0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF);
|
||||
}
|
||||
|
||||
new_val = (value >> 8) & 0xFF;
|
||||
new_val |= (value & 0xFF) << 8;
|
||||
printf("Switch to: 0x%02x%02x, Now: ", (new_val >> 8) & 0xFF, new_val & 0xFF);
|
||||
set_param(RADIO_PARAM_16BIT_ADDR, new_val);
|
||||
if(get_param(RADIO_PARAM_16BIT_ADDR, &value) == RADIO_RESULT_OK) {
|
||||
printf("0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF);
|
||||
}
|
||||
|
||||
new_val = (value >> 8) & 0xFF;
|
||||
new_val |= (value & 0xFF) << 8;
|
||||
printf("Switch to: 0x%02x%02x, Now: ", (new_val >> 8) & 0xFF, new_val & 0xFF);
|
||||
set_param(RADIO_PARAM_16BIT_ADDR, new_val);
|
||||
if(get_param(RADIO_PARAM_16BIT_ADDR, &value) == RADIO_RESULT_OK) {
|
||||
printf("0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
test_64bit_addr(void)
|
||||
{
|
||||
int i;
|
||||
uint8_t new_val[8];
|
||||
|
||||
printf("====================================\n");
|
||||
printf("64-bit Address Test: Invert byte order\n");
|
||||
|
||||
printf("64-bit Address is: ");
|
||||
if(get_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8) == RADIO_RESULT_OK) {
|
||||
print_64bit_addr(ext_addr);
|
||||
}
|
||||
|
||||
for(i = 0; i <= 7; i++) {
|
||||
new_val[7 - i] = ext_addr[i];
|
||||
}
|
||||
|
||||
printf("Setting to : ");
|
||||
print_64bit_addr(new_val);
|
||||
|
||||
printf("64-bit Address is: ");
|
||||
set_object(RADIO_PARAM_64BIT_ADDR, new_val, 8);
|
||||
if(get_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8) == RADIO_RESULT_OK) {
|
||||
print_64bit_addr(ext_addr);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
print_rf_values(void)
|
||||
{
|
||||
printf("====================================\n");
|
||||
printf("RF Values\n");
|
||||
|
||||
printf("Power: ");
|
||||
if(get_param(RADIO_PARAM_POWER_MODE, &value) == RADIO_RESULT_OK) {
|
||||
if(value == RADIO_POWER_MODE_ON) {
|
||||
printf("On\n");
|
||||
} else if(value == RADIO_POWER_MODE_OFF) {
|
||||
printf("Off\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("Channel: ");
|
||||
if(get_param(RADIO_PARAM_CHANNEL, &value) == RADIO_RESULT_OK) {
|
||||
printf("%d\n", value);
|
||||
}
|
||||
|
||||
printf("PAN ID: ");
|
||||
if(get_param(RADIO_PARAM_PAN_ID, &value) == RADIO_RESULT_OK) {
|
||||
printf("0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF);
|
||||
}
|
||||
|
||||
printf("16-bit Address: ");
|
||||
if(get_param(RADIO_PARAM_16BIT_ADDR, &value) == RADIO_RESULT_OK) {
|
||||
printf("0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF);
|
||||
}
|
||||
|
||||
printf("64-bit Address: ");
|
||||
if(get_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8) == RADIO_RESULT_OK) {
|
||||
print_64bit_addr(ext_addr);
|
||||
}
|
||||
|
||||
printf("RX Mode: ");
|
||||
if(get_param(RADIO_PARAM_RX_MODE, &value) == RADIO_RESULT_OK) {
|
||||
printf("Address Filtering is ");
|
||||
if(value & RADIO_RX_MODE_ADDRESS_FILTER) {
|
||||
printf("On, ");
|
||||
} else {
|
||||
printf("Off, ");
|
||||
}
|
||||
printf("Auto ACK is ");
|
||||
if(value & RADIO_RX_MODE_AUTOACK) {
|
||||
printf("On, ");
|
||||
} else {
|
||||
printf("Off, ");
|
||||
}
|
||||
|
||||
printf("(value=%d)\n", value);
|
||||
}
|
||||
|
||||
printf("TX Mode: ");
|
||||
if(get_param(RADIO_PARAM_TX_MODE, &value) == RADIO_RESULT_OK) {
|
||||
printf("%d\n", value);
|
||||
}
|
||||
|
||||
printf("TX Power: ");
|
||||
if(get_param(RADIO_PARAM_TXPOWER, &value) == RADIO_RESULT_OK) {
|
||||
printf("%d dBm [0x%04x]\n", value, (uint16_t)value);
|
||||
}
|
||||
|
||||
printf("CCA Threshold: ");
|
||||
if(get_param(RADIO_PARAM_CCA_THRESHOLD, &value) == RADIO_RESULT_OK) {
|
||||
printf("%d dBm [0x%04x]\n", value, (uint16_t)value);
|
||||
}
|
||||
|
||||
printf("RSSI: ");
|
||||
if(get_param(RADIO_PARAM_RSSI, &value) == RADIO_RESULT_OK) {
|
||||
printf("%d dBm [0x%04x]\n", value, (uint16_t)value);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(extended_rf_api_process, ev, data)
|
||||
{
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
get_rf_consts();
|
||||
print_rf_values();
|
||||
|
||||
test_off_on();
|
||||
test_channels();
|
||||
test_rx_modes();
|
||||
test_tx_powers();
|
||||
test_cca_thresholds();
|
||||
test_pan_id();
|
||||
test_16bit_addr();
|
||||
test_64bit_addr();
|
||||
|
||||
printf("Done\n");
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
37
examples/extended-rf-api/project-conf.h
Normal file
37
examples/extended-rf-api/project-conf.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2014, George Oikonomou (george@contiki-os.org)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PROJECT_CONF_H_
|
||||
#define PROJECT_CONF_H_
|
||||
|
||||
#undef NETSTACK_CONF_RDC
|
||||
#define NETSTACK_CONF_RDC nullrdc_driver
|
||||
|
||||
#endif /* PROJECT_CONF_H_ */
|
|
@ -32,6 +32,15 @@
|
|||
#ifndef PROJECT_RPL_WEB_CONF_H_
|
||||
#define PROJECT_RPL_WEB_CONF_H_
|
||||
|
||||
/* Disabling RDC and CSMA for demo purposes. Core updates often
|
||||
require more memory. */
|
||||
/* For projects, optimize memory and enable RDC and CSMA again. */
|
||||
#undef NETSTACK_CONF_RDC
|
||||
#define NETSTACK_CONF_RDC nullrdc_driver
|
||||
|
||||
#undef NETSTACK_CONF_MAC
|
||||
#define NETSTACK_CONF_MAC nullmac_driver
|
||||
|
||||
#ifndef QUEUEBUF_CONF_NUM
|
||||
#define QUEUEBUF_CONF_NUM 6
|
||||
#endif
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "dev/io-arch.h"
|
||||
#include "dev/dma.h"
|
||||
#include "dev/cc2530-rf.h"
|
||||
#include "dev/radio.h"
|
||||
#include "dev/watchdog.h"
|
||||
#include "dev/clock-isr.h"
|
||||
#include "dev/port2.h"
|
||||
|
@ -79,9 +80,11 @@ fade(int l) CC_NON_BANKED
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_rime_addr(void) CC_NON_BANKED
|
||||
set_rf_params(void) CC_NON_BANKED
|
||||
{
|
||||
char i;
|
||||
uint16_t short_addr;
|
||||
uint8_t ext_addr[8];
|
||||
|
||||
#if CC2530_CONF_MAC_FROM_PRIMARY
|
||||
__xdata unsigned char *macp = &X_IEEE_ADDR;
|
||||
|
@ -114,8 +117,12 @@ set_rime_addr(void) CC_NON_BANKED
|
|||
FMAP = CC2530_LAST_FLASH_BANK;
|
||||
#endif
|
||||
|
||||
for(i = (LINKADDR_SIZE - 1); i >= 0; --i) {
|
||||
linkaddr_node_addr.u8[i] = *macp;
|
||||
/*
|
||||
* Read IEEE address from flash, store in ext_addr.
|
||||
* Invert endianness (from little to big endian)
|
||||
*/
|
||||
for(i = 7; i >= 0; --i) {
|
||||
ext_addr[i] = *macp;
|
||||
macp++;
|
||||
}
|
||||
|
||||
|
@ -125,6 +132,12 @@ set_rime_addr(void) CC_NON_BANKED
|
|||
ENABLE_INTERRUPTS();
|
||||
#endif
|
||||
|
||||
short_addr = ext_addr[7];
|
||||
short_addr |= ext_addr[6] << 8;
|
||||
|
||||
/* Populate linkaddr_node_addr. Maintain endianness */
|
||||
memcpy(&linkaddr_node_addr, &ext_addr[8 - LINKADDR_SIZE], LINKADDR_SIZE);
|
||||
|
||||
/* Now the address is stored MSB first */
|
||||
#if STARTUP_CONF_VERBOSE
|
||||
PUTSTRING("Rime configured with address ");
|
||||
|
@ -136,7 +149,11 @@ set_rime_addr(void) CC_NON_BANKED
|
|||
PUTCHAR('\n');
|
||||
#endif
|
||||
|
||||
cc2530_rf_set_addr(IEEE802154_PANID);
|
||||
/* Write params to RF registers */
|
||||
NETSTACK_RADIO.set_value(RADIO_PARAM_PAN_ID, IEEE802154_PANID);
|
||||
NETSTACK_RADIO.set_value(RADIO_PARAM_16BIT_ADDR, short_addr);
|
||||
NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, CC2530_RF_CHANNEL);
|
||||
NETSTACK_RADIO.set_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8);
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -235,7 +252,7 @@ main(void) CC_NON_BANKED
|
|||
|
||||
/* initialize the netstack */
|
||||
netstack_init();
|
||||
set_rime_addr();
|
||||
set_rf_params();
|
||||
|
||||
#if BUTTON_SENSOR_ON || ADC_SENSOR_ON
|
||||
process_start(&sensors_process, NULL);
|
||||
|
|
|
@ -103,9 +103,18 @@ fade(unsigned char l)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_rime_addr()
|
||||
set_rf_params(void)
|
||||
{
|
||||
ieee_addr_cpy_to(&linkaddr_node_addr.u8[0], LINKADDR_SIZE);
|
||||
uint16_t short_addr;
|
||||
uint8_t ext_addr[8];
|
||||
|
||||
ieee_addr_cpy_to(ext_addr, 8);
|
||||
|
||||
short_addr = ext_addr[7];
|
||||
short_addr |= ext_addr[6] << 8;
|
||||
|
||||
/* Populate linkaddr_node_addr. Maintain endianness */
|
||||
memcpy(&linkaddr_node_addr, &ext_addr[8 - LINKADDR_SIZE], LINKADDR_SIZE);
|
||||
|
||||
#if STARTUP_CONF_VERBOSE
|
||||
{
|
||||
|
@ -118,6 +127,10 @@ set_rime_addr()
|
|||
}
|
||||
#endif
|
||||
|
||||
NETSTACK_RADIO.set_value(RADIO_PARAM_PAN_ID, IEEE802154_PANID);
|
||||
NETSTACK_RADIO.set_value(RADIO_PARAM_16BIT_ADDR, short_addr);
|
||||
NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, CC2538_RF_CHANNEL);
|
||||
NETSTACK_RADIO.set_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -186,9 +199,8 @@ main(void)
|
|||
process_start(&etimer_process, NULL);
|
||||
ctimer_init();
|
||||
|
||||
set_rime_addr();
|
||||
set_rf_params();
|
||||
netstack_init();
|
||||
cc2538_rf_set_addr(IEEE802154_PANID);
|
||||
|
||||
#if UIP_CONF_IPV6
|
||||
memcpy(&uip_lladdr.addr, &linkaddr_node_addr, sizeof(uip_lladdr.addr));
|
||||
|
|
|
@ -272,6 +272,30 @@ init(void)
|
|||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_value(radio_param_t param, radio_value_t *value)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_value(radio_param_t param, radio_value_t value)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_object(radio_param_t param, void *dest, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_object(radio_param_t param, const void *src, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct radio_driver cooja_radio_driver =
|
||||
{
|
||||
init,
|
||||
|
@ -284,6 +308,10 @@ const struct radio_driver cooja_radio_driver =
|
|||
pending_packet,
|
||||
radio_on,
|
||||
radio_off,
|
||||
get_value,
|
||||
set_value,
|
||||
get_object,
|
||||
set_object
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
SIM_INTERFACE(radio_interface,
|
||||
|
|
|
@ -927,6 +927,31 @@ PROCESS_THREAD(mrf24j40_process, ev, data)
|
|||
PROCESS_END();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_value(radio_param_t param, radio_value_t *value)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_value(radio_param_t param, radio_value_t value)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_object(radio_param_t param, void *dest, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_object(radio_param_t param, const void *src, size_t size)
|
||||
{
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct radio_driver mrf24j40_driver = {
|
||||
mrf24j40_init,
|
||||
|
@ -938,7 +963,11 @@ const struct radio_driver mrf24j40_driver = {
|
|||
mrf24j40_receiving_packet,
|
||||
mrf24j40_pending_packet,
|
||||
mrf24j40_on,
|
||||
mrf24j40_off
|
||||
mrf24j40_off,
|
||||
get_value,
|
||||
set_value,
|
||||
get_object,
|
||||
set_object
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
|
Loading…
Reference in a new issue