Skip to content

Commit

Permalink
samples: Add radio trims and PAN for nRF54H20 in DTM, RT and ESB
Browse files Browse the repository at this point in the history
Loading trim values and adding PAN workarounds in the Radio registers
will improve RF performance. PANs implemented: HMPAN-18, HMPAN-103.

Ref. NCSDK-31274

Signed-off-by: Michał Grochala <[email protected]>
  • Loading branch information
grochu committed Jan 14, 2025
1 parent 919489e commit 8305c88
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ DECT NR+
Enhanced ShockBurst (ESB)
-------------------------

|no_changes_yet_note|
* Added loading of radio trims and a fix of a hardware errata for the nRF54H20 SoC to improve the RF performance.

Gazell
------
Expand Down Expand Up @@ -233,8 +233,9 @@ Amazon Sidewalk samples
Bluetooth samples
-----------------

* :ref:`direct_test_mode` sample:

|no_changes_yet_note|
* Added loading of radio trims and a fix of a hardware errata for the nRF54H20 SoC to improve the RF performance.

Bluetooth Fast Pair samples
---------------------------
Expand Down Expand Up @@ -365,7 +366,9 @@ nRF5340 samples
Peripheral samples
------------------

|no_changes_yet_note|
* :ref:`radio_test` sample:

* Added loading of radio trims and a fix of a hardware errata for the nRF54H20 SoC to improve the RF performance.

