ieee802154: cc13xx_cc26xx: workaround for issue in ti driver

This is a temporary workaround for an issue in TI's RF Driver
API. A subsequent release of the SimpleLink SDK will mitigate
the need for it and it can be reverted when hal/ti receives
that update.

Fixes #29418

Signed-off-by: Christopher Friedt <chrisfriedt@gmail.com>
This commit is contained in:
Christopher Friedt 2020-10-22 15:26:45 -04:00 committed by Carles Cufí
parent 8e2978d577
commit bb7c58f65e
2 changed files with 46 additions and 2 deletions

View file

@ -65,11 +65,21 @@ get_dev_data(const struct device *dev)
return dev->data;
}
/* TODO remove when rf driver bugfix is pulled in */
static void update_saved_cmdhandle(RF_CmdHandle ch, RF_CmdHandle *saved)
{
*saved = MAX(ch, *saved);
}
/* 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);
const struct device *dev = &DEVICE_NAME_GET(ieee802154_cc13xx_cc26xx);
struct ieee802154_cc13xx_cc26xx_data *drv_data = get_dev_data(dev);
update_saved_cmdhandle(ch, (RF_CmdHandle *) &drv_data->saved_cmdhandle);
LOG_DBG("e: 0x%" PRIx64, e);
@ -81,11 +91,12 @@ static void cmd_ieee_csma_callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
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);
update_saved_cmdhandle(ch, (RF_CmdHandle *) &drv_data->saved_cmdhandle);
LOG_DBG("e: 0x%" PRIx64, e);
if (e & RF_EventRxBufFull) {
@ -194,6 +205,23 @@ out:
return r;
}
/* TODO remove when rf driver bugfix is pulled in */
static int ieee802154_cc13xx_cc26xx_reset_channel(
const struct device *dev)
{
uint8_t channel;
struct ieee802154_cc13xx_cc26xx_data *drv_data = get_dev_data(dev);
/* extract the channel from cmd_ieee_rx */
channel = drv_data->cmd_ieee_rx.channel;
__ASSERT_NO_MSG(11 <= channel && channel <= 26);
LOG_DBG("re-setting channel to %u", channel);
return ieee802154_cc13xx_cc26xx_set_channel(dev, channel);
}
static int
ieee802154_cc13xx_cc26xx_filter(const struct device *dev, bool set,
enum ieee802154_filter_type type,
@ -268,6 +296,20 @@ static int ieee802154_cc13xx_cc26xx_tx(const struct device *dev,
k_mutex_lock(&drv_data->tx_mutex, K_FOREVER);
/* Workaround for Issue #29418 where the driver stalls after
* wrapping around RF command handle 4096. This change
* effectively empties the RF command queue every ~4 minutes
* but otherwise causes the system to incur little overhead.
* A subsequent SimpleLink SDK release should resolve the issue.
*/
if (drv_data->saved_cmdhandle >= BIT(12) - 5) {
r = ieee802154_cc13xx_cc26xx_reset_channel(dev);
if (r < 0) {
goto out;
}
drv_data->saved_cmdhandle = -1;
}
do {
drv_data->cmd_ieee_csma.status = IDLE;

View file

@ -84,6 +84,8 @@ struct ieee802154_cc13xx_cc26xx_data {
volatile rfc_CMD_IEEE_TX_t cmd_ieee_tx;
volatile rfc_CMD_IEEE_RX_ACK_t cmd_ieee_rx_ack;
volatile rfc_CMD_RADIO_SETUP_t cmd_radio_setup;
volatile int16_t saved_cmdhandle;
};
#endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_CC13XX_CC26XX_H_ */