fix: kw41z: Use correct mapping for dBm

The radio API expects the setting of the TX-power in dBm. The actual
TX-power is however set by a 6bit register, which mapping between
register value and power in dBm is a lookup-table in the datasheet.

This mapping for the kw41z was off, which not only lead to incorrect
output power, but also to a maximal output power of only -1.9 dBm
instead of the possible +3.5 dBm.

Signed-off-by: Tobias Aschenbrenner <tobias.aschenbrenner@blik.io>
Signed-off-by: Franco Saworski <f.saworski@posteo.de>
This commit is contained in:
Tobias Aschenbrenner 2018-12-18 14:16:00 +01:00 committed by Kumar Gala
commit c8b17ec403

View file

@ -87,8 +87,8 @@ int kw41_dbg_idx;
#define RADIO_0_IRQ_PRIO 0x0 #define RADIO_0_IRQ_PRIO 0x0
#define KW41Z_FCS_LENGTH 2 #define KW41Z_FCS_LENGTH 2
#define KW41Z_PSDU_LENGTH 125 #define KW41Z_PSDU_LENGTH 125
#define KW41Z_OUTPUT_POWER_MAX 2 #define KW41Z_OUTPUT_POWER_MAX 4
#define KW41Z_OUTPUT_POWER_MIN (-19) #define KW41Z_OUTPUT_POWER_MIN (-31)
#define IEEE802154_ACK_LENGTH 5 #define IEEE802154_ACK_LENGTH 5
@ -122,16 +122,28 @@ enum {
}; };
/* Lookup table for PA_PWR register */ /* Lookup table for PA_PWR register */
static const u8_t pa_pwr_lt[22] = { static const u8_t pa_pwr_lt[] = {
2, 2, 2, 2, 2, 2, /* -19:-14 dBm */ 1, /* -31.1 dBm: -31 */
4, 4, 4, /* -13:-11 dBm */ 2, 2, 2, 2, 2, 2, 2, /* -25.0 dBm: -30, -29, -28, -27, -26, -25 */
6, 6, 6, /* -10:-8 dBm */ 4, 4, 4, 4, 4, /* -19.0 dBm: -24, -23, -22, -21, -20, -19 */
8, 8, /* -7:-6 dBm */ 6, 6, 6, /* -15.6 dBm: -18, -17, -16 */
10, 10, /* -5:-4 dBm */ 8, 8, /* -13.1 dBm: -15, -14 */
12, /* -3 dBm */ 10, 10, /* -11.2 dBm: -13, -12 */
14, 14, /* -2:-1 dBm */ 12, 12, /* - 9.6 dBm: -11, -10 */
18, 18, /* 0:1 dBm */ 14, /* - 8.3 dBm: -9 */
24 /* 2 dBm */ 16, /* - 7.2 dBm: -8 */
18, /* - 6.2 dBm: -7 */
20, /* - 5.3 dBm: -6 */
22, /* - 4.5 dBm: -5 */
24, /* - 3.8 dBm: -4 */
28, /* - 2.5 dBm: -3 */
30, /* - 1.9 dBm: -2 */
34, /* - 1.0 dBm: -1 */
40, /* + 0.3 dBm: 0 */
44, /* + 1.1 dBm: +1 */
50, /* + 2.1 dBm: +2 */
58, /* + 3.1 dBm: +3 */
62 /* + 3.5 dBm: +4 */
}; };
struct kw41z_context { struct kw41z_context {
@ -433,13 +445,21 @@ static int kw41z_filter(struct device *dev,
static int kw41z_set_txpower(struct device *dev, s16_t dbm) static int kw41z_set_txpower(struct device *dev, s16_t dbm)
{ {
if (dbm < KW41Z_OUTPUT_POWER_MIN) { if (dbm < KW41Z_OUTPUT_POWER_MIN) {
ZLL->PA_PWR = 0; SYS_LOG_INF("TX-power %d dBm below min of %d dBm, using %d dBm",
dbm,
KW41Z_OUTPUT_POWER_MIN,
KW41Z_OUTPUT_POWER_MIN);
dbm = KW41Z_OUTPUT_POWER_MIN;
} else if (dbm > KW41Z_OUTPUT_POWER_MAX) { } else if (dbm > KW41Z_OUTPUT_POWER_MAX) {
ZLL->PA_PWR = 30; SYS_LOG_INF("TX-power %d dBm above max of %d dBm, using %d dBm",
} else { dbm,
ZLL->PA_PWR = pa_pwr_lt[dbm - KW41Z_OUTPUT_POWER_MIN]; KW41Z_OUTPUT_POWER_MAX,
KW41Z_OUTPUT_POWER_MAX);
dbm = KW41Z_OUTPUT_POWER_MAX;
} }
ZLL->PA_PWR = pa_pwr_lt[dbm - KW41Z_OUTPUT_POWER_MIN];
return 0; return 0;
} }