nrf_dppi_hack: Add extra nrf like APIs meant for simulation

To be able to do some extra things users want,
but the nrf HAL does not provide an API for.

Note: These extra APIs are experimental and may change at
any point

Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
This commit is contained in:
Alberto Escolar Piedras 2023-10-04 13:52:20 +02:00
parent 99ae7916fb
commit c77ba72e51
5 changed files with 148 additions and 8 deletions

View File

@ -23,6 +23,7 @@ if(CONFIG_SOC_SERIES_BSIM_NRFXX)
# of those from the original nrfx.
target_include_directories(zephyr_interface BEFORE INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/src/nrfx/mdk_replacements
${CMAKE_CURRENT_SOURCE_DIR}/src/nrfx/hal_replacements
)
zephyr_include_directories(

View File

@ -5,6 +5,7 @@ src/nrfx/hal/nrf_clock.c
src/nrfx/hal/nrf_dppi.c
src/nrfx/hal/nrf_ecb.c
src/nrfx/hal/nrf_egu.c
src/nrfx/hal/nrf_hack.c
src/nrfx/hal/nrf_nvmc.c
src/nrfx/hal/nrf_radio.c
src/nrfx/hal/nrf_rng.c

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2019 Oticon A/S
* Copyright (c) 2020 Nordic Semiconductor ASA
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*
@ -9,11 +9,14 @@
#include "nrfx.h"
#include "bs_tracing.h"
IRQn_Type nrfx_get_irq_number(void const * p_reg){
#define PERIPHERAL_REG_BASE(per, nbr, post) \
(void*)NRF_##per##nbr##post##_BASE
#define IS_PERIPHERAL_REG(p, per, nbr, post) \
(p >= (void*)NRF_##per##nbr##post##_BASE) && \
((intptr_t)p < (intptr_t)NRF_##per##nbr##post##_BASE + sizeof(NRF_##per##_Type))
(p >= PERIPHERAL_REG_BASE(per, nbr, post)) && \
((intptr_t)p < (intptr_t)PERIPHERAL_REG_BASE(per, nbr, post) + sizeof(NRF_##per##_Type))
IRQn_Type nrfx_get_irq_number(void const * p_reg){
#if defined(NRF52833_XXAA)
/*
@ -76,7 +79,7 @@ IRQn_Type nrfx_get_irq_number(void const * p_reg){
return 0x1F;
/*32-..*/
} else {
bs_trace_error_time_line("Tried to get the peripheral number of an address unknown to this HW models\n");
bs_trace_error_time_line("Tried to get the peripheral number of an address unknown to these HW models\n");
return 0; /* unreachable */
}
@ -125,7 +128,7 @@ IRQn_Type nrfx_get_irq_number(void const * p_reg){
} else if (IS_PERIPHERAL_REG(p_reg, SWI, 3, _NS)) {
return SWI3_IRQn;
} else {
bs_trace_error_time_line("Tried to get the peripheral number of an address unknown to this HW models\n");
bs_trace_error_time_line("Tried to get the peripheral number of an address unknown to these HW models\n");
return 0; /* unreachable */
}
#elif defined(NRF5340_XXAA_APPLICATION)
@ -181,7 +184,7 @@ IRQn_Type nrfx_get_irq_number(void const * p_reg){
/* 57 KMU */
/* 68 CRYPTOCELL */
} else {
bs_trace_error_time_line("Tried to get the peripheral number of an address unknown to this HW models\n");
bs_trace_error_time_line("Tried to get the peripheral number of an address unknown to these HW models\n");
return 0; /* unreachable */
}
@ -189,5 +192,4 @@ IRQn_Type nrfx_get_irq_number(void const * p_reg){
#error "Unsuported SOC"
#endif
#undef IS_PERIPHERAL_REG
}

100
src/nrfx/hal/nrf_hack.c Normal file
View File

@ -0,0 +1,100 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#include "nrfx.h"
#include "hal/nrf_aar.h"
#include "hal/nrf_clock.h"
#include "hal/nrf_ccm.h"
#include "hal/nrf_ecb.h"
#include "hal/nrf_egu.h"
#include "hal/nrf_gpiote.h"
#include "hal/nrf_radio.h"
#include "hal/nrf_rng.h"
#include "hal/nrf_rtc.h"
#include "hal/nrf_temp.h"
#include "hal/nrf_timer.h"
#include "bs_tracing.h"
#define PERIPHERAL_REG_BASE(per, nbr, post) \
(void*)NRF_##per##nbr##post##_BASE
#define IS_PERIPHERAL_REG(p, per, nbr, post) \
(p >= PERIPHERAL_REG_BASE(per, nbr, post)) && \
((intptr_t)p < (intptr_t)PERIPHERAL_REG_BASE(per, nbr, post) + sizeof(NRF_##per##_Type))
typedef void (*subscribe_set_f)(void *, int , uint8_t);
typedef void (*subscribe_clear_f)(void *, int);
/*
* Given a pointer to a subscribe register in an unknown peripheral
* get
* A pointer to the HAL subscribe set and clear functions that correspond to it
* The task offset corresponding to that subscribe register
*/
static void nrf_dppi_hack_get_subscribe_from_ptr(void *sub_reg, void **p_reg,
subscribe_set_f *set_f, subscribe_clear_f *clear_f,
int *task) {
#define IF_PER(per, nbr, post, lname) \
if (IS_PERIPHERAL_REG(sub_reg, per, nbr, post)) { \
*p_reg = PERIPHERAL_REG_BASE(per, nbr, post); \
*task = (intptr_t)sub_reg - (intptr_t)*p_reg - 0x80/*Offset between tasks and subscribe registers*/; \
*set_f = (subscribe_set_f)nrf_##lname##_subscribe_set; \
*clear_f = (subscribe_clear_f)nrf_##lname##_subscribe_clear; \
return;
#if defined(NRF5340_XXAA_NETWORK)
/*IF_PER(POWER, , _NS, power)
} else*/ IF_PER(CLOCK, , _NS, clock)
} else IF_PER(RADIO, , _NS, radio)
} else IF_PER(RNG, , _NS, rng)
} else IF_PER(GPIOTE, , _NS, gpiote)
/* 11 WDT */
} else IF_PER(TIMER, 0, _NS, timer)
} else IF_PER(ECB, , _NS, ecb)
} else IF_PER(AAR, , _NS, aar)
} else IF_PER(CCM, , _NS, ccm)
/*} else IF_PER(TEMP, , _NS, temp)*/ //Lacking definition in official nrf HAL
} else IF_PER(RTC, 0, _NS, rtc)
/* 18 IPC */
/* 19 SERIAL0 */
} else IF_PER(EGU, 0, _NS, egu)
} else IF_PER(RTC, 1, _NS, rtc)
} else IF_PER(TIMER, 1, _NS, timer)
} else IF_PER(TIMER, 2, _NS, timer)
} else {
bs_trace_error_time_line("Tried to look for a subscribe register not known to these HW models\n");
return; /* unreachable */
}
#elif defined(NRF5340_XXAA_APPLICATION)
bs_trace_error_time_line("%s not yet implemented for NRF5340_XXAA_APPLICATION\n", __func__);
#endif
#undef IF_PER
}
void nrf_dppi_hack_subscribe_set(void *sub_reg, unsigned int channel)
{
void *p_reg;
int task;
subscribe_set_f set_f;
subscribe_clear_f clear_f;
nrf_dppi_hack_get_subscribe_from_ptr(sub_reg, &p_reg, &set_f, &clear_f, &task);
set_f(p_reg, task, channel);
}
void nrf_dppi_hack_subscribe_clear(void *sub_reg)
{
void *p_reg;
int task;
subscribe_set_f set_f;
subscribe_clear_f clear_f;
nrf_dppi_hack_get_subscribe_from_ptr(sub_reg, &p_reg, &set_f, &clear_f, &task);
clear_f(p_reg, task);
}

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* The integrator should ensure this header is in
* the include path before the real hal/nrf_dppi.h
*/
#ifndef HAL_REPLACEMENTS_HAL_NRF_DPPI_H
#define HAL_REPLACEMENTS_HAL_NRF_DPPI_H
#include_next "hal/nrf_dppi.h"
/*
* Special API for the HW models, which allows setting or clearing
* any subscribe register based on a pointer to the register
*
* These calls are experimental and may change at any point
*/
void nrf_dppi_hack_subscribe_set(void *sub_reg, unsigned int channel);
void nrf_dppi_hack_subscribe_clear(void *sub_reg);
/*#undef NRF_DPPI_ENDPOINT_SETUP
#define NRF_DPPI_ENDPOINT_SETUP(task_or_event, dppi_chan) \
nrf_dppi_hack_subscribe_set((void *)task_or_event, dppi_chan); */
//For this to work, we would need to change the hack version so it would get a task or event instead of adding here NRF_SUBSCRIBE_PUBLISH_OFFSET
/*#undef NRF_DPPI_ENDPOINT_CLEAR
#define NRF_DPPI_ENDPOINT_CLEAR(task_or_event) \
nrf_dppi_hack_subscribe_clear((void *)task_or_event);*/
//For this to work, we would need to change the hack version so it would get a task or event instead of adding here NRF_SUBSCRIBE_PUBLISH_OFFSET
#endif /* HAL_REPLACEMENTS_HAL_NRF_DPPI_H */