diff --git a/cpu/cortexm_common/cortexm_init.c b/cpu/cortexm_common/cortexm_init.c index 8beebaea28..ba9c21b037 100644 --- a/cpu/cortexm_common/cortexm_init.c +++ b/cpu/cortexm_common/cortexm_init.c @@ -20,32 +20,19 @@ #include "cpu.h" -/** - * @name Pattern to write into the co-processor Access Control Register to - * allow full FPU access - */ -#define FULL_FPU_ACCESS (0x00f00000) - /** * Interrupt vector base address, defined by the linker */ extern const void *_isr_vectors; -void cortexm_init(void) +#if defined(CPU_CORTEXM_INIT_SUBFUNCTIONS) +#define CORTEXM_STATIC_INLINE /*empty*/ +#else +#define CORTEXM_STATIC_INLINE static inline +#endif + +CORTEXM_STATIC_INLINE void cortexm_init_isr_priorities(void) { - /* initialize the FPU on Cortex-M4F CPUs */ -#if defined(CPU_ARCH_CORTEX_M4F) || defined(CPU_ARCH_CORTEX_M7) - /* give full access to the FPU */ - SCB->CPACR |= (uint32_t)FULL_FPU_ACCESS; -#endif - - /* configure the vector table location to internal flash */ -#if defined(CPU_ARCH_CORTEX_M3) || defined(CPU_ARCH_CORTEX_M4) || \ - defined(CPU_ARCH_CORTEX_M4F) || defined(CPU_ARCH_CORTEX_M7) || \ - (defined(CPU_ARCH_CORTEX_M0PLUS) && (__VTOR_PRESENT == 1)) - SCB->VTOR = (uint32_t)&_isr_vectors; -#endif - /* initialize the interrupt priorities */ /* set pendSV interrupt to same priority as the rest */ NVIC_SetPriority(PendSV_IRQn, CPU_DEFAULT_IRQ_PRIO); @@ -55,7 +42,10 @@ void cortexm_init(void) for (unsigned i = 0; i < CPU_IRQ_NUMOF; i++) { NVIC_SetPriority((IRQn_Type) i, CPU_DEFAULT_IRQ_PRIO); } +} +CORTEXM_STATIC_INLINE void cortexm_init_misc(void) +{ /* enable wake up on events for __WFE CPU sleep */ SCB->SCR |= SCB_SCR_SEVONPEND_Msk; @@ -67,3 +57,18 @@ void cortexm_init(void) SCB->CCR |= SCB_CCR_STKALIGN_Msk; #endif } + +void cortexm_init(void) +{ + cortexm_init_fpu(); + + /* configure the vector table location to internal flash */ +#if defined(CPU_ARCH_CORTEX_M3) || defined(CPU_ARCH_CORTEX_M4) || \ + defined(CPU_ARCH_CORTEX_M4F) || defined(CPU_ARCH_CORTEX_M7) || \ + (defined(CPU_ARCH_CORTEX_M0PLUS) && (__VTOR_PRESENT == 1)) + SCB->VTOR = (uint32_t)&_isr_vectors; +#endif + + cortexm_init_isr_priorities(); + cortexm_init_misc(); +} diff --git a/cpu/cortexm_common/include/cpu.h b/cpu/cortexm_common/include/cpu.h index 48e355ea2e..50ba3b3e12 100644 --- a/cpu/cortexm_common/include/cpu.h +++ b/cpu/cortexm_common/include/cpu.h @@ -58,6 +58,14 @@ extern "C" { */ #define PROVIDES_PM_SET_LOWEST +/** + * @brief Pattern to write into the co-processor Access Control Register to + * allow full FPU access + * + * Used in the @ref cortexm_init_fpu inline function below. + */ +#define CORTEXM_SCB_CPACR_FPU_ACCESS_FULL (0x00f00000) + /** * @brief Initialization of the CPU */ @@ -65,9 +73,64 @@ void cpu_init(void); /** * @brief Initialize Cortex-M specific core parts of the CPU + * + * @ref cortexm_init calls, in a default order, @ref cortexm_init_fpu, + * @ref cortexm_init_isr_priorities, and @ref cortexm_init_misc. Also + * performs other default initialisations, including ones which you + * may or may not want. + * + * Unless you have special requirements (like nRF52 with SD has), it + * is sufficient to call just @ref cortexm_init and the `cortexm_init_*` + * functions do not need to (and should not) be called separately. + * If you have conflicting requirements, you may want to have a look + * `cpu/nrft/cpu.c` for an example of a non-default approach. */ void cortexm_init(void); +/** + * @brief Initialize Cortex-M FPU + * + * Called from `cpu/nrf52/cpu.c`, since it cannot use the + * whole @ref cortexm_init due to conflicting requirements. + * + * Defined here as a static inline function to allow all + * callers to optimise this away if the FPU is not used. + */ +static inline void cortexm_init_fpu(void) +{ + /* initialize the FPU on Cortex-M4F CPUs */ +#if defined(CPU_ARCH_CORTEX_M4F) || defined(CPU_ARCH_CORTEX_M7) + /* give full access to the FPU */ + SCB->CPACR |= (uint32_t)CORTEXM_SCB_CPACR_FPU_ACCESS_FULL; +#endif +} + +#if defined(CPU_CORTEXM_INIT_SUBFUNCTIONS) || defined(DOXYGEN) + +/** + * @brief Initialize Cortex-M interrupt priorities + * + * Called from `cpu/nrf52/cpu.c`, since it cannot use the + * whole @ref cortexm_init due to conflicting requirements. + * + * Define `CPU_CORTEXM_INIT_SUBFUNCTIONS` to make this function + * publicly available. + */ +void cortexm_init_isr_priorities(void); + +/** + * @brief Initialize Cortex-M misc functions + * + * Called from `cpu/nrf52/cpu.c`, since it cannot use the + * whole @ref cortexm_init due to conflicting requirements. + * + * Define `CPU_CORTEXM_INIT_SUBFUNCTIONS` to make this function + * publicly available. + */ +void cortexm_init_misc(void); + +#endif /* defined(CPU_CORTEXM_INIT_SUBFUNCTIONS) || defined(DOXYGEN) */ + /** * @brief Prints the current content of the link register (lr) */