diff --git a/subsys/mpsl/pin_debug/CMakeLists.txt b/subsys/mpsl/pin_debug/CMakeLists.txt index df8231088c37..8bbf9dbdb568 100644 --- a/subsys/mpsl/pin_debug/CMakeLists.txt +++ b/subsys/mpsl/pin_debug/CMakeLists.txt @@ -7,3 +7,4 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_MPSL_PIN_DEBUG_APP_CORE mpsl_pin_debug_app_core.c) zephyr_library_sources_ifdef(CONFIG_MPSL_PIN_DEBUG_RADIO_CORE mpsl_pin_debug_radio_core.c) +zephyr_library_sources_ifdef(CONFIG_SOC_COMPATIBLE_NRF54LX mpsl_pin_debug_nrf54.c) diff --git a/subsys/mpsl/pin_debug/Kconfig b/subsys/mpsl/pin_debug/Kconfig index 2f8e0fa07d66..c363b92f6758 100644 --- a/subsys/mpsl/pin_debug/Kconfig +++ b/subsys/mpsl/pin_debug/Kconfig @@ -11,7 +11,8 @@ config MPSL_PIN_DEBUG BOARD_NRF52833DK_NRF52833 || \ BOARD_NRF52840DK_NRF52840 || \ BOARD_NRF5340DK_NRF5340_CPUNET || \ - BOARD_NRF5340DK_NRF5340_CPUAPP) + BOARD_NRF5340DK_NRF5340_CPUAPP || \ + BOARD_NRF54L15DK) help Set this option to enable toggling of GPIO pins upon radio events. This can be useful for debugging purposes to figure @@ -27,6 +28,7 @@ config MPSL_PIN_DEBUG_RADIO_CORE bool depends on MPSL_PIN_DEBUG select NRFX_GPIOTE + select NRFX_GPPI select NRFX_PPI if HAS_HW_NRF_PPI select NRFX_DPPI if HAS_HW_NRF_DPPIC default y if (SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF5340_CPUNET) @@ -36,13 +38,19 @@ config MPSL_PIN_DEBUG_RADIO_READY_AND_DISABLED_PIN depends on MPSL_PIN_DEBUG default 3 if SOC_COMPATIBLE_NRF52X default 4 if SOC_COMPATIBLE_NRF53X + default 43 if SOC_COMPATIBLE_NRF54LX help - Only PORT0 can be used. + For nRF52 and nRF53 only PORT0 can be used. + For nRF54L only PORT1 can be used. Here the pin number + is 43 - 32 = 11. config MPSL_PIN_DEBUG_RADIO_ADDRESS_AND_END_PIN int "Pin toggled upon the events RADIO->EVENTS_ADDRESS and RADIO->EVENTS_END" depends on MPSL_PIN_DEBUG default 4 if SOC_COMPATIBLE_NRF52X default 5 if SOC_COMPATIBLE_NRF53X + default 44 if SOC_COMPATIBLE_NRF54LX help - Only PORT0 can be used. + For nRF52 and nRF53 only PORT0 can be used. + For nRF54L only PORT1 can be used. Here the pin number + is 44 - 32 = 12. diff --git a/subsys/mpsl/pin_debug/mpsl_pin_debug_nrf54.c b/subsys/mpsl/pin_debug/mpsl_pin_debug_nrf54.c new file mode 100644 index 000000000000..ae9e0bc51ada --- /dev/null +++ b/subsys/mpsl/pin_debug/mpsl_pin_debug_nrf54.c @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const nrfx_gpiote_t gpiote = NRFX_GPIOTE_INSTANCE(20); +const nrfx_dppi_t dppi_radio_domain = NRFX_DPPI_INSTANCE(10); +const nrfx_dppi_t dppi_gpio_domain = NRFX_DPPI_INSTANCE(20); +LOG_MODULE_REGISTER(mpsl_radio_pin_debug, CONFIG_MPSL_LOG_LEVEL); + +static int m_ppi_config(void) +{ + uint8_t gppi_chan_radio_ready; + uint8_t gppi_chan_radio_disabled; + uint8_t gppi_chan_radio_address; + uint8_t gppi_chan_radio_end; + + uint8_t dppi_chan_gpio_ready; + uint8_t dppi_chan_gpio_disabled; + uint8_t dppi_chan_gpio_address; + uint8_t dppi_chan_gpio_end; + + if (nrfx_gppi_channel_alloc(&gppi_chan_radio_ready) != + NRFX_SUCCESS) { + LOG_ERR("Failed allocating gppi_chan_radio_ready"); + return -ENOMEM; + } + + if (nrfx_gppi_channel_alloc(&gppi_chan_radio_disabled) != + NRFX_SUCCESS) { + LOG_ERR("Failed allocating gppi_chan_radio_disabled"); + return -ENOMEM; + } + + if (nrfx_gppi_channel_alloc(&gppi_chan_radio_address) != + NRFX_SUCCESS) { + LOG_ERR("Failed allocating gppi_chan_radio_address"); + return -ENOMEM; + } + + if (nrfx_gppi_channel_alloc(&gppi_chan_radio_end) != + NRFX_SUCCESS) { + LOG_ERR("Failed allocating gppi_chan_radio_end"); + return -ENOMEM; + } + + if (nrfx_dppi_channel_alloc(&dppi_gpio_domain, &dppi_chan_gpio_ready) != + NRFX_SUCCESS) { + LOG_ERR("Failed allocating dppi_chan_gpio_ready"); + return -ENOMEM; + } + + if (nrfx_dppi_channel_alloc(&dppi_gpio_domain, &dppi_chan_gpio_disabled) != + NRFX_SUCCESS) { + LOG_ERR("Failed allocating dppi_chan_gpio_disabled"); + return -ENOMEM; + } + + if (nrfx_dppi_channel_alloc(&dppi_gpio_domain, &dppi_chan_gpio_address) != + NRFX_SUCCESS) { + LOG_ERR("Failed allocating dppi_chan_gpio_address"); + return -ENOMEM; + } + + if (nrfx_dppi_channel_alloc(&dppi_gpio_domain, &dppi_chan_gpio_end) != + NRFX_SUCCESS) { + LOG_ERR("Failed allocating dppi_chan_gpio_end"); + return -ENOMEM; + } + + if (nrfx_gppi_edge_connection_setup(gppi_chan_radio_ready, + &dppi_radio_domain, + MPSL_DPPI_RADIO_PUBLISH_READY_CHANNEL_IDX, + &dppi_gpio_domain, + dppi_chan_gpio_ready) != NRFX_SUCCESS) { + LOG_ERR("Failed edge setup chan ready"); + return -ENOMEM; + } + + if (nrfx_gppi_edge_connection_setup(gppi_chan_radio_disabled, + &dppi_radio_domain, + MPSL_DPPI_RADIO_PUBLISH_DISABLED_CH_IDX, + &dppi_gpio_domain, + dppi_chan_gpio_disabled) != NRFX_SUCCESS) { + LOG_ERR("Failed edge setup chan disabled"); + return -ENOMEM; + } + + if (nrfx_gppi_edge_connection_setup(gppi_chan_radio_address, + &dppi_radio_domain, + MPSL_DPPI_RADIO_PUBLISH_ADDRESS_CHANNEL_IDX, + &dppi_gpio_domain, + dppi_chan_gpio_address) != NRFX_SUCCESS) { + LOG_ERR("Failed edge setup chan address"); + return -ENOMEM; + } + + /* Setup a PPI bridge between the radio domain and the domain of the GPIO pin. */ + if (nrfx_gppi_edge_connection_setup(gppi_chan_radio_address, + &dppi_radio_domain, + MPSL_DPPI_RADIO_PUBLISH_END_CHANNEL_IDX, + &dppi_gpio_domain, + dppi_chan_gpio_end) != NRFX_SUCCESS) { + LOG_ERR("Failed edge setup chan end"); + return -ENOMEM; + } + + nrf_gpiote_subscribe_set( + gpiote.p_reg, + nrfx_gpiote_set_task_address_get( + &gpiote, CONFIG_MPSL_PIN_DEBUG_RADIO_READY_AND_DISABLED_PIN), + dppi_chan_gpio_ready); + + nrf_gpiote_subscribe_set( + gpiote.p_reg, + nrfx_gpiote_clr_task_address_get( + &gpiote, CONFIG_MPSL_PIN_DEBUG_RADIO_READY_AND_DISABLED_PIN), + dppi_chan_gpio_disabled); + + nrf_gpiote_subscribe_set( + gpiote.p_reg, + nrfx_gpiote_set_task_address_get(&gpiote, + CONFIG_MPSL_PIN_DEBUG_RADIO_ADDRESS_AND_END_PIN), + dppi_chan_gpio_address); + + nrf_gpiote_subscribe_set( + gpiote.p_reg, + nrfx_gpiote_clr_task_address_get(&gpiote, + CONFIG_MPSL_PIN_DEBUG_RADIO_ADDRESS_AND_END_PIN), + dppi_chan_gpio_end); + + nrfx_gppi_channels_enable(NRFX_BIT(gppi_chan_radio_ready) | + NRFX_BIT(gppi_chan_radio_disabled) | + NRFX_BIT(gppi_chan_radio_address) | + NRFX_BIT(gppi_chan_radio_end)); + + if (nrfx_dppi_channel_enable(&dppi_gpio_domain, dppi_chan_gpio_ready) != NRFX_SUCCESS) { + LOG_ERR("Failed chan enable gpio_ready"); + return -ENOMEM; + } + + if (nrfx_dppi_channel_enable(&dppi_gpio_domain, dppi_chan_gpio_disabled) != NRFX_SUCCESS) { + LOG_ERR("Failed chan enable gpio_disabled"); + return -ENOMEM; + } + + if (nrfx_dppi_channel_enable(&dppi_gpio_domain, dppi_chan_gpio_address) != NRFX_SUCCESS) { + LOG_ERR("Failed chan enable gpio_address"); + return -ENOMEM; + } + + if (nrfx_dppi_channel_enable(&dppi_gpio_domain, dppi_chan_gpio_end) != NRFX_SUCCESS) { + LOG_ERR("Failed chan enable gpio_end"); + return -ENOMEM; + } + + return 0; +} + +static int mpsl_radio_pin_debug_init(void) +{ + uint8_t radio_ready_radio_disabled_gpiote_channel; + uint8_t radio_address_radio_end_gpiote_channel; + + const nrfx_gpiote_output_config_t gpiote_output_cfg = NRFX_GPIOTE_DEFAULT_OUTPUT_CONFIG; + + if (nrfx_gpiote_channel_alloc(&gpiote, &radio_ready_radio_disabled_gpiote_channel) != + NRFX_SUCCESS) { + LOG_ERR("Failed allocating GPIOTE chan"); + return -ENOMEM; + } + + if (nrfx_gpiote_channel_alloc(&gpiote, &radio_address_radio_end_gpiote_channel) != + NRFX_SUCCESS) { + LOG_ERR("Failed allocating GPIOTE chan"); + return -ENOMEM; + } + + const nrfx_gpiote_task_config_t task_cfg_ready_disabled = { + .task_ch = radio_ready_radio_disabled_gpiote_channel, + .polarity = NRF_GPIOTE_POLARITY_TOGGLE, + .init_val = NRF_GPIOTE_INITIAL_VALUE_LOW, + }; + + if (nrfx_gpiote_output_configure(&gpiote, + CONFIG_MPSL_PIN_DEBUG_RADIO_READY_AND_DISABLED_PIN, + &gpiote_output_cfg, + &task_cfg_ready_disabled) + != NRFX_SUCCESS) { + LOG_ERR("Failed configuring GPIOTE chan"); + return -ENOMEM; + } + + const nrfx_gpiote_task_config_t task_cfg_address_end = { + .task_ch = radio_address_radio_end_gpiote_channel, + .polarity = NRF_GPIOTE_POLARITY_TOGGLE, + .init_val = NRF_GPIOTE_INITIAL_VALUE_LOW, + }; + + if (nrfx_gpiote_output_configure(&gpiote, CONFIG_MPSL_PIN_DEBUG_RADIO_ADDRESS_AND_END_PIN, + &gpiote_output_cfg, + &task_cfg_address_end) != NRFX_SUCCESS) { + LOG_ERR("Failed configuring GPIOTE chan"); + return -ENOMEM; + } + + if (m_ppi_config() != 0) { + return -ENOMEM; + } + + nrfx_gpiote_out_task_enable(&gpiote, CONFIG_MPSL_PIN_DEBUG_RADIO_READY_AND_DISABLED_PIN); + nrfx_gpiote_out_task_enable(&gpiote, CONFIG_MPSL_PIN_DEBUG_RADIO_ADDRESS_AND_END_PIN); + + return 0; +} + +SYS_INIT(mpsl_radio_pin_debug_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);