Skip to content

Commit

Permalink
drivers: ieee802154: dw1000: set_txpower implementation
Browse files Browse the repository at this point in the history
Add implementation to change the register for Transmit Power Control.
The function will set TX power below or above the nominal
calibration value - within the full ranges allowed by the
TX_POWER register.

Signed-off-by: Marcos Lopez <[email protected]>
  • Loading branch information
loopsmark committed Nov 5, 2023
1 parent 663c1d0 commit 28b4965
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 6 deletions.
90 changes: 87 additions & 3 deletions drivers/ieee802154/ieee802154_dw1000.c
Original file line number Diff line number Diff line change
Expand Up @@ -770,11 +770,95 @@ static int dwt_filter(const struct device *dev,
return -ENOTSUP;
}

static int dwt_set_power(const struct device *dev, int16_t dbm)
uint8_t dwt_encode_power_tx(int16_t target_mdb)
{
uint8_t target_int_x2;
uint8_t coarse_steps;
uint8_t coarse_x2;
uint8_t fine_steps;
uint8_t coarse_reg;
uint8_t fine_reg;
uint8_t reg;

if (target_mdb < 0) {
return DWT_TX_POWER_CTRL_MIN;
} else if (target_mdb > DWT_TX_POWER_CTRL_MAX_MDB) {
return DWT_TX_POWER_CTRL_MAX;
}

target_int_x2 = target_mdb << 1;
coarse_steps = target_int_x2 / DWT_TX_POWER_CTRL_COARSE_STEPS_MDB_X2;

if (coarse_steps > DWT_TX_POWER_CTRL_COARSE_MASK) {
coarse_steps = DWT_TX_POWER_CTRL_COARSE_MASK;
}

coarse_x2 = coarse_steps * DWT_TX_POWER_CTRL_COARSE_STEPS_MDB_X2;
fine_steps = (target_int_x2 - coarse_x2) / DWT_TX_POWER_CTRL_FINE_STEPS_MDB_X2;

if (fine_steps > DWT_TX_POWER_CTRL_FINE_MASK) {
fine_steps = DWT_TX_POWER_CTRL_FINE_MASK;
}

coarse_reg = DWT_TX_POWER_CTRL_COARSE_MASK - coarse_steps;
fine_reg = fine_steps;
reg = (coarse_reg << 5) | fine_reg;

return reg;
}