PMIC samples
------------
Expand Down
57 changes: 56 additions & 1 deletion samples/bluetooth/direct_test_mode/src/dtm.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ BUILD_ASSERT(NRFX_TIMER_CONFIG_LABEL(ANOMALY_172_TIMER_INSTANCE) == 1,
/* Maximimum channel number */
#define DTM_MAX_CHAN_NR 0x27

/* Empty trim value */
#define TRIM_VALUE_EMPTY 0xFFFFFFFF

/* States used for the DTM test implementation */
enum dtm_state {
/* DTM is uninitialized */
Expand Down Expand Up @@ -1149,7 +1152,59 @@ int dtm_init(dtm_iq_report_callback_t callback)
/* Apply HMPAN-102 workaround for nRF54H series */
*(volatile uint32_t *)0x5302C7E4 =
(((*((volatile uint32_t *)0x5302C7E4)) & 0xFF000FFF) | 0x0012C000);
#endif

/* Apply HMPAN-18 workaround for nRF54H series - load trim values*/
if (*(volatile uint32_t *) 0x0FFFE458 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C734 = *(volatile uint32_t *) 0x0FFFE458;
}

if (*(volatile uint32_t *) 0x0FFFE45C != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C738 = *(volatile uint32_t *) 0x0FFFE45C;
}

if (*(volatile uint32_t *) 0x0FFFE460 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C73C = *(volatile uint32_t *) 0x0FFFE460;
}

if (*(volatile uint32_t *) 0x0FFFE464 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C740 = *(volatile uint32_t *) 0x0FFFE464;
}

if (*(volatile uint32_t *) 0x0FFFE468 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C74C = *(volatile uint32_t *) 0x0FFFE468;
}

if (*(volatile uint32_t *) 0x0FFFE46C != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C7D8 = *(volatile uint32_t *) 0x0FFFE46C;
}

if (*(volatile uint32_t *) 0x0FFFE470 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C840 = *(volatile uint32_t *) 0x0FFFE470;
}

if (*(volatile uint32_t *) 0x0FFFE474 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C844 = *(volatile uint32_t *) 0x0FFFE474;
}

if (*(volatile uint32_t *) 0x0FFFE478 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C848 = *(volatile uint32_t *) 0x0FFFE478;
}

if (*(volatile uint32_t *) 0x0FFFE47C != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C84C = *(volatile uint32_t *) 0x0FFFE47C;
}

/* Apply HMPAN-103 workaround for nRF54H series*/
if ((*(volatile uint32_t *) 0x5302C8A0 == 0x80000000) ||
(*(volatile uint32_t *) 0x5302C8A0 == 0x0058120E)) {
*(volatile uint32_t *) 0x5302C8A0 = 0x0058090E;
}

*(volatile uint32_t *) 0x5302C8A4 = 0x00F8AA5F;
*(volatile uint32_t *) 0x5302C7AC = 0x8672827A;
*(volatile uint32_t *) 0x5302C7B0 = 0x7E768672;
*(volatile uint32_t *) 0x5302C7B4 = 0x0406007E;
#endif /* defined(CONFIG_SOC_SERIES_NRF54HX) */

err = timer_init();
if (err) {
Expand Down
68 changes: 65 additions & 3 deletions samples/peripheral/radio_test/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
#include <hal/nrf_lrcconf.h>
#endif

/* Empty trim value */
#define TRIM_VALUE_EMPTY 0xFFFFFFFF

#if defined(CONFIG_CLOCK_CONTROL_NRF)
static void clock_init(void)
{
Expand Down Expand Up @@ -85,6 +88,67 @@ static void clock_init(void)
printk("Clock has started\n");
}

#if defined(CONFIG_SOC_SERIES_NRF54HX)
static void nrf54hx_radio_trim(void)
{
/* Apply HMPAN-102 workaround for nRF54H series */
*(volatile uint32_t *)0x5302C7E4 =
(((*((volatile uint32_t *)0x5302C7E4)) & 0xFF000FFF) | 0x0012C000);

/* Apply HMPAN-18 workaround for nRF54H series - load trim values*/
if (*(volatile uint32_t *) 0x0FFFE458 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C734 = *(volatile uint32_t *) 0x0FFFE458;
}

if (*(volatile uint32_t *) 0x0FFFE45C != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C738 = *(volatile uint32_t *) 0x0FFFE45C;
}

if (*(volatile uint32_t *) 0x0FFFE460 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C73C = *(volatile uint32_t *) 0x0FFFE460;
}

if (*(volatile uint32_t *) 0x0FFFE464 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C740 = *(volatile uint32_t *) 0x0FFFE464;
}

if (*(volatile uint32_t *) 0x0FFFE468 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C74C = *(volatile uint32_t *) 0x0FFFE468;
}

if (*(volatile uint32_t *) 0x0FFFE46C != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C7D8 = *(volatile uint32_t *) 0x0FFFE46C;
}

if (*(volatile uint32_t *) 0x0FFFE470 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C840 = *(volatile uint32_t *) 0x0FFFE470;
}

if (*(volatile uint32_t *) 0x0FFFE474 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C844 = *(volatile uint32_t *) 0x0FFFE474;
}

if (*(volatile uint32_t *) 0x0FFFE478 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C848 = *(volatile uint32_t *) 0x0FFFE478;
}

if (*(volatile uint32_t *) 0x0FFFE47C != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C84C = *(volatile uint32_t *) 0x0FFFE47C;
}

/* Apply HMPAN-103 workaround for nRF54H series*/
if ((*(volatile uint32_t *) 0x5302C8A0 == 0x80000000) ||
(*(volatile uint32_t *) 0x5302C8A0 == 0x0058120E)) {
*(volatile uint32_t *) 0x5302C8A0 = 0x0058090E;
}

*(volatile uint32_t *) 0x5302C8A4 = 0x00F8AA5F;
*(volatile uint32_t *) 0x5302C7AC = 0x8672827A;
*(volatile uint32_t *) 0x5302C7B0 = 0x7E768672;
*(volatile uint32_t *) 0x5302C7B4 = 0x0406007E;
}
#endif /* defined(CONFIG_SOC_SERIES_NRF54HX) */

#else
BUILD_ASSERT(false, "No Clock Control driver");
#endif /* defined(CONFIG_CLOCK_CONTROL_NRF) */
Expand All @@ -96,9 +160,7 @@ int main(void)
clock_init();

#if defined(CONFIG_SOC_SERIES_NRF54HX)
/* Apply HMPAN-102 workaround for nRF54H series */
*(volatile uint32_t *)0x5302C7E4 =
(((*((volatile uint32_t *)0x5302C7E4)) & 0xFF000FFF) | 0x0012C000);
nrf54hx_radio_trim();
#endif

return 0;
Expand Down
57 changes: 56 additions & 1 deletion subsys/esb/esb.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ LOG_MODULE_REGISTER(esb, CONFIG_ESB_LOG_LEVEL);
/* Flag for changing radio channel. */
#define RF_CHANNEL_UPDATE_FLAG 0

/* Empty trim value */
#define TRIM_VALUE_EMPTY 0xFFFFFFFF

/* Internal Enhanced ShockBurst module state. */
enum esb_state {
ESB_STATE_IDLE, /* Idle. */
Expand Down Expand Up @@ -1791,7 +1794,59 @@ int esb_init(const struct esb_config *config)
/* Apply HMPAN-102 workaround for nRF54H series */
*(volatile uint32_t *)0x5302C7E4 =
(((*((volatile uint32_t *)0x5302C7E4)) & 0xFF000FFF) | 0x0012C000);
#endif

/* Apply HMPAN-18 workaround for nRF54H series - load trim values*/
if (*(volatile uint32_t *) 0x0FFFE458 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C734 = *(volatile uint32_t *) 0x0FFFE458;
}

if (*(volatile uint32_t *) 0x0FFFE45C != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C738 = *(volatile uint32_t *) 0x0FFFE45C;
}

if (*(volatile uint32_t *) 0x0FFFE460 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C73C = *(volatile uint32_t *) 0x0FFFE460;
}

if (*(volatile uint32_t *) 0x0FFFE464 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C740 = *(volatile uint32_t *) 0x0FFFE464;
}

if (*(volatile uint32_t *) 0x0FFFE468 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C74C = *(volatile uint32_t *) 0x0FFFE468;
}

if (*(volatile uint32_t *) 0x0FFFE46C != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C7D8 = *(volatile uint32_t *) 0x0FFFE46C;
}

if (*(volatile uint32_t *) 0x0FFFE470 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C840 = *(volatile uint32_t *) 0x0FFFE470;
}

if (*(volatile uint32_t *) 0x0FFFE474 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C844 = *(volatile uint32_t *) 0x0FFFE474;
}

if (*(volatile uint32_t *) 0x0FFFE478 != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C848 = *(volatile uint32_t *) 0x0FFFE478;
}

if (*(volatile uint32_t *) 0x0FFFE47C != TRIM_VALUE_EMPTY) {
*(volatile uint32_t *) 0x5302C84C = *(volatile uint32_t *) 0x0FFFE47C;
}

/* Apply HMPAN-103 workaround for nRF54H series*/
if ((*(volatile uint32_t *) 0x5302C8A0 == 0x80000000) ||
(*(volatile uint32_t *) 0x5302C8A0 == 0x0058120E)) {
*(volatile uint32_t *) 0x5302C8A0 = 0x0058090E;
}

*(volatile uint32_t *) 0x5302C8A4 = 0x00F8AA5F;
*(volatile uint32_t *) 0x5302C7AC = 0x8672827A;
*(volatile uint32_t *) 0x5302C7B0 = 0x7E768672;
*(volatile uint32_t *) 0x5302C7B4 = 0x0406007E;
#endif /* (CONFIG_SOC_SERIES_NRF54HX) */

return 0;
}
Expand Down

0 comments on commit 8305c88

Please sign in to comment.