From 8305c88813a7d1e91e0dc56254d6eb0b1c75370c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grochala?= Date: Fri, 10 Jan 2025 13:22:03 +0000 Subject: [PATCH] samples: Add radio trims and PAN for nRF54H20 in DTM, RT and ESB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../releases/release-notes-changelog.rst | 9 ++- samples/bluetooth/direct_test_mode/src/dtm.c | 57 +++++++++++++++- samples/peripheral/radio_test/src/main.c | 68 ++++++++++++++++++- subsys/esb/esb.c | 57 +++++++++++++++- 4 files changed, 183 insertions(+), 8 deletions(-) diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index 3f89f4940827..874f7d54850d 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -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 ------ @@ -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 --------------------------- @@ -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 ------------ diff --git a/samples/bluetooth/direct_test_mode/src/dtm.c b/samples/bluetooth/direct_test_mode/src/dtm.c index b186474dedff..79b00b6f0514 100644 --- a/samples/bluetooth/direct_test_mode/src/dtm.c +++ b/samples/bluetooth/direct_test_mode/src/dtm.c @@ -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 */ @@ -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) { diff --git a/samples/peripheral/radio_test/src/main.c b/samples/peripheral/radio_test/src/main.c index c5a498383692..ccd3413763f1 100644 --- a/samples/peripheral/radio_test/src/main.c +++ b/samples/peripheral/radio_test/src/main.c @@ -14,6 +14,9 @@ #include #endif +/* Empty trim value */ +#define TRIM_VALUE_EMPTY 0xFFFFFFFF + #if defined(CONFIG_CLOCK_CONTROL_NRF) static void clock_init(void) { @@ -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) */ @@ -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; diff --git a/subsys/esb/esb.c b/subsys/esb/esb.c index eb39700e109a..e391491234f4 100644 --- a/subsys/esb/esb.c +++ b/subsys/esb/esb.c @@ -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. */ @@ -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; }