drivers: ieee802154: cc13xx_cc26xx: add subghz power saving

When stopping the interface, also abort the RX routine and enable RF
power saving. Will re-start RX on iface start.

Also fixed a bug with `cmd_fs` crashing at RF wakeup because `rf_mode`
was allocated on stack.

Signed-off-by: Stancu Florin <niflostancu@gmail.com>
This commit is contained in:
Stancu Florin 2021-07-02 16:50:59 +03:00 committed by Christopher Friedt
commit 67360416f2

View file

@ -36,6 +36,8 @@ static void ieee802154_cc13xx_cc26xx_subg_data_init(
struct ieee802154_cc13xx_cc26xx_subg_data *drv_data);
static int ieee802154_cc13xx_cc26xx_subg_stop(
const struct device *dev);
static int ieee802154_cc13xx_cc26xx_subg_stop_if(
const struct device *dev);
static int ieee802154_cc13xx_cc26xx_subg_rx(
const struct device *dev);
static void ieee802154_cc13xx_cc26xx_subg_setup_rx_buffers(
@ -66,6 +68,12 @@ static uint32_t overrides_sub_ghz[] = {
(uint32_t)0xFFFFFFFF
};
/** RF patches to use (note: RF core keeps a pointer to this, so no stack). */
static RF_Mode rf_mode = {
.rfMode = RF_MODE_MULTIPLE,
.cpePatchFxn = &rf_patch_cpe_multi_protocol,
};
/* Sub GHz power table */
static const RF_TxPowerTable_Entry txPowerTable_sub_ghz[] = {
{ -20, RF_TxPowerTable_DEFAULT_PA_ENTRY(0, 3, 0, 2) },
@ -493,10 +501,14 @@ static void ieee802154_cc13xx_cc26xx_subg_rx_done(
static int ieee802154_cc13xx_cc26xx_subg_start(const struct device *dev)
{
ARG_UNUSED(dev);
/* Start RX */
(void)ieee802154_cc13xx_cc26xx_subg_rx(dev);
return 0;
}
/**
* Flushes / stops all radio commands in RF queue.
*/
static int ieee802154_cc13xx_cc26xx_subg_stop(const struct device *dev)
{
struct ieee802154_cc13xx_cc26xx_subg_data *drv_data =
@ -515,6 +527,26 @@ static int ieee802154_cc13xx_cc26xx_subg_stop(const struct device *dev)
return 0;
}
/**
* Stops the sub-GHz interface and yields the radio (tells RF module to power
* down).
*/
static int ieee802154_cc13xx_cc26xx_subg_stop_if(const struct device *dev)
{
struct ieee802154_cc13xx_cc26xx_subg_data *drv_data =
get_dev_data(dev);
int ret;
ret = ieee802154_cc13xx_cc26xx_subg_stop(dev);
if (ret < 0) {
return ret;
}
/* power down radio */
RF_yield(drv_data->rf_handle);
return 0;
}
static int
ieee802154_cc13xx_cc26xx_subg_configure(const struct device *dev,
enum ieee802154_config_type type,
@ -602,7 +634,7 @@ static struct ieee802154_radio_api
.set_txpower = ieee802154_cc13xx_cc26xx_subg_set_txpower,
.tx = ieee802154_cc13xx_cc26xx_subg_tx,
.start = ieee802154_cc13xx_cc26xx_subg_start,
.stop = ieee802154_cc13xx_cc26xx_subg_stop,
.stop = ieee802154_cc13xx_cc26xx_subg_stop_if,
.configure = ieee802154_cc13xx_cc26xx_subg_configure,
.get_subg_channel_count =
ieee802154_cc13xx_cc26xx_subg_get_subg_channel_count,
@ -612,10 +644,6 @@ static int ieee802154_cc13xx_cc26xx_subg_init(const struct device *dev)
{
RF_Params rf_params;
RF_EventMask reason;
RF_Mode rf_mode = {
.rfMode = RF_MODE_MULTIPLE,
.cpePatchFxn = &rf_patch_cpe_multi_protocol,
};
struct ieee802154_cc13xx_cc26xx_subg_data *drv_data =
get_dev_data(dev);