drivers: ieee802154: cc13xx_cc26xx_subg: PA TX amplifier support

Enhance IEEE802154 Sub-GHz driver to support CC13x2P's internal power
amplifier (20dBm) for TX.

Note: requires board-specific antenna switching for it to work
properly.

Signed-off-by: Stancu Florin <niflostancu@gmail.com>
This commit is contained in:
Stancu Florin 2021-09-13 17:06:02 +03:00 committed by Stephanos Ioannidis
commit e41de9235a
2 changed files with 151 additions and 32 deletions

View file

@ -45,8 +45,15 @@ static int ieee802154_cc13xx_cc26xx_subg_rx(
static void ieee802154_cc13xx_cc26xx_subg_setup_rx_buffers(
struct ieee802154_cc13xx_cc26xx_subg_data *drv_data);
/* Overrides from SmartRF Studio 7 2.18.0 */
static uint32_t overrides_sub_ghz[] = {
#ifndef CMD_PROP_RADIO_DIV_SETUP_PA
/* workaround for older HAL TI SDK (less than 4.40) */
#define CMD_PROP_RADIO_DIV_SETUP_PA CMD_PROP_RADIO_DIV_SETUP
#endif
/* Radio values for CC13x2R (note: CC26x2 does not support sub-GHz radio) */
#if defined(CONFIG_SOC_CC1352R)
/* R overrides from SmartRF Studio (200kbps, 50kHz deviation, 2-GFSK, 311.8kHz Rx BW) */
static uint32_t ieee802154_cc13xx_overrides_sub_ghz[] = {
/* DC/DC regulator: In Tx, use DCDCCTL5[3:0]=0x7 (DITHER_EN=0 and IPEAK=7). */
(uint32_t)0x00F788D3,
/* Set RF_FSCA.ANADIV.DIV_SEL_BIAS = 1. Bits [0:16, 24, 30] are don't care.. */
@ -55,11 +62,13 @@ static uint32_t overrides_sub_ghz[] = {
(uint32_t)0x08141131,
/* Tx: Configure PA ramp time, PACTL2.RC=0x3 (in ADI0, set PACTL2[4:3]=0x3) */
ADI_2HALFREG_OVERRIDE(0, 16, 0x8, 0x8, 17, 0x1, 0x1),
/* Tx: Configure PA ramping, set wait time before turning off (0x1A ticks of 16/24 us = 17.3 us). */
/* Tx: Configure PA ramping, set wait time before turning off */
/* (0x1A ticks of 16/24 us = 17.3 us). */
HW_REG_OVERRIDE(0x6028, 0x001A),
/* Rx: Set AGC reference level to 0x16 (default: 0x2E) */
HW_REG_OVERRIDE(0x609C, 0x0016),
/* Rx: Set RSSI offset to adjust reported RSSI by -1 dB (default: -2), trimmed for external bias and differential configuration */
/* Rx: Set RSSI offset to adjust reported RSSI by -1 dB (default: -2), */
/* trimmed for external bias and differential configuration */
(uint32_t)0x000188A3,
/* Rx: Set anti-aliasing filter bandwidth to 0x8 (in ADI0, set IFAMPCTL3[7:4]=0x8) */
ADI_HALFREG_OVERRIDE(0, 61, 0xF, 0x8),
@ -68,10 +77,26 @@ 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,
/* Radio setup command for CC1312R / CC1352R */
static volatile rfc_CMD_PROP_RADIO_DIV_SETUP_t ieee802154_cc13xx_radio_div_setup = {
.commandNo = CMD_PROP_RADIO_DIV_SETUP,
.condition.rule = COND_NEVER,
.modulation.modType = 1, /* FSK */
.modulation.deviation = 200,
.symbolRate.preScale = 15,
.symbolRate.rateWord = 131072,
.rxBw = 0x59, /* 310.8 kHz */
.preamConf.nPreamBytes = 7,
.formatConf.nSwBits = 24, /* 24-bit of syncword */
.formatConf.bMsbFirst = true,
.formatConf.whitenMode = 7,
.config.biasMode = true,
.formatConf.bMsbFirst = true,
.txPower = 0x013f, /* from Smart RF Studio */
.centerFreq = 915,
.intFreq = 0x0999,
.loDivider = 5,
.pRegOverride = ieee802154_cc13xx_overrides_sub_ghz,
};
/* Sub GHz power table */
@ -94,10 +119,127 @@ static const RF_TxPowerTable_Entry txPowerTable_sub_ghz[] = {
{ 11, RF_TxPowerTable_DEFAULT_PA_ENTRY(26, 2, 0, 51) },
{ 12, RF_TxPowerTable_DEFAULT_PA_ENTRY(16, 0, 0, 82) },
{ 13, RF_TxPowerTable_DEFAULT_PA_ENTRY(36, 0, 0, 89) },
#ifdef CC13X2_CC26X2_BOOST_MODE
{ 14, RF_TxPowerTable_DEFAULT_PA_ENTRY(63, 0, 1, 0) },
#endif
RF_TxPowerTable_TERMINATION_ENTRY
};
/* Radio values for CC13X2P */
#elif defined(CONFIG_SOC_CC1352P)
/* CC1352P overrides from SmartRF Studio (200kbps, 50kHz deviation, 2-GFSK, 311.8kHz Rx BW) */
static uint32_t ieee802154_cc13xx_overrides_sub_ghz[] = {
/* Tx: Configure PA ramp time, PACTL2.RC=0x3 (in ADI0, set PACTL2[4:3]=0x1) */
ADI_2HALFREG_OVERRIDE(0, 16, 0x8, 0x8, 17, 0x1, 0x0),
/* Rx: Set AGC reference level to 0x16 (default: 0x2E) */
HW_REG_OVERRIDE(0x609C, 0x0016),
/* Rx: Set RSSI offset to adjust reported RSSI by -1 dB (default: -2), trimmed */
/* for external bias and differential configuration */
(uint32_t)0x000188A3,
/* Rx: Set anti-aliasing filter bandwidth to 0x6 (in ADI0, set IFAMPCTL3[7:4]=0x8) */
ADI_HALFREG_OVERRIDE(0, 61, 0xF, 0x8),
/* override_prop_common_sub1g.xml */
/* Set RF_FSCA.ANADIV.DIV_SEL_BIAS = 1. Bits [0:16, 24, 30] are don't care.. */
(uint32_t)0x4001405D,
/* Set RF_FSCA.ANADIV.DIV_SEL_BIAS = 1. Bits [0:16, 24, 30] are don't care.. */
(uint32_t)0x08141131,
/* override_prop_common.xml */
/* DC/DC regulator: In Tx with 14 dBm PA setting, use DCDCCTL5[3:0]=0xF */
/* (DITHER_EN=1 and IPEAK=7). In Rx, use default settings. */
(uint32_t)0x00F788D3,
/* TX power override */
/* Tx: Set PA trim to max to maximize its output power (in ADI0, set PACTL0=0xF8) */
ADI_REG_OVERRIDE(0, 12, 0xF8),
(uint32_t)0xFFFFFFFF
};
static uint32_t rf_prop_overrides_tx_std[] = {
/* The TX Power element should always be the first in the list */
TX_STD_POWER_OVERRIDE(0xB224),
/* The ANADIV radio parameter based on the LO divider (0) and front-end (0) settings */
(uint32_t)0x11310703,
/* override_phy_tx_pa_ramp_genfsk_std.xml */
/* Tx: Configure PA ramping, set wait time before turning off */
/* (0x1A ticks of 16/24 us = 17.3 us). */
HW_REG_OVERRIDE(0x6028, 0x001A),
(uint32_t)0xFFFFFFFF
};
static uint32_t rf_prop_overrides_tx_20[] = {
/* The TX Power element should always be the first in the list */
TX20_POWER_OVERRIDE(0x001B8ED2),
/* The ANADIV radio parameter based on the LO divider (0) and front-end (0) settings */
(uint32_t)0x11C10703,
/* override_phy_tx_pa_ramp_genfsk_hpa.xml */
/* Tx: Configure PA ramping, set wait time before turning off */
/* (0x1F ticks of 16/24 us = 20.3 us). */
HW_REG_OVERRIDE(0x6028, 0x001F),
(uint32_t)0xFFFFFFFF
};
/* Radio setup command for CC1312R / CC1352R */
static volatile rfc_CMD_PROP_RADIO_DIV_SETUP_PA_t ieee802154_cc13xx_radio_div_setup = {
.commandNo = CMD_PROP_RADIO_DIV_SETUP_PA,
.condition.rule = COND_NEVER,
.modulation.modType = 1, /* FSK */
.modulation.deviation = 200,
.symbolRate.preScale = 15,
.symbolRate.rateWord = 131072,
.rxBw = 0x59, /* 310.8 kHz */
.preamConf.nPreamBytes = 7,
.formatConf.nSwBits = 24, /* 24-bit of syncword */
.formatConf.bMsbFirst = true,
.formatConf.whitenMode = 7,
.config.biasMode = true,
.formatConf.bMsbFirst = true,
.txPower = 0x013f, /* from Smart RF Studio */
.centerFreq = 915,
.intFreq = 0x0C00,
.loDivider = 5,
.pRegOverride = ieee802154_cc13xx_overrides_sub_ghz,
.pRegOverrideTxStd = rf_prop_overrides_tx_std,
.pRegOverrideTx20 = rf_prop_overrides_tx_20,
};
/* Sub GHz power table */
static const RF_TxPowerTable_Entry txPowerTable_sub_ghz[] = {
{ -20, RF_TxPowerTable_DEFAULT_PA_ENTRY(0, 3, 0, 2) },
{ -15, RF_TxPowerTable_DEFAULT_PA_ENTRY(1, 3, 0, 3) },
{ -10, RF_TxPowerTable_DEFAULT_PA_ENTRY(2, 3, 0, 5) },
{ -5, RF_TxPowerTable_DEFAULT_PA_ENTRY(4, 3, 0, 5) },
{ 0, RF_TxPowerTable_DEFAULT_PA_ENTRY(8, 3, 0, 8) },
{ 1, RF_TxPowerTable_DEFAULT_PA_ENTRY(9, 3, 0, 9) },
{ 2, RF_TxPowerTable_DEFAULT_PA_ENTRY(10, 3, 0, 9) },
{ 3, RF_TxPowerTable_DEFAULT_PA_ENTRY(11, 3, 0, 10) },
{ 4, RF_TxPowerTable_DEFAULT_PA_ENTRY(13, 3, 0, 11) },
{ 5, RF_TxPowerTable_DEFAULT_PA_ENTRY(14, 3, 0, 14) },
{ 6, RF_TxPowerTable_DEFAULT_PA_ENTRY(17, 3, 0, 16) },
{ 7, RF_TxPowerTable_DEFAULT_PA_ENTRY(20, 3, 0, 19) },
{ 8, RF_TxPowerTable_DEFAULT_PA_ENTRY(24, 3, 0, 22) },
{ 9, RF_TxPowerTable_DEFAULT_PA_ENTRY(28, 3, 0, 31) },
{ 10, RF_TxPowerTable_DEFAULT_PA_ENTRY(18, 2, 0, 31) },
{ 11, RF_TxPowerTable_DEFAULT_PA_ENTRY(26, 2, 0, 51) },
{ 12, RF_TxPowerTable_DEFAULT_PA_ENTRY(16, 0, 0, 82) },
{ 13, RF_TxPowerTable_DEFAULT_PA_ENTRY(36, 0, 0, 89) },
#ifdef CC13X2_CC26X2_BOOST_MODE
{ 14, RF_TxPowerTable_DEFAULT_PA_ENTRY(63, 0, 1, 0) },
#endif
{ 15, RF_TxPowerTable_HIGH_PA_ENTRY(18, 0, 0, 36, 0) },
{ 16, RF_TxPowerTable_HIGH_PA_ENTRY(24, 0, 0, 43, 0) },
{ 17, RF_TxPowerTable_HIGH_PA_ENTRY(28, 0, 0, 51, 2) },
{ 18, RF_TxPowerTable_HIGH_PA_ENTRY(34, 0, 0, 64, 4) },
{ 19, RF_TxPowerTable_HIGH_PA_ENTRY(15, 3, 0, 36, 4) },
{ 20, RF_TxPowerTable_HIGH_PA_ENTRY(18, 3, 0, 71, 27) },
RF_TxPowerTable_TERMINATION_ENTRY
};
#endif /* CONFIG_SOC_CC1352* */
/** 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,
};
static inline int ieee802154_cc13xx_cc26xx_subg_channel_to_frequency(
uint16_t channel, uint16_t *frequency, uint16_t *fractFreq)
{
@ -638,7 +780,7 @@ static int ieee802154_cc13xx_cc26xx_subg_init(const struct device *dev)
rf_params.pClientEventCb = client_event_callback;
drv_data->rf_handle = RF_open(&drv_data->rf_object,
&rf_mode, (RF_RadioSetup *)&drv_data->cmd_prop_radio_div_setup,
&rf_mode, (RF_RadioSetup *)&ieee802154_cc13xx_radio_div_setup,
&rf_params);
if (drv_data->rf_handle == NULL) {
LOG_ERR("RF_open() failed");
@ -679,28 +821,6 @@ static struct ieee802154_cc13xx_cc26xx_subg_data
.pQueue = &ieee802154_cc13xx_cc26xx_subg_data.rx_queue,
},
/* Sub-GHz Radio Commands */
.cmd_prop_radio_div_setup = {
.commandNo = CMD_PROP_RADIO_DIV_SETUP,
.condition.rule = COND_NEVER,
.modulation.modType = 1, /* FSK */
.modulation.deviation = 200,
.symbolRate.preScale = 15,
.symbolRate.rateWord = 131072,
.rxBw = 0x59, /* 310.8 kHz */
.preamConf.nPreamBytes = 7,
.formatConf.nSwBits = 24, /* 24-bit of syncword */
.formatConf.bMsbFirst = true,
.formatConf.whitenMode = 7,
.config.biasMode = true,
.formatConf.bMsbFirst = true,
.txPower = 0x013f, /* from Smart RF Studio */
.centerFreq = 915,
.intFreq = 0x0999,
.loDivider = 5,
.pRegOverride = overrides_sub_ghz,
},
.cmd_fs = {
.commandNo = CMD_FS,
.condition.rule = COND_NEVER,

View file

@ -87,7 +87,6 @@ struct ieee802154_cc13xx_cc26xx_subg_data {
volatile rfc_CMD_FS_t cmd_fs;
/* Sub-GHz Radio Commands */
volatile rfc_CMD_PROP_RADIO_DIV_SETUP_t cmd_prop_radio_div_setup;
volatile rfc_CMD_PROP_RX_ADV_t cmd_prop_rx_adv;
volatile rfc_CMD_PROP_TX_ADV_t cmd_prop_tx_adv;
volatile rfc_propRxOutput_t cmd_prop_rx_adv_output;