Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

samples: Add radio trims and PAN for nRF54H20 in DTM, RT and ESB #19878

Merged
merged 1 commit into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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