drivers: ieee802154: cc13xx_cc26xx: use ti rf driver api

This change reworks the cc13xx_cc26xx IEEE 802.15.4 driver to use
the TI RF driver API that is available in modules/hal/ti.

There are a number of benefits to using TI's API including
 - a stable multi-OS vendor library and API
 - API compatibility with the rest of the SimpleLink SDK and SoC family
 - potential multi-protocol & multi-client radio operation
   (e.g. both 15.4 and BLE)
 - coexistence support with other chipsets via gpio
 - vetted TI RF driver resources, such as
   - the radio command queue
   - highly tuned / coupled RTC & RAT (RAdio Timer) API

Fixes #26312

Signed-off-by: Christopher Friedt <chrisfriedt@gmail.com>
This commit is contained in:
Christopher Friedt 2020-10-21 13:36:48 -04:00 committed by Carles Cufí
parent 177ea9316c
commit 8e2978d577
6 changed files with 223 additions and 241 deletions

View file

@ -206,6 +206,7 @@
/drivers/i2s/*litex* @mateusz-holenko @kgugala @pgielda
/drivers/ieee802154/ @jukkar @tbursztyka
/drivers/ieee802154/ieee802154_rf2xx* @jukkar @tbursztyka @nandojve
/drivers/ieee802154/ieee802154_cc13xx* @bwitherspoon @cfriedt
/drivers/interrupt_controller/ @andrewboie
/drivers/interrupt_controller/intc_gic.c @stephanosio
/drivers/*/intc_vexriscv_litex.c @mateusz-holenko @kgugala @pgielda

View file