static int dwt_set_txpower(const struct device *dev, int16_t dbm)
{
struct dwt_context *ctx = dev->data;
uint8_t chan = ctx->rf_cfg.channel;
int16_t mdbm = dbm * 10;
uint32_t tx_power = 0;
void *dwt_txpwr_mdb;

if (ctx->rf_cfg.prf == DWT_PRF_16M) {
dwt_txpwr_mdb = (void *)dwt_txpwr_16_mdb;
} else {
dwt_txpwr_mdb = (void *)dwt_txpwr_64_mdb;
}

#ifdef CONFIG_IEEE802154_DW1000_ENABLE_MANUAL_TX_POWER_CONTROL
/* Manual Transmit Power Control */
uint16_t phr_sd_mdb;
uint8_t phr_sd;

phr_sd_mdb = ((uint16_t *)dwt_txpwr_mdb)[dwt_ch_to_cfg[chan]];
phr_sd = dwt_encode_power_tx(phr_sd_mdb + mdbm);
tx_power |= ((uint32_t)phr_sd << DWT_TX_POWER_TXPOWSD_SHIFT);
tx_power |= ((uint32_t)phr_sd << DWT_TX_POWER_TXPOWPHR_SHIFT);
#else
/* Smart Transmit Power Control */
uint16_t norm_mdb;
uint16_t p500_mdb;
uint16_t p250_mdb;
uint16_t p125_mdb;
uint8_t norm;
uint8_t p500;
uint8_t p250;
uint8_t p125;

norm_mdb = ((uint16_t (*)[4])dwt_txpwr_mdb)[dwt_ch_to_cfg[chan]][0];
p500_mdb = ((uint16_t (*)[4])dwt_txpwr_mdb)[dwt_ch_to_cfg[chan]][1];
p250_mdb = ((uint16_t (*)[4])dwt_txpwr_mdb)[dwt_ch_to_cfg[chan]][2];
p125_mdb = ((uint16_t (*)[4])dwt_txpwr_mdb)[dwt_ch_to_cfg[chan]][3];

norm = dwt_encode_power_tx(norm_mdb + mdbm);
p500 = dwt_encode_power_tx(p500_mdb + mdbm);
p250 = dwt_encode_power_tx(p250_mdb + mdbm);
p125 = dwt_encode_power_tx(p125_mdb + mdbm);

tx_power = norm;
tx_power |= ((uint32_t)p500 << DWT_TX_POWER_BOOSTP500_SHIFT);
tx_power |= ((uint32_t)p250 << DWT_TX_POWER_BOOSTP250_SHIFT);
tx_power |= ((uint32_t)p125 << DWT_TX_POWER_BOOSTP125_SHIFT);
#endif

LOG_INF("set_txpower not supported %p", ctx);
dwt_reg_write_u32(dev, DWT_TX_POWER_ID, 0, tx_power);
LOG_INF("Relative transmit power changed to %d dB", dbm);

return 0;
}
Expand Down Expand Up @@ -1669,7 +1753,7 @@ static struct ieee802154_radio_api dwt_radio_api = {
.cca = dwt_cca,
.set_channel = dwt_set_channel,
.filter = dwt_filter,
.set_txpower = dwt_set_power,
.set_txpower = dwt_set_txpower,
.start = dwt_start,
.stop = dwt_stop,
.configure = dwt_configure,
Expand Down
68 changes: 65 additions & 3 deletions drivers/ieee802154/ieee802154_dw1000_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,16 @@
/* TX Power Control */
#define DWT_TX_POWER_ID 0x1E
#define DWT_TX_POWER_LEN 4

/* Units of TX Power Control. From User Manual 7.2.31.1 */
#define DWT_TX_POWER_CTRL_COARSE_MASK 6
#define DWT_TX_POWER_CTRL_COARSE_STEPS_MDB_X2 50
#define DWT_TX_POWER_CTRL_FINE_MASK 0x1F
#define DWT_TX_POWER_CTRL_FINE_STEPS_MDB_X2 10
#define DWT_TX_POWER_CTRL_MAX_MDB 305
#define DWT_TX_POWER_CTRL_MAX 0x1F
#define DWT_TX_POWER_CTRL_MIN 0xC0

/*
* Mask and shift definition for Smart Transmit Power Control:
*
Expand Down Expand Up @@ -726,11 +736,13 @@
* of the PHY header (PHR) portion of the frame.
*/
#define DWT_TX_POWER_TXPOWPHR_MASK 0x0000FF00UL
#define DWT_TX_POWER_TXPOWPHR_SHIFT 8
/*
* This power setting is applied during the transmission
* of the synchronisation header (SHR) and data portions of the frame.
*/
#define DWT_TX_POWER_TXPOWSD_MASK 0x00FF0000UL
#define DWT_TX_POWER_TXPOWSD_SHIFT 16

/* Channel Control */
#define DWT_CHAN_CTRL_ID 0x1F
Expand Down Expand Up @@ -1925,8 +1937,7 @@ const uint8_t dwt_pgdelay_defs[] = {
DWT_TC_PGDELAY_CH7
};

#ifdef CONFIG_ENABLE_MANUAL_TX_POWER_CONTROL

#ifdef CONFIG_IEEE802154_DW1000_ENABLE_MANUAL_TX_POWER_CONTROL

/*
* Default from Table 20: Reference values Register file:
Expand All @@ -1942,6 +1953,19 @@ const uint32_t dwt_txpwr_64[] = {
0xD1D1D1D1
};

/*
* Defaults decoded from Table 20 at 64 MHz to mdB
* For each channel: TXPOWPHR=TXPOWSD
*/
const uint16_t dwt_txpwr_64_mdb[] = {
135,
135,
105,
180,
75,
85,
};

/*
* Default from Table 20: Reference values Register file:
* 0x1E – Transmit Power Control for Manual Transmit Power Control
Expand All @@ -1956,8 +1980,20 @@ const uint32_t dwt_txpwr_16[] = {
0x92929292
};

#else
/*
* Defaults decoded from Table 20 at 16 MHz to mdB
* For each channel: TXPOWPHR=TXPOWSD
*/
const uint16_t dwt_txpwr_16_mdb[] = {
180,
180,
150,
255,
140,
140,
};

#else

/*
* Defaults from Table 19: Reference values for Register file:
Expand All @@ -1973,6 +2009,19 @@ const uint32_t dwt_txpwr_64[] = {
0x5171B1D1
};

/*
* Defaults decoded from Table 19 to mdB
* For each channel: BOOSTNORM, BOOSTP500, BOOST250, BOOST125
*/
const uint16_t dwt_txpwr_64_mdb[][4] = {
{110, 135, 160, 185},
{110, 135, 160, 185},
{105, 130, 155, 180},
{180, 205, 230, 255},
{90, 110, 130, 150},
{85, 110, 160, 185}
};

/*
* Defaults from Table 19: Reference values for Register file:
* 0x1E – Transmit Power Control for Smart Transmit Power Control
Expand All @@ -1987,6 +2036,19 @@ const uint32_t dwt_txpwr_16[] = {
0x32527292
};

/*
* Defaults decoded from Table 19 at 16 MHz to mdB
* For each channel: BOOSTNORM, BOOSTP500, BOOST250, BOOST125
*/
const uint16_t dwt_txpwr_16_mdb[][4] = {
{180, 205, 230, 255},
{180, 205, 230, 255},
{150, 175, 200, 225},
{255, 280, 305, 305},
{140, 165, 190, 220},
{140, 165, 190, 215}
};

#endif

enum dwt_pulse_repetition_frequency {
Expand Down

0 comments on commit 28b4965

Please sign in to comment.