diff options
author | alexander <alexander.efremov@arm.com> | 2021-03-26 21:42:19 +0000 |
---|---|---|
committer | Kshitij Sisodia <kshitij.sisodia@arm.com> | 2021-03-29 16:29:55 +0100 |
commit | 3c79893217bc632c9b0efa815091bef3c779490c (patch) | |
tree | ad06b444557eb8124652b45621d736fa1b92f65d /source/application/hal/platforms/bare-metal/bsp/cmsis-device | |
parent | 6ad6d55715928de72979b04194da1bdf04a4c51b (diff) | |
download | ml-embedded-evaluation-kit-3c79893217bc632c9b0efa815091bef3c779490c.tar.gz |
Opensource ML embedded evaluation kit21.03
Change-Id: I12e807f19f5cacad7cef82572b6dd48252fd61fd
Diffstat (limited to 'source/application/hal/platforms/bare-metal/bsp/cmsis-device')
4 files changed, 468 insertions, 0 deletions
diff --git a/source/application/hal/platforms/bare-metal/bsp/cmsis-device/cmsis.c b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/cmsis.c new file mode 100644 index 0000000..c9cf53d --- /dev/null +++ b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/cmsis.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2021 Arm Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "cmsis.h" + +extern void *__Vectors; /* see irqs.c */ + +/*----------------------------------------------------------------------------*\ + * Define clocks (uses OSC1 ACLK) * +\*----------------------------------------------------------------------------*/ +#define __XTAL (25000000) /* Oscillator frequency */ +#define __SYSTEM_CLOCK (__XTAL) + +#define STR(x) #x +#define RESET_REG(n) __ASM volatile("MOV " STR(r##n) ", #0" : : : STR(r##n)) + +#if defined(CPU_CORTEX_M55) +#define CCR_DL (1 << 19) +#else +#error "Invalid CPU; This file only services Cortex-M55 CPUs" +#endif /* (CPU_CORTEX_M55) */ + +/*---------------------------------------------------------------------------- + System Core Clock Variable (Core Clock) + *----------------------------------------------------------------------------*/ +uint32_t SystemCoreClock = __SYSTEM_CLOCK; + + +/*---------------------------------------------------------------------------- + Clock functions + *----------------------------------------------------------------------------*/ +/** + * @brief Updates the SystemCoreClock variable with current core Clock + * retrieved from cpu registers. + */ +void SystemCoreClockUpdate(void) +{ + /* Update the SystemCoreClock variable */ + SystemCoreClock = __SYSTEM_CLOCK; +} + +uint32_t GetSystemCoreClock(void) +{ + return SystemCoreClock; +} + +/** + * @brief Setup the microcontroller system. + * Initialize the System. + **/ +void SystemInit(void) +{ +#if (defined (__FPU_USED) && (__FPU_USED == 1U)) || \ + (defined (__MVE_USED) && (__MVE_USED == 1U)) + SCB->CPACR |= ((3U << 10U*2U) | /* enable CP10 Full Access */ + (3U << 11U*2U) ); +#endif + + /* Initialise registers r0-r12 and LR(=r14) + * They must have a valid value before being potentially pushed to stack by + * C calling convention or by context saving in exception handling + */ + RESET_REG(0); + RESET_REG(1); + RESET_REG(2); + RESET_REG(3); + RESET_REG(4); + RESET_REG(5); + RESET_REG(6); + RESET_REG(7); + RESET_REG(8); + RESET_REG(9); + RESET_REG(10); + RESET_REG(11); + RESET_REG(12); + RESET_REG(14); + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + SCB->VTOR = (uint32_t) &__Vectors; +#endif + + /* Enable hard, bus, mem and usage fault detection in SHCSR, bits 16-18. + * Enable stkof, bf, div_0_trp, unalign_trp and usersetm bits in CCR. + */ + SCB->SHCSR = ( + _VAL2FLD(SCB_SHCSR_USGFAULTENA, 1) | + _VAL2FLD(SCB_SHCSR_BUSFAULTENA, 1) | + _VAL2FLD(SCB_SHCSR_MEMFAULTENA, 1)); + + SCB->CCR = (_VAL2FLD(SCB_CCR_USERSETMPEND, 1) | + _VAL2FLD(SCB_CCR_DIV_0_TRP, 1) | + _VAL2FLD(SCB_CCR_BFHFNMIGN, 1) | + _VAL2FLD(SCB_CCR_STKOFHFNMIGN, 1)); +#ifdef UNALIGNED_SUPPORT_DISABLE + SCB->CCR |= _VAL2FLD(SCB_CCR_UNALIGN_TRP, 1); +#endif + + SCB->CCR |= CCR_DL; + + /* Reset pipeline. */ + __DSB(); + __ISB(); + +#ifdef UNALIGNED_SUPPORT_DISABLE + SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; +#endif + + SystemCoreClock = __SYSTEM_CLOCK; +} diff --git a/source/application/hal/platforms/bare-metal/bsp/cmsis-device/include/cmsis.h b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/include/cmsis.h new file mode 100644 index 0000000..969db15 --- /dev/null +++ b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/include/cmsis.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 Arm Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef BAREMETAL_CMSIS_H +#define BAREMETAL_CMSIS_H + +#include "ARMCM55.h" /* Cortex M system header file from CMSIS. */ +#include "irqs.h" /* Interrupt definitions file. */ + +/* Addition to template functions should be mentioned here. */ + +/** + * @brief Gets the internal processor clock. + * @return Clock frequency as unsigned 32 bit value. + **/ +uint32_t GetSystemCoreClock(void); + +#endif /* BAREMETAL_CMSIS_H */ diff --git a/source/application/hal/platforms/bare-metal/bsp/cmsis-device/include/irqs.h b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/include/irqs.h new file mode 100644 index 0000000..0d8dec6 --- /dev/null +++ b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/include/irqs.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 Arm Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef IRQS_H +#define IRQS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "peripheral_irqs.h" + +#include <stdint.h> + +/* Interrupt handler function type. */ +typedef void (*const irq_vec_type)(void); + +/** + * @brief Reset interrupt handler and also, the starting + * point of the application. + **/ +extern void Reset_Handler(void); + +/** + * @brief Gets the system tick triggered cycle counter for the CPU. + * @return 64-bit counter value. + **/ +extern uint64_t Get_SysTick_Cycle_Count(void); + +/** + * @brief Initialises the system tick registers. + * @return Error code return from sys tick configuration function + * (0 = no error). + **/ +extern int Init_SysTick(void); + +#ifdef __cplusplus +} +#endif + +#endif /* IRQS_H */ diff --git a/source/application/hal/platforms/bare-metal/bsp/cmsis-device/irqs.c b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/irqs.c new file mode 100644 index 0000000..c6f54b1 --- /dev/null +++ b/source/application/hal/platforms/bare-metal/bsp/cmsis-device/irqs.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2021 Arm Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "irqs.h" +#include "cmsis.h" + +#include <stdio.h> + +static uint64_t cpu_cycle_count = 0; + +/** + * @brief Dump core registers on stdout + */ +static void LogCoreCPURegisters(void) +{ + printf("CTRL : 0x%08x\n", __get_CONTROL()); + printf("IPSR : 0x%08x\n", __get_IPSR()); + printf("APSR : 0x%08x\n", __get_APSR()); + printf("xPSR : 0x%08x\n", __get_xPSR()); + printf("PSP : 0x%08x\n", __get_PSP()); + printf("MSP : 0x%08x\n", __get_MSP()); + printf("PRIMASK : 0x%08x\n", __get_PRIMASK()); + printf("BASEPRI : 0x%08x\n", __get_BASEPRI()); + printf("FAULTMSK: 0x%08x\n", __get_FAULTMASK()); + printf("PC : 0x%08x\n", __current_pc()); +} + +/** + * @brief Default interrupt handler - an infinite loop. + **/ +__attribute__((noreturn)) static void DefaultHandler(void) +{ + LogCoreCPURegisters(); + while (1) { + /* Without the following line, armclang may optimize away the + * infinite loop because it'd be without side effects and thus + * undefined behaviour. */ + __ASM volatile(""); + } +} + +#define DEFAULT_HANDLER_CALL(type) \ + do { \ + printf("\n%s caught by function %s\n", \ + type, __FUNCTION__); \ + DefaultHandler(); \ + } while (0) + +#define DEFAULT_ERROR_HANDLER_CALL() \ + DEFAULT_HANDLER_CALL("Exception") + +#define DEFAULT_IRQ_HANDLER_CALL() \ + DEFAULT_HANDLER_CALL("Interrupt") + +/** + * Dummy Exception Handlers for core interrupts. + * + * Weak definitions provided to be used if the user chooses not + * to override them. + **/ + +/** + * @brief Non maskable interrupt handler. + **/ + __attribute__((weak)) void NMI_Handler(void) +{ + DEFAULT_ERROR_HANDLER_CALL(); +} + +/** + * @brief Hardfault interrupt handler. + **/ + __attribute__((weak)) void HardFault_Handler(void) +{ + DEFAULT_ERROR_HANDLER_CALL(); +} + +/** + * @brief Memory management interrupt handler. + **/ +__attribute__((weak)) void MemManage_Handler(void) +{ + DEFAULT_IRQ_HANDLER_CALL(); +} + +/** + * @brief Bus fault interrupt handler. + **/ +__attribute__((weak)) void BusFault_Handler(void) +{ + DEFAULT_ERROR_HANDLER_CALL(); +} + +/** + * @brief Usage fault interrupt handler. + **/ +__attribute__((weak)) void UsageFault_Handler(void) +{ + DEFAULT_ERROR_HANDLER_CALL(); +} + +/** + * @brief Secure access fault interrupt handler. + **/ +__attribute__((weak)) void SecureFault_Handler(void) +{ + DEFAULT_ERROR_HANDLER_CALL(); +} + +/** + * @brief Supervisor call interrupt handler. + **/ +__attribute__((weak)) void SVC_Handler(void) +{ + DEFAULT_IRQ_HANDLER_CALL(); +} + +/** + * @brief Debug monitor interrupt handler. + **/ +__attribute__((weak)) void DebugMon_Handler(void) +{ + DEFAULT_IRQ_HANDLER_CALL(); +} + +/** + * @brief Pending SV call interrupt handler. + */ +__attribute__((weak)) void PendSV_Handler(void) +{ + DEFAULT_IRQ_HANDLER_CALL(); +} + +/** + * @brief System tick interrupt handler. + **/ +void SysTick_Handler(void) +{ + /* Increment the cycle counter based on load value. */ + cpu_cycle_count += SysTick->LOAD + 1; +} + +uint64_t Get_SysTick_Cycle_Count(void) +{ + uint32_t systick_val; + + NVIC_DisableIRQ(SysTick_IRQn); + systick_val = SysTick->VAL & SysTick_VAL_CURRENT_Msk; + NVIC_EnableIRQ(SysTick_IRQn); + + return cpu_cycle_count + (SysTick->LOAD - systick_val); +} + + +/** + * These symbols are provided by the ARM lib - needs the stack and heap + * regions in the scatter file. + */ +extern void Image$$ARM_LIB_STACK$$ZI$$Base(); +extern void Image$$ARM_LIB_STACK$$ZI$$Limit(); +extern void Image$$ARM_LIB_HEAP$$ZI$$Base(); +extern void Image$$ARM_LIB_HEAP$$ZI$$Limit(); +extern __attribute__((noreturn)) void __main(); + +__attribute__((naked, used)) void __user_setup_stackheap() +{ + __ASM volatile("LDR r0, =Image$$ARM_LIB_HEAP$$ZI$$Base"); + __ASM volatile("LDR r1, =Image$$ARM_LIB_STACK$$ZI$$Limit"); + __ASM volatile("LDR r2, =Image$$ARM_LIB_HEAP$$ZI$$Limit"); + __ASM volatile("LDR r3, =Image$$ARM_LIB_STACK$$ZI$$Base"); + __ASM volatile("bx lr"); +} + +/** + * Interrupt vector table. + */ +irq_vec_type __Vectors[] __attribute__((section("RESET"), used)) = { + &Image$$ARM_LIB_STACK$$ZI$$Limit, /* 0 Initial SP */ + &Reset_Handler , /* 1 Initial PC, set to entry point */ + + &NMI_Handler , /* 2 (-14) NMI Handler */ + &HardFault_Handler , /* 3 (-13) Hard Fault Handler */ + &MemManage_Handler , /* 4 (-12) MPU Fault Handler */ + &BusFault_Handler , /* 5 (-11) Bus Fault Handler */ + &UsageFault_Handler , /* 6 (-10) Usage Fault Handler */ + &SecureFault_Handler, /* 7 ( -9) Secure Fault Handler */ + 0 , /* 8 ( -8) Reserved */ + 0 , /* 9 ( -7) Reserved */ + 0 , /* 10 ( -6) Reserved */ + &SVC_Handler , /* 11 ( -5) SVCall Handler */ + &DebugMon_Handler , /* 12 ( -4) Debug Monitor Handler */ + 0 , /* 13 ( -3) Reserved */ + &PendSV_Handler , /* 14 ( -2) PendSV Handler */ + &SysTick_Handler , /* 15 ( -1) SysTick Handler */ + + /* External sources to be populated by user. */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 16 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 - 32 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 32 - 48 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 48 - 64 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 64 - 80 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 96 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 96 - 112 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 112 - 128 */ +}; + +int Init_SysTick(void) +{ + const uint32_t ticks_10ms = GetSystemCoreClock()/100 + 1; + int err = 0; + + /* Reset CPU cycle count value. */ + cpu_cycle_count = 0; + + /* Changing configuration for sys tick => guard from being + * interrupted. */ + NVIC_DisableIRQ(SysTick_IRQn); + + /* SysTick init - this will enable interrupt too. */ + err = SysTick_Config(ticks_10ms); + + /* Enable interrupt again. */ + NVIC_EnableIRQ(SysTick_IRQn); + + return err; +} + +/* Reset handler - starting point of our application. */ +__attribute__((used)) void Reset_Handler(void) +{ + /* Initialise system. */ + SystemInit(); + + /* Configure the system tick. */ + Init_SysTick(); + + /* libcxx supplied entry point. */ + __main(); +} + +#ifdef __cplusplus +} +#endif |