@ -20,10 +20,4 @@ config IEEE802154_CC13XX_CC26XX_INIT_PRIO
help
Set the initialization priority number.
config IEEE802154_CC13XX_CC26XX_RX_STACK_SIZE
int "TI CC13xx / CC26xx IEEE 802.15.4 driver's RX thread stack size"
default 800
help
This option sets the driver's stack size for its internal RX thread.
endif # IEEE802154_CC13XX_CC26XX

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2019 Brett Witherspoon
* Copyright (c) 2020 Friedt Professional Engineering Services, Inc
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -18,18 +19,14 @@ LOG_MODULE_REGISTER(ieee802154_cc13xx_cc26xx);
#include <string.h>
#include <sys/sys_io.h>
#include <ti/drivers/dpl/HwiP.h>
#include <driverlib/aon_rtc.h>
#include <driverlib/osc.h>
#include <driverlib/prcm.h>
#include <driverlib/rf_ieee_mailbox.h>
#include <driverlib/rfc.h>
#include <inc/hw_ccfg.h>
#include <inc/hw_fcfg1.h>
#include <rf_patches/rf_patch_cpe_ieee_802_15_4.h>
#include <ti/drivers/rf/RF.h>
#include "ieee802154_cc13xx_cc26xx.h"
DEVICE_DECLARE(ieee802154_cc13xx_cc26xx);
@ -43,7 +40,24 @@ static uint32_t overrides[] = {
0xFFFFFFFF
};
static HwiP_Struct RF_hwiCpe0Obj;
/* 2.4 GHz power table */
static const RF_TxPowerTable_Entry txPowerTable_2_4[] = {
{-20, RF_TxPowerTable_DEFAULT_PA_ENTRY(6, 3, 0, 2)},
{-15, RF_TxPowerTable_DEFAULT_PA_ENTRY(10, 3, 0, 3)},
{-10, RF_TxPowerTable_DEFAULT_PA_ENTRY(15, 3, 0, 5)},
{-5, RF_TxPowerTable_DEFAULT_PA_ENTRY(22, 3, 0, 9)},
{0, RF_TxPowerTable_DEFAULT_PA_ENTRY(19, 1, 0, 20)},
{1, RF_TxPowerTable_DEFAULT_PA_ENTRY(22, 1, 0, 20)},
{2, RF_TxPowerTable_DEFAULT_PA_ENTRY(25, 1, 0, 25)},
{3, RF_TxPowerTable_DEFAULT_PA_ENTRY(29, 1, 0, 28)},
{4, RF_TxPowerTable_DEFAULT_PA_ENTRY(35, 1, 0, 39)},
{5, RF_TxPowerTable_DEFAULT_PA_ENTRY(23, 0, 0, 57)},
RF_TxPowerTable_TERMINATION_ENTRY,
};
static void ieee802154_cc13xx_cc26xx_rx_done(
struct ieee802154_cc13xx_cc26xx_data *drv_data);
static int ieee802154_cc13xx_cc26xx_stop(const struct device *dev);
static inline struct ieee802154_cc13xx_cc26xx_data *
get_dev_data(const struct device *dev)
@ -51,6 +65,55 @@ get_dev_data(const struct device *dev)
return dev->data;
}
/* This is really the TX callback, because CSMA and TX are chained */
static void cmd_ieee_csma_callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
{
ARG_UNUSED(h);
ARG_UNUSED(ch);
LOG_DBG("e: 0x%" PRIx64, e);
if (e & RF_EventInternalError) {
LOG_ERR("Internal error");
}
}
static void cmd_ieee_rx_callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
{
ARG_UNUSED(h);
ARG_UNUSED(ch);
const struct device *dev = &DEVICE_NAME_GET(ieee802154_cc13xx_cc26xx);
struct ieee802154_cc13xx_cc26xx_data *drv_data = get_dev_data(dev);
LOG_DBG("e: 0x%" PRIx64, e);
if (e & RF_EventRxBufFull) {
LOG_WRN("RX buffer is full");
}
if (e & RF_EventInternalError) {
LOG_ERR("Internal error");
}
if (e & RF_EventRxEntryDone) {
ieee802154_cc13xx_cc26xx_rx_done(drv_data);
}
}
static void client_error_callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
{
ARG_UNUSED(h);
ARG_UNUSED(ch);
LOG_DBG("e: 0x%" PRIx64, e);
}
static void client_event_callback(RF_Handle h, RF_ClientEvent event, void *arg)
{
ARG_UNUSED(h);
LOG_DBG("event: %d arg: %p", event, arg);
}
static enum ieee802154_hw_caps
ieee802154_cc13xx_cc26xx_get_capabilities(const struct device *dev)
{
@ -62,16 +125,15 @@ ieee802154_cc13xx_cc26xx_get_capabilities(const struct device *dev)
static int ieee802154_cc13xx_cc26xx_cca(const struct device *dev)
{
struct ieee802154_cc13xx_cc26xx_data *drv_data = get_dev_data(dev);
uint32_t status;
RF_Stat status;
status = RFCDoorbellSendTo((uint32_t)&drv_data->cmd_ieee_cca_req);
if (status != CMDSTA_Done) {
status = RF_runImmediateCmd(drv_data->rf_handle,
(uint32_t *)&drv_data->cmd_ieee_cca_req);
if (status != RF_StatSuccess) {
LOG_ERR("Failed to request CCA (0x%x)", status);
return -EIO;
}
k_sem_take(&drv_data->fg_done, K_FOREVER);
switch (drv_data->cmd_ieee_cca_req.ccaInfo.ccaState) {
case 0:
return 0;
@ -85,8 +147,10 @@ static int ieee802154_cc13xx_cc26xx_cca(const struct device *dev)
static int ieee802154_cc13xx_cc26xx_set_channel(const struct device *dev,
uint16_t channel)
{
int r;
RF_Stat status;
RF_CmdHandle cmd_handle;
struct ieee802154_cc13xx_cc26xx_data *drv_data = get_dev_data(dev);
uint32_t status;
/* TODO Support sub-GHz for CC13xx */
if (channel < 11 || channel > 26) {
@ -94,25 +158,40 @@ static int ieee802154_cc13xx_cc26xx_set_channel(const struct device *dev,
}
/* Abort FG and BG processes */
RFCDoorbellSendTo(CMDR_DIR_CMD(CMD_ABORT));
if (ieee802154_cc13xx_cc26xx_stop(dev) < 0) {
r = -EIO;
goto out;
}
/* Block TX while changing channel */
k_mutex_lock(&drv_data->tx_mutex, K_FOREVER);
/* Set all RX entries to empty */
status = RFCDoorbellSendTo((uint32_t)&drv_data->cmd_clear_rx);
if (status != CMDSTA_Done) {
LOG_ERR("Failed to clear RX queue (0x%x)", status);
return -EIO;
status = RF_runImmediateCmd(drv_data->rf_handle,
(uint32_t *)&drv_data->cmd_clear_rx);
if (status != RF_StatCmdDoneSuccess && status != RF_StatSuccess) {
LOG_ERR("Failed to clear RX queue (%d)", status);
r = -EIO;
goto out;
}
/* Run BG receive process on requested channel */
drv_data->cmd_ieee_rx.status = IDLE;
drv_data->cmd_ieee_rx.channel = channel;
status = RFCDoorbellSendTo((uint32_t)&drv_data->cmd_ieee_rx);
if (status != CMDSTA_Done) {
LOG_ERR("Failed to submit RX command (0x%x)", status);
return -EIO;
cmd_handle = RF_postCmd(drv_data->rf_handle,
(RF_Op *)&drv_data->cmd_ieee_rx, RF_PriorityNormal,
cmd_ieee_rx_callback, RF_EventRxEntryDone);
if (cmd_handle < 0) {
LOG_ERR("Failed to post RX command (%d)", cmd_handle);
r = -EIO;
goto out;
}
return 0;
r = 0;
out:
k_mutex_unlock(&drv_data->tx_mutex);
return r;
}
static int
@ -144,48 +223,23 @@ ieee802154_cc13xx_cc26xx_filter(const struct device *dev, bool set,
static int ieee802154_cc13xx_cc26xx_set_txpower(const struct device *dev,
int16_t dbm)
{
RF_Stat status;
const RF_TxPowerTable_Entry *table;
struct ieee802154_cc13xx_cc26xx_data *drv_data = get_dev_data(dev);
uint32_t status;
/* Values from SmartRF Studio 7 2.13.0 */
switch (dbm) {
case -20:
drv_data->cmd_set_tx_power.txPower = 0x04C6;
break;
case -15:
drv_data->cmd_set_tx_power.txPower = 0x06CA;
break;
case -10:
drv_data->cmd_set_tx_power.txPower = 0x0ACF;
break;
case -5:
drv_data->cmd_set_tx_power.txPower = 0x12D6;
break;
case 0:
drv_data->cmd_set_tx_power.txPower = 0x2853;
break;
case 1:
drv_data->cmd_set_tx_power.txPower = 0x2856;
break;
case 2:
drv_data->cmd_set_tx_power.txPower = 0x3259;
break;
case 3:
drv_data->cmd_set_tx_power.txPower = 0x385D;
break;
case 4:
drv_data->cmd_set_tx_power.txPower = 0x4E63;
break;
case 5:
drv_data->cmd_set_tx_power.txPower = 0x7217;
break;
default:
/* TODO Support sub-GHz for CC13xx */
table = txPowerTable_2_4;
RF_TxPowerTable_Value power_table_value = RF_TxPowerTable_findValue(
(RF_TxPowerTable_Entry *)table, dbm);
if (power_table_value.rawValue == RF_TxPowerTable_INVALID_VALUE) {
LOG_ERR("RF_TxPowerTable_findValue() failed");
return -EINVAL;
}
status = RFCDoorbellSendTo((uint32_t)&drv_data->cmd_set_tx_power);
if (status != CMDSTA_Done) {
LOG_DBG("Failed to set TX power (0x%x)", status);
status = RF_setTxPower(drv_data->rf_handle, power_table_value);
if (status != RF_StatSuccess) {
LOG_ERR("RF_setTxPower() failed: %d", status);
return -EIO;
}
@ -198,40 +252,48 @@ static int ieee802154_cc13xx_cc26xx_tx(const struct device *dev,
struct net_pkt *pkt,
struct net_buf *frag)
{
int r;
RF_EventMask reason;
RF_ScheduleCmdParams sched_params = {
.allowDelay = true,
};
struct ieee802154_cc13xx_cc26xx_data *drv_data = get_dev_data(dev);
bool ack = ieee802154_is_ar_flag_set(frag);
int retry = CONFIG_NET_L2_IEEE802154_RADIO_TX_RETRIES;
uint32_t status;
if (mode != IEEE802154_TX_MODE_CSMA_CA) {
NET_ERR("TX mode %d not supported", mode);
return -ENOTSUP;
}
drv_data->cmd_ieee_csma.status = IDLE;
drv_data->cmd_ieee_csma.randomState = sys_rand32_get();
drv_data->cmd_ieee_tx.status = IDLE;
drv_data->cmd_ieee_tx.payloadLen = frag->len;
drv_data->cmd_ieee_tx.pPayload = frag->data;
drv_data->cmd_ieee_tx.condition.rule =
ack ? COND_STOP_ON_FALSE : COND_NEVER;
if (ack) {
drv_data->cmd_ieee_rx_ack.status = IDLE;
drv_data->cmd_ieee_rx_ack.seqNo = frag->data[2];
}
__ASSERT_NO_MSG(k_sem_count_get(&drv_data->fg_done) == 0);
k_mutex_lock(&drv_data->tx_mutex, K_FOREVER);
do {
status = RFCDoorbellSendTo((uint32_t)&drv_data->cmd_ieee_csma);
if (status != CMDSTA_Done) {
LOG_ERR("Failed to submit TX command (0x%x)", status);
return -EIO;
drv_data->cmd_ieee_csma.status = IDLE;
drv_data->cmd_ieee_csma.randomState = sys_rand32_get();
drv_data->cmd_ieee_tx.status = IDLE;
drv_data->cmd_ieee_tx.payloadLen = frag->len;
drv_data->cmd_ieee_tx.pPayload = frag->data;
drv_data->cmd_ieee_tx.condition.rule =
ack ? COND_STOP_ON_FALSE : COND_NEVER;
if (ack) {
drv_data->cmd_ieee_rx_ack.status = IDLE;
drv_data->cmd_ieee_rx_ack.seqNo = frag->data[2];
}
k_sem_take(&drv_data->fg_done, K_FOREVER);
reason = RF_runScheduleCmd(drv_data->rf_handle,
(RF_Op *)&drv_data->cmd_ieee_csma, &sched_params,
cmd_ieee_csma_callback,
RF_EventLastFGCmdDone | RF_EventLastCmdDone);
if ((reason & (RF_EventLastFGCmdDone | RF_EventLastCmdDone))
== 0) {
LOG_DBG("Failed to run command (0x%" PRIx64 ")",
reason);
continue;
}
if (drv_data->cmd_ieee_csma.status != IEEE_DONE_OK) {
LOG_DBG("Channel access failure (0x%x)",
@ -247,7 +309,8 @@ static int ieee802154_cc13xx_cc26xx_tx(const struct device *dev,
if (!ack || drv_data->cmd_ieee_rx_ack.status == IEEE_DONE_ACK ||
drv_data->cmd_ieee_rx_ack.status == IEEE_DONE_ACKPEND) {
return 0;
r = 0;
goto out;
}
LOG_DBG("No acknowledgment (0x%x)",
@ -255,8 +318,11 @@ static int ieee802154_cc13xx_cc26xx_tx(const struct device *dev,
} while (retry-- > 0);
LOG_DBG("Failed to TX");
r = -EIO;
return -EIO;
out:
k_mutex_unlock(&drv_data->tx_mutex);
return r;
}
static inline uint8_t ieee802154_cc13xx_cc26xx_convert_rssi(int8_t rssi)
@ -326,20 +392,6 @@ static void ieee802154_cc13xx_cc26xx_rx_done(
}
}
static void ieee802154_cc13xx_cc26xx_rx(void *arg1, void *arg2, void *arg3)
{
struct ieee802154_cc13xx_cc26xx_data *drv_data = arg1;
ARG_UNUSED(arg2);
ARG_UNUSED(arg3);
while (true) {
k_sem_take(&drv_data->rx_done, K_FOREVER);
ieee802154_cc13xx_cc26xx_rx_done(drv_data);
}
}
static int ieee802154_cc13xx_cc26xx_start(const struct device *dev)
{
ARG_UNUSED(dev);
@ -349,9 +401,16 @@ static int ieee802154_cc13xx_cc26xx_start(const struct device *dev)
static int ieee802154_cc13xx_cc26xx_stop(const struct device *dev)
{
ARG_UNUSED(dev);
struct ieee802154_cc13xx_cc26xx_data *drv_data = get_dev_data(dev);
RFCDoorbellSendTo(CMDR_DIR_CMD(CMD_STOP));
RF_Stat status;
status = RF_flushCmd(drv_data->rf_handle, RF_CMDHANDLE_FLUSH_ALL, RF_ABORT_PREEMPTION);
if (!(status == RF_StatCmdDoneSuccess || status == RF_StatSuccess
|| status == RF_StatInvalidParamsError)) {
LOG_ERR("Failed to abort radio operations (%d)", status);
return -EIO;
}
return 0;
}
@ -364,39 +423,6 @@ ieee802154_cc13xx_cc26xx_configure(const struct device *dev,
return -ENOTSUP;
}
static void ieee802154_cc13xx_cc26xx_cpe0_isr(void *arg)
{
struct ieee802154_cc13xx_cc26xx_data *drv_data = get_dev_data(arg);
uint32_t flags;
flags = RFCCpeIntGetAndClear(IRQ_RX_ENTRY_DONE |
IRQ_LAST_FG_COMMAND_DONE);
if (flags & IRQ_RX_ENTRY_DONE) {
k_sem_give(&drv_data->rx_done);
}
if (flags & IRQ_LAST_FG_COMMAND_DONE) {
k_sem_give(&drv_data->fg_done);
}
}
static void ieee802154_cc13xx_cc26xx_cpe1_isr(const void *arg)
{
uint32_t flags;
ARG_UNUSED(arg);
flags = RFCCpeIntGetAndClear(IRQ_RX_BUF_FULL | IRQ_INTERNAL_ERROR);
if (flags & IRQ_RX_BUF_FULL) {
LOG_WRN("Receive buffer full");
}
if (flags & IRQ_INTERNAL_ERROR) {
LOG_ERR("Internal error");
}
}
static void ieee802154_cc13xx_cc26xx_data_init(const struct device *dev)
{
@ -431,13 +457,7 @@ static void ieee802154_cc13xx_cc26xx_data_init(const struct device *dev)
drv_data->rx_queue.pCurrEntry = (uint8_t *)&drv_data->rx_entry[0];
drv_data->rx_queue.pLastEntry = NULL;
k_sem_init(&drv_data->fg_done, 0, UINT_MAX);
k_sem_init(&drv_data->rx_done, 0, UINT_MAX);
k_thread_create(&drv_data->rx_thread, drv_data->rx_stack,
K_KERNEL_STACK_SIZEOF(drv_data->rx_stack),
ieee802154_cc13xx_cc26xx_rx, drv_data, NULL, NULL,
K_PRIO_COOP(2), 0, K_NO_WAIT);
k_mutex_init(&drv_data->tx_mutex);
}
static void ieee802154_cc13xx_cc26xx_iface_init(struct net_if *iface)
@ -469,99 +489,46 @@ static struct ieee802154_radio_api ieee802154_cc13xx_cc26xx_radio_api = {
static int ieee802154_cc13xx_cc26xx_init(const struct device *dev)
{
RF_Params rf_params;
RF_EventMask reason;
RF_Mode rf_mode = {
.rfMode = RF_MODE_IEEE_15_4,
.cpePatchFxn = &rf_patch_cpe_ieee_802_15_4,
};
struct ieee802154_cc13xx_cc26xx_data *drv_data = get_dev_data(dev);
bool set_osc_hf;
uint32_t key, status;
HwiP_Params params;
/* Apply RF patches */
rf_patch_cpe_ieee_802_15_4();
/* Need to set crystal oscillator as high frequency clock source */
set_osc_hf = OSCClockSourceGet(OSC_SRC_CLK_HF) != OSC_XOSC_HF;
/* Enable 48 MHz crystal oscillator */
if (set_osc_hf) {
OSCClockSourceSet(OSC_SRC_CLK_HF, OSC_XOSC_HF);
}
/* Initialize data while waiting for oscillator to stablize */
/* Initialize driver data */
ieee802154_cc13xx_cc26xx_data_init(dev);
/* Switch high frequency clock to crystal oscillator after stable */
if (set_osc_hf) {
while (!OSCHfSourceReady()) {
continue;
}
key = irq_lock();
OSCHfSourceSwitch();
irq_unlock(key);
}
/* Enable power domain and wait to avoid faults */
PRCMPowerDomainOn(PRCM_DOMAIN_RFCORE);
while (PRCMPowerDomainStatus(PRCM_DOMAIN_RFCORE) ==
PRCM_DOMAIN_POWER_OFF) {
continue;
}
/* Enable clock domain and wait for PRCM registers to update */
PRCMDomainEnable(PRCM_DOMAIN_RFCORE);
PRCMLoadSet();
while (!PRCMLoadGet()) {
continue;
}
__ASSERT_NO_MSG(PRCMRfReady());
/* Disable all CPE interrupts */
RFCCpeIntDisable(0xFFFFFFFF);
/* Enable CPE0 interrupts */
/*
* Use HwiP_construct() to connect the irq for CPE0. IRQ_CONNECT() can
* only be called once for a given irq, and we need to keep it within
* HwiP so that TI's RF driver can plug the same interrupt.
*/
HwiP_Params_init(&params);
params.priority = INT_PRI_LEVEL1;
params.arg = (uintptr_t)DEVICE_GET(ieee802154_cc13xx_cc26xx);
HwiP_construct(&RF_hwiCpe0Obj, INT_RFC_CPE_0,
(HwiP_Fxn)ieee802154_cc13xx_cc26xx_cpe0_isr, &params);
RFCCpe0IntSelectClearEnable(IRQ_RX_ENTRY_DONE |
IRQ_LAST_FG_COMMAND_DONE);
/* Enable CPE1 interrupts */
IRQ_CONNECT(CC13XX_CC26XX_CPE1_IRQ, 0,
ieee802154_cc13xx_cc26xx_cpe1_isr, NULL, 0);
irq_enable(CC13XX_CC26XX_CPE1_IRQ);
RFCCpe1IntSelectClearEnable(IRQ_RX_BUF_FULL | IRQ_INTERNAL_ERROR);
/* Enable essential clocks for CPE to boot */
RFCClockEnable();
/* Attempt to ping CPE */
status = RFCDoorbellSendTo(CMDR_DIR_CMD(CMD_PING));
if (status != CMDSTA_Done) {
LOG_DBG("Failed to ping CPE (0x%x)", status);
return -EIO;
}
/* Enable 16 kHz from RTC to RAT for synchronization (TRM 25.2.4.3) */
sys_set_bit(AON_RTC_BASE + AON_RTC_O_CTL, AON_RTC_CTL_RTC_UPD_EN_BITN);
/* Asynchronously start RAT */
status = RFCDoorbellSendTo(CMDR_DIR_CMD(CMD_START_RAT));
if (status != CMDSTA_Done) {
LOG_DBG("Failed to start RAT (0x%x)", status);
return -EIO;
}
/* Setup radio */
status = RFCDoorbellSendTo((uint32_t)&drv_data->cmd_radio_setup);
if (status != CMDSTA_Done) {
LOG_DBG("Failed to submit setup radio command (0x%x)", status);
RF_Params_init(&rf_params);
rf_params.pErrCb = client_error_callback;
rf_params.pClientEventCb = client_event_callback;
drv_data->rf_handle = RF_open(&drv_data->rf_object,
&rf_mode, (RF_RadioSetup *)&drv_data->cmd_radio_setup,
&rf_params);
if (drv_data->rf_handle == NULL) {
LOG_ERR("RF_open() failed");
return -EIO;
}
/*
* Run CMD_FS with frequency 0 to ensure RF_currClient is not NULL.
* RF_currClient is a static variable in the TI RF Driver library.
* If this is not done, then even CMD_ABORT fails.
*/
drv_data->cmd_fs.status = IDLE;
drv_data->cmd_fs.pNextOp = NULL;
drv_data->cmd_fs.condition.rule = COND_NEVER;
drv_data->cmd_fs.synthConf.bTxMode = false;
drv_data->cmd_fs.frequency = 0;
drv_data->cmd_fs.fractFreq = 0;
reason = RF_runCmd(drv_data->rf_handle, (RF_Op *)&drv_data->cmd_fs,
RF_PriorityNormal, NULL, 0);
if (reason != RF_EventLastCmdDone) {
LOG_ERR("Failed to set frequency: 0x%" PRIx64, reason);
return -EIO;
}
@ -569,6 +536,10 @@ static int ieee802154_cc13xx_cc26xx_init(const struct device *dev)
}
static struct ieee802154_cc13xx_cc26xx_data ieee802154_cc13xx_cc26xx_data = {
.cmd_fs = {
.commandNo = CMD_FS,
},
.cmd_ieee_cca_req = {
.commandNo = CMD_IEEE_CCA_REQ,
},

View file

@ -10,6 +10,8 @@
#include <kernel.h>
#include <net/net_if.h>
#include <ti/drivers/rf/RF.h>
#include <driverlib/rf_common_cmd.h>
#include <driverlib/rf_data_entry.h>
#include <driverlib/rf_ieee_cmd.h>
@ -59,22 +61,21 @@
#define CC13XX_CC26XX_RSSI_DYNAMIC_RANGE 95
struct ieee802154_cc13xx_cc26xx_data {
RF_Handle rf_handle;
RF_Object rf_object;
struct net_if *iface;
uint8_t mac[8];
struct k_sem fg_done;
struct k_sem rx_done;
K_KERNEL_STACK_MEMBER(rx_stack,
CONFIG_IEEE802154_CC13XX_CC26XX_RX_STACK_SIZE);
struct k_thread rx_thread;
struct k_mutex tx_mutex;
dataQueue_t rx_queue;
rfc_dataEntryPointer_t rx_entry[CC13XX_CC26XX_RX_BUF_SIZE];
rfc_dataEntryPointer_t rx_entry[CC13XX_CC26XX_NUM_RX_BUF];
uint8_t rx_data[CC13XX_CC26XX_NUM_RX_BUF]
[CC13XX_CC26XX_RX_BUF_SIZE] __aligned(4);
volatile rfc_CMD_FS_t cmd_fs;
volatile rfc_CMD_IEEE_CCA_REQ_t cmd_ieee_cca_req;
volatile rfc_CMD_CLEAR_RX_t cmd_clear_rx;
volatile rfc_CMD_IEEE_RX_t cmd_ieee_rx;

View file

@ -53,6 +53,10 @@ if IEEE802154
config IEEE802154_CC13XX_CC26XX
default y
# required for linking with PowerCC26X2_config in
# soc/arm/ti_simplelink/cc13x2_cc26x2/power.c
select SYS_POWER_MANAGEMENT
select SYS_POWER_SLEEP_STATES
config NET_CONFIG_IEEE802154_DEV_NAME
default IEEE802154_CC13XX_CC26XX_DRV_NAME

View file

@ -23,16 +23,27 @@
#define LOG_LEVEL CONFIG_SOC_LOG_LEVEL
LOG_MODULE_REGISTER(soc);
const PowerCC26X2_Config PowerCC26X2_config = {
#if defined(CONFIG_IEEE802154_CC13XX_CC26XX) \
|| defined(CONFIG_BLE_CC13XX_CC26XX)
/* TODO: check for IEEE802154_CC13XX_CC26XX_SUB_GHZ */
.policyInitFxn = NULL,
.policyFxn = NULL,
.calibrateFxn = &PowerCC26XX_calibrate,
.enablePolicy = false,
.calibrateRCOSC_LF = true,
.calibrateRCOSC_HF = true
#else
/* Configuring TI Power module to not use its policy function (we use Zephyr's
* instead), and disable oscillator calibration functionality for now.
*/
const PowerCC26X2_Config PowerCC26X2_config = {
.policyInitFxn = NULL,
.policyFxn = NULL,
.calibrateFxn = NULL,
.enablePolicy = false,
.calibrateRCOSC_LF = false,
.calibrateRCOSC_HF = false
#endif
};
extern PowerCC26X2_ModuleState PowerCC26X2_module;