From a03591d6e3b4a441199c73a342dcf70156b9ae07 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Thu, 12 Oct 2017 13:05:25 -0500 Subject: [PATCH 01/26] CMSIS/RTX: Update CMSIS and RTX to 22b68c This includes Cortex A support and directory reshuffle. --- .../{TOOLCHAIN_ARM => }/cmsis_armcc.h | 518 +- .../{TOOLCHAIN_ARM => }/cmsis_armclang.h | 519 +- cmsis/TARGET_CORTEX_A/cmsis_compiler.h | 36 +- cmsis/TARGET_CORTEX_A/cmsis_cp15.h | 437 + cmsis/TARGET_CORTEX_A/cmsis_gcc.h | 737 ++ cmsis/TARGET_CORTEX_A/cmsis_iccarm.h | 591 ++ cmsis/{ => TARGET_CORTEX_A}/core_ca.h | 1086 ++- cmsis/TARGET_CORTEX_A/core_ca9.h | 276 - cmsis/TARGET_CORTEX_A/core_caFunc.h | 1444 ---- cmsis/TARGET_CORTEX_A/core_caInstr.h | 45 - cmsis/TARGET_CORTEX_A/core_ca_mmu.h | 847 -- cmsis/TARGET_CORTEX_A/core_cm4_simd.h | 673 -- cmsis/TARGET_CORTEX_A/core_cmInstr.h | 916 --- cmsis/TARGET_CORTEX_A/irq_ctrl.h | 180 + cmsis/TARGET_CORTEX_A/irq_ctrl_gic.c | 404 + .../{TOOLCHAIN_ARM => }/cmsis_armcc.h | 61 +- .../{TOOLCHAIN_ARM => }/cmsis_armclang.h | 131 +- cmsis/TARGET_CORTEX_M/cmsis_compiler.h | 104 +- .../{TOOLCHAIN_GCC => }/cmsis_gcc.h | 100 +- cmsis/TARGET_CORTEX_M/cmsis_iccarm.h | 771 ++ cmsis/TARGET_CORTEX_M/cmsis_version.h | 39 + cmsis/{ => TARGET_CORTEX_M}/core_armv8mbl.h | 32 +- cmsis/{ => TARGET_CORTEX_M}/core_armv8mml.h | 74 +- cmsis/{ => TARGET_CORTEX_M}/core_cm0.h | 10 +- cmsis/{ => TARGET_CORTEX_M}/core_cm0plus.h | 21 +- cmsis/{ => TARGET_CORTEX_M}/core_cm23.h | 32 +- cmsis/{ => TARGET_CORTEX_M}/core_cm3.h | 21 +- cmsis/{ => TARGET_CORTEX_M}/core_cm33.h | 80 +- cmsis/{ => TARGET_CORTEX_M}/core_cm4.h | 24 +- cmsis/{ => TARGET_CORTEX_M}/core_cm7.h | 23 +- cmsis/{ => TARGET_CORTEX_M}/core_sc000.h | 10 +- cmsis/{ => TARGET_CORTEX_M}/core_sc300.h | 10 +- cmsis/TARGET_CORTEX_M/mpu_armv7.h | 191 + cmsis/TARGET_CORTEX_M/mpu_armv8.h | 323 + cmsis/{ => TARGET_CORTEX_M}/tz_context.h | 0 cmsis/TOOLCHAIN_GCC/TARGET_CORTEX_A/cache.S | 94 - cmsis/TOOLCHAIN_IAR/TARGET_CORTEX_A/cache.S | 97 - cmsis/TOOLCHAIN_IAR/cmain.S | 101 - cmsis/arm_math.h | 7257 ----------------- cmsis/core_cmSecureAccess.h | 201 - rtos/TARGET_CORTEX/rtx4/cmsis_os.h | 25 +- .../rtx5/{ => Include}/cmsis_os2.h | 46 +- rtos/TARGET_CORTEX/rtx5/Include/os_tick.h | 74 + .../rtx5/{ => RTX/Config}/RTX_Config.c | 2 +- .../rtx5/{ => RTX/Config}/RTX_Config.h | 7 +- .../RTX/Config/TARGET_CORTEX_A/handlers.c | 153 + .../rtx5/{ => RTX/Include}/rtx_evr.h | 7 +- .../rtx5/{ => RTX/Include}/rtx_os.h | 37 +- .../TOOLCHAIN_ARM/TARGET_CORTEX_A/irq_ca.s | 447 + .../Source/TOOLCHAIN_ARM/TARGET_M0/irq_cm0.s} | 2 +- .../TOOLCHAIN_ARM/TARGET_M0P/irq_cm0.s} | 2 +- .../TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl.s} | 45 +- .../TARGET_M23/irq_armv8mbl_ns.s | 3 + .../Source/TOOLCHAIN_ARM/TARGET_M3/irq_cm3.s} | 2 +- .../TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml.s} | 68 +- .../TARGET_M33/irq_armv8mml_ns.s | 3 + .../TARGET_RTOS_M4_M7/irq_cm4f.s} | 8 +- .../TOOLCHAIN_GCC/TARGET_CORTEX_A/irq_ca.S | 455 ++ .../Source/TOOLCHAIN_GCC/TARGET_M0}/irq_cm0.S | 2 +- .../TOOLCHAIN_GCC/TARGET_M0P}/irq_cm0.S | 2 +- .../TOOLCHAIN_GCC/TARGET_M23}/irq_armv8mbl.S | 35 +- .../TARGET_M23/irq_armv8mbl_ns.S | 3 + .../Source/TOOLCHAIN_GCC/TARGET_M3}/irq_cm3.S | 17 +- .../TOOLCHAIN_GCC/TARGET_M33}/irq_armv8mml.S | 56 +- .../TARGET_M33/irq_armv8mml_fp.S | 3 + .../TARGET_M33/irq_armv8mml_fp_ns.S | 4 + .../TARGET_M33/irq_armv8mml_ns.S | 3 + .../TARGET_RTOS_M4_M7}/irq_cm4f.S | 24 +- .../TOOLCHAIN_IAR/TARGET_CORTEX_A/irq_ca.s | 431 + .../Source/TOOLCHAIN_IAR/TARGET_M0/irq_cm0.s} | 2 +- .../TOOLCHAIN_IAR/TARGET_M0P/irq_cm0.s} | 2 +- .../TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl.s | 5 + .../TARGET_M23/irq_armv8mbl_common.s} | 32 +- .../TARGET_M23/irq_armv8mbl_ns.s | 5 + .../Source/TOOLCHAIN_IAR/TARGET_M3/irq_cm3.s} | 2 +- .../TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml.s | 5 + .../TARGET_M33/irq_armv8mml_common.s} | 52 +- .../TARGET_M33/irq_armv8mml_ns.s | 5 + .../TARGET_RTOS_M4_M7/irq_cm4f.s} | 8 +- .../rtx5/RTX/Source/rtx_core_c.h | 66 + .../rtx5/RTX/Source/rtx_core_ca.h | 1100 +++ .../{core_cm.h => RTX/Source/rtx_core_cm.h} | 181 +- .../rtx5/{ => RTX/Source}/rtx_delay.c | 13 +- .../rtx5/{ => RTX/Source}/rtx_evflags.c | 0 .../rtx5/{ => RTX/Source}/rtx_evr.c | 10 +- .../rtx5/{ => RTX/Source}/rtx_kernel.c | 78 +- .../rtx5/{ => RTX/Source}/rtx_lib.c | 16 +- .../rtx5/{ => RTX/Source}/rtx_lib.h | 15 +- .../rtx5/{ => RTX/Source}/rtx_memory.c | 0 .../rtx5/{ => RTX/Source}/rtx_mempool.c | 0 .../rtx5/{ => RTX/Source}/rtx_msgqueue.c | 3 +- .../rtx5/{ => RTX/Source}/rtx_mutex.c | 40 +- .../rtx5/{ => RTX/Source}/rtx_semaphore.c | 0 .../rtx5/{ => RTX/Source}/rtx_system.c | 50 +- .../rtx5/{ => RTX/Source}/rtx_thread.c | 56 +- .../rtx5/{ => RTX/Source}/rtx_timer.c | 0 rtos/TARGET_CORTEX/rtx5/Source/os_systick.c | 134 + rtos/TARGET_CORTEX/rtx5/Source/os_tick_gtim.c | 192 + rtos/TARGET_CORTEX/rtx5/Source/os_tick_ptim.c | 170 + rtos/TARGET_CORTEX/rtx5/rt_OsEventObserver.c | 51 - rtos/TARGET_CORTEX/rtx5/rt_OsEventObserver.h | 51 - 101 files changed, 8997 insertions(+), 13829 deletions(-) rename cmsis/TARGET_CORTEX_A/{TOOLCHAIN_ARM => }/cmsis_armcc.h (59%) rename cmsis/TARGET_CORTEX_A/{TOOLCHAIN_ARM => }/cmsis_armclang.h (57%) create mode 100644 cmsis/TARGET_CORTEX_A/cmsis_cp15.h create mode 100644 cmsis/TARGET_CORTEX_A/cmsis_gcc.h create mode 100644 cmsis/TARGET_CORTEX_A/cmsis_iccarm.h rename cmsis/{ => TARGET_CORTEX_A}/core_ca.h (58%) delete mode 100644 cmsis/TARGET_CORTEX_A/core_ca9.h delete mode 100644 cmsis/TARGET_CORTEX_A/core_caFunc.h delete mode 100644 cmsis/TARGET_CORTEX_A/core_caInstr.h delete mode 100644 cmsis/TARGET_CORTEX_A/core_ca_mmu.h delete mode 100644 cmsis/TARGET_CORTEX_A/core_cm4_simd.h delete mode 100644 cmsis/TARGET_CORTEX_A/core_cmInstr.h create mode 100644 cmsis/TARGET_CORTEX_A/irq_ctrl.h create mode 100644 cmsis/TARGET_CORTEX_A/irq_ctrl_gic.c rename cmsis/TARGET_CORTEX_M/{TOOLCHAIN_ARM => }/cmsis_armcc.h (94%) rename cmsis/TARGET_CORTEX_M/{TOOLCHAIN_ARM => }/cmsis_armclang.h (95%) rename cmsis/TARGET_CORTEX_M/{TOOLCHAIN_GCC => }/cmsis_gcc.h (95%) create mode 100644 cmsis/TARGET_CORTEX_M/cmsis_iccarm.h create mode 100644 cmsis/TARGET_CORTEX_M/cmsis_version.h rename cmsis/{ => TARGET_CORTEX_M}/core_armv8mbl.h (99%) rename cmsis/{ => TARGET_CORTEX_M}/core_armv8mml.h (98%) rename cmsis/{ => TARGET_CORTEX_M}/core_cm0.h (99%) rename cmsis/{ => TARGET_CORTEX_M}/core_cm0plus.h (98%) rename cmsis/{ => TARGET_CORTEX_M}/core_cm23.h (99%) rename cmsis/{ => TARGET_CORTEX_M}/core_cm3.h (99%) rename cmsis/{ => TARGET_CORTEX_M}/core_cm33.h (98%) rename cmsis/{ => TARGET_CORTEX_M}/core_cm4.h (99%) rename cmsis/{ => TARGET_CORTEX_M}/core_cm7.h (99%) rename cmsis/{ => TARGET_CORTEX_M}/core_sc000.h (99%) rename cmsis/{ => TARGET_CORTEX_M}/core_sc300.h (99%) create mode 100644 cmsis/TARGET_CORTEX_M/mpu_armv7.h create mode 100644 cmsis/TARGET_CORTEX_M/mpu_armv8.h rename cmsis/{ => TARGET_CORTEX_M}/tz_context.h (100%) delete mode 100644 cmsis/TOOLCHAIN_GCC/TARGET_CORTEX_A/cache.S delete mode 100644 cmsis/TOOLCHAIN_IAR/TARGET_CORTEX_A/cache.S delete mode 100644 cmsis/TOOLCHAIN_IAR/cmain.S delete mode 100644 cmsis/arm_math.h delete mode 100644 cmsis/core_cmSecureAccess.h rename rtos/TARGET_CORTEX/rtx5/{ => Include}/cmsis_os2.h (96%) create mode 100644 rtos/TARGET_CORTEX/rtx5/Include/os_tick.h rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Config}/RTX_Config.c (99%) rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Config}/RTX_Config.h (99%) create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Config/TARGET_CORTEX_A/handlers.c rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Include}/rtx_evr.h (99%) rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Include}/rtx_os.h (94%) create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_CORTEX_A/irq_ca.s rename rtos/TARGET_CORTEX/rtx5/{TARGET_M0/TOOLCHAIN_ARM/irq_cm0.S => RTX/Source/TOOLCHAIN_ARM/TARGET_M0/irq_cm0.s} (98%) rename rtos/TARGET_CORTEX/rtx5/{TARGET_M0P/TOOLCHAIN_ARM/irq_cm0.S => RTX/Source/TOOLCHAIN_ARM/TARGET_M0P/irq_cm0.s} (98%) rename rtos/TARGET_CORTEX/rtx5/{TARGET_M23/TOOLCHAIN_ARM/irq_armv8mbl.S => RTX/Source/TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl.s} (94%) create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl_ns.s rename rtos/TARGET_CORTEX/rtx5/{TARGET_M3/TOOLCHAIN_ARM/irq_cm3.S => RTX/Source/TOOLCHAIN_ARM/TARGET_M3/irq_cm3.s} (98%) rename rtos/TARGET_CORTEX/rtx5/{TARGET_M33/TOOLCHAIN_ARM/irq_armv8mml.S => RTX/Source/TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml.s} (89%) create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml_ns.s rename rtos/TARGET_CORTEX/rtx5/{TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.S => RTX/Source/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/irq_cm4f.s} (97%) create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_CORTEX_A/irq_ca.S rename rtos/TARGET_CORTEX/rtx5/{TARGET_M0P/TOOLCHAIN_GCC => RTX/Source/TOOLCHAIN_GCC/TARGET_M0}/irq_cm0.S (98%) rename rtos/TARGET_CORTEX/rtx5/{TARGET_M0/TOOLCHAIN_GCC => RTX/Source/TOOLCHAIN_GCC/TARGET_M0P}/irq_cm0.S (98%) rename rtos/TARGET_CORTEX/rtx5/{TARGET_M23/TOOLCHAIN_GCC => RTX/Source/TOOLCHAIN_GCC/TARGET_M23}/irq_armv8mbl.S (95%) create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M23/irq_armv8mbl_ns.S rename rtos/TARGET_CORTEX/rtx5/{TARGET_M3/TOOLCHAIN_GCC => RTX/Source/TOOLCHAIN_GCC/TARGET_M3}/irq_cm3.S (84%) rename rtos/TARGET_CORTEX/rtx5/{TARGET_M33/TOOLCHAIN_GCC => RTX/Source/TOOLCHAIN_GCC/TARGET_M33}/irq_armv8mml.S (92%) create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M33/irq_armv8mml_fp.S create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M33/irq_armv8mml_fp_ns.S create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M33/irq_armv8mml_ns.S rename rtos/TARGET_CORTEX/rtx5/{TARGET_RTOS_M4_M7/TOOLCHAIN_GCC => RTX/Source/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7}/irq_cm4f.S (85%) create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_CORTEX_A/irq_ca.s rename rtos/TARGET_CORTEX/rtx5/{TARGET_M0/TOOLCHAIN_IAR/irq_cm0.S => RTX/Source/TOOLCHAIN_IAR/TARGET_M0/irq_cm0.s} (98%) rename rtos/TARGET_CORTEX/rtx5/{TARGET_M0P/TOOLCHAIN_IAR/irq_cm0.S => RTX/Source/TOOLCHAIN_IAR/TARGET_M0P/irq_cm0.s} (98%) create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl.s rename rtos/TARGET_CORTEX/rtx5/{TARGET_M23/TOOLCHAIN_IAR/irq_armv8mbl.S => RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl_common.s} (96%) create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl_ns.s rename rtos/TARGET_CORTEX/rtx5/{TARGET_M3/TOOLCHAIN_IAR/irq_cm3.S => RTX/Source/TOOLCHAIN_IAR/TARGET_M3/irq_cm3.s} (98%) create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml.s rename rtos/TARGET_CORTEX/rtx5/{TARGET_M33/TOOLCHAIN_IAR/irq_armv8mml.S => RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml_common.s} (93%) create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml_ns.s rename rtos/TARGET_CORTEX/rtx5/{TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.S => RTX/Source/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/irq_cm4f.s} (97%) create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_c.h create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_ca.h rename rtos/TARGET_CORTEX/rtx5/{core_cm.h => RTX/Source/rtx_core_cm.h} (90%) rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Source}/rtx_delay.c (83%) rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Source}/rtx_evflags.c (100%) rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Source}/rtx_evr.c (99%) rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Source}/rtx_kernel.c (92%) rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Source}/rtx_lib.c (97%) rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Source}/rtx_lib.h (97%) rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Source}/rtx_memory.c (100%) rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Source}/rtx_mempool.c (100%) rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Source}/rtx_msgqueue.c (99%) rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Source}/rtx_mutex.c (93%) rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Source}/rtx_semaphore.c (100%) rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Source}/rtx_system.c (84%) rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Source}/rtx_thread.c (96%) rename rtos/TARGET_CORTEX/rtx5/{ => RTX/Source}/rtx_timer.c (100%) create mode 100644 rtos/TARGET_CORTEX/rtx5/Source/os_systick.c create mode 100644 rtos/TARGET_CORTEX/rtx5/Source/os_tick_gtim.c create mode 100644 rtos/TARGET_CORTEX/rtx5/Source/os_tick_ptim.c delete mode 100644 rtos/TARGET_CORTEX/rtx5/rt_OsEventObserver.c delete mode 100644 rtos/TARGET_CORTEX/rtx5/rt_OsEventObserver.h diff --git a/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armcc.h b/cmsis/TARGET_CORTEX_A/cmsis_armcc.h similarity index 59% rename from cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armcc.h rename to cmsis/TARGET_CORTEX_A/cmsis_armcc.h index 80f9dd95791..1b4ab2c321c 100644 --- a/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armcc.h +++ b/cmsis/TARGET_CORTEX_A/cmsis_armcc.h @@ -1,8 +1,8 @@ /**************************************************************************//** * @file cmsis_armcc.h * @brief CMSIS compiler specific macros, functions, instructions - * @version V1.00 - * @date 22. Feb 2017 + * @version V1.0.1 + * @date 07. Sep 2017 ******************************************************************************/ /* * Copyright (c) 2009-2017 ARM Limited. All rights reserved. @@ -36,68 +36,53 @@ /* CMSIS compiler specific defines */ #ifndef __ASM - #define __ASM __asm + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __FORCEINLINE + #define __FORCEINLINE __forceinline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) #endif -#ifndef __INLINE - #define __INLINE __inline -#endif -#ifndef __STATIC_INLINE - #define __STATIC_INLINE static __inline +#ifndef __PACKED + #define __PACKED __attribute__((packed)) #endif -#ifndef __STATIC_ASM - #define __STATIC_ASM static __asm +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct #endif -#ifndef __NO_RETURN - #define __NO_RETURN __declspec(noreturn) +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) #endif -#ifndef __USED - #define __USED __attribute__((used)) +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) #endif -#ifndef __WEAK - #define __WEAK __attribute__((weak)) +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) #endif -#ifndef __UNALIGNED_UINT32 - #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) #endif #ifndef __ALIGNED - #define __ALIGNED(x) __attribute__((aligned(x))) -#endif -#ifndef __PACKED - #define __PACKED __attribute__((packed)) -#endif - - -/* ########################### Core Function Access ########################### */ - -/** - \brief Get FPSCR - \return Floating Point Status/Control register value - */ -__STATIC_INLINE uint32_t __get_FPSCR(void) -{ -#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ - (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) - register uint32_t __regfpscr __ASM("fpscr"); - return(__regfpscr); -#else - return(0U); + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) #endif -} - -/** - \brief Set FPSCR - \param [in] fpscr Floating Point Status/Control value to set - */ -__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) -{ -#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ - (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) - register uint32_t __regfpscr __ASM("fpscr"); - __regfpscr = (fpscr); -#else - (void)fpscr; -#endif -} /* ########################## Core Instruction Access ######################### */ /** @@ -209,7 +194,142 @@ __attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(in */ #define __CLZ __clz -/** \brief Get CPSR Register +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + +/* ########################### Core Function Access ########################### */ + +/** + \brief Get FPSCR (Floating Point Status/Control) + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + +/** + \brief Set FPSCR (Floating Point Status/Control) + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + +/** \brief Get CPSR (Current Program Status Register) \return CPSR Register value */ __STATIC_INLINE uint32_t __get_CPSR(void) @@ -219,7 +339,7 @@ __STATIC_INLINE uint32_t __get_CPSR(void) } -/** \brief Set CPSR Register +/** \brief Set CPSR (Current Program Status Register) \param [in] cpsr CPSR value to set */ __STATIC_INLINE void __set_CPSR(uint32_t cpsr) @@ -244,7 +364,16 @@ __STATIC_INLINE __ASM void __set_mode(uint32_t mode) { BX r1 } -/** \brief Set Stack Pointer +/** \brief Get Stack Pointer + \return Stack Pointer + */ +__STATIC_INLINE __ASM uint32_t __get_SP(void) +{ + MOV r0, sp + BX lr +} + +/** \brief Set Stack Pointer \param [in] stack Stack Pointer value to set */ __STATIC_INLINE __ASM void __set_SP(uint32_t stack) @@ -253,35 +382,41 @@ __STATIC_INLINE __ASM void __set_SP(uint32_t stack) BX lr } -/** \brief Set Process Stack Pointer - \param [in] topOfProcStack USR/SYS Stack Pointer value to set + +/** \brief Get USR/SYS Stack Pointer + \return USR/SYSStack Pointer */ -__STATIC_INLINE __ASM void __set_PSP(uint32_t topOfProcStack) +__STATIC_INLINE __ASM uint32_t __get_SP_usr(void) { ARM PRESERVE8 - BIC R0, R0, #7 ;ensure stack is 8-byte aligned MRS R1, CPSR CPS #0x1F ;no effect in USR mode - MOV SP, R0 + MOV R0, SP MSR CPSR_c, R1 ;no effect in USR mode ISB BX LR } -/** \brief Set User Mode +/** \brief Set USR/SYS Stack Pointer + \param [in] topOfProcStack USR/SYS Stack Pointer value to set */ -__STATIC_INLINE __ASM void __set_CPS_USR(void) +__STATIC_INLINE __ASM void __set_SP_usr(uint32_t topOfProcStack) { ARM + PRESERVE8 - CPS #0x10 - BX LR + MRS R1, CPSR + CPS #0x1F ;no effect in USR mode + MOV SP, R0 + MSR CPSR_c, R1 ;no effect in USR mode + ISB + BX LR } -/** \brief Get FPEXC - \return Floating Point Exception Control register value +/** \brief Get FPEXC (Floating Point Exception Control Register) + \return Floating Point Exception Control Register value */ __STATIC_INLINE uint32_t __get_FPEXC(void) { @@ -293,7 +428,7 @@ __STATIC_INLINE uint32_t __get_FPEXC(void) #endif } -/** \brief Set FPEXC +/** \brief Set FPEXC (Floating Point Exception Control Register) \param [in] fpexc Floating Point Exception Control value to set */ __STATIC_INLINE void __set_FPEXC(uint32_t fpexc) @@ -304,243 +439,18 @@ __STATIC_INLINE void __set_FPEXC(uint32_t fpexc) #endif } -/** \brief Get CPACR - \return Coprocessor Access Control register value - */ -__STATIC_INLINE uint32_t __get_CPACR(void) -{ - register uint32_t __regCPACR __ASM("cp15:0:c1:c0:2"); - return __regCPACR; -} - -/** \brief Set CPACR - \param [in] cpacr Coprocessor Acccess Control value to set - */ -__STATIC_INLINE void __set_CPACR(uint32_t cpacr) -{ - register uint32_t __regCPACR __ASM("cp15:0:c1:c0:2"); - __regCPACR = cpacr; -} - -/** \brief Get CBAR - \return Configuration Base Address register value - */ -__STATIC_INLINE uint32_t __get_CBAR() { - register uint32_t __regCBAR __ASM("cp15:4:c15:c0:0"); - return(__regCBAR); -} - -/** \brief Get TTBR0 - - This function returns the value of the Translation Table Base Register 0. - - \return Translation Table Base Register 0 value - */ -__STATIC_INLINE uint32_t __get_TTBR0() { - register uint32_t __regTTBR0 __ASM("cp15:0:c2:c0:0"); - return(__regTTBR0); -} - -/** \brief Set TTBR0 - - This function assigns the given value to the Translation Table Base Register 0. - - \param [in] ttbr0 Translation Table Base Register 0 value to set - */ -__STATIC_INLINE void __set_TTBR0(uint32_t ttbr0) { - register uint32_t __regTTBR0 __ASM("cp15:0:c2:c0:0"); - __regTTBR0 = ttbr0; -} - -/** \brief Get DACR - - This function returns the value of the Domain Access Control Register. - - \return Domain Access Control Register value - */ -__STATIC_INLINE uint32_t __get_DACR() { - register uint32_t __regDACR __ASM("cp15:0:c3:c0:0"); - return(__regDACR); -} - -/** \brief Set DACR - - This function assigns the given value to the Domain Access Control Register. - - \param [in] dacr Domain Access Control Register value to set - */ -__STATIC_INLINE void __set_DACR(uint32_t dacr) { - register uint32_t __regDACR __ASM("cp15:0:c3:c0:0"); - __regDACR = dacr; -} - -/** \brief Set SCTLR - - This function assigns the given value to the System Control Register. - - \param [in] sctlr System Control Register value to set - */ -__STATIC_INLINE void __set_SCTLR(uint32_t sctlr) -{ - register uint32_t __regSCTLR __ASM("cp15:0:c1:c0:0"); - __regSCTLR = sctlr; -} - -/** \brief Get SCTLR - \return System Control Register value - */ -__STATIC_INLINE uint32_t __get_SCTLR() { - register uint32_t __regSCTLR __ASM("cp15:0:c1:c0:0"); - return(__regSCTLR); -} - -/** \brief Set ACTRL - \param [in] actrl Auxiliary Control Register value to set - */ -__STATIC_INLINE void __set_ACTRL(uint32_t actrl) -{ - register uint32_t __regACTRL __ASM("cp15:0:c1:c0:1"); - __regACTRL = actrl; -} - -/** \brief Get ACTRL - \return Auxiliary Control Register value - */ -__STATIC_INLINE uint32_t __get_ACTRL(void) -{ - register uint32_t __regACTRL __ASM("cp15:0:c1:c0:1"); - return(__regACTRL); -} - -/** \brief Get MPIDR - - This function returns the value of the Multiprocessor Affinity Register. - - \return Multiprocessor Affinity Register value - */ -__STATIC_INLINE uint32_t __get_MPIDR(void) -{ - register uint32_t __regMPIDR __ASM("cp15:0:c0:c0:5"); - return(__regMPIDR); -} - - /** \brief Get VBAR - - This function returns the value of the Vector Base Address Register. - - \return Vector Base Address Register - */ -__STATIC_INLINE uint32_t __get_VBAR(void) -{ - register uint32_t __regVBAR __ASM("cp15:0:c12:c0:0"); - return(__regVBAR); -} - -/** \brief Set VBAR - - This function assigns the given value to the Vector Base Address Register. - - \param [in] vbar Vector Base Address Register value to set - */ -__STATIC_INLINE void __set_VBAR(uint32_t vbar) -{ - register uint32_t __regVBAR __ASM("cp15:0:c12:c0:0"); - __regVBAR = vbar; -} - -/** \brief Set CNTP_TVAL - - This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL). - - \param [in] value CNTP_TVAL Register value to set -*/ -__STATIC_INLINE void __set_CNTP_TVAL(uint32_t value) { - register uint32_t __regCNTP_TVAL __ASM("cp15:0:c14:c2:0"); - __regCNTP_TVAL = value; -} - -/** \brief Get CNTP_TVAL - - This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL). - - \return CNTP_TVAL Register value - */ -__STATIC_INLINE uint32_t __get_CNTP_TVAL() { - register uint32_t __regCNTP_TVAL __ASM("cp15:0:c14:c2:0"); - return(__regCNTP_TVAL); -} - -/** \brief Set CNTP_CTL - - This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL). - - \param [in] value CNTP_CTL Register value to set -*/ -__STATIC_INLINE void __set_CNTP_CTL(uint32_t value) { - register uint32_t __regCNTP_CTL __ASM("cp15:0:c14:c2:1"); - __regCNTP_CTL = value; -} - -/** \brief Set TLBIALL - - TLB Invalidate All - */ -__STATIC_INLINE void __set_TLBIALL(uint32_t value) { - register uint32_t __TLBIALL __ASM("cp15:0:c8:c7:0"); - __TLBIALL = value; -} - -/** \brief Set BPIALL. - - Branch Predictor Invalidate All - */ -__STATIC_INLINE void __set_BPIALL(uint32_t value) { - register uint32_t __BPIALL __ASM("cp15:0:c7:c5:6"); - __BPIALL = value; -} - -/** \brief Set ICIALLU - - Instruction Cache Invalidate All - */ -__STATIC_INLINE void __set_ICIALLU(uint32_t value) { - register uint32_t __ICIALLU __ASM("cp15:0:c7:c5:0"); - __ICIALLU = value; -} - -/** \brief Set DCCMVAC - - Data cache clean - */ -__STATIC_INLINE void __set_DCCMVAC(uint32_t value) { - register uint32_t __DCCMVAC __ASM("cp15:0:c7:c10:1"); - __DCCMVAC = value; -} - -/** \brief Set DCIMVAC - - Data cache invalidate +/* + * Include common core functions to access Coprocessor 15 registers */ -__STATIC_INLINE void __set_DCIMVAC(uint32_t value) { - register uint32_t __DCIMVAC __ASM("cp15:0:c7:c6:1"); - __DCIMVAC = value; -} - -/** \brief Set DCCIMVAC + +#define __get_CP(cp, op1, Rt, CRn, CRm, op2) do { register uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); Rt = tmp; } while(0) +#define __set_CP(cp, op1, Rt, CRn, CRm, op2) do { register uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); tmp = Rt; } while(0) - Data cache clean and invalidate - */ -__STATIC_INLINE void __set_DCCIMVAC(uint32_t value) { - register uint32_t __DCCIMVAC __ASM("cp15:0:c7:c14:1"); - __DCCIMVAC = value; -} +#include "cmsis_cp15.h" /** \brief Clean and Invalidate the entire data or unified cache - - Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency + * \param [in] op 0 - invalidate, 1 - clean, otherwise - invalidate and clean */ -#pragma push -#pragma arm __STATIC_INLINE __ASM void __L1C_CleanInvalidateCache(uint32_t op) { ARM @@ -595,14 +505,11 @@ Finished POP {R4-R11} BX lr } -#pragma pop /** \brief Enable Floating Point Unit Critical section, called from undef handler, so systick is disabled */ -#pragma push -#pragma arm __STATIC_INLINE __ASM void __FPU_Enable(void) { ARM @@ -668,6 +575,5 @@ __STATIC_INLINE __ASM void __FPU_Enable(void) { BX LR } -#pragma pop #endif /* __CMSIS_ARMCC_H */ diff --git a/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armclang.h b/cmsis/TARGET_CORTEX_A/cmsis_armclang.h similarity index 57% rename from cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armclang.h rename to cmsis/TARGET_CORTEX_A/cmsis_armclang.h index 40069837d15..9c93f2fd1d5 100644 --- a/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armclang.h +++ b/cmsis/TARGET_CORTEX_A/cmsis_armclang.h @@ -1,8 +1,8 @@ /**************************************************************************//** * @file cmsis_armclang.h * @brief CMSIS compiler specific macros, functions, instructions - * @version V1.00 - * @date 05. Apr 2017 + * @version V1.0.1 + * @date 07. Sep 2017 ******************************************************************************/ /* * Copyright (c) 2009-2017 ARM Limited. All rights reserved. @@ -31,68 +31,72 @@ /* CMSIS compiler specific defines */ #ifndef __ASM - #define __ASM __asm + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __FORCEINLINE + #define __FORCEINLINE __attribute__((always_inline)) +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) #endif -#ifndef __INLINE - #define __INLINE __inline -#endif -#ifndef __STATIC_INLINE - #define __STATIC_INLINE static __inline +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) #endif -#ifndef __STATIC_ASM - #define __STATIC_ASM static __asm +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) #endif -#ifndef __NO_RETURN - #define __NO_RETURN __declspec(noreturn) +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) #endif -#ifndef __USED - #define __USED __attribute__((used)) +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) #endif -#ifndef __WEAK - #define __WEAK __attribute__((weak)) +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) #endif -#ifndef __UNALIGNED_UINT32 - #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) #endif #ifndef __ALIGNED - #define __ALIGNED(x) __attribute__((aligned(x))) -#endif -#ifndef __PACKED - #define __PACKED __attribute__((packed)) -#endif - - -/* ########################### Core Function Access ########################### */ - -/** - \brief Get FPSCR - \return Floating Point Status/Control register value - */ -__STATIC_INLINE uint32_t __get_FPSCR(void) -{ -#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ - (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) - uint32_t result; - __ASM volatile("MRS %0, fpscr" : "=r" (result) ); - return(result); -#else - return(0U); -#endif -} - -/** - \brief Set FPSCR - \param [in] fpscr Floating Point Status/Control value to set - */ -__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) -{ -#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ - (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) - __ASM volatile ("MSR fpscr, %0" : : "r" (fpscr) : "memory"); -#else - (void)fpscr; + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) #endif -} /* ########################## Core Instruction Access ######################### */ /** @@ -210,316 +214,226 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint */ #define __CLZ __builtin_clz -/** \brief Get CPSR Register - \return CPSR Register value - */ -__STATIC_INLINE uint32_t __get_CPSR(void) -{ - uint32_t result; - __ASM volatile("MRS %0, cpsr" : "=r" (result) ); - return(result); -} - -/** \brief Get Mode - \return Processor Mode +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) */ -__STATIC_INLINE uint32_t __get_mode(void) { - return (__get_CPSR() & 0x1FU); -} +#define __LDREXB (uint8_t)__builtin_arm_ldrex -/** \brief Set Mode - \param [in] mode Mode value to set - */ -__STATIC_INLINE void __set_mode(uint32_t mode) { - __ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory"); -} -/** \brief Set Stack Pointer - \param [in] stack Stack Pointer value to set +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) */ -__STATIC_INLINE void __set_SP(uint32_t stack) -{ - __ASM volatile("MOV sp, %0" : : "r" (stack) : "memory"); -} +#define __LDREXH (uint16_t)__builtin_arm_ldrex -/** \brief Set Process Stack Pointer - \param [in] topOfProcStack USR/SYS Stack Pointer value to set +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) */ -__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) -{ - __ASM volatile( - ".preserve8 \n" - "BIC r0, r0, #7 \n" // ensure stack is 8-byte aligned - "MRS r1, cpsr \n" - "CPS #0x1F \n" // no effect in USR mode - "MOV sp, r0 \n" - "MSR cpsr_c, r1 \n" // no effect in USR mode - "ISB" - ); -} +#define __LDREXW (uint32_t)__builtin_arm_ldrex -/** \brief Set User Mode +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed */ -__STATIC_INLINE void __set_CPS_USR(void) -{ - __ASM volatile("CPS #0x10"); -} +#define __STREXB (uint32_t)__builtin_arm_strex -/** \brief Get FPEXC - \return Floating Point Exception Control register value +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed */ -__STATIC_INLINE uint32_t __get_FPEXC(void) -{ -#if (__FPU_PRESENT == 1) - uint32_t result; - __ASM volatile("MRS %0, fpexc" : "=r" (result) ); - return(result); -#else - return(0); -#endif -} +#define __STREXH (uint32_t)__builtin_arm_strex -/** \brief Set FPEXC - \param [in] fpexc Floating Point Exception Control value to set +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed */ -__STATIC_INLINE void __set_FPEXC(uint32_t fpexc) -{ -#if (__FPU_PRESENT == 1) - __ASM volatile ("MSR fpexc, %0" : : "r" (fpexc) : "memory"); -#endif -} +#define __STREXW (uint32_t)__builtin_arm_strex -/** \brief Get CPACR - \return Coprocessor Access Control register value +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. */ -__STATIC_INLINE uint32_t __get_CPACR(void) -{ - uint32_t result; - __ASM volatile("MRC p15, 0, %0, c1, c0, 2" : "=r"(result)); - return result; -} +#define __CLREX __builtin_arm_clrex -/** \brief Set CPACR - \param [in] cpacr Coprocessor Acccess Control value to set +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value */ -__STATIC_INLINE void __set_CPACR(uint32_t cpacr) -{ - __ASM volatile("MCR p15, 0, %0, c1, c0, 2" : : "r"(cpacr) : "memory"); -} +#define __SSAT __builtin_arm_ssat -/** \brief Get CBAR - \return Configuration Base Address register value +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value */ -__STATIC_INLINE uint32_t __get_CBAR() { - uint32_t result; - __ASM volatile("MRC p15, 4, %0, c15, c0, 0" : "=r"(result)); - return result; -} +#define __USAT __builtin_arm_usat -/** \brief Get TTBR0 - This function returns the value of the Translation Table Base Register 0. +/* ########################### Core Function Access ########################### */ - \return Translation Table Base Register 0 value +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value */ -__STATIC_INLINE uint32_t __get_TTBR0() { - uint32_t result; - __ASM volatile("MRC p15, 0, %0, c2, c0, 0" : "=r"(result)); - return result; -} - -/** \brief Set TTBR0 +#define __get_FPSCR __builtin_arm_get_fpscr - This function assigns the given value to the Translation Table Base Register 0. - - \param [in] ttbr0 Translation Table Base Register 0 value to set +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set */ -__STATIC_INLINE void __set_TTBR0(uint32_t ttbr0) { - __ASM volatile("MCR p15, 0, %0, c2, c0, 0" : : "r"(ttbr0) : "memory"); -} - -/** \brief Get DACR +#define __set_FPSCR __builtin_arm_set_fpscr - This function returns the value of the Domain Access Control Register. - - \return Domain Access Control Register value +/** \brief Get CPSR Register + \return CPSR Register value */ -__STATIC_INLINE uint32_t __get_DACR() { +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_CPSR(void) +{ uint32_t result; - __ASM volatile("MRC p15, 0, %0, c3, c0, 0" : "=r"(result)); - return result; -} - -/** \brief Set DACR - - This function assigns the given value to the Domain Access Control Register. - - \param [in] dacr Domain Access Control Register value to set - */ -__STATIC_INLINE void __set_DACR(uint32_t dacr) { - __ASM volatile("MCR p15, 0, %0, c3, c0, 0" : : "r"(dacr) : "memory"); + __ASM volatile("MRS %0, cpsr" : "=r" (result) ); + return(result); } -/** \brief Set SCTLR - - This function assigns the given value to the System Control Register. - - \param [in] sctlr System Control Register value to set +/** \brief Set CPSR Register + \param [in] cpsr CPSR value to set */ -__STATIC_INLINE void __set_SCTLR(uint32_t sctlr) +__attribute__((always_inline)) __STATIC_INLINE void __set_CPSR(uint32_t cpsr) { - __ASM volatile("MCR p15, 0, %0, c1, c0, 0" : : "r"(sctlr) : "memory"); +__ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "memory"); } -/** \brief Get SCTLR - \return System Control Register value +/** \brief Get Mode + \return Processor Mode */ -__STATIC_INLINE uint32_t __get_SCTLR() { - uint32_t result; - __ASM volatile("MRC p15, 0, %0, c1, c0, 0" : "=r"(result)); - return result; +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_mode(void) +{ + return (__get_CPSR() & 0x1FU); } -/** \brief Set ACTRL - \param [in] actrl Auxiliary Control Register value to set +/** \brief Set Mode + \param [in] mode Mode value to set */ -__STATIC_INLINE void __set_ACTRL(uint32_t actrl) +__attribute__((always_inline)) __STATIC_INLINE void __set_mode(uint32_t mode) { - __ASM volatile("MCR p15, 0, %0, c1, c0, 1" : : "r"(actrl) : "memory"); + __ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory"); } -/** \brief Get ACTRL - \return Auxiliary Control Register value +/** \brief Get Stack Pointer + \return Stack Pointer value */ -__STATIC_INLINE uint32_t __get_ACTRL(void) +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_SP() { uint32_t result; - __ASM volatile("MRC p15, 0, %0, c1, c0, 1" : "=r"(result)); + __ASM volatile("MOV %0, sp" : "=r" (result) : : "memory"); return result; } -/** \brief Get MPIDR - - This function returns the value of the Multiprocessor Affinity Register. - - \return Multiprocessor Affinity Register value +/** \brief Set Stack Pointer + \param [in] stack Stack Pointer value to set */ -__STATIC_INLINE uint32_t __get_MPIDR(void) +__attribute__((always_inline)) __STATIC_INLINE void __set_SP(uint32_t stack) { - uint32_t result; - __ASM volatile("MRC p15, 0, %0, c0, c0, 5" : "=r"(result)); - return result; + __ASM volatile("MOV sp, %0" : : "r" (stack) : "memory"); } - /** \brief Get VBAR - - This function returns the value of the Vector Base Address Register. - - \return Vector Base Address Register +/** \brief Get USR/SYS Stack Pointer + \return USR/SYS Stack Pointer value */ -__STATIC_INLINE uint32_t __get_VBAR(void) +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_SP_usr() { + uint32_t cpsr; uint32_t result; - __ASM volatile("MRC p15, 0, %0, c12, c0, 0" : "=r"(result)); + __ASM volatile( + "MRS %0, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV %1, sp \n" + "MSR cpsr_c, %2 \n" // no effect in USR mode + "ISB" : "=r"(cpsr), "=r"(result) : "r"(cpsr) : "memory" + ); return result; } -/** \brief Set VBAR - - This function assigns the given value to the Vector Base Address Register. - - \param [in] vbar Vector Base Address Register value to set +/** \brief Set USR/SYS Stack Pointer + \param [in] topOfProcStack USR/SYS Stack Pointer value to set */ -__STATIC_INLINE void __set_VBAR(uint32_t vbar) +__attribute__((always_inline)) __STATIC_INLINE void __set_SP_usr(uint32_t topOfProcStack) { - __ASM volatile("MCR p15, 0, %0, c12, c0, 1" : : "r"(vbar) : "memory"); -} - -/** \brief Set CNTP_TVAL - - This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL). - - \param [in] value CNTP_TVAL Register value to set -*/ -__STATIC_INLINE void __set_CNTP_TVAL(uint32_t value) { - __ASM volatile("MCR p15, 0, %0, c14, c2, 0" : : "r"(value) : "memory"); + uint32_t cpsr; + __ASM volatile( + "MRS %0, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV sp, %1 \n" + "MSR cpsr_c, %2 \n" // no effect in USR mode + "ISB" : "=r"(cpsr) : "r" (topOfProcStack), "r"(cpsr) : "memory" + ); } -/** \brief Get CNTP_TVAL - - This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL). - - \return CNTP_TVAL Register value +/** \brief Get FPEXC + \return Floating Point Exception Control register value */ -__STATIC_INLINE uint32_t __get_CNTP_TVAL() { +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPEXC(void) +{ +#if (__FPU_PRESENT == 1) uint32_t result; - __ASM volatile("MRC p15, 0, %0, c14, c2, 0" : "=r"(result)); - return result; -} - -/** \brief Set CNTP_CTL - - This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL). - - \param [in] value CNTP_CTL Register value to set -*/ -__STATIC_INLINE void __set_CNTP_CTL(uint32_t value) { - __ASM volatile("MCR p15, 0, %0, c14, c2, 1" : : "r"(value) : "memory"); -} - -/** \brief Set TLBIALL - - TLB Invalidate All - */ -__STATIC_INLINE void __set_TLBIALL(uint32_t value) { - __ASM volatile("MCR p15, 0, %0, c8, c7, 0" : : "r"(value) : "memory"); -} - -/** \brief Set BPIALL. - - Branch Predictor Invalidate All - */ -__STATIC_INLINE void __set_BPIALL(uint32_t value) { - __ASM volatile("MCR p15, 0, %0, c7, c5, 6" : : "r"(value) : "memory"); + __ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory"); + return(result); +#else + return(0); +#endif } -/** \brief Set ICIALLU - - Instruction Cache Invalidate All +/** \brief Set FPEXC + \param [in] fpexc Floating Point Exception Control value to set */ -__STATIC_INLINE void __set_ICIALLU(uint32_t value) { - __ASM volatile("MCR p15, 0, %0, c7, c5, 0" : : "r"(value) : "memory"); +__attribute__((always_inline)) __STATIC_INLINE void __set_FPEXC(uint32_t fpexc) +{ +#if (__FPU_PRESENT == 1) + __ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory"); +#endif } -/** \brief Set DCCMVAC - - Data cache clean +/* + * Include common core functions to access Coprocessor 15 registers */ -__STATIC_INLINE void __set_DCCMVAC(uint32_t value) { - __ASM volatile("MCR p15, 0, %0, c7, c10, 1" : : "r"(value) : "memory"); -} - -/** \brief Set DCIMVAC - Data cache invalidate - */ -__STATIC_INLINE void __set_DCIMVAC(uint32_t value) { - __ASM volatile("MCR p15, 0, %0, c7, c6, 1" : : "r"(value) : "memory"); -} +#define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) +#define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) -/** \brief Set DCCIMVAC +#include "cmsis_cp15.h" - Data cache clean and invalidate - */ -__STATIC_INLINE void __set_DCCIMVAC(uint32_t value) { - __ASM volatile("MCR p15, 0, %0, c7, c14, 1" : : "r"(value) : "memory"); -} /** \brief Clean and Invalidate the entire data or unified cache Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency */ -__STATIC_INLINE void __L1C_CleanInvalidateCache(uint32_t op) { +__STATIC_INLINE void __L1C_CleanInvalidateCache(uint32_t op) +{ __ASM volatile( " PUSH {R4-R11} \n" @@ -577,26 +491,27 @@ __STATIC_INLINE void __L1C_CleanInvalidateCache(uint32_t op) { Critical section, called from undef handler, so systick is disabled */ -__STATIC_INLINE void __FPU_Enable(void) { +__STATIC_INLINE void __FPU_Enable(void) +{ __ASM volatile( - //Permit access to VFP/NEON, registers by modifying CPACR + //Permit access to VFP/NEON, registers by modifying CPACR " MRC p15,0,R1,c1,c0,2 \n" " ORR R1,R1,#0x00F00000 \n" " MCR p15,0,R1,c1,c0,2 \n" - //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted " ISB \n" - //Enable VFP/NEON + //Enable VFP/NEON " VMRS R1,FPEXC \n" " ORR R1,R1,#0x40000000 \n" " VMSR FPEXC,R1 \n" - //Initialise VFP/NEON registers to 0 + //Initialise VFP/NEON registers to 0 " MOV R2,#0 \n" -#if 0 // TODO: Initialize FPU registers according to available register count - ".if {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} >= 16 \n" - //Initialise D16 registers to 0 + +#if TARGET_FEATURE_EXTENSION_REGISTER_COUNT >= 16 + //Initialise D16 registers to 0 " VMOV D0, R2,R2 \n" " VMOV D1, R2,R2 \n" " VMOV D2, R2,R2 \n" @@ -613,10 +528,10 @@ __STATIC_INLINE void __FPU_Enable(void) { " VMOV D13,R2,R2 \n" " VMOV D14,R2,R2 \n" " VMOV D15,R2,R2 \n" - ".endif \n" +#endif - ".if {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 \n" - //Initialise D32 registers to 0 +#if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 32 + //Initialise D32 registers to 0 " VMOV D16,R2,R2 \n" " VMOV D17,R2,R2 \n" " VMOV D18,R2,R2 \n" @@ -635,7 +550,7 @@ __STATIC_INLINE void __FPU_Enable(void) { " VMOV D31,R2,R2 \n" ".endif \n" #endif - //Initialise FPSCR to a known state + //Initialise FPSCR to a known state " VMRS R2,FPSCR \n" " LDR R3,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. " AND R2,R2,R3 \n" @@ -643,4 +558,4 @@ __STATIC_INLINE void __FPU_Enable(void) { ); } -#endif /* __CMSIS_ARMCC_H */ +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/cmsis/TARGET_CORTEX_A/cmsis_compiler.h b/cmsis/TARGET_CORTEX_A/cmsis_compiler.h index 9fa0e0ea49d..ec27cfeac8e 100644 --- a/cmsis/TARGET_CORTEX_A/cmsis_compiler.h +++ b/cmsis/TARGET_CORTEX_A/cmsis_compiler.h @@ -52,41 +52,9 @@ * IAR Compiler */ #elif defined ( __ICCARM__ ) + #include "cmsis_iccarm.h" - #ifndef __ASM - #define __ASM __asm - #endif - #ifndef __INLINE - #define __INLINE inline - #endif - #ifndef __STATIC_INLINE - #define __STATIC_INLINE static inline - #endif - - #include - - #ifndef __NO_RETURN - #define __NO_RETURN __noreturn - #endif - #ifndef __USED - #define __USED __root - #endif - #ifndef __WEAK - #define __WEAK __weak - #endif - #ifndef __UNALIGNED_UINT32 - __packed struct T_UINT32 { uint32_t v; }; - #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) - #endif - #ifndef __ALIGNED - #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. - #define __ALIGNED(x) - #endif - #ifndef __PACKED - #define __PACKED __packed - #endif - - + /* * TI ARM Compiler */ diff --git a/cmsis/TARGET_CORTEX_A/cmsis_cp15.h b/cmsis/TARGET_CORTEX_A/cmsis_cp15.h new file mode 100644 index 00000000000..68b39f30921 --- /dev/null +++ b/cmsis/TARGET_CORTEX_A/cmsis_cp15.h @@ -0,0 +1,437 @@ +/**************************************************************************//** + * @file cmsis_cp15.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.0.1 + * @date 07. Sep 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 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 + * + * 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 __CMSIS_CP15_H +#define __CMSIS_CP15_H + +/** \brief Get ACTLR + \return Auxiliary Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_ACTLR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 0, %0, c1, c0, 1" : "=r" (result) : : "memory" ); + __get_CP(15, 0, result, 1, 0, 1); + return(result); +} + +/** \brief Set ACTLR + \param [in] actlr Auxiliary Control value to set + */ +__STATIC_FORCEINLINE void __set_ACTLR(uint32_t actlr) +{ + // __ASM volatile ("MCR p15, 0, %0, c1, c0, 1" : : "r" (actlr) : "memory"); + __set_CP(15, 0, actlr, 1, 0, 1); +} + +/** \brief Get CPACR + \return Coprocessor Access Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_CPACR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 0, %0, c1, c0, 2" : "=r"(result) : : "memory"); + __get_CP(15, 0, result, 1, 0, 2); + return result; +} + +/** \brief Set CPACR + \param [in] cpacr Coprocessor Access Control value to set + */ +__STATIC_FORCEINLINE void __set_CPACR(uint32_t cpacr) +{ +// __ASM volatile("MCR p15, 0, %0, c1, c0, 2" : : "r"(cpacr) : "memory"); + __set_CP(15, 0, cpacr, 1, 0, 2); +} + +/** \brief Get DFSR + \return Data Fault Status Register value + */ +__STATIC_FORCEINLINE uint32_t __get_DFSR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 0, %0, c5, c0, 0" : "=r"(result) : : "memory"); + __get_CP(15, 0, result, 5, 0, 0); + return result; +} + +/** \brief Set DFSR + \param [in] dfsr Data Fault Status value to set + */ +__STATIC_FORCEINLINE void __set_DFSR(uint32_t dfsr) +{ +// __ASM volatile("MCR p15, 0, %0, c5, c0, 0" : : "r"(dfsr) : "memory"); + __set_CP(15, 0, dfsr, 5, 0, 0); +} + +/** \brief Get IFSR + \return Instruction Fault Status Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IFSR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 0, %0, c5, c0, 1" : "=r"(result) : : "memory"); + __get_CP(15, 0, result, 5, 0, 1); + return result; +} + +/** \brief Set IFSR + \param [in] ifsr Instruction Fault Status value to set + */ +__STATIC_FORCEINLINE void __set_IFSR(uint32_t ifsr) +{ +// __ASM volatile("MCR p15, 0, %0, c5, c0, 1" : : "r"(ifsr) : "memory"); + __set_CP(15, 0, ifsr, 5, 0, 1); +} + +/** \brief Get ISR + \return Interrupt Status Register value + */ +__STATIC_FORCEINLINE uint32_t __get_ISR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 0, %0, c12, c1, 0" : "=r"(result) : : "memory"); + __get_CP(15, 0, result, 12, 1, 0); + return result; +} + +/** \brief Get CBAR + \return Configuration Base Address register value + */ +__STATIC_FORCEINLINE uint32_t __get_CBAR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 4, %0, c15, c0, 0" : "=r"(result) : : "memory"); + __get_CP(15, 4, result, 15, 0, 0); + return result; +} + +/** \brief Get TTBR0 + + This function returns the value of the Translation Table Base Register 0. + + \return Translation Table Base Register 0 value + */ +__STATIC_FORCEINLINE uint32_t __get_TTBR0(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 0, %0, c2, c0, 0" : "=r"(result) : : "memory"); + __get_CP(15, 0, result, 2, 0, 0); + return result; +} + +/** \brief Set TTBR0 + + This function assigns the given value to the Translation Table Base Register 0. + + \param [in] ttbr0 Translation Table Base Register 0 value to set + */ +__STATIC_FORCEINLINE void __set_TTBR0(uint32_t ttbr0) +{ +// __ASM volatile("MCR p15, 0, %0, c2, c0, 0" : : "r"(ttbr0) : "memory"); + __set_CP(15, 0, ttbr0, 2, 0, 0); +} + +/** \brief Get DACR + + This function returns the value of the Domain Access Control Register. + + \return Domain Access Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_DACR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 0, %0, c3, c0, 0" : "=r"(result) : : "memory"); + __get_CP(15, 0, result, 3, 0, 0); + return result; +} + +/** \brief Set DACR + + This function assigns the given value to the Domain Access Control Register. + + \param [in] dacr Domain Access Control Register value to set + */ +__STATIC_FORCEINLINE void __set_DACR(uint32_t dacr) +{ +// __ASM volatile("MCR p15, 0, %0, c3, c0, 0" : : "r"(dacr) : "memory"); + __set_CP(15, 0, dacr, 3, 0, 0); +} + +/** \brief Set SCTLR + + This function assigns the given value to the System Control Register. + + \param [in] sctlr System Control Register value to set + */ +__STATIC_FORCEINLINE void __set_SCTLR(uint32_t sctlr) +{ +// __ASM volatile("MCR p15, 0, %0, c1, c0, 0" : : "r"(sctlr) : "memory"); + __set_CP(15, 0, sctlr, 1, 0, 0); +} + +/** \brief Get SCTLR + \return System Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_SCTLR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 0, %0, c1, c0, 0" : "=r"(result) : : "memory"); + __get_CP(15, 0, result, 1, 0, 0); + return result; +} + +/** \brief Set ACTRL + \param [in] actrl Auxiliary Control Register value to set + */ +__STATIC_FORCEINLINE void __set_ACTRL(uint32_t actrl) +{ +// __ASM volatile("MCR p15, 0, %0, c1, c0, 1" : : "r"(actrl) : "memory"); + __set_CP(15, 0, actrl, 1, 0, 1); +} + +/** \brief Get ACTRL + \return Auxiliary Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_ACTRL(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 0, %0, c1, c0, 1" : "=r"(result) : : "memory"); + __get_CP(15, 0, result, 1, 0, 1); + return result; +} + +/** \brief Get MPIDR + + This function returns the value of the Multiprocessor Affinity Register. + + \return Multiprocessor Affinity Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MPIDR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 0, %0, c0, c0, 5" : "=r"(result) : : "memory"); + __get_CP(15, 0, result, 0, 0, 5); + return result; +} + + /** \brief Get VBAR + + This function returns the value of the Vector Base Address Register. + + \return Vector Base Address Register + */ +__STATIC_FORCEINLINE uint32_t __get_VBAR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 0, %0, c12, c0, 0" : "=r"(result) : : "memory"); + __get_CP(15, 0, result, 12, 0, 0); + return result; +} + +/** \brief Set VBAR + + This function assigns the given value to the Vector Base Address Register. + + \param [in] vbar Vector Base Address Register value to set + */ +__STATIC_FORCEINLINE void __set_VBAR(uint32_t vbar) +{ +// __ASM volatile("MCR p15, 0, %0, c12, c0, 1" : : "r"(vbar) : "memory"); + __set_CP(15, 0, vbar, 12, 0, 1); +} + +#if (defined(__CORTEX_A) && (__CORTEX_A == 7U) && \ + defined(__TIM_PRESENT) && (__TIM_PRESENT == 1U)) || \ + defined(DOXYGEN) + +/** \brief Set CNTFRQ + + This function assigns the given value to PL1 Physical Timer Counter Frequency Register (CNTFRQ). + + \param [in] value CNTFRQ Register value to set +*/ +__STATIC_FORCEINLINE void __set_CNTFRQ(uint32_t value) +{ + // __ASM volatile("MCR p15, 0, %0, c14, c0, 0" : : "r"(value) : "memory"); + __set_CP(15, 0, value, 14, 0, 0); +} + +/** \brief Get CNTFRQ + + This function returns the value of the PL1 Physical Timer Counter Frequency Register (CNTFRQ). + + \return CNTFRQ Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CNTFRQ(void) +{ + uint32_t result; + // __ASM volatile("MRC p15, 0, %0, c14, c0, 0" : "=r"(result) : : "memory"); + __get_CP(15, 0, result, 14, 0 , 0); + return result; +} + +/** \brief Set CNTP_TVAL + + This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL). + + \param [in] value CNTP_TVAL Register value to set +*/ +__STATIC_FORCEINLINE void __set_CNTP_TVAL(uint32_t value) +{ + // __ASM volatile("MCR p15, 0, %0, c14, c2, 0" : : "r"(value) : "memory"); + __set_CP(15, 0, value, 14, 2, 0); +} + +/** \brief Get CNTP_TVAL + + This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL). + + \return CNTP_TVAL Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CNTP_TVAL(void) +{ + uint32_t result; + // __ASM volatile("MRC p15, 0, %0, c14, c2, 0" : "=r"(result) : : "memory"); + __get_CP(15, 0, result, 14, 2, 0); + return result; +} + +/** \brief Set CNTP_CTL + + This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL). + + \param [in] value CNTP_CTL Register value to set +*/ +__STATIC_FORCEINLINE void __set_CNTP_CTL(uint32_t value) +{ + // __ASM volatile("MCR p15, 0, %0, c14, c2, 1" : : "r"(value) : "memory"); + __set_CP(15, 0, value, 14, 2, 1); +} + +/** \brief Get CNTP_CTL register + \return CNTP_CTL Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CNTP_CTL(void) +{ + uint32_t result; + // __ASM volatile("MRC p15, 0, %0, c14, c2, 1" : "=r"(result) : : "memory"); + __get_CP(15, 0, result, 14, 2, 1); + return result; +} + +#endif + +/** \brief Set TLBIALL + + TLB Invalidate All + */ +__STATIC_FORCEINLINE void __set_TLBIALL(uint32_t value) +{ +// __ASM volatile("MCR p15, 0, %0, c8, c7, 0" : : "r"(value) : "memory"); + __set_CP(15, 0, value, 8, 7, 0); +} + +/** \brief Set BPIALL. + + Branch Predictor Invalidate All + */ +__STATIC_FORCEINLINE void __set_BPIALL(uint32_t value) +{ +// __ASM volatile("MCR p15, 0, %0, c7, c5, 6" : : "r"(value) : "memory"); + __set_CP(15, 0, value, 7, 5, 6); +} + +/** \brief Set ICIALLU + + Instruction Cache Invalidate All + */ +__STATIC_FORCEINLINE void __set_ICIALLU(uint32_t value) +{ +// __ASM volatile("MCR p15, 0, %0, c7, c5, 0" : : "r"(value) : "memory"); + __set_CP(15, 0, value, 7, 5, 0); +} + +/** \brief Set DCCMVAC + + Data cache clean + */ +__STATIC_FORCEINLINE void __set_DCCMVAC(uint32_t value) +{ +// __ASM volatile("MCR p15, 0, %0, c7, c10, 1" : : "r"(value) : "memory"); + __set_CP(15, 0, value, 7, 10, 1); +} + +/** \brief Set DCIMVAC + + Data cache invalidate + */ +__STATIC_FORCEINLINE void __set_DCIMVAC(uint32_t value) +{ +// __ASM volatile("MCR p15, 0, %0, c7, c6, 1" : : "r"(value) : "memory"); + __set_CP(15, 0, value, 7, 6, 1); +} + +/** \brief Set DCCIMVAC + + Data cache clean and invalidate + */ +__STATIC_FORCEINLINE void __set_DCCIMVAC(uint32_t value) +{ +// __ASM volatile("MCR p15, 0, %0, c7, c14, 1" : : "r"(value) : "memory"); + __set_CP(15, 0, value, 7, 14, 1); +} + + +/** \brief Set CCSIDR + */ +__STATIC_FORCEINLINE void __set_CCSIDR(uint32_t value) +{ +// __ASM volatile("MCR p15, 2, %0, c0, c0, 0" : : "r"(value) : "memory"); + __set_CP(15, 2, value, 0, 0, 0); +} + +/** \brief Get CCSIDR + \return CCSIDR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CCSIDR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 1, %0, c0, c0, 0" : "=r"(result) : : "memory"); + __get_CP(15, 1, result, 0, 0, 0); + return result; +} + +/** \brief Get CLIDR + \return CLIDR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CLIDR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 1, %0, c0, c0, 1" : "=r"(result) : : "memory"); + __get_CP(15, 1, result, 0, 0, 1); + return result; +} + +#endif diff --git a/cmsis/TARGET_CORTEX_A/cmsis_gcc.h b/cmsis/TARGET_CORTEX_A/cmsis_gcc.h new file mode 100644 index 00000000000..45b6129456f --- /dev/null +++ b/cmsis/TARGET_CORTEX_A/cmsis_gcc.h @@ -0,0 +1,737 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.0.1 + * @date 07. Sep 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 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 + * + * 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 __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __FORCEINLINE + #define __FORCEINLINE __attribute__((always_inline)) +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif + +/* ########################## Core Instruction Access ######################### */ +/** + \brief No Operation + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + */ +#define __WFI() __ASM volatile ("wfi") + +/** + \brief Wait For Event + */ +#define __WFE() __ASM volatile ("wfe") + +/** + \brief Send Event + */ +#define __SEV() __ASM volatile ("sev") + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in integer value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + +/** + \brief Reverse byte order (16 bit) + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + __ASM volatile("rev16 %0, %1" : "=r" (result) : "r" (value)); + return result; +} +#endif + +/** + \brief Reverse byte order in signed short value + \details Reverses the byte order in a signed short value with sign extension to integer. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int32_t __REVSH(int32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (short)__builtin_bswap16(value); +#else + int32_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32U - op2)); +} + +/** + \brief Breakpoint + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return(result); +} + +/** + \brief Count leading zeros + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __builtin_clz + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +/* ########################### Core Function Access ########################### */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value +*/ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #if __has_builtin(__builtin_arm_get_fpscr) || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); + #else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); + #endif + #else + return(0U); + #endif +} + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set +*/ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #if __has_builtin(__builtin_arm_set_fpscr) || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); + #else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); + #endif + #else + (void)fpscr; + #endif +} + +/** \brief Get CPSR Register + \return CPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CPSR(void) +{ + uint32_t result; + __ASM volatile("MRS %0, cpsr" : "=r" (result) ); + return(result); +} + +/** \brief Set CPSR Register + \param [in] cpsr CPSR value to set + */ +__STATIC_FORCEINLINE void __set_CPSR(uint32_t cpsr) +{ +__ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "memory"); +} + +/** \brief Get Mode + \return Processor Mode + */ +__STATIC_FORCEINLINE uint32_t __get_mode(void) { + return (__get_CPSR() & 0x1FU); +} + +/** \brief Set Mode + \param [in] mode Mode value to set + */ +__STATIC_FORCEINLINE void __set_mode(uint32_t mode) { + __ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory"); +} + +/** \brief Get Stack Pointer + \return Stack Pointer value + */ +__STATIC_FORCEINLINE uint32_t __get_SP(void) +{ + uint32_t result; + __ASM volatile("MOV %0, sp" : "=r" (result) : : "memory"); + return result; +} + +/** \brief Set Stack Pointer + \param [in] stack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_SP(uint32_t stack) +{ + __ASM volatile("MOV sp, %0" : : "r" (stack) : "memory"); +} + +/** \brief Get USR/SYS Stack Pointer + \return USR/SYS Stack Pointer value + */ +__STATIC_FORCEINLINE uint32_t __get_SP_usr(void) +{ + uint32_t cpsr = __get_CPSR(); + uint32_t result; + __ASM volatile( + "CPS #0x1F \n" + "MOV %0, sp " : "=r"(result) : : "memory" + ); + __set_CPSR(cpsr); + __ISB(); + return result; +} + +/** \brief Set USR/SYS Stack Pointer + \param [in] topOfProcStack USR/SYS Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_SP_usr(uint32_t topOfProcStack) +{ + uint32_t cpsr = __get_CPSR(); + __ASM volatile( + "CPS #0x1F \n" + "MOV sp, %0 " : : "r" (topOfProcStack) : "memory" + ); + __set_CPSR(cpsr); + __ISB(); +} + +/** \brief Get FPEXC + \return Floating Point Exception Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPEXC(void) +{ +#if (__FPU_PRESENT == 1) + uint32_t result; + __ASM volatile("VMRS %0, fpexc" : "=r" (result) ); + return(result); +#else + return(0); +#endif +} + +/** \brief Set FPEXC + \param [in] fpexc Floating Point Exception Control value to set + */ +__STATIC_FORCEINLINE void __set_FPEXC(uint32_t fpexc) +{ +#if (__FPU_PRESENT == 1) + __ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory"); +#endif +} + +/* + * Include common core functions to access Coprocessor 15 registers + */ + +#define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) +#define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) + +#include "cmsis_cp15.h" + +__STATIC_FORCEINLINE int32_t log2_up(uint32_t n) +{ + int32_t log = -1; + uint32_t t = n; + while(t) + { + log++; t >>=1; + } + /* if n not power of 2 -> round up*/ + if ( n & (n - 1) ) log++; + return log; +} + +__STATIC_INLINE void __L1C_MaintainDCacheSetWay(uint32_t level, uint32_t maint) +{ + register volatile uint32_t Dummy; + register volatile uint32_t ccsidr; + uint32_t num_sets; + uint32_t num_ways; + uint32_t shift_way; + uint32_t log2_linesize; + uint32_t log2_num_ways; + + Dummy = level << 1; + /* set csselr, select ccsidr register */ + __set_CCSIDR(Dummy); + /* get current ccsidr register */ + ccsidr = __get_CCSIDR(); + num_sets = ((ccsidr & 0x0FFFE000) >> 13) + 1; + num_ways = ((ccsidr & 0x00001FF8) >> 3) + 1; + log2_linesize = (ccsidr & 0x00000007) + 2 + 2; + log2_num_ways = log2_up(num_ways); + shift_way = 32 - log2_num_ways; + for(int way = num_ways-1; way >= 0; way--) { + for(int set = num_sets-1; set >= 0; set--) { + Dummy = (level << 1) | (set << log2_linesize) | (way << shift_way); + switch (maint) + { + case 0: + __ASM volatile("MCR p15, 0, %0, c7, c6, 2" : : "r"(Dummy) : "memory"); // DCISW. Invalidate by Set/Way + break; + + case 1: + __ASM volatile("MCR p15, 0, %0, c7, c10, 2" : : "r"(Dummy) : "memory"); // DCCSW. Clean by Set/Way + break; + + default: + __ASM volatile("MCR p15, 0, %0, c7, c14, 2" : : "r"(Dummy) : "memory"); // DCCISW. Clean and Invalidate by Set/Way + break; + + } + } + } + __DMB(); +} + +/** \brief Clean and Invalidate the entire data or unified cache + + Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency + */ +__STATIC_INLINE void __L1C_CleanInvalidateCache(uint32_t op) { + register volatile uint32_t clidr; + uint32_t cache_type; + clidr = __get_CLIDR(); + for(uint32_t i = 0; i<7; i++) + { + cache_type = (clidr >> i*3) & 0x7UL; + if ((cache_type >= 2) && (cache_type <= 4)) + { + __L1C_MaintainDCacheSetWay(i, op); + } + } + +} + +/** \brief Enable Floating Point Unit + + Critical section, called from undef handler, so systick is disabled + */ +__STATIC_INLINE void __FPU_Enable(void) { + __ASM volatile( + //Permit access to VFP/NEON, registers by modifying CPACR + " MRC p15,0,R1,c1,c0,2 \n" + " ORR R1,R1,#0x00F00000 \n" + " MCR p15,0,R1,c1,c0,2 \n" + + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + " ISB \n" + + //Enable VFP/NEON + " VMRS R1,FPEXC \n" + " ORR R1,R1,#0x40000000 \n" + " VMSR FPEXC,R1 \n" + + //Initialise VFP/NEON registers to 0 + " MOV R2,#0 \n" + +#if TARGET_FEATURE_EXTENSION_REGISTER_COUNT >= 16 + //Initialise D16 registers to 0 + " VMOV D0, R2,R2 \n" + " VMOV D1, R2,R2 \n" + " VMOV D2, R2,R2 \n" + " VMOV D3, R2,R2 \n" + " VMOV D4, R2,R2 \n" + " VMOV D5, R2,R2 \n" + " VMOV D6, R2,R2 \n" + " VMOV D7, R2,R2 \n" + " VMOV D8, R2,R2 \n" + " VMOV D9, R2,R2 \n" + " VMOV D10,R2,R2 \n" + " VMOV D11,R2,R2 \n" + " VMOV D12,R2,R2 \n" + " VMOV D13,R2,R2 \n" + " VMOV D14,R2,R2 \n" + " VMOV D15,R2,R2 \n" +#endif + +#if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 32 + //Initialise D32 registers to 0 + " VMOV D16,R2,R2 \n" + " VMOV D17,R2,R2 \n" + " VMOV D18,R2,R2 \n" + " VMOV D19,R2,R2 \n" + " VMOV D20,R2,R2 \n" + " VMOV D21,R2,R2 \n" + " VMOV D22,R2,R2 \n" + " VMOV D23,R2,R2 \n" + " VMOV D24,R2,R2 \n" + " VMOV D25,R2,R2 \n" + " VMOV D26,R2,R2 \n" + " VMOV D27,R2,R2 \n" + " VMOV D28,R2,R2 \n" + " VMOV D29,R2,R2 \n" + " VMOV D30,R2,R2 \n" + " VMOV D31,R2,R2 \n" +#endif + //Initialise FPSCR to a known state + " VMRS R2,FPSCR \n" + " LDR R3,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. + " AND R2,R2,R3 \n" + " VMSR FPSCR,R2 " + ); +} + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/cmsis/TARGET_CORTEX_A/cmsis_iccarm.h b/cmsis/TARGET_CORTEX_A/cmsis_iccarm.h new file mode 100644 index 00000000000..18e6e6acfb0 --- /dev/null +++ b/cmsis/TARGET_CORTEX_A/cmsis_iccarm.h @@ -0,0 +1,591 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR compiler) header file + * @version V5.0.3 + * @date 29. August 2017 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017 IAR Systems +// +// 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 __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#pragma language=extended + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_7A__ +/* Macro already defined */ +#else + #if defined(__ARM7A__) + #define __ARM_ARCH_7A__ 1 + #endif +#endif + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #define __NO_RETURN _Pragma("object_attribute=__noreturn") +#endif + +#ifndef __PACKED + /* Needs IAR language extensions */ + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + /* Needs IAR language extensions */ + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + /* Needs IAR language extensions */ + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #define __RESTRICT restrict +#endif + + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE _Pragma("inline=forced") static inline +#endif +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __UNALIGNED_UINT16_READ + #pragma language=save + #pragma language=extended + __IAR_FT uint16_t __iar_uint16_read(void const *ptr) { + return *(__packed uint16_t*)(ptr); + } + #pragma language=restore + #define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE + #pragma language=save + #pragma language=extended + __IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) { + *(__packed uint16_t*)(ptr) = val;; + } + #pragma language=restore + #define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ + #pragma language=save + #pragma language=extended + __IAR_FT uint32_t __iar_uint32_read(void const *ptr) { + return *(__packed uint32_t*)(ptr); + } + #pragma language=restore + #define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE + #pragma language=save + #pragma language=extended + __IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) { + *(__packed uint32_t*)(ptr) = val;; + } + #pragma language=restore + #define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#if 0 +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma language=save + #pragma language=extended + __packed struct __iar_u32 { uint32_t v; }; + #pragma language=restore + #define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __enable_irq __iar_builtin_enable_interrupt + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + #if __FPU_PRESENT + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #else + #define __get_FPSCR() ( 0 ) + #endif + + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", VALUE)) + + #define __get_CPSR() (__arm_rsr("CPSR")) + #define __get_mode() (__get_CPSR() & 0x1FU) + + #define __set_CPSR(VALUE) (__arm_wsr("CPSR", (VALUE))) + #define __set_mode(VALUE) (__arm_wsr("CPSR_c", (VALUE))) + + + #define __get_FPEXC() (__arm_rsr("FPEXC")) + #define __set_FPEXC(VALUE) (__arm_wsr("FPEXC", VALUE)) + + #define __get_CP(cp, op1, RT, CRn, CRm, op2) \ + (RT = __arm_rsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2)) + + #define __set_CP(cp, op1, RT, CRn, CRm, op2) \ + (__arm_wsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2, RT)) + + #include "cmsis_cp15.h" + + #define __NOP __iar_builtin_no_operation + + __IAR_FT uint8_t __CLZ(uint32_t val) { + return __iar_builtin_CLZ(val); + } + + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int32_t __REVSH(int32_t val) { + return __iar_builtin_REVSH((int16_t)val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #define __SSAT __iar_builtin_SSAT + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #define __USAT __iar_builtin_USAT + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if !__FPU_PRESENT + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #endif + + #include + + #if !__FPU_PRESENT + #define __get_FPSCR() (0) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + __IAR_FT void __set_mode(uint32_t mode) + { + __ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory"); + } + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) { + return __STREX(value, (unsigned long *)ptr); + } + + + __IAR_FT uint32_t __RRX(uint32_t value) { + uint32_t result; + __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); + return(result); + } + + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + __IAR_FT uint32_t __get_FPEXC(void) + { + #if (__FPU_PRESENT == 1) + uint32_t result; + __ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory"); + return(result); + #else + return(0); + #endif + } + + __IAR_FT void __set_FPEXC(uint32_t fpexc) + { + #if (__FPU_PRESENT == 1) + __ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory"); + #endif + } + + + #define __get_CP(cp, op1, Rt, CRn, CRm, op2) \ + __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) + #define __set_CP(cp, op1, Rt, CRn, CRm, op2) \ + __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) + + #include "cmsis_cp15.h" + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + + +__IAR_FT uint32_t __get_SP_usr(void) +{ + uint32_t cpsr; + uint32_t result; + __ASM volatile( + "MRS %0, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV %1, sp \n" + "MSR cpsr_c, %2 \n" // no effect in USR mode + "ISB" : "=r"(cpsr), "=r"(result) : "r"(cpsr) : "memory" + ); + return result; +} + +__IAR_FT void __set_SP_usr(uint32_t topOfProcStack) +{ + uint32_t cpsr; + __ASM volatile( + "MRS %0, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV sp, %1 \n" + "MSR cpsr_c, %2 \n" // no effect in USR mode + "ISB" : "=r"(cpsr) : "r" (topOfProcStack), "r"(cpsr) : "memory" + ); +} + +#define __get_mode() (__get_CPSR() & 0x1FU) + + +__STATIC_INLINE +void __L1C_CleanInvalidateCache(uint32_t op) +{ + __ASM volatile( + " PUSH {R4-R11} \n" + + " MRC p15, 1, R6, c0, c0, 1 \n" // Read CLIDR + " ANDS R3, R6, #0x07000000 \n" // Extract coherency level + " MOV R3, R3, LSR #23 \n" // Total cache levels << 1 + " BEQ Finished \n" // If 0, no need to clean + + " MOV R10, #0 \n" // R10 holds current cache level << 1 + "Loop1: ADD R2, R10, R10, LSR #1 \n" // R2 holds cache "Set" position + " MOV R1, R6, LSR R2 \n" // Bottom 3 bits are the Cache-type for this level + " AND R1, R1, #7 \n" // Isolate those lower 3 bits + " CMP R1, #2 \n" + " BLT Skip \n" // No cache or only instruction cache at this level + + " MCR p15, 2, R10, c0, c0, 0 \n" // Write the Cache Size selection register + " ISB \n" // ISB to sync the change to the CacheSizeID reg + " MRC p15, 1, R1, c0, c0, 0 \n" // Reads current Cache Size ID register + " AND R2, R1, #7 \n" // Extract the line length field + " ADD R2, R2, #4 \n" // Add 4 for the line length offset (log2 16 bytes) + " MOVW R4, #0x3FF \n" + " ANDS R4, R4, R1, LSR #3 \n" // R4 is the max number on the way size (right aligned) + " CLZ R5, R4 \n" // R5 is the bit position of the way size increment + " MOVW R7, #0x7FFF \n" + " ANDS R7, R7, R1, LSR #13 \n" // R7 is the max number of the index size (right aligned) + + "Loop2: MOV R9, R4 \n" // R9 working copy of the max way size (right aligned) + + "Loop3: ORR R11, R10, R9, LSL R5 \n" // Factor in the Way number and cache number into R11 + " ORR R11, R11, R7, LSL R2 \n" // Factor in the Set number + " CMP R0, #0 \n" + " BNE Dccsw \n" + " MCR p15, 0, R11, c7, c6, 2 \n" // DCISW. Invalidate by Set/Way + " B cont \n" + "Dccsw: CMP R0, #1 \n" + " BNE Dccisw \n" + " MCR p15, 0, R11, c7, c10, 2 \n" // DCCSW. Clean by Set/Way + " B cont \n" + "Dccisw: MCR p15, 0, R11, c7, c14, 2 \n" // DCCISW. Clean and Invalidate by Set/Way + "cont: SUBS R9, R9, #1 \n" // Decrement the Way number + " BGE Loop3 \n" + " SUBS R7, R7, #1 \n" // Decrement the Set number + " BGE Loop2 \n" + "Skip: ADD R10, R10, #2 \n" // Increment the cache number + " CMP R3, R10 \n" + " BGT Loop1 \n" + + "Finished: \n" + " DSB \n" + " POP {R4-R11} " + ); +} + + +__STATIC_INLINE +void __FPU_Enable(void) +{ + __ASM volatile( + //Permit access to VFP/NEON, registers by modifying CPACR + " MRC p15,0,R1,c1,c0,2 \n" + " ORR R1,R1,#0x00F00000 \n" + " MCR p15,0,R1,c1,c0,2 \n" + + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + " ISB \n" + + //Enable VFP/NEON + " VMRS R1,FPEXC \n" + " ORR R1,R1,#0x40000000 \n" + " VMSR FPEXC,R1 \n" + + //Initialise VFP/NEON registers to 0 + " MOV R2,#0 \n" + +#if TARGET_FEATURE_EXTENSION_REGISTER_COUNT >= 16 + //Initialise D16 registers to 0 + " VMOV D0, R2,R2 \n" + " VMOV D1, R2,R2 \n" + " VMOV D2, R2,R2 \n" + " VMOV D3, R2,R2 \n" + " VMOV D4, R2,R2 \n" + " VMOV D5, R2,R2 \n" + " VMOV D6, R2,R2 \n" + " VMOV D7, R2,R2 \n" + " VMOV D8, R2,R2 \n" + " VMOV D9, R2,R2 \n" + " VMOV D10,R2,R2 \n" + " VMOV D11,R2,R2 \n" + " VMOV D12,R2,R2 \n" + " VMOV D13,R2,R2 \n" + " VMOV D14,R2,R2 \n" + " VMOV D15,R2,R2 \n" +#endif + +#if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 32 + //Initialise D32 registers to 0 + " VMOV D16,R2,R2 \n" + " VMOV D17,R2,R2 \n" + " VMOV D18,R2,R2 \n" + " VMOV D19,R2,R2 \n" + " VMOV D20,R2,R2 \n" + " VMOV D21,R2,R2 \n" + " VMOV D22,R2,R2 \n" + " VMOV D23,R2,R2 \n" + " VMOV D24,R2,R2 \n" + " VMOV D25,R2,R2 \n" + " VMOV D26,R2,R2 \n" + " VMOV D27,R2,R2 \n" + " VMOV D28,R2,R2 \n" + " VMOV D29,R2,R2 \n" + " VMOV D30,R2,R2 \n" + " VMOV D31,R2,R2 \n" + ".endif \n" +#endif + //Initialise FPSCR to a known state + " VMRS R2,FPSCR \n" + " MOV32 R3,#0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. + " AND R2,R2,R3 \n" + " VMSR FPSCR,R2 \n"); +} + + + +#undef __IAR_FT +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/cmsis/core_ca.h b/cmsis/TARGET_CORTEX_A/core_ca.h similarity index 58% rename from cmsis/core_ca.h rename to cmsis/TARGET_CORTEX_A/core_ca.h index 6d1e29f60ff..1792dc35db7 100644 --- a/cmsis/core_ca.h +++ b/cmsis/TARGET_CORTEX_A/core_ca.h @@ -39,10 +39,10 @@ ******************************************************************************/ /* CMSIS CA definitions */ -#define __CA_CMSIS_VERSION_MAIN (1U) /*!< \brief [31:16] CMSIS HAL main version */ -#define __CA_CMSIS_VERSION_SUB (0U) /*!< \brief [15:0] CMSIS HAL sub version */ +#define __CA_CMSIS_VERSION_MAIN (1U) /*!< \brief [31:16] CMSIS-Core(A) main version */ +#define __CA_CMSIS_VERSION_SUB (0U) /*!< \brief [15:0] CMSIS-Core(A) sub version */ #define __CA_CMSIS_VERSION ((__CA_CMSIS_VERSION_MAIN << 16U) | \ - __CA_CMSIS_VERSION_SUB ) /*!< \brief CMSIS HAL version number */ + __CA_CMSIS_VERSION_SUB ) /*!< \brief CMSIS-Core(A) version number */ #if defined ( __CC_ARM ) #if defined __TARGET_FPU_VFP @@ -56,6 +56,18 @@ #define __FPU_USED 0U #endif +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #if (__FPU_PRESENT == 1) @@ -133,12 +145,7 @@ #define __FPU_PRESENT 0U #warning "__FPU_PRESENT not defined in device header file; using default!" #endif - - #ifndef __MPU_PRESENT - #define __MPU_PRESENT 0U - #warning "__MPU_PRESENT not defined in device header file; using default!" - #endif - + #ifndef __GIC_PRESENT #define __GIC_PRESENT 1U #warning "__GIC_PRESENT not defined in device header file; using default!" @@ -168,7 +175,7 @@ #define __IM volatile const /*!< \brief Defines 'read only' structure member permissions */ #define __OM volatile /*!< \brief Defines 'write only' structure member permissions */ #define __IOM volatile /*!< \brief Defines 'read / write' structure member permissions */ - +#define RESERVED(N, T) T RESERVED##N; // placeholder struct members used for "reserved" areas /******************************************************************************* * Register Abstraction @@ -193,7 +200,7 @@ typedef union uint32_t E:1; /*!< \brief bit: 9 Endianness execution state bit */ uint32_t IT1:6; /*!< \brief bit: 10..15 If-Then execution state bits 2-7 */ uint32_t GE:4; /*!< \brief bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved0:4; /*!< \brief bit: 20..23 Reserved */ + RESERVED(0:4, uint32_t) uint32_t J:1; /*!< \brief bit: 24 Jazelle bit */ uint32_t IT0:2; /*!< \brief bit: 25..26 If-Then execution state bits 0-1 */ uint32_t Q:1; /*!< \brief bit: 27 Saturation condition flag */ @@ -205,6 +212,8 @@ typedef union uint32_t w; /*!< \brief Type used for word access */ } CPSR_Type; + + /* CPSR Register Definitions */ #define CPSR_N_Pos 31U /*!< \brief CPSR: N Position */ #define CPSR_N_Msk (1UL << CPSR_N_Pos) /*!< \brief CPSR: N Mask */ @@ -251,6 +260,16 @@ typedef union #define CPSR_M_Pos 0U /*!< \brief CPSR: M Position */ #define CPSR_M_Msk (0x1FUL << CPSR_M_Pos) /*!< \brief CPSR: M Mask */ +#define CPSR_M_USR 0x10U /*!< \brief CPSR: M User mode (PL0) */ +#define CPSR_M_FIQ 0x11U /*!< \brief CPSR: M Fast Interrupt mode (PL1) */ +#define CPSR_M_IRQ 0x12U /*!< \brief CPSR: M Interrupt mode (PL1) */ +#define CPSR_M_SVC 0x13U /*!< \brief CPSR: M Supervisor mode (PL1) */ +#define CPSR_M_MON 0x16U /*!< \brief CPSR: M Monitor mode (PL1) */ +#define CPSR_M_ABT 0x17U /*!< \brief CPSR: M Abort mode (PL1) */ +#define CPSR_M_HYP 0x1AU /*!< \brief CPSR: M Hypervisor mode (PL2) */ +#define CPSR_M_UND 0x1BU /*!< \brief CPSR: M Undefined mode (PL1) */ +#define CPSR_M_SYS 0x1FU /*!< \brief CPSR: M System mode (PL1) */ + /* CP15 Register SCTLR */ typedef union { @@ -259,32 +278,32 @@ typedef union uint32_t M:1; /*!< \brief bit: 0 MMU enable */ uint32_t A:1; /*!< \brief bit: 1 Alignment check enable */ uint32_t C:1; /*!< \brief bit: 2 Cache enable */ - uint32_t _reserved0:2; /*!< \brief bit: 3.. 4 Reserved */ + RESERVED(0:2, uint32_t) uint32_t CP15BEN:1; /*!< \brief bit: 5 CP15 barrier enable */ - uint32_t _reserved1:1; /*!< \brief bit: 6 Reserved */ + RESERVED(1:1, uint32_t) uint32_t B:1; /*!< \brief bit: 7 Endianness model */ - uint32_t _reserved2:2; /*!< \brief bit: 8.. 9 Reserved */ + RESERVED(2:2, uint32_t) uint32_t SW:1; /*!< \brief bit: 10 SWP and SWPB enable */ uint32_t Z:1; /*!< \brief bit: 11 Branch prediction enable */ uint32_t I:1; /*!< \brief bit: 12 Instruction cache enable */ uint32_t V:1; /*!< \brief bit: 13 Vectors bit */ uint32_t RR:1; /*!< \brief bit: 14 Round Robin select */ - uint32_t _reserved3:2; /*!< \brief bit:15..16 Reserved */ + RESERVED(3:2, uint32_t) uint32_t HA:1; /*!< \brief bit: 17 Hardware Access flag enable */ - uint32_t _reserved4:1; /*!< \brief bit: 18 Reserved */ + RESERVED(4:1, uint32_t) uint32_t WXN:1; /*!< \brief bit: 19 Write permission implies XN */ uint32_t UWXN:1; /*!< \brief bit: 20 Unprivileged write permission implies PL1 XN */ uint32_t FI:1; /*!< \brief bit: 21 Fast interrupts configuration enable */ uint32_t U:1; /*!< \brief bit: 22 Alignment model */ - uint32_t _reserved5:1; /*!< \brief bit: 23 Reserved */ + RESERVED(5:1, uint32_t) uint32_t VE:1; /*!< \brief bit: 24 Interrupt Vectors Enable */ uint32_t EE:1; /*!< \brief bit: 25 Exception Endianness */ - uint32_t _reserved6:1; /*!< \brief bit: 26 Reserved */ + RESERVED(6:1, uint32_t) uint32_t NMFI:1; /*!< \brief bit: 27 Non-maskable FIQ (NMFI) support */ uint32_t TRE:1; /*!< \brief bit: 28 TEX remap enable. */ uint32_t AFE:1; /*!< \brief bit: 29 Access flag enable */ uint32_t TE:1; /*!< \brief bit: 30 Thumb Exception enable */ - uint32_t _reserved7:1; /*!< \brief bit: 31 Reserved */ + RESERVED(7:1, uint32_t) } b; /*!< \brief Structure used for bit access */ uint32_t w; /*!< \brief Type used for word access */ } SCTLR_Type; @@ -352,15 +371,144 @@ typedef union #define SCTLR_M_Pos 0U /*!< \brief SCTLR: M Position */ #define SCTLR_M_Msk (1UL << SCTLR_M_Pos) /*!< \brief SCTLR: M Mask */ +/* CP15 Register ACTLR */ +typedef union +{ +#if __CORTEX_A == 5 || defined(DOXYGEN) + /** \brief Structure used for bit access on Cortex-A5 */ + struct + { + uint32_t FW:1; /*!< \brief bit: 0 Cache and TLB maintenance broadcast */ + RESERVED(0:5, uint32_t) + uint32_t SMP:1; /*!< \brief bit: 6 Enables coherent requests to the processor */ + uint32_t EXCL:1; /*!< \brief bit: 7 Exclusive L1/L2 cache control */ + RESERVED(1:2, uint32_t) + uint32_t DODMBS:1; /*!< \brief bit: 10 Disable optimized data memory barrier behavior */ + uint32_t DWBST:1; /*!< \brief bit: 11 AXI data write bursts to Normal memory */ + uint32_t RADIS:1; /*!< \brief bit: 12 L1 Data Cache read-allocate mode disable */ + uint32_t L1PCTL:2; /*!< \brief bit:13..14 L1 Data prefetch control */ + uint32_t BP:2; /*!< \brief bit:16..15 Branch prediction policy */ + uint32_t RSDIS:1; /*!< \brief bit: 17 Disable return stack operation */ + uint32_t BTDIS:1; /*!< \brief bit: 18 Disable indirect Branch Target Address Cache (BTAC) */ + RESERVED(3:9, uint32_t) + uint32_t DBDI:1; /*!< \brief bit: 28 Disable branch dual issue */ + RESERVED(7:3, uint32_t) + } b; +#endif +#if __CORTEX_A == 7 || defined(DOXYGEN) + /** \brief Structure used for bit access on Cortex-A7 */ + struct + { + RESERVED(0:6, uint32_t) + uint32_t SMP:1; /*!< \brief bit: 6 Enables coherent requests to the processor */ + RESERVED(1:3, uint32_t) + uint32_t DODMBS:1; /*!< \brief bit: 10 Disable optimized data memory barrier behavior */ + uint32_t L2RADIS:1; /*!< \brief bit: 11 L2 Data Cache read-allocate mode disable */ + uint32_t L1RADIS:1; /*!< \brief bit: 12 L1 Data Cache read-allocate mode disable */ + uint32_t L1PCTL:2; /*!< \brief bit:13..14 L1 Data prefetch control */ + uint32_t DDVM:1; /*!< \brief bit: 15 Disable Distributed Virtual Memory (DVM) transactions */ + RESERVED(3:12, uint32_t) + uint32_t DDI:1; /*!< \brief bit: 28 Disable dual issue */ + RESERVED(7:3, uint32_t) + } b; +#endif +#if __CORTEX_A == 9 || defined(DOXYGEN) + /** \brief Structure used for bit access on Cortex-A9 */ + struct + { + uint32_t FW:1; /*!< \brief bit: 0 Cache and TLB maintenance broadcast */ + RESERVED(0:1, uint32_t) + uint32_t L1PE:1; /*!< \brief bit: 2 Dside prefetch */ + uint32_t WFLZM:1; /*!< \brief bit: 3 Cache and TLB maintenance broadcast */ + RESERVED(1:2, uint32_t) + uint32_t SMP:1; /*!< \brief bit: 6 Enables coherent requests to the processor */ + uint32_t EXCL:1; /*!< \brief bit: 7 Exclusive L1/L2 cache control */ + uint32_t AOW:1; /*!< \brief bit: 8 Enable allocation in one cache way only */ + uint32_t PARITY:1; /*!< \brief bit: 9 Support for parity checking, if implemented */ + RESERVED(7:22, uint32_t) + } b; +#endif + uint32_t w; /*!< \brief Type used for word access */ +} ACTLR_Type; + +#define ACTLR_DDI_Pos 28U /*!< \brief ACTLR: DDI Position */ +#define ACTLR_DDI_Msk (1UL << ACTLR_DDI_Pos) /*!< \brief ACTLR: DDI Mask */ + +#define ACTLR_DBDI_Pos 28U /*!< \brief ACTLR: DBDI Position */ +#define ACTLR_DBDI_Msk (1UL << ACTLR_DBDI_Pos) /*!< \brief ACTLR: DBDI Mask */ + +#define ACTLR_BTDIS_Pos 18U /*!< \brief ACTLR: BTDIS Position */ +#define ACTLR_BTDIS_Msk (1UL << ACTLR_BTDIS_Pos) /*!< \brief ACTLR: BTDIS Mask */ + +#define ACTLR_RSDIS_Pos 17U /*!< \brief ACTLR: RSDIS Position */ +#define ACTLR_RSDIS_Msk (1UL << ACTLR_RSDIS_Pos) /*!< \brief ACTLR: RSDIS Mask */ + +#define ACTLR_BP_Pos 15U /*!< \brief ACTLR: BP Position */ +#define ACTLR_BP_Msk (3UL << ACTLR_BP_Pos) /*!< \brief ACTLR: BP Mask */ + +#define ACTLR_DDVM_Pos 15U /*!< \brief ACTLR: DDVM Position */ +#define ACTLR_DDVM_Msk (1UL << ACTLR_DDVM_Pos) /*!< \brief ACTLR: DDVM Mask */ + +#define ACTLR_L1PCTL_Pos 13U /*!< \brief ACTLR: L1PCTL Position */ +#define ACTLR_L1PCTL_Msk (3UL << ACTLR_L1PCTL_Pos) /*!< \brief ACTLR: L1PCTL Mask */ + +#define ACTLR_RADIS_Pos 12U /*!< \brief ACTLR: RADIS Position */ +#define ACTLR_RADIS_Msk (1UL << ACTLR_RADIS_Pos) /*!< \brief ACTLR: RADIS Mask */ + +#define ACTLR_L1RADIS_Pos 12U /*!< \brief ACTLR: L1RADIS Position */ +#define ACTLR_L1RADIS_Msk (1UL << ACTLR_L1RADIS_Pos) /*!< \brief ACTLR: L1RADIS Mask */ + +#define ACTLR_DWBST_Pos 11U /*!< \brief ACTLR: DWBST Position */ +#define ACTLR_DWBST_Msk (1UL << ACTLR_DWBST_Pos) /*!< \brief ACTLR: DWBST Mask */ + +#define ACTLR_L2RADIS_Pos 11U /*!< \brief ACTLR: L2RADIS Position */ +#define ACTLR_L2RADIS_Msk (1UL << ACTLR_L2RADIS_Pos) /*!< \brief ACTLR: L2RADIS Mask */ + +#define ACTLR_DODMBS_Pos 10U /*!< \brief ACTLR: DODMBS Position */ +#define ACTLR_DODMBS_Msk (1UL << ACTLR_DODMBS_Pos) /*!< \brief ACTLR: DODMBS Mask */ + +#define ACTLR_PARITY_Pos 9U /*!< \brief ACTLR: PARITY Position */ +#define ACTLR_PARITY_Msk (1UL << ACTLR_PARITY_Pos) /*!< \brief ACTLR: PARITY Mask */ + +#define ACTLR_AOW_Pos 8U /*!< \brief ACTLR: AOW Position */ +#define ACTLR_AOW_Msk (1UL << ACTLR_AOW_Pos) /*!< \brief ACTLR: AOW Mask */ + +#define ACTLR_EXCL_Pos 7U /*!< \brief ACTLR: EXCL Position */ +#define ACTLR_EXCL_Msk (1UL << ACTLR_EXCL_Pos) /*!< \brief ACTLR: EXCL Mask */ + +#define ACTLR_SMP_Pos 6U /*!< \brief ACTLR: SMP Position */ +#define ACTLR_SMP_Msk (1UL << ACTLR_SMP_Pos) /*!< \brief ACTLR: SMP Mask */ + +#define ACTLR_WFLZM_Pos 3U /*!< \brief ACTLR: WFLZM Position */ +#define ACTLR_WFLZM_Msk (1UL << ACTLR_WFLZM_Pos) /*!< \brief ACTLR: WFLZM Mask */ + +#define ACTLR_L1PE_Pos 2U /*!< \brief ACTLR: L1PE Position */ +#define ACTLR_L1PE_Msk (1UL << ACTLR_L1PE_Pos) /*!< \brief ACTLR: L1PE Mask */ + +#define ACTLR_FW_Pos 0U /*!< \brief ACTLR: FW Position */ +#define ACTLR_FW_Msk (1UL << ACTLR_FW_Pos) /*!< \brief ACTLR: FW Mask */ + /* CP15 Register CPACR */ typedef union { struct { - uint32_t _reserved0:20; /*!< \brief bit: 0..19 Reserved */ - uint32_t cp10:2; /*!< \brief bit:20..21 Access rights for coprocessor 10 */ - uint32_t cp11:2; /*!< \brief bit:22..23 Access rights for coprocessor 11 */ - uint32_t _reserved1:6; /*!< \brief bit:24..29 Reserved */ + uint32_t CP0:2; /*!< \brief bit: 0..1 Access rights for coprocessor 0 */ + uint32_t CP1:2; /*!< \brief bit: 2..3 Access rights for coprocessor 1 */ + uint32_t CP2:2; /*!< \brief bit: 4..5 Access rights for coprocessor 2 */ + uint32_t CP3:2; /*!< \brief bit: 6..7 Access rights for coprocessor 3 */ + uint32_t CP4:2; /*!< \brief bit: 8..9 Access rights for coprocessor 4 */ + uint32_t CP5:2; /*!< \brief bit:10..11 Access rights for coprocessor 5 */ + uint32_t CP6:2; /*!< \brief bit:12..13 Access rights for coprocessor 6 */ + uint32_t CP7:2; /*!< \brief bit:14..15 Access rights for coprocessor 7 */ + uint32_t CP8:2; /*!< \brief bit:16..17 Access rights for coprocessor 8 */ + uint32_t CP9:2; /*!< \brief bit:18..19 Access rights for coprocessor 9 */ + uint32_t CP10:2; /*!< \brief bit:20..21 Access rights for coprocessor 10 */ + uint32_t CP11:2; /*!< \brief bit:22..23 Access rights for coprocessor 11 */ + uint32_t CP12:2; /*!< \brief bit:24..25 Access rights for coprocessor 11 */ + uint32_t CP13:2; /*!< \brief bit:26..27 Access rights for coprocessor 11 */ + uint32_t TRCDIS:1; /*!< \brief bit: 28 Disable CP14 access to trace registers */ + RESERVED(0:1, uint32_t) uint32_t D32DIS:1; /*!< \brief bit: 30 Disable use of registers D16-D31 of the VFP register file */ uint32_t ASEDIS:1; /*!< \brief bit: 31 Disable Advanced SIMD Functionality */ } b; /*!< \brief Structure used for bit access */ @@ -373,11 +521,15 @@ typedef union #define CPACR_D32DIS_Pos 30U /*!< \brief CPACR: D32DIS Position */ #define CPACR_D32DIS_Msk (1UL << CPACR_D32DIS_Pos) /*!< \brief CPACR: D32DIS Mask */ -#define CPACR_cp11_Pos 22U /*!< \brief CPACR: cp11 Position */ -#define CPACR_cp11_Msk (3UL << CPACR_cp11_Pos) /*!< \brief CPACR: cp11 Mask */ +#define CPACR_TRCDIS_Pos 28U /*!< \brief CPACR: D32DIS Position */ +#define CPACR_TRCDIS_Msk (1UL << CPACR_D32DIS_Pos) /*!< \brief CPACR: D32DIS Mask */ -#define CPACR_cp10_Pos 20U /*!< \brief CPACR: cp10 Position */ -#define CPACR_cp10_Msk (3UL << CPACR_cp10_Pos) /*!< \brief CPACR: cp10 Mask */ +#define CPACR_CP_Pos_(n) (n*2U) /*!< \brief CPACR: CPn Position */ +#define CPACR_CP_Msk_(n) (3UL << CPACR_CP_Pos_(n)) /*!< \brief CPACR: CPn Mask */ + +#define CPACR_CP_NA 0U /*!< \brief CPACR CPn field: Access denied. */ +#define CPACR_CP_PL1 1U /*!< \brief CPACR CPn field: Accessible from PL1 only. */ +#define CPACR_CP_FA 3U /*!< \brief CPACR CPn field: Full access. */ /* CP15 Register DFSR */ typedef union @@ -386,13 +538,25 @@ typedef union { uint32_t FS0:4; /*!< \brief bit: 0.. 3 Fault Status bits bit 0-3 */ uint32_t Domain:4; /*!< \brief bit: 4.. 7 Fault on which domain */ - uint32_t _reserved0:2; /*!< \brief bit: 8.. 9 Reserved */ + RESERVED(0:1, uint32_t) + uint32_t LPAE:1; /*!< \brief bit: 9 Large Physical Address Extension */ uint32_t FS1:1; /*!< \brief bit: 10 Fault Status bits bit 4 */ uint32_t WnR:1; /*!< \brief bit: 11 Write not Read bit */ uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ uint32_t CM:1; /*!< \brief bit: 13 Cache maintenance fault */ - uint32_t _reserved1:18; /*!< \brief bit:14..31 Reserved */ - } b; /*!< \brief Structure used for bit access */ + RESERVED(1:18, uint32_t) + } s; /*!< \brief Structure used for bit access in short format */ + struct + { + uint32_t STATUS:5; /*!< \brief bit: 0.. 5 Fault Status bits */ + RESERVED(0:3, uint32_t) + uint32_t LPAE:1; /*!< \brief bit: 9 Large Physical Address Extension */ + RESERVED(1:1, uint32_t) + uint32_t WnR:1; /*!< \brief bit: 11 Write not Read bit */ + uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ + uint32_t CM:1; /*!< \brief bit: 13 Cache maintenance fault */ + RESERVED(2:18, uint32_t) + } l; /*!< \brief Structure used for bit access in long format */ uint32_t w; /*!< \brief Type used for word access */ } DFSR_Type; @@ -408,24 +572,40 @@ typedef union #define DFSR_FS1_Pos 10U /*!< \brief DFSR: FS1 Position */ #define DFSR_FS1_Msk (1UL << DFSR_FS1_Pos) /*!< \brief DFSR: FS1 Mask */ +#define DFSR_LPAE_Pos 9U /*!< \brief DFSR: LPAE Position */ +#define DFSR_LPAE_Msk (1UL << DFSR_LPAE_Pos) /*!< \brief DFSR: LPAE Mask */ + #define DFSR_Domain_Pos 4U /*!< \brief DFSR: Domain Position */ #define DFSR_Domain_Msk (0xFUL << DFSR_Domain_Pos) /*!< \brief DFSR: Domain Mask */ #define DFSR_FS0_Pos 0U /*!< \brief DFSR: FS0 Position */ #define DFSR_FS0_Msk (0xFUL << DFSR_FS0_Pos) /*!< \brief DFSR: FS0 Mask */ +#define DFSR_STATUS_Pos 0U /*!< \brief DFSR: STATUS Position */ +#define DFSR_STATUS_Msk (0x3FUL << DFSR_STATUS_Pos) /*!< \brief DFSR: STATUS Mask */ + /* CP15 Register IFSR */ typedef union { struct { uint32_t FS0:4; /*!< \brief bit: 0.. 3 Fault Status bits bit 0-3 */ - uint32_t _reserved0:6; /*!< \brief bit: 4.. 9 Reserved */ + RESERVED(0:5, uint32_t) + uint32_t LPAE:1; /*!< \brief bit: 9 Large Physical Address Extension */ uint32_t FS1:1; /*!< \brief bit: 10 Fault Status bits bit 4 */ - uint32_t _reserved1:1; /*!< \brief bit: 11 Reserved */ + RESERVED(1:1, uint32_t) uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ - uint32_t _reserved2:19; /*!< \brief bit:13..31 Reserved */ - } b; /*!< \brief Structure used for bit access */ + RESERVED(2:19, uint32_t) + } s; /*!< \brief Structure used for bit access in short format */ + struct + { + uint32_t STATUS:6; /*!< \brief bit: 0.. 5 Fault Status bits */ + RESERVED(0:3, uint32_t) + uint32_t LPAE:1; /*!< \brief bit: 9 Large Physical Address Extension */ + RESERVED(1:2, uint32_t) + uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ + RESERVED(2:19, uint32_t) + } l; /*!< \brief Structure used for bit access in long format */ uint32_t w; /*!< \brief Type used for word access */ } IFSR_Type; @@ -435,19 +615,25 @@ typedef union #define IFSR_FS1_Pos 10U /*!< \brief IFSR: FS1 Position */ #define IFSR_FS1_Msk (1UL << IFSR_FS1_Pos) /*!< \brief IFSR: FS1 Mask */ +#define IFSR_LPAE_Pos 9U /*!< \brief IFSR: LPAE Position */ +#define IFSR_LPAE_Msk (0x1UL << IFSR_LPAE_Pos) /*!< \brief IFSR: LPAE Mask */ + #define IFSR_FS0_Pos 0U /*!< \brief IFSR: FS0 Position */ #define IFSR_FS0_Msk (0xFUL << IFSR_FS0_Pos) /*!< \brief IFSR: FS0 Mask */ +#define IFSR_STATUS_Pos 0U /*!< \brief IFSR: STATUS Position */ +#define IFSR_STATUS_Msk (0x3FUL << IFSR_STATUS_Pos) /*!< \brief IFSR: STATUS Mask */ + /* CP15 Register ISR */ typedef union { struct { - uint32_t _reserved0:6; /*!< \brief bit: 0.. 5 Reserved */ + RESERVED(0:6, uint32_t) uint32_t F:1; /*!< \brief bit: 6 FIQ pending bit */ uint32_t I:1; /*!< \brief bit: 7 IRQ pending bit */ uint32_t A:1; /*!< \brief bit: 8 External abort pending bit */ - uint32_t _reserved1:23; /*!< \brief bit:14..31 Reserved */ + RESERVED(1:23, uint32_t) } b; /*!< \brief Structure used for bit access */ uint32_t w; /*!< \brief Type used for word access */ } ISR_Type; @@ -461,136 +647,188 @@ typedef union #define ISR_F_Pos 11U /*!< \brief ISR: F Position */ #define ISR_F_Msk (1UL << ISR_F_Pos) /*!< \brief ISR: F Mask */ +/* DACR Register */ +#define DACR_D_Pos_(n) (2U*n) /*!< \brief DACR: Dn Position */ +#define DACR_D_Msk_(n) (3UL << DACR_D_Pos_(n)) /*!< \brief DACR: Dn Mask */ +#define DACR_Dn_NOACCESS 0U /*!< \brief DACR Dn field: No access */ +#define DACR_Dn_CLIENT 1U /*!< \brief DACR Dn field: Client */ +#define DACR_Dn_MANAGER 3U /*!< \brief DACR Dn field: Manager */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param [in] field Name of the register bit field. + \param [in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param [in] field Name of the register bit field. + \param [in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + /** \brief Union type to access the L2C_310 Cache Controller. */ -#if (__L2C_PRESENT == 1U) +#if (__L2C_PRESENT == 1U) || defined(DOXYGEN) typedef struct { - __I uint32_t CACHE_ID; /*!< \brief Offset: 0x0000 Cache ID Register */ - __I uint32_t CACHE_TYPE; /*!< \brief Offset: 0x0004 Cache Type Register */ - uint32_t RESERVED0[0x3e]; - __IO uint32_t CONTROL; /*!< \brief Offset: 0x0100 Control Register */ - __IO uint32_t AUX_CNT; /*!< \brief Offset: 0x0104 Auxiliary Control */ - uint32_t RESERVED1[0x3e]; - __IO uint32_t EVENT_CONTROL; /*!< \brief Offset: 0x0200 Event Counter Control */ - __IO uint32_t EVENT_COUNTER1_CONF; /*!< \brief Offset: 0x0204 Event Counter 1 Configuration */ - __IO uint32_t EVENT_COUNTER0_CONF; /*!< \brief Offset: 0x0208 Event Counter 1 Configuration */ - uint32_t RESERVED2[0x2]; - __IO uint32_t INTERRUPT_MASK; /*!< \brief Offset: 0x0214 Interrupt Mask */ - __I uint32_t MASKED_INT_STATUS; /*!< \brief Offset: 0x0218 Masked Interrupt Status */ - __I uint32_t RAW_INT_STATUS; /*!< \brief Offset: 0x021c Raw Interrupt Status */ - __O uint32_t INTERRUPT_CLEAR; /*!< \brief Offset: 0x0220 Interrupt Clear */ - uint32_t RESERVED3[0x143]; - __IO uint32_t CACHE_SYNC; /*!< \brief Offset: 0x0730 Cache Sync */ - uint32_t RESERVED4[0xf]; - __IO uint32_t INV_LINE_PA; /*!< \brief Offset: 0x0770 Invalidate Line By PA */ - uint32_t RESERVED6[2]; - __IO uint32_t INV_WAY; /*!< \brief Offset: 0x077c Invalidate by Way */ - uint32_t RESERVED5[0xc]; - __IO uint32_t CLEAN_LINE_PA; /*!< \brief Offset: 0x07b0 Clean Line by PA */ - uint32_t RESERVED7[1]; - __IO uint32_t CLEAN_LINE_INDEX_WAY; /*!< \brief Offset: 0x07b8 Clean Line by Index/Way */ - __IO uint32_t CLEAN_WAY; /*!< \brief Offset: 0x07bc Clean by Way */ - uint32_t RESERVED8[0xc]; - __IO uint32_t CLEAN_INV_LINE_PA; /*!< \brief Offset: 0x07f0 Clean and Invalidate Line by PA */ - uint32_t RESERVED9[1]; - __IO uint32_t CLEAN_INV_LINE_INDEX_WAY; /*!< \brief Offset: 0x07f8 Clean and Invalidate Line by Index/Way */ - __IO uint32_t CLEAN_INV_WAY; /*!< \brief Offset: 0x07fc Clean and Invalidate by Way */ - uint32_t RESERVED10[0x40]; - __IO uint32_t DATA_LOCK_0_WAY; /*!< \brief Offset: 0x0900 Data Lockdown 0 by Way */ - __IO uint32_t INST_LOCK_0_WAY; /*!< \brief Offset: 0x0904 Instruction Lockdown 0 by Way */ - __IO uint32_t DATA_LOCK_1_WAY; /*!< \brief Offset: 0x0908 Data Lockdown 1 by Way */ - __IO uint32_t INST_LOCK_1_WAY; /*!< \brief Offset: 0x090c Instruction Lockdown 1 by Way */ - __IO uint32_t DATA_LOCK_2_WAY; /*!< \brief Offset: 0x0910 Data Lockdown 2 by Way */ - __IO uint32_t INST_LOCK_2_WAY; /*!< \brief Offset: 0x0914 Instruction Lockdown 2 by Way */ - __IO uint32_t DATA_LOCK_3_WAY; /*!< \brief Offset: 0x0918 Data Lockdown 3 by Way */ - __IO uint32_t INST_LOCK_3_WAY; /*!< \brief Offset: 0x091c Instruction Lockdown 3 by Way */ - __IO uint32_t DATA_LOCK_4_WAY; /*!< \brief Offset: 0x0920 Data Lockdown 4 by Way */ - __IO uint32_t INST_LOCK_4_WAY; /*!< \brief Offset: 0x0924 Instruction Lockdown 4 by Way */ - __IO uint32_t DATA_LOCK_5_WAY; /*!< \brief Offset: 0x0928 Data Lockdown 5 by Way */ - __IO uint32_t INST_LOCK_5_WAY; /*!< \brief Offset: 0x092c Instruction Lockdown 5 by Way */ - __IO uint32_t DATA_LOCK_6_WAY; /*!< \brief Offset: 0x0930 Data Lockdown 5 by Way */ - __IO uint32_t INST_LOCK_6_WAY; /*!< \brief Offset: 0x0934 Instruction Lockdown 5 by Way */ - __IO uint32_t DATA_LOCK_7_WAY; /*!< \brief Offset: 0x0938 Data Lockdown 6 by Way */ - __IO uint32_t INST_LOCK_7_WAY; /*!< \brief Offset: 0x093c Instruction Lockdown 6 by Way */ - uint32_t RESERVED11[0x4]; - __IO uint32_t LOCK_LINE_EN; /*!< \brief Offset: 0x0950 Lockdown by Line Enable */ - __IO uint32_t UNLOCK_ALL_BY_WAY; /*!< \brief Offset: 0x0954 Unlock All Lines by Way */ - uint32_t RESERVED12[0xaa]; - __IO uint32_t ADDRESS_FILTER_START; /*!< \brief Offset: 0x0c00 Address Filtering Start */ - __IO uint32_t ADDRESS_FILTER_END; /*!< \brief Offset: 0x0c04 Address Filtering End */ - uint32_t RESERVED13[0xce]; - __IO uint32_t DEBUG_CONTROL; /*!< \brief Offset: 0x0f40 Debug Control Register */ + __IM uint32_t CACHE_ID; /*!< \brief Offset: 0x0000 (R/ ) Cache ID Register */ + __IM uint32_t CACHE_TYPE; /*!< \brief Offset: 0x0004 (R/ ) Cache Type Register */ + RESERVED(0[0x3e], uint32_t) + __IOM uint32_t CONTROL; /*!< \brief Offset: 0x0100 (R/W) Control Register */ + __IOM uint32_t AUX_CNT; /*!< \brief Offset: 0x0104 (R/W) Auxiliary Control */ + RESERVED(1[0x3e], uint32_t) + __IOM uint32_t EVENT_CONTROL; /*!< \brief Offset: 0x0200 (R/W) Event Counter Control */ + __IOM uint32_t EVENT_COUNTER1_CONF; /*!< \brief Offset: 0x0204 (R/W) Event Counter 1 Configuration */ + __IOM uint32_t EVENT_COUNTER0_CONF; /*!< \brief Offset: 0x0208 (R/W) Event Counter 1 Configuration */ + RESERVED(2[0x2], uint32_t) + __IOM uint32_t INTERRUPT_MASK; /*!< \brief Offset: 0x0214 (R/W) Interrupt Mask */ + __IM uint32_t MASKED_INT_STATUS; /*!< \brief Offset: 0x0218 (R/ ) Masked Interrupt Status */ + __IM uint32_t RAW_INT_STATUS; /*!< \brief Offset: 0x021c (R/ ) Raw Interrupt Status */ + __OM uint32_t INTERRUPT_CLEAR; /*!< \brief Offset: 0x0220 ( /W) Interrupt Clear */ + RESERVED(3[0x143], uint32_t) + __IOM uint32_t CACHE_SYNC; /*!< \brief Offset: 0x0730 (R/W) Cache Sync */ + RESERVED(4[0xf], uint32_t) + __IOM uint32_t INV_LINE_PA; /*!< \brief Offset: 0x0770 (R/W) Invalidate Line By PA */ + RESERVED(6[2], uint32_t) + __IOM uint32_t INV_WAY; /*!< \brief Offset: 0x077c (R/W) Invalidate by Way */ + RESERVED(5[0xc], uint32_t) + __IOM uint32_t CLEAN_LINE_PA; /*!< \brief Offset: 0x07b0 (R/W) Clean Line by PA */ + RESERVED(7[1], uint32_t) + __IOM uint32_t CLEAN_LINE_INDEX_WAY; /*!< \brief Offset: 0x07b8 (R/W) Clean Line by Index/Way */ + __IOM uint32_t CLEAN_WAY; /*!< \brief Offset: 0x07bc (R/W) Clean by Way */ + RESERVED(8[0xc], uint32_t) + __IOM uint32_t CLEAN_INV_LINE_PA; /*!< \brief Offset: 0x07f0 (R/W) Clean and Invalidate Line by PA */ + RESERVED(9[1], uint32_t) + __IOM uint32_t CLEAN_INV_LINE_INDEX_WAY; /*!< \brief Offset: 0x07f8 (R/W) Clean and Invalidate Line by Index/Way */ + __IOM uint32_t CLEAN_INV_WAY; /*!< \brief Offset: 0x07fc (R/W) Clean and Invalidate by Way */ + RESERVED(10[0x40], uint32_t) + __IOM uint32_t DATA_LOCK_0_WAY; /*!< \brief Offset: 0x0900 (R/W) Data Lockdown 0 by Way */ + __IOM uint32_t INST_LOCK_0_WAY; /*!< \brief Offset: 0x0904 (R/W) Instruction Lockdown 0 by Way */ + __IOM uint32_t DATA_LOCK_1_WAY; /*!< \brief Offset: 0x0908 (R/W) Data Lockdown 1 by Way */ + __IOM uint32_t INST_LOCK_1_WAY; /*!< \brief Offset: 0x090c (R/W) Instruction Lockdown 1 by Way */ + __IOM uint32_t DATA_LOCK_2_WAY; /*!< \brief Offset: 0x0910 (R/W) Data Lockdown 2 by Way */ + __IOM uint32_t INST_LOCK_2_WAY; /*!< \brief Offset: 0x0914 (R/W) Instruction Lockdown 2 by Way */ + __IOM uint32_t DATA_LOCK_3_WAY; /*!< \brief Offset: 0x0918 (R/W) Data Lockdown 3 by Way */ + __IOM uint32_t INST_LOCK_3_WAY; /*!< \brief Offset: 0x091c (R/W) Instruction Lockdown 3 by Way */ + __IOM uint32_t DATA_LOCK_4_WAY; /*!< \brief Offset: 0x0920 (R/W) Data Lockdown 4 by Way */ + __IOM uint32_t INST_LOCK_4_WAY; /*!< \brief Offset: 0x0924 (R/W) Instruction Lockdown 4 by Way */ + __IOM uint32_t DATA_LOCK_5_WAY; /*!< \brief Offset: 0x0928 (R/W) Data Lockdown 5 by Way */ + __IOM uint32_t INST_LOCK_5_WAY; /*!< \brief Offset: 0x092c (R/W) Instruction Lockdown 5 by Way */ + __IOM uint32_t DATA_LOCK_6_WAY; /*!< \brief Offset: 0x0930 (R/W) Data Lockdown 5 by Way */ + __IOM uint32_t INST_LOCK_6_WAY; /*!< \brief Offset: 0x0934 (R/W) Instruction Lockdown 5 by Way */ + __IOM uint32_t DATA_LOCK_7_WAY; /*!< \brief Offset: 0x0938 (R/W) Data Lockdown 6 by Way */ + __IOM uint32_t INST_LOCK_7_WAY; /*!< \brief Offset: 0x093c (R/W) Instruction Lockdown 6 by Way */ + RESERVED(11[0x4], uint32_t) + __IOM uint32_t LOCK_LINE_EN; /*!< \brief Offset: 0x0950 (R/W) Lockdown by Line Enable */ + __IOM uint32_t UNLOCK_ALL_BY_WAY; /*!< \brief Offset: 0x0954 (R/W) Unlock All Lines by Way */ + RESERVED(12[0xaa], uint32_t) + __IOM uint32_t ADDRESS_FILTER_START; /*!< \brief Offset: 0x0c00 (R/W) Address Filtering Start */ + __IOM uint32_t ADDRESS_FILTER_END; /*!< \brief Offset: 0x0c04 (R/W) Address Filtering End */ + RESERVED(13[0xce], uint32_t) + __IOM uint32_t DEBUG_CONTROL; /*!< \brief Offset: 0x0f40 (R/W) Debug Control Register */ } L2C_310_TypeDef; -#define L2C_310 ((L2C_310_TypeDef *)L2C_310_BASE) /*!< \brief L2C_310 Declaration */ +#define L2C_310 ((L2C_310_TypeDef *)L2C_310_BASE) /*!< \brief L2C_310 register set access pointer */ #endif -#if (__GIC_PRESENT == 1U) +#if (__GIC_PRESENT == 1U) || defined(DOXYGEN) + /** \brief Structure type to access the Generic Interrupt Controller Distributor (GICD) */ typedef struct { - __IO uint32_t ICDDCR; - __I uint32_t ICDICTR; - __I uint32_t ICDIIDR; - uint32_t RESERVED0[29]; - __IO uint32_t ICDISR[32]; - __IO uint32_t ICDISER[32]; - __IO uint32_t ICDICER[32]; - __IO uint32_t ICDISPR[32]; - __IO uint32_t ICDICPR[32]; - __I uint32_t ICDABR[32]; - uint32_t RESERVED1[32]; - __IO uint32_t ICDIPR[256]; - __IO uint32_t ICDIPTR[256]; - __IO uint32_t ICDICFR[64]; - uint32_t RESERVED2[128]; - __IO uint32_t ICDSGIR; + __IOM uint32_t CTLR; /*!< \brief Offset: 0x000 (R/W) Distributor Control Register */ + __IM uint32_t TYPER; /*!< \brief Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IM uint32_t IIDR; /*!< \brief Offset: 0x008 (R/ ) Distributor Implementer Identification Register */ + RESERVED(0, uint32_t) + __IOM uint32_t STATUSR; /*!< \brief Offset: 0x010 (R/W) Error Reporting Status Register, optional */ + RESERVED(1[11], uint32_t) + __OM uint32_t SETSPI_NSR; /*!< \brief Offset: 0x040 ( /W) Set SPI Register */ + RESERVED(2, uint32_t) + __OM uint32_t CLRSPI_NSR; /*!< \brief Offset: 0x048 ( /W) Clear SPI Register */ + RESERVED(3, uint32_t) + __OM uint32_t SETSPI_SR; /*!< \brief Offset: 0x050 ( /W) Set SPI, Secure Register */ + RESERVED(4, uint32_t) + __OM uint32_t CLRSPI_SR; /*!< \brief Offset: 0x058 ( /W) Clear SPI, Secure Register */ + RESERVED(5[9], uint32_t) + __IOM uint32_t IGROUPR[32]; /*!< \brief Offset: 0x080 (R/W) Interrupt Group Registers */ + __IOM uint32_t ISENABLER[32]; /*!< \brief Offset: 0x100 (R/W) Interrupt Set-Enable Registers */ + __IOM uint32_t ICENABLER[32]; /*!< \brief Offset: 0x180 (R/W) Interrupt Clear-Enable Registers */ + __IOM uint32_t ISPENDR[32]; /*!< \brief Offset: 0x200 (R/W) Interrupt Set-Pending Registers */ + __IOM uint32_t ICPENDR[32]; /*!< \brief Offset: 0x280 (R/W) Interrupt Clear-Pending Registers */ + __IOM uint32_t ISACTIVER[32]; /*!< \brief Offset: 0x300 (R/W) Interrupt Set-Active Registers */ + __IOM uint32_t ICACTIVER[32]; /*!< \brief Offset: 0x380 (R/W) Interrupt Clear-Active Registers */ + __IOM uint32_t IPRIORITYR[255]; /*!< \brief Offset: 0x400 (R/W) Interrupt Priority Registers */ + RESERVED(6, uint32_t) + __IOM uint32_t ITARGETSR[255]; /*!< \brief Offset: 0x800 (R/W) Interrupt Targets Registers */ + RESERVED(7, uint32_t) + __IOM uint32_t ICFGR[64]; /*!< \brief Offset: 0xC00 (R/W) Interrupt Configuration Registers */ + __IOM uint32_t IGRPMODR[32]; /*!< \brief Offset: 0xD00 (R/W) Interrupt Group Modifier Registers */ + RESERVED(8[32], uint32_t) + __IOM uint32_t NSACR[64]; /*!< \brief Offset: 0xE00 (R/W) Non-secure Access Control Registers */ + __OM uint32_t SGIR; /*!< \brief Offset: 0xF00 ( /W) Software Generated Interrupt Register */ + RESERVED(9[3], uint32_t) + __IOM uint32_t CPENDSGIR[4]; /*!< \brief Offset: 0xF10 (R/W) SGI Clear-Pending Registers */ + __IOM uint32_t SPENDSGIR[4]; /*!< \brief Offset: 0xF20 (R/W) SGI Set-Pending Registers */ + RESERVED(10[5236], uint32_t) + __IOM uint64_t IROUTER[988]; /*!< \brief Offset: 0x6100(R/W) Interrupt Routing Registers */ } GICDistributor_Type; -#define GICDistributor ((GICDistributor_Type *) GIC_DISTRIBUTOR_BASE ) /*!< GIC Distributor configuration struct */ +#define GICDistributor ((GICDistributor_Type *) GIC_DISTRIBUTOR_BASE ) /*!< \brief GIC Distributor register set access pointer */ /** \brief Structure type to access the Generic Interrupt Controller Interface (GICC) */ typedef struct { - __IO uint32_t ICCICR; //!< \brief +0x000 - RW - CPU Interface Control Register - __IO uint32_t ICCPMR; //!< \brief +0x004 - RW - Interrupt Priority Mask Register - __IO uint32_t ICCBPR; //!< \brief +0x008 - RW - Binary Point Register - __I uint32_t ICCIAR; //!< \brief +0x00C - RO - Interrupt Acknowledge Register - __IO uint32_t ICCEOIR; //!< \brief +0x010 - WO - End of Interrupt Register - __I uint32_t ICCRPR; //!< \brief +0x014 - RO - Running Priority Register - __I uint32_t ICCHPIR; //!< \brief +0x018 - RO - Highest Pending Interrupt Register - __IO uint32_t ICCABPR; //!< \brief +0x01C - RW - Aliased Binary Point Register - uint32_t RESERVED[55]; - __I uint32_t ICCIIDR; //!< \brief +0x0FC - RO - CPU Interface Identification Register + __IOM uint32_t CTLR; /*!< \brief Offset: 0x000 (R/W) CPU Interface Control Register */ + __IOM uint32_t PMR; /*!< \brief Offset: 0x004 (R/W) Interrupt Priority Mask Register */ + __IOM uint32_t BPR; /*!< \brief Offset: 0x008 (R/W) Binary Point Register */ + __IM uint32_t IAR; /*!< \brief Offset: 0x00C (R/ ) Interrupt Acknowledge Register */ + __OM uint32_t EOIR; /*!< \brief Offset: 0x010 ( /W) End Of Interrupt Register */ + __IM uint32_t RPR; /*!< \brief Offset: 0x014 (R/ ) Running Priority Register */ + __IM uint32_t HPPIR; /*!< \brief Offset: 0x018 (R/ ) Highest Priority Pending Interrupt Register */ + __IOM uint32_t ABPR; /*!< \brief Offset: 0x01C (R/W) Aliased Binary Point Register */ + __IM uint32_t AIAR; /*!< \brief Offset: 0x020 (R/ ) Aliased Interrupt Acknowledge Register */ + __OM uint32_t AEOIR; /*!< \brief Offset: 0x024 ( /W) Aliased End Of Interrupt Register */ + __IM uint32_t AHPPIR; /*!< \brief Offset: 0x028 (R/ ) Aliased Highest Priority Pending Interrupt Register */ + __IOM uint32_t STATUSR; /*!< \brief Offset: 0x02C (R/W) Error Reporting Status Register, optional */ + RESERVED(1[40], uint32_t) + __IOM uint32_t APR[4]; /*!< \brief Offset: 0x0D0 (R/W) Active Priority Register */ + __IOM uint32_t NSAPR[4]; /*!< \brief Offset: 0x0E0 (R/W) Non-secure Active Priority Register */ + RESERVED(2[3], uint32_t) + __IM uint32_t IIDR; /*!< \brief Offset: 0x0FC (R/ ) CPU Interface Identification Register */ + RESERVED(3[960], uint32_t) + __OM uint32_t DIR; /*!< \brief Offset: 0x1000( /W) Deactivate Interrupt Register */ } GICInterface_Type; -#define GICInterface ((GICInterface_Type *) GIC_INTERFACE_BASE ) /*!< GIC Interface configuration struct */ +#define GICInterface ((GICInterface_Type *) GIC_INTERFACE_BASE ) /*!< \brief GIC Interface register set access pointer */ #endif -#if (__TIM_PRESENT == 1U) -#if ((__CORTEX_A == 5U)||(__CORTEX_A == 9U)) +#if (__TIM_PRESENT == 1U) || defined(DOXYGEN) +#if ((__CORTEX_A == 5U) || (__CORTEX_A == 9U)) || defined(DOXYGEN) /** \brief Structure type to access the Private Timer */ typedef struct { - __IO uint32_t LOAD; //!< \brief +0x000 - RW - Private Timer Load Register - __IO uint32_t COUNTER; //!< \brief +0x004 - RW - Private Timer Counter Register - __IO uint32_t CONTROL; //!< \brief +0x008 - RW - Private Timer Control Register - __IO uint32_t ISR; //!< \brief +0x00C - RO - Private Timer Interrupt Status Register - uint32_t RESERVED[8]; - __IO uint32_t WLOAD; //!< \brief +0x020 - RW - Watchdog Load Register - __IO uint32_t WCOUNTER; //!< \brief +0x024 - RW - Watchdog Counter Register - __IO uint32_t WCONTROL; //!< \brief +0x028 - RW - Watchdog Control Register - __IO uint32_t WISR; //!< \brief +0x02C - RW - Watchdog Interrupt Status Register - __IO uint32_t WRESET; //!< \brief +0x030 - RW - Watchdog Reset Status Register - __I uint32_t WDISABLE; //!< \brief +0x0FC - RO - Watchdog Disable Register + __IOM uint32_t LOAD; //!< \brief Offset: 0x000 (R/W) Private Timer Load Register + __IOM uint32_t COUNTER; //!< \brief Offset: 0x004 (R/W) Private Timer Counter Register + __IOM uint32_t CONTROL; //!< \brief Offset: 0x008 (R/W) Private Timer Control Register + __IOM uint32_t ISR; //!< \brief Offset: 0x00C (R/W) Private Timer Interrupt Status Register + RESERVED(0[4], uint32_t) + __IOM uint32_t WLOAD; //!< \brief Offset: 0x020 (R/W) Watchdog Load Register + __IOM uint32_t WCOUNTER; //!< \brief Offset: 0x024 (R/W) Watchdog Counter Register + __IOM uint32_t WCONTROL; //!< \brief Offset: 0x028 (R/W) Watchdog Control Register + __IOM uint32_t WISR; //!< \brief Offset: 0x02C (R/W) Watchdog Interrupt Status Register + __IOM uint32_t WRESET; //!< \brief Offset: 0x030 (R/W) Watchdog Reset Status Register + __OM uint32_t WDISABLE; //!< \brief Offset: 0x034 ( /W) Watchdog Disable Register } Timer_Type; -#define PTIM ((Timer_Type *) TIMER_BASE ) /*!< \brief Timer configuration struct */ +#define PTIM ((Timer_Type *) TIMER_BASE ) /*!< \brief Timer register struct */ #endif #endif @@ -606,60 +844,43 @@ typedef struct /* ########################## L1 Cache functions ################################# */ -/** \brief Enable Caches - - Enable Caches - */ +/** \brief Enable Caches by setting I and C bits in SCTLR register. +*/ __STATIC_INLINE void L1C_EnableCaches(void) { - // Set I bit 12 to enable I Cache - // Set C bit 2 to enable D Cache - __set_SCTLR( __get_SCTLR() | (1 << 12) | (1 << 2)); + __set_SCTLR( __get_SCTLR() | (1U << SCTLR_I_Pos) | (1U << SCTLR_C_Pos)); + __ISB(); } -/** \brief Disable Caches - - Disable Caches - */ +/** \brief Disable Caches by clearing I and C bits in SCTLR register. +*/ __STATIC_INLINE void L1C_DisableCaches(void) { - // Clear I bit 12 to disable I Cache - // Clear C bit 2 to disable D Cache - __set_SCTLR( __get_SCTLR() & ~(1 << 12) & ~(1 << 2)); + __set_SCTLR( __get_SCTLR() & ~(1U << SCTLR_I_Pos) & ~(1U << SCTLR_C_Pos)); __ISB(); } -/** \brief Enable BTAC - - Enable BTAC - */ +/** \brief Enable Branch Prediction by setting Z bit in SCTLR register. +*/ __STATIC_INLINE void L1C_EnableBTAC(void) { - // Set Z bit 11 to enable branch prediction - __set_SCTLR( __get_SCTLR() | (1 << 11)); + __set_SCTLR( __get_SCTLR() | (1U << SCTLR_Z_Pos)); __ISB(); } -/** \brief Disable BTAC - - Disable BTAC - */ +/** \brief Disable Branch Prediction by clearing Z bit in SCTLR register. +*/ __STATIC_INLINE void L1C_DisableBTAC(void) { - // Clear Z bit 11 to disable branch prediction - __set_SCTLR( __get_SCTLR() & ~(1 << 11)); + __set_SCTLR( __get_SCTLR() & ~(1U << SCTLR_Z_Pos)); + __ISB(); } /** \brief Invalidate entire branch predictor array - - BPIALL. Branch Predictor Invalidate All. - */ - +*/ __STATIC_INLINE void L1C_InvalidateBTAC(void) { __set_BPIALL(0); __DSB(); //ensure completion of the invalidation __ISB(); //ensure instruction fetch path sees new state } -/** \brief Invalidate the whole I$ - - ICIALLU. Instruction Cache Invalidate All to PoU +/** \brief Invalidate the whole instruction cache */ __STATIC_INLINE void L1C_InvalidateICacheAll(void) { __set_ICIALLU(0); @@ -667,27 +888,24 @@ __STATIC_INLINE void L1C_InvalidateICacheAll(void) { __ISB(); //ensure instruction fetch path sees new I cache state } -/** \brief Clean D$ by MVA - - DCCMVAC. Data cache clean by MVA to PoC +/** \brief Clean data cache line by address. +* \param [in] va Pointer to data to clear the cache for. */ __STATIC_INLINE void L1C_CleanDCacheMVA(void *va) { __set_DCCMVAC((uint32_t)va); __DMB(); //ensure the ordering of data cache maintenance operations and their effects } -/** \brief Invalidate D$ by MVA - - DCIMVAC. Data cache invalidate by MVA to PoC +/** \brief Invalidate data cache line by address. +* \param [in] va Pointer to data to invalidate the cache for. */ __STATIC_INLINE void L1C_InvalidateDCacheMVA(void *va) { __set_DCIMVAC((uint32_t)va); __DMB(); //ensure the ordering of data cache maintenance operations and their effects } -/** \brief Clean and Invalidate D$ by MVA - - DCCIMVAC. Data cache clean and invalidate by MVA to PoC +/** \brief Clean and Invalidate data cache by address. +* \param [in] va Pointer to data to invalidate the cache for. */ __STATIC_INLINE void L1C_CleanInvalidateDCacheMVA(void *va) { __set_DCCIMVAC((uint32_t)va); @@ -695,95 +913,95 @@ __STATIC_INLINE void L1C_CleanInvalidateDCacheMVA(void *va) { } /** \brief Clean and Invalidate the entire data or unified cache - - Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency. +* \param [in] op 0 - invalidate, 1 - clean, otherwise - invalidate and clean +* \see __L1C_CleanInvalidateCache */ __STATIC_INLINE void L1C_CleanInvalidateCache(uint32_t op) { - __L1C_CleanInvalidateCache(op); // compiler specific call + __L1C_CleanInvalidateCache(op); } - -/** \brief Invalidate the whole D$ - - DCISW. Invalidate by Set/Way +/** \brief Invalidate the whole data cache. */ - __STATIC_INLINE void L1C_InvalidateDCacheAll(void) { L1C_CleanInvalidateCache(0); } -/** \brief Clean the whole D$ - - DCCSW. Clean by Set/Way +/** \brief Clean the whole data cache. */ - __STATIC_INLINE void L1C_CleanDCacheAll(void) { L1C_CleanInvalidateCache(1); } -/** \brief Clean and invalidate the whole D$ - - DCCISW. Clean and Invalidate by Set/Way +/** \brief Clean and invalidate the whole data cache. */ - __STATIC_INLINE void L1C_CleanInvalidateDCacheAll(void) { L1C_CleanInvalidateCache(2); } /* ########################## L2 Cache functions ################################# */ -#if (__L2C_PRESENT == 1U) -//Cache Sync operation +#if (__L2C_PRESENT == 1U) || defined(DOXYGEN) +/** \brief Cache Sync operation by writing CACHE_SYNC register. +*/ __STATIC_INLINE void L2C_Sync(void) { L2C_310->CACHE_SYNC = 0x0; } -//return Cache controller cache ID +/** \brief Read cache controller cache ID from CACHE_ID register. + * \return L2C_310_TypeDef::CACHE_ID + */ __STATIC_INLINE int L2C_GetID (void) { return L2C_310->CACHE_ID; } -//return Cache controller cache Type +/** \brief Read cache controller cache type from CACHE_TYPE register. +* \return L2C_310_TypeDef::CACHE_TYPE +*/ __STATIC_INLINE int L2C_GetType (void) { return L2C_310->CACHE_TYPE; } -//Invalidate all cache by way +/** \brief Invalidate all cache by way +*/ __STATIC_INLINE void L2C_InvAllByWay (void) { unsigned int assoc; - if (L2C_310->AUX_CNT & (1<<16)) - assoc = 16; - else - assoc = 8; - - L2C_310->INV_WAY = (1 << assoc) - 1; - while(L2C_310->INV_WAY & ((1 << assoc) - 1)); //poll invalidate + if (L2C_310->AUX_CNT & (1U << 16U)) { + assoc = 16U; + } else { + assoc = 8U; + } + + L2C_310->INV_WAY = (1U << assoc) - 1U; + while(L2C_310->INV_WAY & ((1U << assoc) - 1U)); //poll invalidate L2C_Sync(); } -//Clean and Invalidate all cache by way +/** \brief Clean and Invalidate all cache by way +*/ __STATIC_INLINE void L2C_CleanInvAllByWay (void) { unsigned int assoc; - if (L2C_310->AUX_CNT & (1<<16)) - assoc = 16; - else - assoc = 8; + if (L2C_310->AUX_CNT & (1U << 16U)) { + assoc = 16U; + } else { + assoc = 8U; + } - L2C_310->CLEAN_INV_WAY = (1 << assoc) - 1; - while(L2C_310->CLEAN_INV_WAY & ((1 << assoc) - 1)); //poll invalidate + L2C_310->CLEAN_INV_WAY = (1U << assoc) - 1U; + while(L2C_310->CLEAN_INV_WAY & ((1U << assoc) - 1U)); //poll invalidate L2C_Sync(); } -//Enable Cache +/** \brief Enable Level 2 Cache +*/ __STATIC_INLINE void L2C_Enable(void) { L2C_310->CONTROL = 0; @@ -794,28 +1012,36 @@ __STATIC_INLINE void L2C_Enable(void) L2C_310->CONTROL = 0x01; L2C_Sync(); } -//Disable Cache + +/** \brief Disable Level 2 Cache +*/ __STATIC_INLINE void L2C_Disable(void) { L2C_310->CONTROL = 0x00; L2C_Sync(); } -//Invalidate cache by physical address +/** \brief Invalidate cache by physical address +* \param [in] pa Pointer to data to invalidate cache for. +*/ __STATIC_INLINE void L2C_InvPa (void *pa) { L2C_310->INV_LINE_PA = (unsigned int)pa; L2C_Sync(); } -//Clean cache by physical address +/** \brief Clean cache by physical address +* \param [in] pa Pointer to data to invalidate cache for. +*/ __STATIC_INLINE void L2C_CleanPa (void *pa) { L2C_310->CLEAN_LINE_PA = (unsigned int)pa; L2C_Sync(); } -//Clean and invalidate cache by physical address +/** \brief Clean and invalidate cache by physical address +* \param [in] pa Pointer to data to invalidate cache for. +*/ __STATIC_INLINE void L2C_CleanInvPa (void *pa) { L2C_310->CLEAN_INV_LINE_PA = (unsigned int)pa; @@ -824,159 +1050,315 @@ __STATIC_INLINE void L2C_CleanInvPa (void *pa) #endif /* ########################## GIC functions ###################################### */ -#if (__GIC_PRESENT == 1U) +#if (__GIC_PRESENT == 1U) || defined(DOXYGEN) +/** \brief Enable the interrupt distributor using the GIC's CTLR register. +*/ __STATIC_INLINE void GIC_EnableDistributor(void) { - GICDistributor->ICDDCR |= 1; //enable distributor + GICDistributor->CTLR |= 1U; } +/** \brief Disable the interrupt distributor using the GIC's CTLR register. +*/ __STATIC_INLINE void GIC_DisableDistributor(void) { - GICDistributor->ICDDCR &=~1; //disable distributor + GICDistributor->CTLR &=~1U; } +/** \brief Read the GIC's TYPER register. +* \return GICDistributor_Type::TYPER +*/ __STATIC_INLINE uint32_t GIC_DistributorInfo(void) { - return (uint32_t)(GICDistributor->ICDICTR); + return (GICDistributor->TYPER); } +/** \brief Reads the GIC's IIDR register. +* \return GICDistributor_Type::IIDR +*/ __STATIC_INLINE uint32_t GIC_DistributorImplementer(void) { - return (uint32_t)(GICDistributor->ICDIIDR); + return (GICDistributor->IIDR); } +/** \brief Sets the GIC's ITARGETSR register for the given interrupt. +* \param [in] IRQn Interrupt to be configured. +* \param [in] cpu_target CPU interfaces to assign this interrupt to. +*/ __STATIC_INLINE void GIC_SetTarget(IRQn_Type IRQn, uint32_t cpu_target) { - char* field = (char*)&(GICDistributor->ICDIPTR[IRQn / 4]); - field += IRQn % 4; - *field = (char)cpu_target & 0xf; -} - -__STATIC_INLINE void GIC_SetICDICFR (const uint32_t *ICDICFRn) -{ - uint32_t i, num_irq; - - //Get the maximum number of interrupts that the GIC supports - num_irq = 32 * ((GIC_DistributorInfo() & 0x1f) + 1); - - for (i = 0; i < (num_irq/16); i++) - { - GICDistributor->ICDISPR[i] = *ICDICFRn++; - } + uint32_t mask = GICDistributor->ITARGETSR[IRQn / 4U] & ~(0xFFUL << ((IRQn % 4U) * 8U)); + GICDistributor->ITARGETSR[IRQn / 4U] = mask | ((cpu_target & 0xFFUL) << ((IRQn % 4U) * 8U)); } +/** \brief Read the GIC's ITARGETSR register. +* \param [in] IRQn Interrupt to acquire the configuration for. +* \return GICDistributor_Type::ITARGETSR +*/ __STATIC_INLINE uint32_t GIC_GetTarget(IRQn_Type IRQn) { - char* field = (char*)&(GICDistributor->ICDIPTR[IRQn / 4]); - field += IRQn % 4; - return ((uint32_t)*field & 0xf); + return (GICDistributor->ITARGETSR[IRQn / 4U] >> ((IRQn % 4U) * 8U)) & 0xFFUL; } +/** \brief Enable the CPU's interrupt interface. +*/ __STATIC_INLINE void GIC_EnableInterface(void) { - GICInterface->ICCICR |= 1; //enable interface + GICInterface->CTLR |= 1U; //enable interface } +/** \brief Disable the CPU's interrupt interface. +*/ __STATIC_INLINE void GIC_DisableInterface(void) { - GICInterface->ICCICR &=~1; //disable distributor + GICInterface->CTLR &=~1U; //disable distributor } +/** \brief Read the CPU's IAR register. +* \return GICInterface_Type::IAR +*/ __STATIC_INLINE IRQn_Type GIC_AcknowledgePending(void) { - return (IRQn_Type)(GICInterface->ICCIAR); + return (IRQn_Type)(GICInterface->IAR); } +/** \brief Writes the given interrupt number to the CPU's EOIR register. +* \param [in] IRQn The interrupt to be signaled as finished. +*/ __STATIC_INLINE void GIC_EndInterrupt(IRQn_Type IRQn) { - GICInterface->ICCEOIR = IRQn; + GICInterface->EOIR = IRQn; } +/** \brief Enables the given interrupt using GIC's ISENABLER register. +* \param [in] IRQn The interrupt to be enabled. +*/ __STATIC_INLINE void GIC_EnableIRQ(IRQn_Type IRQn) { - GICDistributor->ICDISER[IRQn / 32] = 1 << (IRQn % 32); + GICDistributor->ISENABLER[IRQn / 32U] = 1U << (IRQn % 32U); } +/** \brief Get interrupt enable status using GIC's ISENABLER register. +* \param [in] IRQn The interrupt to be queried. +* \return 0 - interrupt is not enabled, 1 - interrupt is enabled. +*/ +__STATIC_INLINE uint32_t GIC_GetEnableIRQ(IRQn_Type IRQn) +{ + return (GICDistributor->ISENABLER[IRQn / 32U] >> (IRQn % 32U)) & 1UL; +} + +/** \brief Disables the given interrupt using GIC's ICENABLER register. +* \param [in] IRQn The interrupt to be disabled. +*/ __STATIC_INLINE void GIC_DisableIRQ(IRQn_Type IRQn) { - GICDistributor->ICDICER[IRQn / 32] = 1 << (IRQn % 32); + GICDistributor->ICENABLER[IRQn / 32U] = 1U << (IRQn % 32U); } +/** \brief Get interrupt pending status from GIC's ISPENDR register. +* \param [in] IRQn The interrupt to be queried. +* \return 0 - interrupt is not pending, 1 - interrupt is pendig. +*/ +__STATIC_INLINE uint32_t GIC_GetPendingIRQ(IRQn_Type IRQn) +{ + uint32_t pend; + + if (IRQn >= 16U) { + pend = (GICDistributor->ISPENDR[IRQn / 32U] >> (IRQn % 32U)) & 1UL; + } else { + // INTID 0-15 Software Generated Interrupt + pend = (GICDistributor->SPENDSGIR[IRQn / 4U] >> ((IRQn % 4U) * 8U)) & 0xFFUL; + // No CPU identification offered + if (pend != 0U) { + pend = 1U; + } else { + pend = 0U; + } + } + + return (pend); +} + +/** \brief Sets the given interrupt as pending using GIC's ISPENDR register. +* \param [in] IRQn The interrupt to be enabled. +*/ __STATIC_INLINE void GIC_SetPendingIRQ(IRQn_Type IRQn) { - GICDistributor->ICDISPR[IRQn / 32] = 1 << (IRQn % 32); + if (IRQn >= 16U) { + GICDistributor->ISPENDR[IRQn / 32U] = 1U << (IRQn % 32U); + } else { + // INTID 0-15 Software Generated Interrupt + GICDistributor->SPENDSGIR[IRQn / 4U] = 1U << ((IRQn % 4U) * 8U); + // Forward the interrupt to the CPU interface that requested it + GICDistributor->SGIR = (IRQn | 0x02000000U); + } } +/** \brief Clears the given interrupt from being pending using GIC's ICPENDR register. +* \param [in] IRQn The interrupt to be enabled. +*/ __STATIC_INLINE void GIC_ClearPendingIRQ(IRQn_Type IRQn) { - GICDistributor->ICDICPR[IRQn / 32] = 1 << (IRQn % 32); + if (IRQn >= 16U) { + GICDistributor->ICPENDR[IRQn / 32U] = 1U << (IRQn % 32U); + } else { + // INTID 0-15 Software Generated Interrupt + GICDistributor->CPENDSGIR[IRQn / 4U] = 1U << ((IRQn % 4U) * 8U); + } } -__STATIC_INLINE void GIC_SetLevelModel(IRQn_Type IRQn, int8_t edge_level, int8_t model) -{ - // Word-size read/writes must be used to access this register - volatile uint32_t * field = &(GICDistributor->ICDICFR[IRQn / 16]); - unsigned bit_shift = (IRQn % 16)<<1; - unsigned int save_word; +/** \brief Sets the interrupt configuration using GIC's ICFGR register. +* \param [in] IRQn The interrupt to be configured. +* \param [in] int_config Int_config field value. Bit 0: Reserved (0 - N-N model, 1 - 1-N model for some GIC before v1) +* Bit 1: 0 - level sensitive, 1 - edge triggered +*/ +__STATIC_INLINE void GIC_SetConfiguration(IRQn_Type IRQn, uint32_t int_config) +{ + uint32_t icfgr = GICDistributor->ICFGR[IRQn / 16U]; + uint32_t shift = (IRQn % 16U) << 1U; - save_word = *field; - save_word &= (~(3 << bit_shift)); + icfgr &= (~(3U << shift)); + icfgr |= ( int_config << shift); + + GICDistributor->ICFGR[IRQn / 16U] = icfgr; +} - *field = (save_word | (((edge_level<<1) | model) << bit_shift)); +/** \brief Get the interrupt configuration from the GIC's ICFGR register. +* \param [in] IRQn Interrupt to acquire the configuration for. +* \return Int_config field value. Bit 0: Reserved (0 - N-N model, 1 - 1-N model for some GIC before v1) +* Bit 1: 0 - level sensitive, 1 - edge triggered +*/ +__STATIC_INLINE uint32_t GIC_GetConfiguration(IRQn_Type IRQn) +{ + return (GICDistributor->ICFGR[IRQn / 16U] >> ((IRQn % 16U) >> 1U)); } +/** \brief Set the priority for the given interrupt in the GIC's IPRIORITYR register. +* \param [in] IRQn The interrupt to be configured. +* \param [in] priority The priority for the interrupt, lower values denote higher priorities. +*/ __STATIC_INLINE void GIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { - char* field = (char*)&(GICDistributor->ICDIPR[IRQn / 4]); - field += IRQn % 4; - *field = (char)priority; + uint32_t mask = GICDistributor->IPRIORITYR[IRQn / 4U] & ~(0xFFUL << ((IRQn % 4U) * 8U)); + GICDistributor->IPRIORITYR[IRQn / 4U] = mask | ((priority & 0xFFUL) << ((IRQn % 4U) * 8U)); } +/** \brief Read the current interrupt priority from GIC's IPRIORITYR register. +* \param [in] IRQn The interrupt to be queried. +*/ __STATIC_INLINE uint32_t GIC_GetPriority(IRQn_Type IRQn) { - char* field = (char*)&(GICDistributor->ICDIPR[IRQn / 4]); - field += IRQn % 4; - return (uint32_t)*field; + return (GICDistributor->IPRIORITYR[IRQn / 4U] >> ((IRQn % 4U) * 8U)) & 0xFFUL; } -__STATIC_INLINE void GIC_InterfacePriorityMask(uint32_t priority) +/** \brief Set the interrupt priority mask using CPU's PMR register. +* \param [in] priority Priority mask to be set. +*/ +__STATIC_INLINE void GIC_SetInterfacePriorityMask(uint32_t priority) { - GICInterface->ICCPMR = priority & 0xff; //set priority mask + GICInterface->PMR = priority & 0xFFUL; //set priority mask } +/** \brief Read the current interrupt priority mask from CPU's PMR register. +* \result GICInterface_Type::PMR +*/ +__STATIC_INLINE uint32_t GIC_GetInterfacePriorityMask(void) +{ + return GICInterface->PMR; +} + +/** \brief Configures the group priority and subpriority split point using CPU's BPR register. +* \param [in] binary_point Amount of bits used as subpriority. +*/ __STATIC_INLINE void GIC_SetBinaryPoint(uint32_t binary_point) { - GICInterface->ICCBPR = binary_point & 0x07; //set binary point + GICInterface->BPR = binary_point & 7U; //set binary point } -__STATIC_INLINE uint32_t GIC_GetBinaryPoint(uint32_t binary_point) +/** \brief Read the current group priority and subpriority split point from CPU's BPR register. +* \return GICInterface_Type::BPR +*/ +__STATIC_INLINE uint32_t GIC_GetBinaryPoint(void) { - return (uint32_t)GICInterface->ICCBPR; + return GICInterface->BPR; } +/** \brief Get the status for a given interrupt. +* \param [in] IRQn The interrupt to get status for. +* \return 0 - not pending/active, 1 - pending, 2 - active, 3 - pending and active +*/ __STATIC_INLINE uint32_t GIC_GetIRQStatus(IRQn_Type IRQn) { uint32_t pending, active; - active = ((GICDistributor->ICDABR[IRQn / 32]) >> (IRQn % 32)) & 0x1; - pending =((GICDistributor->ICDISPR[IRQn / 32]) >> (IRQn % 32)) & 0x1; + active = ((GICDistributor->ISACTIVER[IRQn / 32U]) >> (IRQn % 32U)) & 1UL; + pending = ((GICDistributor->ISPENDR[IRQn / 32U]) >> (IRQn % 32U)) & 1UL; - return ((active<<1) | pending); + return ((active<<1U) | pending); } +/** \brief Generate a software interrupt using GIC's SGIR register. +* \param [in] IRQn Software interrupt to be generated. +* \param [in] target_list List of CPUs the software interrupt should be forwarded to. +* \param [in] filter_list Filter to be applied to determine interrupt receivers. +*/ __STATIC_INLINE void GIC_SendSGI(IRQn_Type IRQn, uint32_t target_list, uint32_t filter_list) { - GICDistributor->ICDSGIR = ((filter_list & 0x3) << 24) | ((target_list & 0xff) << 16) | (IRQn & 0xf); + GICDistributor->SGIR = ((filter_list & 3U) << 24U) | ((target_list & 0xFFUL) << 16U) | (IRQn & 0x0FUL); +} + +/** \brief Get the interrupt number of the highest interrupt pending from CPU's HPPIR register. +* \return GICInterface_Type::HPPIR +*/ +__STATIC_INLINE uint32_t GIC_GetHighPendingIRQ(void) +{ + return GICInterface->HPPIR; +} + +/** \brief Provides information about the implementer and revision of the CPU interface. +* \return GICInterface_Type::IIDR +*/ +__STATIC_INLINE uint32_t GIC_GetInterfaceId(void) +{ + return GICInterface->IIDR; +} + +/** \brief Set the interrupt group from the GIC's IGROUPR register. +* \param [in] IRQn The interrupt to be queried. +* \param [in] group Interrupt group number: 0 - Group 0, 1 - Group 1 +*/ +__STATIC_INLINE void GIC_SetGroup(IRQn_Type IRQn, uint32_t group) +{ + uint32_t igroupr = GICDistributor->IGROUPR[IRQn / 32U]; + uint32_t shift = (IRQn % 32U); + + igroupr &= (~(1U << shift)); + igroupr |= ( (group & 1U) << shift); + + GICDistributor->IGROUPR[IRQn / 32U] = igroupr; +} +#define GIC_SetSecurity GIC_SetGroup + +/** \brief Get the interrupt group from the GIC's IGROUPR register. +* \param [in] IRQn The interrupt to be queried. +* \return 0 - Group 0, 1 - Group 1 +*/ +__STATIC_INLINE uint32_t GIC_GetGroup(IRQn_Type IRQn) +{ + return (GICDistributor->IGROUPR[IRQn / 32U] >> (IRQn % 32U)) & 1UL; } +#define GIC_GetSecurity GIC_GetGroup +/** \brief Initialize the interrupt distributor. +*/ __STATIC_INLINE void GIC_DistInit(void) { IRQn_Type i; uint32_t num_irq = 0; uint32_t priority_field; - //A reset sets all bits in the ICDISRs corresponding to the SPIs to 0, + //A reset sets all bits in the IGROUPRs corresponding to the SPIs to 0, //configuring all of the interrupts as Secure. //Disable interrupt forwarding @@ -985,7 +1367,7 @@ __STATIC_INLINE void GIC_DistInit(void) num_irq = 32 * ((GIC_DistributorInfo() & 0x1f) + 1); /* Priority level is implementation defined. - To determine the number of priority bits implemented write 0xFF to an ICDIPR + To determine the number of priority bits implemented write 0xFF to an IPRIORITYR priority field and read back the value stored.*/ GIC_SetPriority((IRQn_Type)0, 0xff); priority_field = GIC_GetPriority((IRQn_Type)0); @@ -994,8 +1376,10 @@ __STATIC_INLINE void GIC_DistInit(void) { //Disable the SPI interrupt GIC_DisableIRQ(i); - //Set level-sensitive and 1-N model - GIC_SetLevelModel(i, 0, 1); + if (i > 15) { + //Set level-sensitive (and N-N model) + GIC_SetConfiguration(i, 0); + } //Set priority GIC_SetPriority(i, priority_field/2); //Set target list to CPU0 @@ -1005,19 +1389,21 @@ __STATIC_INLINE void GIC_DistInit(void) GIC_EnableDistributor(); } +/** \brief Initialize the CPU's interrupt interface +*/ __STATIC_INLINE void GIC_CPUInterfaceInit(void) { IRQn_Type i; uint32_t priority_field; - //A reset sets all bits in the ICDISRs corresponding to the SPIs to 0, + //A reset sets all bits in the IGROUPRs corresponding to the SPIs to 0, //configuring all of the interrupts as Secure. //Disable interrupt forwarding GIC_DisableInterface(); /* Priority level is implementation defined. - To determine the number of priority bits implemented write 0xFF to an ICDIPR + To determine the number of priority bits implemented write 0xFF to an IPRIORITYR priority field and read back the value stored.*/ GIC_SetPriority((IRQn_Type)0, 0xff); priority_field = GIC_GetPriority((IRQn_Type)0); @@ -1025,22 +1411,25 @@ __STATIC_INLINE void GIC_CPUInterfaceInit(void) //SGI and PPI for (i = (IRQn_Type)0; i < 32; i++) { - //Set level-sensitive and 1-N model for PPI - if(i > 15) - GIC_SetLevelModel(i, 0, 1); - //Disable SGI and PPI interrupts - GIC_DisableIRQ(i); - //Set priority - GIC_SetPriority(i, priority_field/2); + if(i > 15) { + //Set level-sensitive (and N-N model) for PPI + GIC_SetConfiguration(i, 0U); + } + //Disable SGI and PPI interrupts + GIC_DisableIRQ(i); + //Set priority + GIC_SetPriority(i, priority_field/2); } //Enable interface GIC_EnableInterface(); //Set binary point to 0 GIC_SetBinaryPoint(0); //Set priority mask - GIC_InterfacePriorityMask(0xff); + GIC_SetInterfacePriorityMask(0xff); } +/** \brief Initialize and enable the GIC +*/ __STATIC_INLINE void GIC_Enable(void) { GIC_DistInit(); @@ -1049,47 +1438,129 @@ __STATIC_INLINE void GIC_Enable(void) #endif /* ########################## Generic Timer functions ############################ */ -#if (__TIM_PRESENT == 1U) +#if (__TIM_PRESENT == 1U) || defined(DOXYGEN) /* PL1 Physical Timer */ -#if (__CORTEX_A == 7U) -__STATIC_INLINE void PL1_SetLoadValue(uint32_t value) { +#if (__CORTEX_A == 7U) || defined(DOXYGEN) + +/** \brief Physical Timer Control register */ +typedef union +{ + struct + { + uint32_t ENABLE:1; /*!< \brief bit: 0 Enables the timer. */ + uint32_t IMASK:1; /*!< \brief bit: 1 Timer output signal mask bit. */ + uint32_t ISTATUS:1; /*!< \brief bit: 2 The status of the timer. */ + RESERVED(0:29, uint32_t) + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} CNTP_CTL_Type; + +/** \brief Configures the frequency the timer shall run at. +* \param [in] value The timer frequency in Hz. +*/ +__STATIC_INLINE void PL1_SetCounterFrequency(uint32_t value) +{ + __set_CNTFRQ(value); + __ISB(); +} + +/** \brief Sets the reset value of the timer. +* \param [in] value The value the timer is loaded with. +*/ +__STATIC_INLINE void PL1_SetLoadValue(uint32_t value) +{ __set_CNTP_TVAL(value); __ISB(); } -__STATIC_INLINE uint32_t PL1_GetCurrentValue() { +/** \brief Get the current counter value. +* \return Current counter value. +*/ +__STATIC_INLINE uint32_t PL1_GetCurrentValue() +{ return(__get_CNTP_TVAL()); } -__STATIC_INLINE void PL1_SetControl(uint32_t value) { +/** \brief Configure the timer by setting the control value. +* \param [in] value New timer control value. +*/ +__STATIC_INLINE void PL1_SetControl(uint32_t value) +{ __set_CNTP_CTL(value); __ISB(); } +/** \brief Get the control value. +* \return Control value. +*/ +__STATIC_INLINE uint32_t PL1_GetControl() +{ + return(__get_CNTP_CTL()); +} +#endif + /* Private Timer */ -#elif ((__CORTEX_A == 5U)||(__CORTEX_A == 9U)) -__STATIC_INLINE void PTIM_SetLoadValue(uint32_t value) { +#if ((__CORTEX_A == 5U) || (__CORTEX_A == 9U)) || defined(DOXYGEN) +/** \brief Set the load value to timers LOAD register. +* \param [in] value The load value to be set. +*/ +__STATIC_INLINE void PTIM_SetLoadValue(uint32_t value) +{ PTIM->LOAD = value; } -__STATIC_INLINE uint32_t PTIM_GetLoadValue() { +/** \brief Get the load value from timers LOAD register. +* \return Timer_Type::LOAD +*/ +__STATIC_INLINE uint32_t PTIM_GetLoadValue(void) +{ return(PTIM->LOAD); } -__STATIC_INLINE uint32_t PTIM_GetCurrentValue() { +/** \brief Set current counter value from its COUNTER register. +*/ +__STATIC_INLINE void PTIM_SetCurrentValue(uint32_t value) +{ + PTIM->COUNTER = value; +} + +/** \brief Get current counter value from timers COUNTER register. +* \result Timer_Type::COUNTER +*/ +__STATIC_INLINE uint32_t PTIM_GetCurrentValue(void) +{ return(PTIM->COUNTER); } -__STATIC_INLINE void PTIM_SetControl(uint32_t value) { +/** \brief Configure the timer using its CONTROL register. +* \param [in] value The new configuration value to be set. +*/ +__STATIC_INLINE void PTIM_SetControl(uint32_t value) +{ PTIM->CONTROL = value; } -__STATIC_INLINE uint32_t PTIM_GetControl(void) { +/** ref Timer_Type::CONTROL Get the current timer configuration from its CONTROL register. +* \return Timer_Type::CONTROL +*/ +__STATIC_INLINE uint32_t PTIM_GetControl(void) +{ return(PTIM->CONTROL); } -__STATIC_INLINE void PTIM_ClearEventFlag(void) { +/** ref Timer_Type::CONTROL Get the event flag in timers ISR register. +* \return 0 - flag is not set, 1- flag is set +*/ +__STATIC_INLINE uint32_t PTIM_GetEventFlag(void) +{ + return (PTIM->ISR & 1UL); +} + +/** ref Timer_Type::CONTROL Clears the event flag in timers ISR register. +*/ +__STATIC_INLINE void PTIM_ClearEventFlag(void) +{ PTIM->ISR = 1; } #endif @@ -1974,10 +2445,9 @@ __STATIC_INLINE void MMU_TTPage64k(uint32_t *ttb, uint32_t base_address, uint32_ } /** \brief Enable MMU - - Enable MMU */ -__STATIC_INLINE void MMU_Enable(void) { +__STATIC_INLINE void MMU_Enable(void) +{ // Set M bit 0 to enable the MMU // Set AFE bit to enable simplified access permissions model // Clear TRE bit to disable TEX remap and A bit to disable strict alignment fault checking @@ -1986,21 +2456,19 @@ __STATIC_INLINE void MMU_Enable(void) { } /** \brief Disable MMU - - Disable MMU */ -__STATIC_INLINE void MMU_Disable(void) { +__STATIC_INLINE void MMU_Disable(void) +{ // Clear M bit 0 to disable the MMU __set_SCTLR( __get_SCTLR() & ~1); __ISB(); } /** \brief Invalidate entire unified TLB - - TLBIALL. Invalidate entire unified TLB */ -__STATIC_INLINE void MMU_InvalidateTLB(void) { +__STATIC_INLINE void MMU_InvalidateTLB(void) +{ __set_TLBIALL(0); __DSB(); //ensure completion of the invalidation __ISB(); //ensure instruction fetch path sees new state diff --git a/cmsis/TARGET_CORTEX_A/core_ca9.h b/cmsis/TARGET_CORTEX_A/core_ca9.h deleted file mode 100644 index c7c402d7508..00000000000 --- a/cmsis/TARGET_CORTEX_A/core_ca9.h +++ /dev/null @@ -1,276 +0,0 @@ -/**************************************************************************//** - * @file core_ca9.h - * @brief CMSIS Cortex-A9 Core Peripheral Access Layer Header File - * @version - * @date 25 March 2013 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2012 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#endif - -#ifdef __cplusplus - extern "C" { -#endif - -#ifndef __CORE_CA9_H_GENERIC -#define __CORE_CA9_H_GENERIC - - -/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions - CMSIS violates the following MISRA-C:2004 rules: - - \li Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'. - - \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers. - - \li Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code. - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** \ingroup Cortex_A9 - @{ - */ - -/* CMSIS CA9 definitions */ -#define __CA9_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ -#define __CA9_CMSIS_VERSION_SUB (0x10) /*!< [15:0] CMSIS HAL sub version */ -#define __CA9_CMSIS_VERSION ((__CA9_CMSIS_VERSION_MAIN << 16) | \ - __CA9_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ - -#define __CORTEX_A (0x09) /*!< Cortex-A Core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - #define __STATIC_ASM static __asm - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - #define __STATIC_INLINE static inline - #define __STATIC_ASM static __asm - -#include -inline uint32_t __get_PSR(void) { - __ASM("mrs r0, cpsr"); -} - -#elif defined ( __TMS470__ ) - #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ - #define __STATIC_INLINE static inline - #define __STATIC_ASM static __asm - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - #define __STATIC_INLINE static inline - #define __STATIC_ASM static __asm - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - #define __STATIC_INLINE static inline - #define __STATIC_ASM static __asm - -#endif - -/** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. -*/ -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __TMS470__ ) - #if defined __TI_VFP_SUPPORT__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __TASKING__ ) - #if defined __FPU_VFP__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif -#endif - -#include /*!< standard types definitions */ -#include "core_caInstr.h" /*!< Core Instruction Access */ -#include "core_caFunc.h" /*!< Core Function Access */ -#include "core_cm4_simd.h" /*!< Compiler specific SIMD Intrinsics */ - -#endif /* __CORE_CA9_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_CA9_H_DEPENDANT -#define __CORE_CA9_H_DEPENDANT - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CA9_REV - #define __CA9_REV 0x0000 - #warning "__CA9_REV not defined in device header file; using default!" - #endif - - #ifndef __FPU_PRESENT - #define __FPU_PRESENT 1 - #warning "__FPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 1 - #endif - - #if __Vendor_SysTickConfig == 0 - #error "__Vendor_SysTickConfig set to 0, but vendor systick timer must be supplied for Cortex-A9" - #endif -#endif - -/* IO definitions (access restrictions to peripheral registers) */ -/** - \defgroup CMSIS_glob_defs CMSIS Global Defines - - IO Type Qualifiers are used - \li to specify the access to peripheral variables. - \li for automatic generation of peripheral register debug information. -*/ -#ifdef __cplusplus - #define __I volatile /*!< Defines 'read only' permissions */ -#else - #define __I volatile const /*!< Defines 'read only' permissions */ -#endif -#define __O volatile /*!< Defines 'write only' permissions */ -#define __IO volatile /*!< Defines 'read / write' permissions */ - -/*@} end of group Cortex_A9 */ - - -/******************************************************************************* - * Register Abstraction - ******************************************************************************/ -/** \defgroup CMSIS_core_register Defines and Type Definitions - \brief Type definitions and defines for Cortex-A processor based devices. -*/ - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CORE Status and Control Registers - \brief Core Register type definitions. - @{ - */ - -/** \brief Union type to access the Application Program Status Register (APSR). - */ -typedef union -{ - struct - { - uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t reserved1:7; /*!< bit: 20..23 Reserved */ - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} APSR_Type; - - -/*@} end of group CMSIS_CORE */ - -/*@} end of CMSIS_Core_FPUFunctions */ - - -#endif /* __CORE_CA9_H_GENERIC */ - -#endif /* __CMSIS_GENERIC */ - -#ifdef __cplusplus -} - - -#endif diff --git a/cmsis/TARGET_CORTEX_A/core_caFunc.h b/cmsis/TARGET_CORTEX_A/core_caFunc.h deleted file mode 100644 index 6e473214b68..00000000000 --- a/cmsis/TARGET_CORTEX_A/core_caFunc.h +++ /dev/null @@ -1,1444 +0,0 @@ -/**************************************************************************//** - * @file core_caFunc.h - * @brief CMSIS Cortex-A Core Function Access Header File - * @version V3.10 - * @date 30 Oct 2013 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2013 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#ifndef __CORE_CAFUNC_H__ -#define __CORE_CAFUNC_H__ - - -/* ########################### Core Function Access ########################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions - @{ - */ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -#if (__ARMCC_VERSION < 400677) - #error "Please use ARM Compiler Toolchain V4.0.677 or later!" -#endif - -#define MODE_USR 0x10 -#define MODE_FIQ 0x11 -#define MODE_IRQ 0x12 -#define MODE_SVC 0x13 -#define MODE_MON 0x16 -#define MODE_ABT 0x17 -#define MODE_HYP 0x1A -#define MODE_UND 0x1B -#define MODE_SYS 0x1F - -/** \brief Get APSR Register - - This function returns the content of the APSR Register. - - \return APSR Register value - */ -__STATIC_INLINE uint32_t __get_APSR(void) -{ - register uint32_t __regAPSR __ASM("apsr"); - return(__regAPSR); -} - - -/** \brief Get CPSR Register - - This function returns the content of the CPSR Register. - - \return CPSR Register value - */ -__STATIC_INLINE uint32_t __get_CPSR(void) -{ - register uint32_t __regCPSR __ASM("cpsr"); - return(__regCPSR); -} - -/** \brief Set Stack Pointer - - This function assigns the given value to the current stack pointer. - - \param [in] topOfStack Stack Pointer value to set - */ -register uint32_t __regSP __ASM("sp"); -__STATIC_INLINE void __set_SP(uint32_t topOfStack) -{ - __regSP = topOfStack; -} - - -/** \brief Get link register - - This function returns the value of the link register - - \return Value of link register - */ -register uint32_t __reglr __ASM("lr"); -__STATIC_INLINE uint32_t __get_LR(void) -{ - return(__reglr); -} - -/** \brief Set link register - - This function sets the value of the link register - - \param [in] lr LR value to set - */ -__STATIC_INLINE void __set_LR(uint32_t lr) -{ - __reglr = lr; -} - -/** \brief Set Process Stack Pointer - - This function assigns the given value to the USR/SYS Stack Pointer (PSP). - - \param [in] topOfProcStack USR/SYS Stack Pointer value to set - */ -__STATIC_ASM void __set_PSP(uint32_t topOfProcStack) -{ - ARM - PRESERVE8 - - BIC R0, R0, #7 ;ensure stack is 8-byte aligned - MRS R1, CPSR - CPS #MODE_SYS ;no effect in USR mode - MOV SP, R0 - MSR CPSR_c, R1 ;no effect in USR mode - ISB - BX LR - -} - -/** \brief Set User Mode - - This function changes the processor state to User Mode - */ -__STATIC_ASM void __set_CPS_USR(void) -{ - ARM - - CPS #MODE_USR - BX LR -} - - -/** \brief Enable FIQ - - This function enables FIQ interrupts by clearing the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -#define __enable_fault_irq __enable_fiq - - -/** \brief Disable FIQ - - This function disables FIQ interrupts by setting the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -#define __disable_fault_irq __disable_fiq - - -/** \brief Get FPSCR - - This function returns the current value of the Floating Point Status/Control register. - - \return Floating Point Status/Control register value - */ -__STATIC_INLINE uint32_t __get_FPSCR(void) -{ -#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - register uint32_t __regfpscr __ASM("fpscr"); - return(__regfpscr); -#else - return(0); -#endif -} - - -/** \brief Set FPSCR - - This function assigns the given value to the Floating Point Status/Control register. - - \param [in] fpscr Floating Point Status/Control value to set - */ -__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) -{ -#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - register uint32_t __regfpscr __ASM("fpscr"); - __regfpscr = (fpscr); -#endif -} - -/** \brief Get FPEXC - - This function returns the current value of the Floating Point Exception Control register. - - \return Floating Point Exception Control register value - */ -__STATIC_INLINE uint32_t __get_FPEXC(void) -{ -#if (__FPU_PRESENT == 1) - register uint32_t __regfpexc __ASM("fpexc"); - return(__regfpexc); -#else - return(0); -#endif -} - - -/** \brief Set FPEXC - - This function assigns the given value to the Floating Point Exception Control register. - - \param [in] fpscr Floating Point Exception Control value to set - */ -__STATIC_INLINE void __set_FPEXC(uint32_t fpexc) -{ -#if (__FPU_PRESENT == 1) - register uint32_t __regfpexc __ASM("fpexc"); - __regfpexc = (fpexc); -#endif -} - -/** \brief Get CPACR - - This function returns the current value of the Coprocessor Access Control register. - - \return Coprocessor Access Control register value - */ -__STATIC_INLINE uint32_t __get_CPACR(void) -{ - register uint32_t __regCPACR __ASM("cp15:0:c1:c0:2"); - return __regCPACR; -} - -/** \brief Set CPACR - - This function assigns the given value to the Coprocessor Access Control register. - - \param [in] cpacr Coprocessor Acccess Control value to set - */ -__STATIC_INLINE void __set_CPACR(uint32_t cpacr) -{ - register uint32_t __regCPACR __ASM("cp15:0:c1:c0:2"); - __regCPACR = cpacr; - __ISB(); -} - -/** \brief Get CBAR - - This function returns the value of the Configuration Base Address register. - - \return Configuration Base Address register value - */ -__STATIC_INLINE uint32_t __get_CBAR() { - register uint32_t __regCBAR __ASM("cp15:4:c15:c0:0"); - return(__regCBAR); -} - -/** \brief Get TTBR0 - - This function returns the value of the Translation Table Base Register 0. - - \return Translation Table Base Register 0 value - */ -__STATIC_INLINE uint32_t __get_TTBR0() { - register uint32_t __regTTBR0 __ASM("cp15:0:c2:c0:0"); - return(__regTTBR0); -} - -/** \brief Set TTBR0 - - This function assigns the given value to the Translation Table Base Register 0. - - \param [in] ttbr0 Translation Table Base Register 0 value to set - */ -__STATIC_INLINE void __set_TTBR0(uint32_t ttbr0) { - register uint32_t __regTTBR0 __ASM("cp15:0:c2:c0:0"); - __regTTBR0 = ttbr0; - __ISB(); -} - -/** \brief Get DACR - - This function returns the value of the Domain Access Control Register. - - \return Domain Access Control Register value - */ -__STATIC_INLINE uint32_t __get_DACR() { - register uint32_t __regDACR __ASM("cp15:0:c3:c0:0"); - return(__regDACR); -} - -/** \brief Set DACR - - This function assigns the given value to the Domain Access Control Register. - - \param [in] dacr Domain Access Control Register value to set - */ -__STATIC_INLINE void __set_DACR(uint32_t dacr) { - register uint32_t __regDACR __ASM("cp15:0:c3:c0:0"); - __regDACR = dacr; - __ISB(); -} - -/******************************** Cache and BTAC enable ****************************************************/ - -/** \brief Set SCTLR - - This function assigns the given value to the System Control Register. - - \param [in] sctlr System Control Register value to set - */ -__STATIC_INLINE void __set_SCTLR(uint32_t sctlr) -{ - register uint32_t __regSCTLR __ASM("cp15:0:c1:c0:0"); - __regSCTLR = sctlr; -} - -/** \brief Get SCTLR - - This function returns the value of the System Control Register. - - \return System Control Register value - */ -__STATIC_INLINE uint32_t __get_SCTLR() { - register uint32_t __regSCTLR __ASM("cp15:0:c1:c0:0"); - return(__regSCTLR); -} - -/** \brief Enable Caches - - Enable Caches - */ -__STATIC_INLINE void __enable_caches(void) { - // Set I bit 12 to enable I Cache - // Set C bit 2 to enable D Cache - __set_SCTLR( __get_SCTLR() | (1 << 12) | (1 << 2)); -} - -/** \brief Disable Caches - - Disable Caches - */ -__STATIC_INLINE void __disable_caches(void) { - // Clear I bit 12 to disable I Cache - // Clear C bit 2 to disable D Cache - __set_SCTLR( __get_SCTLR() & ~(1 << 12) & ~(1 << 2)); - __ISB(); -} - -/** \brief Enable BTAC - - Enable BTAC - */ -__STATIC_INLINE void __enable_btac(void) { - // Set Z bit 11 to enable branch prediction - __set_SCTLR( __get_SCTLR() | (1 << 11)); - __ISB(); -} - -/** \brief Disable BTAC - - Disable BTAC - */ -__STATIC_INLINE void __disable_btac(void) { - // Clear Z bit 11 to disable branch prediction - __set_SCTLR( __get_SCTLR() & ~(1 << 11)); -} - - -/** \brief Enable MMU - - Enable MMU - */ -__STATIC_INLINE void __enable_mmu(void) { - // Set M bit 0 to enable the MMU - // Set AFE bit to enable simplified access permissions model - // Clear TRE bit to disable TEX remap and A bit to disable strict alignment fault checking - __set_SCTLR( (__get_SCTLR() & ~(1 << 28) & ~(1 << 1)) | 1 | (1 << 29)); - __ISB(); -} - -/** \brief Disable MMU - - Disable MMU - */ -__STATIC_INLINE void __disable_mmu(void) { - // Clear M bit 0 to disable the MMU - __set_SCTLR( __get_SCTLR() & ~1); - __ISB(); -} - -/******************************** TLB maintenance operations ************************************************/ -/** \brief Invalidate the whole tlb - - TLBIALL. Invalidate the whole tlb - */ - -__STATIC_INLINE void __ca9u_inv_tlb_all(void) { - register uint32_t __TLBIALL __ASM("cp15:0:c8:c7:0"); - __TLBIALL = 0; - __DSB(); - __ISB(); -} - -/******************************** BTB maintenance operations ************************************************/ -/** \brief Invalidate entire branch predictor array - - BPIALL. Branch Predictor Invalidate All. - */ - -__STATIC_INLINE void __v7_inv_btac(void) { - register uint32_t __BPIALL __ASM("cp15:0:c7:c5:6"); - __BPIALL = 0; - __DSB(); //ensure completion of the invalidation - __ISB(); //ensure instruction fetch path sees new state -} - - -/******************************** L1 cache operations ******************************************************/ - -/** \brief Invalidate the whole I$ - - ICIALLU. Instruction Cache Invalidate All to PoU - */ -__STATIC_INLINE void __v7_inv_icache_all(void) { - register uint32_t __ICIALLU __ASM("cp15:0:c7:c5:0"); - __ICIALLU = 0; - __DSB(); //ensure completion of the invalidation - __ISB(); //ensure instruction fetch path sees new I cache state -} - -/** \brief Clean D$ by MVA - - DCCMVAC. Data cache clean by MVA to PoC - */ -__STATIC_INLINE void __v7_clean_dcache_mva(void *va) { - register uint32_t __DCCMVAC __ASM("cp15:0:c7:c10:1"); - __DCCMVAC = (uint32_t)va; - __DMB(); //ensure the ordering of data cache maintenance operations and their effects -} - -/** \brief Invalidate D$ by MVA - - DCIMVAC. Data cache invalidate by MVA to PoC - */ -__STATIC_INLINE void __v7_inv_dcache_mva(void *va) { - register uint32_t __DCIMVAC __ASM("cp15:0:c7:c6:1"); - __DCIMVAC = (uint32_t)va; - __DMB(); //ensure the ordering of data cache maintenance operations and their effects -} - -/** \brief Clean and Invalidate D$ by MVA - - DCCIMVAC. Data cache clean and invalidate by MVA to PoC - */ -__STATIC_INLINE void __v7_clean_inv_dcache_mva(void *va) { - register uint32_t __DCCIMVAC __ASM("cp15:0:c7:c14:1"); - __DCCIMVAC = (uint32_t)va; - __DMB(); //ensure the ordering of data cache maintenance operations and their effects -} - -/** \brief Clean and Invalidate the entire data or unified cache - - Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency. - */ -#pragma push -#pragma arm -__STATIC_ASM void __v7_all_cache(uint32_t op) { - ARM - - PUSH {R4-R11} - - MRC p15, 1, R6, c0, c0, 1 // Read CLIDR - ANDS R3, R6, #0x07000000 // Extract coherency level - MOV R3, R3, LSR #23 // Total cache levels << 1 - BEQ Finished // If 0, no need to clean - - MOV R10, #0 // R10 holds current cache level << 1 -Loop1 ADD R2, R10, R10, LSR #1 // R2 holds cache "Set" position - MOV R1, R6, LSR R2 // Bottom 3 bits are the Cache-type for this level - AND R1, R1, #7 // Isolate those lower 3 bits - CMP R1, #2 - BLT Skip // No cache or only instruction cache at this level - - MCR p15, 2, R10, c0, c0, 0 // Write the Cache Size selection register - ISB // ISB to sync the change to the CacheSizeID reg - MRC p15, 1, R1, c0, c0, 0 // Reads current Cache Size ID register - AND R2, R1, #7 // Extract the line length field - ADD R2, R2, #4 // Add 4 for the line length offset (log2 16 bytes) - LDR R4, =0x3FF - ANDS R4, R4, R1, LSR #3 // R4 is the max number on the way size (right aligned) - CLZ R5, R4 // R5 is the bit position of the way size increment - LDR R7, =0x7FFF - ANDS R7, R7, R1, LSR #13 // R7 is the max number of the index size (right aligned) - -Loop2 MOV R9, R4 // R9 working copy of the max way size (right aligned) - -Loop3 ORR R11, R10, R9, LSL R5 // Factor in the Way number and cache number into R11 - ORR R11, R11, R7, LSL R2 // Factor in the Set number - CMP R0, #0 - BNE Dccsw - MCR p15, 0, R11, c7, c6, 2 // DCISW. Invalidate by Set/Way - B cont -Dccsw CMP R0, #1 - BNE Dccisw - MCR p15, 0, R11, c7, c10, 2 // DCCSW. Clean by Set/Way - B cont -Dccisw MCR p15, 0, R11, c7, c14, 2 // DCCISW. Clean and Invalidate by Set/Way -cont SUBS R9, R9, #1 // Decrement the Way number - BGE Loop3 - SUBS R7, R7, #1 // Decrement the Set number - BGE Loop2 -Skip ADD R10, R10, #2 // Increment the cache number - CMP R3, R10 - BGT Loop1 - -Finished - DSB - POP {R4-R11} - BX lr - -} -#pragma pop - - -/** \brief Invalidate the whole D$ - - DCISW. Invalidate by Set/Way - */ - -__STATIC_INLINE void __v7_inv_dcache_all(void) { - __v7_all_cache(0); -} - -/** \brief Clean the whole D$ - - DCCSW. Clean by Set/Way - */ - -__STATIC_INLINE void __v7_clean_dcache_all(void) { - __v7_all_cache(1); -} - -/** \brief Clean and invalidate the whole D$ - - DCCISW. Clean and Invalidate by Set/Way - */ - -__STATIC_INLINE void __v7_clean_inv_dcache_all(void) { - __v7_all_cache(2); -} - -#include "core_ca_mmu.h" - -#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/ - -#define __inline inline - -inline static uint32_t __disable_irq_iar() { - int irq_dis = __get_CPSR() & 0x80; // 7bit CPSR.I - __disable_irq(); - return irq_dis; -} - -#define MODE_USR 0x10 -#define MODE_FIQ 0x11 -#define MODE_IRQ 0x12 -#define MODE_SVC 0x13 -#define MODE_MON 0x16 -#define MODE_ABT 0x17 -#define MODE_HYP 0x1A -#define MODE_UND 0x1B -#define MODE_SYS 0x1F - -/** \brief Set Process Stack Pointer - - This function assigns the given value to the USR/SYS Stack Pointer (PSP). - - \param [in] topOfProcStack USR/SYS Stack Pointer value to set - */ -// from rt_CMSIS.c -__arm static inline void __set_PSP(uint32_t topOfProcStack) { -__asm( - " ARM\n" -// " PRESERVE8\n" - - " BIC R0, R0, #7 ;ensure stack is 8-byte aligned \n" - " MRS R1, CPSR \n" - " CPS #0x1F ;no effect in USR mode \n" // MODE_SYS - " MOV SP, R0 \n" - " MSR CPSR_c, R1 ;no effect in USR mode \n" - " ISB \n" - " BX LR \n"); -} - -/** \brief Set User Mode - - This function changes the processor state to User Mode - */ -// from rt_CMSIS.c -__arm static inline void __set_CPS_USR(void) { -__asm( - " ARM \n" - - " CPS #0x10 \n" // MODE_USR - " BX LR\n"); -} - -/** \brief Set TTBR0 - - This function assigns the given value to the Translation Table Base Register 0. - - \param [in] ttbr0 Translation Table Base Register 0 value to set - */ -// from mmu_Renesas_RZ_A1.c -__STATIC_INLINE void __set_TTBR0(uint32_t ttbr0) { - __MCR(15, 0, ttbr0, 2, 0, 0); // reg to cp15 - __ISB(); -} - -/** \brief Set DACR - - This function assigns the given value to the Domain Access Control Register. - - \param [in] dacr Domain Access Control Register value to set - */ -// from mmu_Renesas_RZ_A1.c -__STATIC_INLINE void __set_DACR(uint32_t dacr) { - __MCR(15, 0, dacr, 3, 0, 0); // reg to cp15 - __ISB(); -} - - -/******************************** Cache and BTAC enable ****************************************************/ -/** \brief Set SCTLR - - This function assigns the given value to the System Control Register. - - \param [in] sctlr System Control Register value to set - */ -// from __enable_mmu() -__STATIC_INLINE void __set_SCTLR(uint32_t sctlr) { - __MCR(15, 0, sctlr, 1, 0, 0); // reg to cp15 -} - -/** \brief Get SCTLR - - This function returns the value of the System Control Register. - - \return System Control Register value - */ -// from __enable_mmu() -__STATIC_INLINE uint32_t __get_SCTLR() { - uint32_t __regSCTLR = __MRC(15, 0, 1, 0, 0); - return __regSCTLR; -} - -/** \brief Enable Caches - - Enable Caches - */ -// from system_Renesas_RZ_A1.c -__STATIC_INLINE void __enable_caches(void) { - __set_SCTLR( __get_SCTLR() | (1 << 12) | (1 << 2)); -} - -/** \brief Enable BTAC - - Enable BTAC - */ -// from system_Renesas_RZ_A1.c -__STATIC_INLINE void __enable_btac(void) { - __set_SCTLR( __get_SCTLR() | (1 << 11)); - __ISB(); -} - -/** \brief Enable MMU - - Enable MMU - */ -// from system_Renesas_RZ_A1.c -__STATIC_INLINE void __enable_mmu(void) { - // Set M bit 0 to enable the MMU - // Set AFE bit to enable simplified access permissions model - // Clear TRE bit to disable TEX remap and A bit to disable strict alignment fault checking - __set_SCTLR( (__get_SCTLR() & ~(1 << 28) & ~(1 << 1)) | 1 | (1 << 29)); - __ISB(); -} - -/******************************** TLB maintenance operations ************************************************/ -/** \brief Invalidate the whole tlb - - TLBIALL. Invalidate the whole tlb - */ -// from system_Renesas_RZ_A1.c -__STATIC_INLINE void __ca9u_inv_tlb_all(void) { - uint32_t val = 0; - __MCR(15, 0, val, 8, 7, 0); // reg to cp15 - __MCR(15, 0, val, 8, 6, 0); // reg to cp15 - __MCR(15, 0, val, 8, 5, 0); // reg to cp15 - __DSB(); - __ISB(); -} - -/******************************** BTB maintenance operations ************************************************/ -/** \brief Invalidate entire branch predictor array - - BPIALL. Branch Predictor Invalidate All. - */ -// from system_Renesas_RZ_A1.c -__STATIC_INLINE void __v7_inv_btac(void) { - uint32_t val = 0; - __MCR(15, 0, val, 7, 5, 6); // reg to cp15 - __DSB(); //ensure completion of the invalidation - __ISB(); //ensure instruction fetch path sees new state -} - - -/******************************** L1 cache operations ******************************************************/ - -/** \brief Invalidate the whole I$ - - ICIALLU. Instruction Cache Invalidate All to PoU - */ -// from system_Renesas_RZ_A1.c -__STATIC_INLINE void __v7_inv_icache_all(void) { - uint32_t val = 0; - __MCR(15, 0, val, 7, 5, 0); // reg to cp15 - __DSB(); //ensure completion of the invalidation - __ISB(); //ensure instruction fetch path sees new I cache state -} - -// from __v7_inv_dcache_all() -__arm static inline void __v7_all_cache(uint32_t op) { -__asm( - " ARM \n" - - " PUSH {R4-R11} \n" - - " MRC p15, 1, R6, c0, c0, 1\n" // Read CLIDR - " ANDS R3, R6, #0x07000000\n" // Extract coherency level - " MOV R3, R3, LSR #23\n" // Total cache levels << 1 - " BEQ Finished\n" // If 0, no need to clean - - " MOV R10, #0\n" // R10 holds current cache level << 1 - "Loop1: ADD R2, R10, R10, LSR #1\n" // R2 holds cache "Set" position - " MOV R1, R6, LSR R2 \n" // Bottom 3 bits are the Cache-type for this level - " AND R1, R1, #7 \n" // Isolate those lower 3 bits - " CMP R1, #2 \n" - " BLT Skip \n" // No cache or only instruction cache at this level - - " MCR p15, 2, R10, c0, c0, 0 \n" // Write the Cache Size selection register - " ISB \n" // ISB to sync the change to the CacheSizeID reg - " MRC p15, 1, R1, c0, c0, 0 \n" // Reads current Cache Size ID register - " AND R2, R1, #7 \n" // Extract the line length field - " ADD R2, R2, #4 \n" // Add 4 for the line length offset (log2 16 bytes) - " movw R4, #0x3FF \n" - " ANDS R4, R4, R1, LSR #3 \n" // R4 is the max number on the way size (right aligned) - " CLZ R5, R4 \n" // R5 is the bit position of the way size increment - " movw R7, #0x7FFF \n" - " ANDS R7, R7, R1, LSR #13 \n" // R7 is the max number of the index size (right aligned) - - "Loop2: MOV R9, R4 \n" // R9 working copy of the max way size (right aligned) - - "Loop3: ORR R11, R10, R9, LSL R5 \n" // Factor in the Way number and cache number into R11 - " ORR R11, R11, R7, LSL R2 \n" // Factor in the Set number - " CMP R0, #0 \n" - " BNE Dccsw \n" - " MCR p15, 0, R11, c7, c6, 2 \n" // DCISW. Invalidate by Set/Way - " B cont \n" - "Dccsw: CMP R0, #1 \n" - " BNE Dccisw \n" - " MCR p15, 0, R11, c7, c10, 2 \n" // DCCSW. Clean by Set/Way - " B cont \n" - "Dccisw: MCR p15, 0, R11, c7, c14, 2 \n" // DCCISW, Clean and Invalidate by Set/Way - "cont: SUBS R9, R9, #1 \n" // Decrement the Way number - " BGE Loop3 \n" - " SUBS R7, R7, #1 \n" // Decrement the Set number - " BGE Loop2 \n" - "Skip: ADD R10, R10, #2 \n" // increment the cache number - " CMP R3, R10 \n" - " BGT Loop1 \n" - - "Finished: \n" - " DSB \n" - " POP {R4-R11} \n" - " BX lr \n" ); -} - -/** \brief Invalidate the whole D$ - - DCISW. Invalidate by Set/Way - */ -// from system_Renesas_RZ_A1.c -__STATIC_INLINE void __v7_inv_dcache_all(void) { - __v7_all_cache(0); -} -/** \brief Clean the whole D$ - - DCCSW. Clean by Set/Way - */ - -__STATIC_INLINE void __v7_clean_dcache_all(void) { - __v7_all_cache(1); -} - -/** \brief Clean and invalidate the whole D$ - - DCCISW. Clean and Invalidate by Set/Way - */ - -__STATIC_INLINE void __v7_clean_inv_dcache_all(void) { - __v7_all_cache(2); -} -/** \brief Clean and Invalidate D$ by MVA - - DCCIMVAC. Data cache clean and invalidate by MVA to PoC - */ -__STATIC_INLINE void __v7_clean_inv_dcache_mva(void *va) { - __MCR(15, 0, (uint32_t)va, 7, 14, 1); - __DMB(); -} - -#include "core_ca_mmu.h" - -#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -#define MODE_USR 0x10 -#define MODE_FIQ 0x11 -#define MODE_IRQ 0x12 -#define MODE_SVC 0x13 -#define MODE_MON 0x16 -#define MODE_ABT 0x17 -#define MODE_HYP 0x1A -#define MODE_UND 0x1B -#define MODE_SYS 0x1F - - -__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) -{ - __ASM volatile ("cpsie i"); -} - -/** \brief Disable IRQ Interrupts - - This function disables IRQ interrupts by setting the I-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __disable_irq(void) -{ - uint32_t result; - - __ASM volatile ("mrs %0, cpsr" : "=r" (result)); - __ASM volatile ("cpsid i"); - return(result & 0x80); -} - - -/** \brief Get APSR Register - - This function returns the content of the APSR Register. - - \return APSR Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) -{ -#if 1 - register uint32_t __regAPSR; - __ASM volatile ("mrs %0, apsr" : "=r" (__regAPSR) ); -#else - register uint32_t __regAPSR __ASM("apsr"); -#endif - return(__regAPSR); -} - - -/** \brief Get CPSR Register - - This function returns the content of the CPSR Register. - - \return CPSR Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CPSR(void) -{ -#if 1 - register uint32_t __regCPSR; - __ASM volatile ("mrs %0, cpsr" : "=r" (__regCPSR)); -#else - register uint32_t __regCPSR __ASM("cpsr"); -#endif - return(__regCPSR); -} - -#if 0 -/** \brief Set Stack Pointer - - This function assigns the given value to the current stack pointer. - - \param [in] topOfStack Stack Pointer value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_SP(uint32_t topOfStack) -{ - register uint32_t __regSP __ASM("sp"); - __regSP = topOfStack; -} -#endif - -/** \brief Get link register - - This function returns the value of the link register - - \return Value of link register - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_LR(void) -{ - register uint32_t __reglr __ASM("lr"); - return(__reglr); -} - -#if 0 -/** \brief Set link register - - This function sets the value of the link register - - \param [in] lr LR value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_LR(uint32_t lr) -{ - register uint32_t __reglr __ASM("lr"); - __reglr = lr; -} -#endif - -/** \brief Set Process Stack Pointer - - This function assigns the given value to the USR/SYS Stack Pointer (PSP). - - \param [in] topOfProcStack USR/SYS Stack Pointer value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) -{ - __asm__ volatile ( - ".ARM;" - ".eabi_attribute Tag_ABI_align8_preserved,1;" - - "BIC R0, R0, #7;" /* ;ensure stack is 8-byte aligned */ - "MRS R1, CPSR;" - "CPS %0;" /* ;no effect in USR mode */ - "MOV SP, R0;" - "MSR CPSR_c, R1;" /* ;no effect in USR mode */ - "ISB;" - //"BX LR;" - : - : "i"(MODE_SYS) - : "r0", "r1"); - return; -} - -/** \brief Set User Mode - - This function changes the processor state to User Mode - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CPS_USR(void) -{ - __asm__ volatile ( - ".ARM;" - - "CPS %0;" - //"BX LR;" - : - : "i"(MODE_USR) - : ); - return; -} - - -/** \brief Enable FIQ - - This function enables FIQ interrupts by clearing the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -#define __enable_fault_irq() __asm__ volatile ("cpsie f") - - -/** \brief Disable FIQ - - This function disables FIQ interrupts by setting the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -#define __disable_fault_irq() __asm__ volatile ("cpsid f") - - -/** \brief Get FPSCR - - This function returns the current value of the Floating Point Status/Control register. - - \return Floating Point Status/Control register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) -{ -#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) -#if 1 - uint32_t result; - - __ASM volatile ("vmrs %0, fpscr" : "=r" (result) ); - return (result); -#else - register uint32_t __regfpscr __ASM("fpscr"); - return(__regfpscr); -#endif -#else - return(0); -#endif -} - - -/** \brief Set FPSCR - - This function assigns the given value to the Floating Point Status/Control register. - - \param [in] fpscr Floating Point Status/Control value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) -{ -#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) -#if 1 - __ASM volatile ("vmsr fpscr, %0" : : "r" (fpscr) ); -#else - register uint32_t __regfpscr __ASM("fpscr"); - __regfpscr = (fpscr); -#endif -#endif -} - -/** \brief Get FPEXC - - This function returns the current value of the Floating Point Exception Control register. - - \return Floating Point Exception Control register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPEXC(void) -{ -#if (__FPU_PRESENT == 1) -#if 1 - uint32_t result; - - __ASM volatile ("vmrs %0, fpexc" : "=r" (result)); - return (result); -#else - register uint32_t __regfpexc __ASM("fpexc"); - return(__regfpexc); -#endif -#else - return(0); -#endif -} - - -/** \brief Set FPEXC - - This function assigns the given value to the Floating Point Exception Control register. - - \param [in] fpscr Floating Point Exception Control value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPEXC(uint32_t fpexc) -{ -#if (__FPU_PRESENT == 1) -#if 1 - __ASM volatile ("vmsr fpexc, %0" : : "r" (fpexc)); -#else - register uint32_t __regfpexc __ASM("fpexc"); - __regfpexc = (fpexc); -#endif -#endif -} - -/** \brief Get CPACR - - This function returns the current value of the Coprocessor Access Control register. - - \return Coprocessor Access Control register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CPACR(void) -{ -#if 1 - register uint32_t __regCPACR; - __ASM volatile ("mrc p15, 0, %0, c1, c0, 2" : "=r" (__regCPACR)); -#else - register uint32_t __regCPACR __ASM("cp15:0:c1:c0:2"); -#endif - return __regCPACR; -} - -/** \brief Set CPACR - - This function assigns the given value to the Coprocessor Access Control register. - - \param [in] cpacr Coprocessor Acccess Control value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CPACR(uint32_t cpacr) -{ -#if 1 - __ASM volatile ("mcr p15, 0, %0, c1, c0, 2" : : "r" (cpacr)); -#else - register uint32_t __regCPACR __ASM("cp15:0:c1:c0:2"); - __regCPACR = cpacr; -#endif - __ISB(); -} - -/** \brief Get CBAR - - This function returns the value of the Configuration Base Address register. - - \return Configuration Base Address register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CBAR() { -#if 1 - register uint32_t __regCBAR; - __ASM volatile ("mrc p15, 4, %0, c15, c0, 0" : "=r" (__regCBAR)); -#else - register uint32_t __regCBAR __ASM("cp15:4:c15:c0:0"); -#endif - return(__regCBAR); -} - -/** \brief Get TTBR0 - - This function returns the value of the Translation Table Base Register 0. - - \return Translation Table Base Register 0 value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_TTBR0() { -#if 1 - register uint32_t __regTTBR0; - __ASM volatile ("mrc p15, 0, %0, c2, c0, 0" : "=r" (__regTTBR0)); -#else - register uint32_t __regTTBR0 __ASM("cp15:0:c2:c0:0"); -#endif - return(__regTTBR0); -} - -/** \brief Set TTBR0 - - This function assigns the given value to the Translation Table Base Register 0. - - \param [in] ttbr0 Translation Table Base Register 0 value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_TTBR0(uint32_t ttbr0) { -#if 1 - __ASM volatile ("mcr p15, 0, %0, c2, c0, 0" : : "r" (ttbr0)); -#else - register uint32_t __regTTBR0 __ASM("cp15:0:c2:c0:0"); - __regTTBR0 = ttbr0; -#endif - __ISB(); -} - -/** \brief Get DACR - - This function returns the value of the Domain Access Control Register. - - \return Domain Access Control Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_DACR() { -#if 1 - register uint32_t __regDACR; - __ASM volatile ("mrc p15, 0, %0, c3, c0, 0" : "=r" (__regDACR)); -#else - register uint32_t __regDACR __ASM("cp15:0:c3:c0:0"); -#endif - return(__regDACR); -} - -/** \brief Set DACR - - This function assigns the given value to the Domain Access Control Register. - - \param [in] dacr Domain Access Control Register value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_DACR(uint32_t dacr) { -#if 1 - __ASM volatile ("mcr p15, 0, %0, c3, c0, 0" : : "r" (dacr)); -#else - register uint32_t __regDACR __ASM("cp15:0:c3:c0:0"); - __regDACR = dacr; -#endif - __ISB(); -} - -/******************************** Cache and BTAC enable ****************************************************/ - -/** \brief Set SCTLR - - This function assigns the given value to the System Control Register. - - \param [in] sctlr System Control Register value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_SCTLR(uint32_t sctlr) -{ -#if 1 - __ASM volatile ("mcr p15, 0, %0, c1, c0, 0" : : "r" (sctlr)); -#else - register uint32_t __regSCTLR __ASM("cp15:0:c1:c0:0"); - __regSCTLR = sctlr; -#endif -} - -/** \brief Get SCTLR - - This function returns the value of the System Control Register. - - \return System Control Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_SCTLR() { -#if 1 - register uint32_t __regSCTLR; - __ASM volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r" (__regSCTLR)); -#else - register uint32_t __regSCTLR __ASM("cp15:0:c1:c0:0"); -#endif - return(__regSCTLR); -} - -/** \brief Enable Caches - - Enable Caches - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_caches(void) { - // Set I bit 12 to enable I Cache - // Set C bit 2 to enable D Cache - __set_SCTLR( __get_SCTLR() | (1 << 12) | (1 << 2)); -} - -/** \brief Disable Caches - - Disable Caches - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_caches(void) { - // Clear I bit 12 to disable I Cache - // Clear C bit 2 to disable D Cache - __set_SCTLR( __get_SCTLR() & ~(1 << 12) & ~(1 << 2)); - __ISB(); -} - -/** \brief Enable BTAC - - Enable BTAC - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_btac(void) { - // Set Z bit 11 to enable branch prediction - __set_SCTLR( __get_SCTLR() | (1 << 11)); - __ISB(); -} - -/** \brief Disable BTAC - - Disable BTAC - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_btac(void) { - // Clear Z bit 11 to disable branch prediction - __set_SCTLR( __get_SCTLR() & ~(1 << 11)); -} - - -/** \brief Enable MMU - - Enable MMU - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_mmu(void) { - // Set M bit 0 to enable the MMU - // Set AFE bit to enable simplified access permissions model - // Clear TRE bit to disable TEX remap and A bit to disable strict alignment fault checking - __set_SCTLR( (__get_SCTLR() & ~(1 << 28) & ~(1 << 1)) | 1 | (1 << 29)); - __ISB(); -} - -/** \brief Disable MMU - - Disable MMU - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_mmu(void) { - // Clear M bit 0 to disable the MMU - __set_SCTLR( __get_SCTLR() & ~1); - __ISB(); -} - -/******************************** TLB maintenance operations ************************************************/ -/** \brief Invalidate the whole tlb - - TLBIALL. Invalidate the whole tlb - */ - -__attribute__( ( always_inline ) ) __STATIC_INLINE void __ca9u_inv_tlb_all(void) { -#if 1 - __ASM volatile ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0)); -#else - register uint32_t __TLBIALL __ASM("cp15:0:c8:c7:0"); - __TLBIALL = 0; -#endif - __DSB(); - __ISB(); -} - -/******************************** BTB maintenance operations ************************************************/ -/** \brief Invalidate entire branch predictor array - - BPIALL. Branch Predictor Invalidate All. - */ - -__attribute__( ( always_inline ) ) __STATIC_INLINE void __v7_inv_btac(void) { -#if 1 - __ASM volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0)); -#else - register uint32_t __BPIALL __ASM("cp15:0:c7:c5:6"); - __BPIALL = 0; -#endif - __DSB(); //ensure completion of the invalidation - __ISB(); //ensure instruction fetch path sees new state -} - - -/******************************** L1 cache operations ******************************************************/ - -/** \brief Invalidate the whole I$ - - ICIALLU. Instruction Cache Invalidate All to PoU - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __v7_inv_icache_all(void) { -#if 1 - __ASM volatile ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0)); -#else - register uint32_t __ICIALLU __ASM("cp15:0:c7:c5:0"); - __ICIALLU = 0; -#endif - __DSB(); //ensure completion of the invalidation - __ISB(); //ensure instruction fetch path sees new I cache state -} - -/** \brief Clean D$ by MVA - - DCCMVAC. Data cache clean by MVA to PoC - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __v7_clean_dcache_mva(void *va) { -#if 1 - __ASM volatile ("mcr p15, 0, %0, c7, c10, 1" : : "r" ((uint32_t)va)); -#else - register uint32_t __DCCMVAC __ASM("cp15:0:c7:c10:1"); - __DCCMVAC = (uint32_t)va; -#endif - __DMB(); //ensure the ordering of data cache maintenance operations and their effects -} - -/** \brief Invalidate D$ by MVA - - DCIMVAC. Data cache invalidate by MVA to PoC - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __v7_inv_dcache_mva(void *va) { -#if 1 - __ASM volatile ("mcr p15, 0, %0, c7, c6, 1" : : "r" ((uint32_t)va)); -#else - register uint32_t __DCIMVAC __ASM("cp15:0:c7:c6:1"); - __DCIMVAC = (uint32_t)va; -#endif - __DMB(); //ensure the ordering of data cache maintenance operations and their effects -} - -/** \brief Clean and Invalidate D$ by MVA - - DCCIMVAC. Data cache clean and invalidate by MVA to PoC - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __v7_clean_inv_dcache_mva(void *va) { -#if 1 - __ASM volatile ("mcr p15, 0, %0, c7, c14, 1" : : "r" ((uint32_t)va)); -#else - register uint32_t __DCCIMVAC __ASM("cp15:0:c7:c14:1"); - __DCCIMVAC = (uint32_t)va; -#endif - __DMB(); //ensure the ordering of data cache maintenance operations and their effects -} - -/** \brief Clean and Invalidate the entire data or unified cache - - Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency. - */ -extern void __v7_all_cache(uint32_t op); - - -/** \brief Invalidate the whole D$ - - DCISW. Invalidate by Set/Way - */ - -__attribute__( ( always_inline ) ) __STATIC_INLINE void __v7_inv_dcache_all(void) { - __v7_all_cache(0); -} - -/** \brief Clean the whole D$ - - DCCSW. Clean by Set/Way - */ - -__attribute__( ( always_inline ) ) __STATIC_INLINE void __v7_clean_dcache_all(void) { - __v7_all_cache(1); -} - -/** \brief Clean and invalidate the whole D$ - - DCCISW. Clean and Invalidate by Set/Way - */ - -__attribute__( ( always_inline ) ) __STATIC_INLINE void __v7_clean_inv_dcache_all(void) { - __v7_all_cache(2); -} - -#include "core_ca_mmu.h" - -#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/ - -#error TASKING Compiler support not implemented for Cortex-A - -#endif - -/*@} end of CMSIS_Core_RegAccFunctions */ - - -#endif /* __CORE_CAFUNC_H__ */ diff --git a/cmsis/TARGET_CORTEX_A/core_caInstr.h b/cmsis/TARGET_CORTEX_A/core_caInstr.h deleted file mode 100644 index b1d34357650..00000000000 --- a/cmsis/TARGET_CORTEX_A/core_caInstr.h +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************//** - * @file core_caInstr.h - * @brief CMSIS Cortex-A9 Core Peripheral Access Layer Header File - * @version - * @date 04. December 2012 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2012 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - -#ifndef __CORE_CAINSTR_H__ -#define __CORE_CAINSTR_H__ - -#define __CORTEX_M 0x3 -#include "core_cmInstr.h" -#undef __CORTEX_M - -#endif - diff --git a/cmsis/TARGET_CORTEX_A/core_ca_mmu.h b/cmsis/TARGET_CORTEX_A/core_ca_mmu.h deleted file mode 100644 index 189b073dbc9..00000000000 --- a/cmsis/TARGET_CORTEX_A/core_ca_mmu.h +++ /dev/null @@ -1,847 +0,0 @@ -;/**************************************************************************//** -; * @file core_ca_mmu.h -; * @brief MMU Startup File for A9_MP Device Series -; * @version V1.01 -; * @date 10 Sept 2014 -; * -; * @note -; * -; ******************************************************************************/ -;/* Copyright (c) 2012-2014 ARM LIMITED -; -; All rights reserved. -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; - Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; - Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; - Neither the name of ARM nor the names of its contributors may be used -; to endorse or promote products derived from this software without -; specific prior written permission. -; * -; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; POSSIBILITY OF SUCH DAMAGE. -; ---------------------------------------------------------------------------*/ - -#ifdef __cplusplus - extern "C" { -#endif - -#ifndef _MMU_FUNC_H -#define _MMU_FUNC_H - -#define SECTION_DESCRIPTOR (0x2) -#define SECTION_MASK (0xFFFFFFFC) - -#define SECTION_TEXCB_MASK (0xFFFF8FF3) -#define SECTION_B_SHIFT (2) -#define SECTION_C_SHIFT (3) -#define SECTION_TEX0_SHIFT (12) -#define SECTION_TEX1_SHIFT (13) -#define SECTION_TEX2_SHIFT (14) - -#define SECTION_XN_MASK (0xFFFFFFEF) -#define SECTION_XN_SHIFT (4) - -#define SECTION_DOMAIN_MASK (0xFFFFFE1F) -#define SECTION_DOMAIN_SHIFT (5) - -#define SECTION_P_MASK (0xFFFFFDFF) -#define SECTION_P_SHIFT (9) - -#define SECTION_AP_MASK (0xFFFF73FF) -#define SECTION_AP_SHIFT (10) -#define SECTION_AP2_SHIFT (15) - -#define SECTION_S_MASK (0xFFFEFFFF) -#define SECTION_S_SHIFT (16) - -#define SECTION_NG_MASK (0xFFFDFFFF) -#define SECTION_NG_SHIFT (17) - -#define SECTION_NS_MASK (0xFFF7FFFF) -#define SECTION_NS_SHIFT (19) - - -#define PAGE_L1_DESCRIPTOR (0x1) -#define PAGE_L1_MASK (0xFFFFFFFC) - -#define PAGE_L2_4K_DESC (0x2) -#define PAGE_L2_4K_MASK (0xFFFFFFFD) - -#define PAGE_L2_64K_DESC (0x1) -#define PAGE_L2_64K_MASK (0xFFFFFFFC) - -#define PAGE_4K_TEXCB_MASK (0xFFFFFE33) -#define PAGE_4K_B_SHIFT (2) -#define PAGE_4K_C_SHIFT (3) -#define PAGE_4K_TEX0_SHIFT (6) -#define PAGE_4K_TEX1_SHIFT (7) -#define PAGE_4K_TEX2_SHIFT (8) - -#define PAGE_64K_TEXCB_MASK (0xFFFF8FF3) -#define PAGE_64K_B_SHIFT (2) -#define PAGE_64K_C_SHIFT (3) -#define PAGE_64K_TEX0_SHIFT (12) -#define PAGE_64K_TEX1_SHIFT (13) -#define PAGE_64K_TEX2_SHIFT (14) - -#define PAGE_TEXCB_MASK (0xFFFF8FF3) -#define PAGE_B_SHIFT (2) -#define PAGE_C_SHIFT (3) -#define PAGE_TEX_SHIFT (12) - -#define PAGE_XN_4K_MASK (0xFFFFFFFE) -#define PAGE_XN_4K_SHIFT (0) -#define PAGE_XN_64K_MASK (0xFFFF7FFF) -#define PAGE_XN_64K_SHIFT (15) - - -#define PAGE_DOMAIN_MASK (0xFFFFFE1F) -#define PAGE_DOMAIN_SHIFT (5) - -#define PAGE_P_MASK (0xFFFFFDFF) -#define PAGE_P_SHIFT (9) - -#define PAGE_AP_MASK (0xFFFFFDCF) -#define PAGE_AP_SHIFT (4) -#define PAGE_AP2_SHIFT (9) - -#define PAGE_S_MASK (0xFFFFFBFF) -#define PAGE_S_SHIFT (10) - -#define PAGE_NG_MASK (0xFFFFF7FF) -#define PAGE_NG_SHIFT (11) - -#define PAGE_NS_MASK (0xFFFFFFF7) -#define PAGE_NS_SHIFT (3) - -#define OFFSET_1M (0x00100000) -#define OFFSET_64K (0x00010000) -#define OFFSET_4K (0x00001000) - -#define DESCRIPTOR_FAULT (0x00000000) - -/* ########################### MMU Function Access ########################### */ -/** \ingroup MMU_FunctionInterface - \defgroup MMU_Functions MMU Functions Interface - @{ - */ - -/* Attributes enumerations */ - -/* Region size attributes */ -typedef enum -{ - SECTION, - PAGE_4k, - PAGE_64k, -} mmu_region_size_Type; - -/* Region type attributes */ -typedef enum -{ - NORMAL, - DEVICE, - SHARED_DEVICE, - NON_SHARED_DEVICE, - STRONGLY_ORDERED -} mmu_memory_Type; - -/* Region cacheability attributes */ -typedef enum -{ - NON_CACHEABLE, - WB_WA, - WT, - WB_NO_WA, -} mmu_cacheability_Type; - -/* Region parity check attributes */ -typedef enum -{ - ECC_DISABLED, - ECC_ENABLED, -} mmu_ecc_check_Type; - -/* Region execution attributes */ -typedef enum -{ - EXECUTE, - NON_EXECUTE, -} mmu_execute_Type; - -/* Region global attributes */ -typedef enum -{ - GLOBAL, - NON_GLOBAL, -} mmu_global_Type; - -/* Region shareability attributes */ -typedef enum -{ - NON_SHARED, - SHARED, -} mmu_shared_Type; - -/* Region security attributes */ -typedef enum -{ - SECURE, - NON_SECURE, -} mmu_secure_Type; - -/* Region access attributes */ -typedef enum -{ - NO_ACCESS, - RW, - READ, -} mmu_access_Type; - -/* Memory Region definition */ -typedef struct RegionStruct { - mmu_region_size_Type rg_t; - mmu_memory_Type mem_t; - uint8_t domain; - mmu_cacheability_Type inner_norm_t; - mmu_cacheability_Type outer_norm_t; - mmu_ecc_check_Type e_t; - mmu_execute_Type xn_t; - mmu_global_Type g_t; - mmu_secure_Type sec_t; - mmu_access_Type priv_t; - mmu_access_Type user_t; - mmu_shared_Type sh_t; - -} mmu_region_attributes_Type; - -/** \brief Set section execution-never attribute - - The function sets section execution-never attribute - - \param [out] descriptor_l1 L1 descriptor. - \param [in] xn Section execution-never attribute : EXECUTE , NON_EXECUTE. - - \return 0 - */ -__STATIC_INLINE int __xn_section(uint32_t *descriptor_l1, mmu_execute_Type xn) -{ - *descriptor_l1 &= SECTION_XN_MASK; - *descriptor_l1 |= ((xn & 0x1) << SECTION_XN_SHIFT); - return 0; -} - -/** \brief Set section domain - - The function sets section domain - - \param [out] descriptor_l1 L1 descriptor. - \param [in] domain Section domain - - \return 0 - */ -__STATIC_INLINE int __domain_section(uint32_t *descriptor_l1, uint8_t domain) -{ - *descriptor_l1 &= SECTION_DOMAIN_MASK; - *descriptor_l1 |= ((domain & 0xF) << SECTION_DOMAIN_SHIFT); - return 0; -} - -/** \brief Set section parity check - - The function sets section parity check - - \param [out] descriptor_l1 L1 descriptor. - \param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED - - \return 0 - */ -__STATIC_INLINE int __p_section(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit) -{ - *descriptor_l1 &= SECTION_P_MASK; - *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT); - return 0; -} - -/** \brief Set section access privileges - - The function sets section access privileges - - \param [out] descriptor_l1 L1 descriptor. - \param [in] user User Level Access: NO_ACCESS, RW, READ - \param [in] priv Privilege Level Access: NO_ACCESS, RW, READ - \param [in] afe Access flag enable - - \return 0 - */ -__STATIC_INLINE int __ap_section(uint32_t *descriptor_l1, mmu_access_Type user, mmu_access_Type priv, uint32_t afe) -{ - uint32_t ap = 0; - - if (afe == 0) { //full access - if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; } - else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } - else if ((priv == RW) && (user == READ)) { ap = 0x2; } - else if ((priv == RW) && (user == RW)) { ap = 0x3; } - else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } - else if ((priv == READ) && (user == READ)) { ap = 0x7; } - } - - else { //Simplified access - if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } - else if ((priv == RW) && (user == RW)) { ap = 0x3; } - else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } - else if ((priv == READ) && (user == READ)) { ap = 0x7; } - } - - *descriptor_l1 &= SECTION_AP_MASK; - *descriptor_l1 |= (ap & 0x3) << SECTION_AP_SHIFT; - *descriptor_l1 |= ((ap & 0x4)>>2) << SECTION_AP2_SHIFT; - - return 0; -} - -/** \brief Set section shareability - - The function sets section shareability - - \param [out] descriptor_l1 L1 descriptor. - \param [in] s_bit Section shareability: NON_SHARED, SHARED - - \return 0 - */ -__STATIC_INLINE int __shared_section(uint32_t *descriptor_l1, mmu_shared_Type s_bit) -{ - *descriptor_l1 &= SECTION_S_MASK; - *descriptor_l1 |= ((s_bit & 0x1) << SECTION_S_SHIFT); - return 0; -} - -/** \brief Set section Global attribute - - The function sets section Global attribute - - \param [out] descriptor_l1 L1 descriptor. - \param [in] g_bit Section attribute: GLOBAL, NON_GLOBAL - - \return 0 - */ -__STATIC_INLINE int __global_section(uint32_t *descriptor_l1, mmu_global_Type g_bit) -{ - *descriptor_l1 &= SECTION_NG_MASK; - *descriptor_l1 |= ((g_bit & 0x1) << SECTION_NG_SHIFT); - return 0; -} - -/** \brief Set section Security attribute - - The function sets section Global attribute - - \param [out] descriptor_l1 L1 descriptor. - \param [in] s_bit Section Security attribute: SECURE, NON_SECURE - - \return 0 - */ -__STATIC_INLINE int __secure_section(uint32_t *descriptor_l1, mmu_secure_Type s_bit) -{ - *descriptor_l1 &= SECTION_NS_MASK; - *descriptor_l1 |= ((s_bit & 0x1) << SECTION_NS_SHIFT); - return 0; -} - -/* Page 4k or 64k */ -/** \brief Set 4k/64k page execution-never attribute - - The function sets 4k/64k page execution-never attribute - - \param [out] descriptor_l2 L2 descriptor. - \param [in] xn Page execution-never attribute : EXECUTE , NON_EXECUTE. - \param [in] page Page size: PAGE_4k, PAGE_64k, - - \return 0 - */ -__STATIC_INLINE int __xn_page(uint32_t *descriptor_l2, mmu_execute_Type xn, mmu_region_size_Type page) -{ - if (page == PAGE_4k) - { - *descriptor_l2 &= PAGE_XN_4K_MASK; - *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_4K_SHIFT); - } - else - { - *descriptor_l2 &= PAGE_XN_64K_MASK; - *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_64K_SHIFT); - } - return 0; -} - -/** \brief Set 4k/64k page domain - - The function sets 4k/64k page domain - - \param [out] descriptor_l1 L1 descriptor. - \param [in] domain Page domain - - \return 0 - */ -__STATIC_INLINE int __domain_page(uint32_t *descriptor_l1, uint8_t domain) -{ - *descriptor_l1 &= PAGE_DOMAIN_MASK; - *descriptor_l1 |= ((domain & 0xf) << PAGE_DOMAIN_SHIFT); - return 0; -} - -/** \brief Set 4k/64k page parity check - - The function sets 4k/64k page parity check - - \param [out] descriptor_l1 L1 descriptor. - \param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED - - \return 0 - */ -__STATIC_INLINE int __p_page(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit) -{ - *descriptor_l1 &= SECTION_P_MASK; - *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT); - return 0; -} - -/** \brief Set 4k/64k page access privileges - - The function sets 4k/64k page access privileges - - \param [out] descriptor_l2 L2 descriptor. - \param [in] user User Level Access: NO_ACCESS, RW, READ - \param [in] priv Privilege Level Access: NO_ACCESS, RW, READ - \param [in] afe Access flag enable - - \return 0 - */ -__STATIC_INLINE int __ap_page(uint32_t *descriptor_l2, mmu_access_Type user, mmu_access_Type priv, uint32_t afe) -{ - uint32_t ap = 0; - - if (afe == 0) { //full access - if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; } - else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } - else if ((priv == RW) && (user == READ)) { ap = 0x2; } - else if ((priv == RW) && (user == RW)) { ap = 0x3; } - else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } - else if ((priv == READ) && (user == READ)) { ap = 0x6; } - } - - else { //Simplified access - if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } - else if ((priv == RW) && (user == RW)) { ap = 0x3; } - else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } - else if ((priv == READ) && (user == READ)) { ap = 0x7; } - } - - *descriptor_l2 &= PAGE_AP_MASK; - *descriptor_l2 |= (ap & 0x3) << PAGE_AP_SHIFT; - *descriptor_l2 |= ((ap & 0x4)>>2) << PAGE_AP2_SHIFT; - - return 0; -} - -/** \brief Set 4k/64k page shareability - - The function sets 4k/64k page shareability - - \param [out] descriptor_l2 L2 descriptor. - \param [in] s_bit 4k/64k page shareability: NON_SHARED, SHARED - - \return 0 - */ -__STATIC_INLINE int __shared_page(uint32_t *descriptor_l2, mmu_shared_Type s_bit) -{ - *descriptor_l2 &= PAGE_S_MASK; - *descriptor_l2 |= ((s_bit & 0x1) << PAGE_S_SHIFT); - return 0; -} - -/** \brief Set 4k/64k page Global attribute - - The function sets 4k/64k page Global attribute - - \param [out] descriptor_l2 L2 descriptor. - \param [in] g_bit 4k/64k page attribute: GLOBAL, NON_GLOBAL - - \return 0 - */ -__STATIC_INLINE int __global_page(uint32_t *descriptor_l2, mmu_global_Type g_bit) -{ - *descriptor_l2 &= PAGE_NG_MASK; - *descriptor_l2 |= ((g_bit & 0x1) << PAGE_NG_SHIFT); - return 0; -} - -/** \brief Set 4k/64k page Security attribute - - The function sets 4k/64k page Global attribute - - \param [out] descriptor_l1 L1 descriptor. - \param [in] s_bit 4k/64k page Security attribute: SECURE, NON_SECURE - - \return 0 - */ -__STATIC_INLINE int __secure_page(uint32_t *descriptor_l1, mmu_secure_Type s_bit) -{ - *descriptor_l1 &= PAGE_NS_MASK; - *descriptor_l1 |= ((s_bit & 0x1) << PAGE_NS_SHIFT); - return 0; -} - - -/** \brief Set Section memory attributes - - The function sets section memory attributes - - \param [out] descriptor_l1 L1 descriptor. - \param [in] mem Section memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED - \param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, - \param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, - - \return 0 - */ -__STATIC_INLINE int __memory_section(uint32_t *descriptor_l1, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner) -{ - *descriptor_l1 &= SECTION_TEXCB_MASK; - - if (STRONGLY_ORDERED == mem) - { - return 0; - } - else if (SHARED_DEVICE == mem) - { - *descriptor_l1 |= (1 << SECTION_B_SHIFT); - } - else if (NON_SHARED_DEVICE == mem) - { - *descriptor_l1 |= (1 << SECTION_TEX1_SHIFT); - } - else if (NORMAL == mem) - { - *descriptor_l1 |= 1 << SECTION_TEX2_SHIFT; - switch(inner) - { - case NON_CACHEABLE: - break; - case WB_WA: - *descriptor_l1 |= (1 << SECTION_B_SHIFT); - break; - case WT: - *descriptor_l1 |= 1 << SECTION_C_SHIFT; - break; - case WB_NO_WA: - *descriptor_l1 |= (1 << SECTION_B_SHIFT) | (1 << SECTION_C_SHIFT); - break; - } - switch(outer) - { - case NON_CACHEABLE: - break; - case WB_WA: - *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT); - break; - case WT: - *descriptor_l1 |= 1 << SECTION_TEX1_SHIFT; - break; - case WB_NO_WA: - *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT) | (1 << SECTION_TEX0_SHIFT); - break; - } - } - - return 0; -} - -/** \brief Set 4k/64k page memory attributes - - The function sets 4k/64k page memory attributes - - \param [out] descriptor_l2 L2 descriptor. - \param [in] mem 4k/64k page memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED - \param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, - \param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, - - \return 0 - */ -__STATIC_INLINE int __memory_page(uint32_t *descriptor_l2, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner, mmu_region_size_Type page) -{ - *descriptor_l2 &= PAGE_4K_TEXCB_MASK; - - if (page == PAGE_64k) - { - //same as section - __memory_section(descriptor_l2, mem, outer, inner); - } - else - { - if (STRONGLY_ORDERED == mem) - { - return 0; - } - else if (SHARED_DEVICE == mem) - { - *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT); - } - else if (NON_SHARED_DEVICE == mem) - { - *descriptor_l2 |= (1 << PAGE_4K_TEX1_SHIFT); - } - else if (NORMAL == mem) - { - *descriptor_l2 |= 1 << PAGE_4K_TEX2_SHIFT; - switch(inner) - { - case NON_CACHEABLE: - break; - case WB_WA: - *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT); - break; - case WT: - *descriptor_l2 |= 1 << PAGE_4K_C_SHIFT; - break; - case WB_NO_WA: - *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT) | (1 << PAGE_4K_C_SHIFT); - break; - } - switch(outer) - { - case NON_CACHEABLE: - break; - case WB_WA: - *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT); - break; - case WT: - *descriptor_l2 |= 1 << PAGE_4K_TEX1_SHIFT; - break; - case WB_NO_WA: - *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT) | (1 << PAGE_4K_TEX0_SHIFT); - break; - } - } - } - - return 0; -} - -/** \brief Create a L1 section descriptor - - The function creates a section descriptor. - - Assumptions: - - 16MB super sections not supported - - TEX remap disabled, so memory type and attributes are described directly by bits in the descriptor - - Functions always return 0 - - \param [out] descriptor L1 descriptor - \param [out] descriptor2 L2 descriptor - \param [in] reg Section attributes - - \return 0 - */ -__STATIC_INLINE int __get_section_descriptor(uint32_t *descriptor, mmu_region_attributes_Type reg) -{ - *descriptor = 0; - - __memory_section(descriptor, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t); - __xn_section(descriptor,reg.xn_t); - __domain_section(descriptor, reg.domain); - __p_section(descriptor, reg.e_t); - __ap_section(descriptor, reg.priv_t, reg.user_t, 1); - __shared_section(descriptor,reg.sh_t); - __global_section(descriptor,reg.g_t); - __secure_section(descriptor,reg.sec_t); - *descriptor &= SECTION_MASK; - *descriptor |= SECTION_DESCRIPTOR; - - return 0; - -} - - -/** \brief Create a L1 and L2 4k/64k page descriptor - - The function creates a 4k/64k page descriptor. - Assumptions: - - TEX remap disabled, so memory type and attributes are described directly by bits in the descriptor - - Functions always return 0 - - \param [out] descriptor L1 descriptor - \param [out] descriptor2 L2 descriptor - \param [in] reg 4k/64k page attributes - - \return 0 - */ -__STATIC_INLINE int __get_page_descriptor(uint32_t *descriptor, uint32_t *descriptor2, mmu_region_attributes_Type reg) -{ - *descriptor = 0; - *descriptor2 = 0; - - switch (reg.rg_t) - { - case PAGE_4k: - __memory_page(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_4k); - __xn_page(descriptor2, reg.xn_t, PAGE_4k); - __domain_page(descriptor, reg.domain); - __p_page(descriptor, reg.e_t); - __ap_page(descriptor2, reg.priv_t, reg.user_t, 1); - __shared_page(descriptor2,reg.sh_t); - __global_page(descriptor2,reg.g_t); - __secure_page(descriptor,reg.sec_t); - *descriptor &= PAGE_L1_MASK; - *descriptor |= PAGE_L1_DESCRIPTOR; - *descriptor2 &= PAGE_L2_4K_MASK; - *descriptor2 |= PAGE_L2_4K_DESC; - break; - - case PAGE_64k: - __memory_page(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_64k); - __xn_page(descriptor2, reg.xn_t, PAGE_64k); - __domain_page(descriptor, reg.domain); - __p_page(descriptor, reg.e_t); - __ap_page(descriptor2, reg.priv_t, reg.user_t, 1); - __shared_page(descriptor2,reg.sh_t); - __global_page(descriptor2,reg.g_t); - __secure_page(descriptor,reg.sec_t); - *descriptor &= PAGE_L1_MASK; - *descriptor |= PAGE_L1_DESCRIPTOR; - *descriptor2 &= PAGE_L2_64K_MASK; - *descriptor2 |= PAGE_L2_64K_DESC; - break; - - case SECTION: - //error - break; - - } - - return 0; - -} - -/** \brief Create a 1MB Section - - \param [in] ttb Translation table base address - \param [in] base_address Section base address - \param [in] count Number of sections to create - \param [in] descriptor_l1 L1 descriptor (region attributes) - - */ -__STATIC_INLINE void __TTSection(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1) -{ - uint32_t offset; - uint32_t entry; - uint32_t i; - - offset = base_address >> 20; - entry = (base_address & 0xFFF00000) | descriptor_l1; - - //4 bytes aligned - ttb = ttb + offset; - - for (i = 0; i < count; i++ ) - { - //4 bytes aligned - *ttb++ = entry; - entry += OFFSET_1M; - } -} - -/** \brief Create a 4k page entry - - \param [in] ttb L1 table base address - \param [in] base_address 4k base address - \param [in] count Number of 4k pages to create - \param [in] descriptor_l1 L1 descriptor (region attributes) - \param [in] ttb_l2 L2 table base address - \param [in] descriptor_l2 L2 descriptor (region attributes) - - */ -__STATIC_INLINE void __TTPage_4k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 ) -{ - - uint32_t offset, offset2; - uint32_t entry, entry2; - uint32_t i; - - - offset = base_address >> 20; - entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1; - - //4 bytes aligned - ttb += offset; - //create l1_entry - *ttb = entry; - - offset2 = (base_address & 0xff000) >> 12; - ttb_l2 += offset2; - entry2 = (base_address & 0xFFFFF000) | descriptor_l2; - for (i = 0; i < count; i++ ) - { - //4 bytes aligned - *ttb_l2++ = entry2; - entry2 += OFFSET_4K; - } -} - -/** \brief Create a 64k page entry - - \param [in] ttb L1 table base address - \param [in] base_address 64k base address - \param [in] count Number of 64k pages to create - \param [in] descriptor_l1 L1 descriptor (region attributes) - \param [in] ttb_l2 L2 table base address - \param [in] descriptor_l2 L2 descriptor (region attributes) - - */ -__STATIC_INLINE void __TTPage_64k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 ) -{ - uint32_t offset, offset2; - uint32_t entry, entry2; - uint32_t i,j; - - - offset = base_address >> 20; - entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1; - - //4 bytes aligned - ttb += offset; - //create l1_entry - *ttb = entry; - - offset2 = (base_address & 0xff000) >> 12; - ttb_l2 += offset2; - entry2 = (base_address & 0xFFFF0000) | descriptor_l2; - for (i = 0; i < count; i++ ) - { - //create 16 entries - for (j = 0; j < 16; j++) - //4 bytes aligned - *ttb_l2++ = entry2; - entry2 += OFFSET_64K; - } -} - -/*@} end of MMU_Functions */ -#endif - -#ifdef __cplusplus -} -#endif diff --git a/cmsis/TARGET_CORTEX_A/core_cm4_simd.h b/cmsis/TARGET_CORTEX_A/core_cm4_simd.h deleted file mode 100644 index 83db95b5f11..00000000000 --- a/cmsis/TARGET_CORTEX_A/core_cm4_simd.h +++ /dev/null @@ -1,673 +0,0 @@ -/**************************************************************************//** - * @file core_cm4_simd.h - * @brief CMSIS Cortex-M4 SIMD Header File - * @version V3.20 - * @date 25. February 2013 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2013 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#ifdef __cplusplus - extern "C" { -#endif - -#ifndef __CORE_CM4_SIMD_H -#define __CORE_CM4_SIMD_H - - -/******************************************************************************* - * Hardware Abstraction Layer - ******************************************************************************/ - - -/* ################### Compiler specific Intrinsics ########################### */ -/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics - Access to dedicated SIMD instructions - @{ -*/ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ -#define __SADD8 __sadd8 -#define __QADD8 __qadd8 -#define __SHADD8 __shadd8 -#define __UADD8 __uadd8 -#define __UQADD8 __uqadd8 -#define __UHADD8 __uhadd8 -#define __SSUB8 __ssub8 -#define __QSUB8 __qsub8 -#define __SHSUB8 __shsub8 -#define __USUB8 __usub8 -#define __UQSUB8 __uqsub8 -#define __UHSUB8 __uhsub8 -#define __SADD16 __sadd16 -#define __QADD16 __qadd16 -#define __SHADD16 __shadd16 -#define __UADD16 __uadd16 -#define __UQADD16 __uqadd16 -#define __UHADD16 __uhadd16 -#define __SSUB16 __ssub16 -#define __QSUB16 __qsub16 -#define __SHSUB16 __shsub16 -#define __USUB16 __usub16 -#define __UQSUB16 __uqsub16 -#define __UHSUB16 __uhsub16 -#define __SASX __sasx -#define __QASX __qasx -#define __SHASX __shasx -#define __UASX __uasx -#define __UQASX __uqasx -#define __UHASX __uhasx -#define __SSAX __ssax -#define __QSAX __qsax -#define __SHSAX __shsax -#define __USAX __usax -#define __UQSAX __uqsax -#define __UHSAX __uhsax -#define __USAD8 __usad8 -#define __USADA8 __usada8 -#define __SSAT16 __ssat16 -#define __USAT16 __usat16 -#define __UXTB16 __uxtb16 -#define __UXTAB16 __uxtab16 -#define __SXTB16 __sxtb16 -#define __SXTAB16 __sxtab16 -#define __SMUAD __smuad -#define __SMUADX __smuadx -#define __SMLAD __smlad -#define __SMLADX __smladx -#define __SMLALD __smlald -#define __SMLALDX __smlaldx -#define __SMUSD __smusd -#define __SMUSDX __smusdx -#define __SMLSD __smlsd -#define __SMLSDX __smlsdx -#define __SMLSLD __smlsld -#define __SMLSLDX __smlsldx -#define __SEL __sel -#define __QADD __qadd -#define __QSUB __qsub - -#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ - ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) - -#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ - ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) - -#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ - ((int64_t)(ARG3) << 32) ) >> 32)) - -/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ - - - -#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ - -/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ -#include - -/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ - - - -#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ -/* TI CCS specific functions */ - -/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ -#include - -/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ - - - -#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -#define __SSAT16(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - -#define __USAT16(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) -{ - uint32_t result; - - __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) -{ - uint32_t result; - - __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -#define __SMLALD(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \ - __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ - (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ - }) - -#define __SMLALDX(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \ - __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ - (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ - }) - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -#define __SMLSLD(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \ - __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ - (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ - }) - -#define __SMLSLDX(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \ - __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ - (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ - }) - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -#define __PKHBT(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ - __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ - __RES; \ - }) - -#define __PKHTB(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ - if (ARG3 == 0) \ - __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ - else \ - __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ - __RES; \ - }) - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) -{ - int32_t result; - - __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ - - - -#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ -/* TASKING carm specific functions */ - - -/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ -/* not yet supported */ -/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ - - -#endif - -/*@} end of group CMSIS_SIMD_intrinsics */ - - -#endif /* __CORE_CM4_SIMD_H */ - -#ifdef __cplusplus -} -#endif diff --git a/cmsis/TARGET_CORTEX_A/core_cmInstr.h b/cmsis/TARGET_CORTEX_A/core_cmInstr.h deleted file mode 100644 index fca425c51db..00000000000 --- a/cmsis/TARGET_CORTEX_A/core_cmInstr.h +++ /dev/null @@ -1,916 +0,0 @@ -/**************************************************************************//** - * @file core_cmInstr.h - * @brief CMSIS Cortex-M Core Instruction Access Header File - * @version V4.10 - * @date 18. March 2015 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2014 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#ifndef __CORE_CMINSTR_H -#define __CORE_CMINSTR_H - - -/* ########################## Core Instruction Access ######################### */ -/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface - Access to dedicated instructions - @{ -*/ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -#if (__ARMCC_VERSION < 400677) - #error "Please use ARM Compiler Toolchain V4.0.677 or later!" -#endif - - -/** \brief No Operation - - No Operation does nothing. This instruction can be used for code alignment purposes. - */ -#define __NOP __nop - - -/** \brief Wait For Interrupt - - Wait For Interrupt is a hint instruction that suspends execution - until one of a number of events occurs. - */ -#define __WFI __wfi - - -/** \brief Wait For Event - - Wait For Event is a hint instruction that permits the processor to enter - a low-power state until one of a number of events occurs. - */ -#define __WFE __wfe - - -/** \brief Send Event - - Send Event is a hint instruction. It causes an event to be signaled to the CPU. - */ -#define __SEV __sev - - -/** \brief Instruction Synchronization Barrier - - Instruction Synchronization Barrier flushes the pipeline in the processor, - so that all instructions following the ISB are fetched from cache or - memory, after the instruction has been completed. - */ -#define __ISB() do {\ - __schedule_barrier();\ - __isb(0xF);\ - __schedule_barrier();\ - } while (0) - -/** \brief Data Synchronization Barrier - - This function acts as a special kind of Data Memory Barrier. - It completes when all explicit memory accesses before this instruction complete. - */ -#define __DSB() do {\ - __schedule_barrier();\ - __dsb(0xF);\ - __schedule_barrier();\ - } while (0) - -/** \brief Data Memory Barrier - - This function ensures the apparent order of the explicit memory operations before - and after the instruction, without ensuring their completion. - */ -#define __DMB() do {\ - __schedule_barrier();\ - __dmb(0xF);\ - __schedule_barrier();\ - } while (0) - -/** \brief Reverse byte order (32 bit) - - This function reverses the byte order in integer value. - - \param [in] value Value to reverse - \return Reversed value - */ -#define __REV __rev - - -/** \brief Reverse byte order (16 bit) - - This function reverses the byte order in two unsigned short values. - - \param [in] value Value to reverse - \return Reversed value - */ -#ifndef __NO_EMBEDDED_ASM -__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) -{ - rev16 r0, r0 - bx lr -} -#endif - -/** \brief Reverse byte order in signed short value - - This function reverses the byte order in a signed short value with sign extension to integer. - - \param [in] value Value to reverse - \return Reversed value - */ -#ifndef __NO_EMBEDDED_ASM -__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) -{ - revsh r0, r0 - bx lr -} -#endif - - -/** \brief Rotate Right in unsigned value (32 bit) - - This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. - - \param [in] value Value to rotate - \param [in] value Number of Bits to rotate - \return Rotated value - */ -#define __ROR __ror - - -/** \brief Breakpoint - - This function causes the processor to enter Debug state. - Debug tools can use this to investigate system state when the instruction at a particular address is reached. - - \param [in] value is ignored by the processor. - If required, a debugger can use it to store additional information about the breakpoint. - */ -#define __BKPT(value) __breakpoint(value) - - -/** \brief Reverse bit order of value - - This function reverses the bit order of the given value. - - \param [in] value Value to reverse - \return Reversed value - */ -#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) - #define __RBIT __rbit -#else -__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) -{ - uint32_t result; - int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end - - result = value; // r will be reversed bits of v; first get LSB of v - for (value >>= 1; value; value >>= 1) - { - result <<= 1; - result |= value & 1; - s--; - } - result <<= s; // shift when v's highest bits are zero - return(result); -} -#endif - - -/** \brief Count leading zeros - - This function counts the number of leading zeros of a data value. - - \param [in] value Value to count the leading zeros - \return number of leading zeros in value - */ -#define __CLZ __clz - - -#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) - -/** \brief LDR Exclusive (8 bit) - - This function executes a exclusive LDR instruction for 8 bit value. - - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) - - -/** \brief LDR Exclusive (16 bit) - - This function executes a exclusive LDR instruction for 16 bit values. - - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) - */ -#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) - - -/** \brief LDR Exclusive (32 bit) - - This function executes a exclusive LDR instruction for 32 bit values. - - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) - */ -#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) - - -/** \brief STR Exclusive (8 bit) - - This function executes a exclusive STR instruction for 8 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -#define __STREXB(value, ptr) __strex(value, ptr) - - -/** \brief STR Exclusive (16 bit) - - This function executes a exclusive STR instruction for 16 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -#define __STREXH(value, ptr) __strex(value, ptr) - - -/** \brief STR Exclusive (32 bit) - - This function executes a exclusive STR instruction for 32 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -#define __STREXW(value, ptr) __strex(value, ptr) - - -/** \brief Remove the exclusive lock - - This function removes the exclusive lock which is created by LDREX. - - */ -#define __CLREX __clrex - - -/** \brief Signed Saturate - - This function saturates a signed value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (1..32) - \return Saturated value - */ -#define __SSAT __ssat - - -/** \brief Unsigned Saturate - - This function saturates an unsigned value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (0..31) - \return Saturated value - */ -#define __USAT __usat - - -/** \brief Rotate Right with Extend (32 bit) - - This function moves each bit of a bitstring right by one bit. - The carry input is shifted in at the left end of the bitstring. - - \param [in] value Value to rotate - \return Rotated value - */ -#ifndef __NO_EMBEDDED_ASM -__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) -{ - rrx r0, r0 - bx lr -} -#endif - - -/** \brief LDRT Unprivileged (8 bit) - - This function executes a Unprivileged LDRT instruction for 8 bit value. - - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) - - -/** \brief LDRT Unprivileged (16 bit) - - This function executes a Unprivileged LDRT instruction for 16 bit values. - - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) - */ -#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) - - -/** \brief LDRT Unprivileged (32 bit) - - This function executes a Unprivileged LDRT instruction for 32 bit values. - - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) - */ -#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) - - -/** \brief STRT Unprivileged (8 bit) - - This function executes a Unprivileged STRT instruction for 8 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -#define __STRBT(value, ptr) __strt(value, ptr) - - -/** \brief STRT Unprivileged (16 bit) - - This function executes a Unprivileged STRT instruction for 16 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -#define __STRHT(value, ptr) __strt(value, ptr) - - -/** \brief STRT Unprivileged (32 bit) - - This function executes a Unprivileged STRT instruction for 32 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -#define __STRT(value, ptr) __strt(value, ptr) - -#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */ - - -#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -/* Define macros for porting to both thumb1 and thumb2. - * For thumb1, use low register (r0-r7), specified by constrant "l" - * Otherwise, use general registers, specified by constrant "r" */ -#if defined (__thumb__) && !defined (__thumb2__) -#define __CMSIS_GCC_OUT_REG(r) "=l" (r) -#define __CMSIS_GCC_USE_REG(r) "l" (r) -#else -#define __CMSIS_GCC_OUT_REG(r) "=r" (r) -#define __CMSIS_GCC_USE_REG(r) "r" (r) -#endif - -/** \brief No Operation - - No Operation does nothing. This instruction can be used for code alignment purposes. - */ -__attribute__((always_inline)) __STATIC_INLINE void __NOP(void) -{ - __ASM volatile ("nop"); -} - - -/** \brief Wait For Interrupt - - Wait For Interrupt is a hint instruction that suspends execution - until one of a number of events occurs. - */ -__attribute__((always_inline)) __STATIC_INLINE void __WFI(void) -{ - __ASM volatile ("wfi"); -} - - -/** \brief Wait For Event - - Wait For Event is a hint instruction that permits the processor to enter - a low-power state until one of a number of events occurs. - */ -__attribute__((always_inline)) __STATIC_INLINE void __WFE(void) -{ - __ASM volatile ("wfe"); -} - - -/** \brief Send Event - - Send Event is a hint instruction. It causes an event to be signaled to the CPU. - */ -__attribute__((always_inline)) __STATIC_INLINE void __SEV(void) -{ - __ASM volatile ("sev"); -} - - -/** \brief Instruction Synchronization Barrier - - Instruction Synchronization Barrier flushes the pipeline in the processor, - so that all instructions following the ISB are fetched from cache or - memory, after the instruction has been completed. - */ -__attribute__((always_inline)) __STATIC_INLINE void __ISB(void) -{ - __ASM volatile ("isb 0xF":::"memory"); -} - - -/** \brief Data Synchronization Barrier - - This function acts as a special kind of Data Memory Barrier. - It completes when all explicit memory accesses before this instruction complete. - */ -__attribute__((always_inline)) __STATIC_INLINE void __DSB(void) -{ - __ASM volatile ("dsb 0xF":::"memory"); -} - - -/** \brief Data Memory Barrier - - This function ensures the apparent order of the explicit memory operations before - and after the instruction, without ensuring their completion. - */ -__attribute__((always_inline)) __STATIC_INLINE void __DMB(void) -{ - __ASM volatile ("dmb 0xF":::"memory"); -} - - -/** \brief Reverse byte order (32 bit) - - This function reverses the byte order in integer value. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value) -{ -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) - return __builtin_bswap32(value); -#else - uint32_t result; - - __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); -#endif -} - - -/** \brief Reverse byte order (16 bit) - - This function reverses the byte order in two unsigned short values. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); -} - - -/** \brief Reverse byte order in signed short value - - This function reverses the byte order in a signed short value with sign extension to integer. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) -{ -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - return (short)__builtin_bswap16(value); -#else - uint32_t result; - - __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); -#endif -} - - -/** \brief Rotate Right in unsigned value (32 bit) - - This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. - - \param [in] value Value to rotate - \param [in] value Number of Bits to rotate - \return Rotated value - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) -{ - return (op1 >> op2) | (op1 << (32 - op2)); -} - - -/** \brief Breakpoint - - This function causes the processor to enter Debug state. - Debug tools can use this to investigate system state when the instruction at a particular address is reached. - - \param [in] value is ignored by the processor. - If required, a debugger can use it to store additional information about the breakpoint. - */ -#define __BKPT(value) __ASM volatile ("bkpt "#value) - - -/** \brief Reverse bit order of value - - This function reverses the bit order of the given value. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) -{ - uint32_t result; - -#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) - __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); -#else - int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end - - result = value; // r will be reversed bits of v; first get LSB of v - for (value >>= 1; value; value >>= 1) - { - result <<= 1; - result |= value & 1; - s--; - } - result <<= s; // shift when v's highest bits are zero -#endif - return(result); -} - - -/** \brief Count leading zeros - - This function counts the number of leading zeros of a data value. - - \param [in] value Value to count the leading zeros - \return number of leading zeros in value - */ -#define __CLZ __builtin_clz - - -#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) - -/** \brief LDR Exclusive (8 bit) - - This function executes a exclusive LDR instruction for 8 bit value. - - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) -{ - uint32_t result; - -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); -#else - /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not - accepted by assembler. So has to use following less efficient pattern. - */ - __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); -#endif - return ((uint8_t) result); /* Add explicit type cast here */ -} - - -/** \brief LDR Exclusive (16 bit) - - This function executes a exclusive LDR instruction for 16 bit values. - - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) - */ -__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) -{ - uint32_t result; - -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); -#else - /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not - accepted by assembler. So has to use following less efficient pattern. - */ - __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); -#endif - return ((uint16_t) result); /* Add explicit type cast here */ -} - - -/** \brief LDR Exclusive (32 bit) - - This function executes a exclusive LDR instruction for 32 bit values. - - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) -{ - uint32_t result; - - __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); - return(result); -} - - -/** \brief STR Exclusive (8 bit) - - This function executes a exclusive STR instruction for 8 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) -{ - uint32_t result; - - __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); - return(result); -} - - -/** \brief STR Exclusive (16 bit) - - This function executes a exclusive STR instruction for 16 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) -{ - uint32_t result; - - __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); - return(result); -} - - -/** \brief STR Exclusive (32 bit) - - This function executes a exclusive STR instruction for 32 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) -{ - uint32_t result; - - __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); - return(result); -} - - -/** \brief Remove the exclusive lock - - This function removes the exclusive lock which is created by LDREX. - - */ -__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void) -{ - __ASM volatile ("clrex" ::: "memory"); -} - - -/** \brief Signed Saturate - - This function saturates a signed value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (1..32) - \return Saturated value - */ -#define __SSAT(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - - -/** \brief Unsigned Saturate - - This function saturates an unsigned value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (0..31) - \return Saturated value - */ -#define __USAT(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - - -/** \brief Rotate Right with Extend (32 bit) - - This function moves each bit of a bitstring right by one bit. - The carry input is shifted in at the left end of the bitstring. - - \param [in] value Value to rotate - \return Rotated value - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); -} - - -/** \brief LDRT Unprivileged (8 bit) - - This function executes a Unprivileged LDRT instruction for 8 bit value. - - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr) -{ - uint32_t result; - -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) ); -#else - /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not - accepted by assembler. So has to use following less efficient pattern. - */ - __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); -#endif - return ((uint8_t) result); /* Add explicit type cast here */ -} - - -/** \brief LDRT Unprivileged (16 bit) - - This function executes a Unprivileged LDRT instruction for 16 bit values. - - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) - */ -__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr) -{ - uint32_t result; - -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) ); -#else - /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not - accepted by assembler. So has to use following less efficient pattern. - */ - __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); -#endif - return ((uint16_t) result); /* Add explicit type cast here */ -} - - -/** \brief LDRT Unprivileged (32 bit) - - This function executes a Unprivileged LDRT instruction for 32 bit values. - - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr) -{ - uint32_t result; - - __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) ); - return(result); -} - - -/** \brief STRT Unprivileged (8 bit) - - This function executes a Unprivileged STRT instruction for 8 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr) -{ - __ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); -} - - -/** \brief STRT Unprivileged (16 bit) - - This function executes a Unprivileged STRT instruction for 16 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr) -{ - __ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); -} - - -/** \brief STRT Unprivileged (32 bit) - - This function executes a Unprivileged STRT instruction for 32 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr) -{ - __ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) ); -} - -#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */ - - -#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ -#include - - -#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ -/* TI CCS specific functions */ -#include - - -#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ -/* TASKING carm specific functions */ -/* - * The CMSIS functions have been implemented as intrinsics in the compiler. - * Please use "carm -?i" to get an up to date list of all intrinsics, - * Including the CMSIS ones. - */ - - -#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ -/* Cosmic specific functions */ -#include - -#endif - -/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ - -#endif /* __CORE_CMINSTR_H */ diff --git a/cmsis/TARGET_CORTEX_A/irq_ctrl.h b/cmsis/TARGET_CORTEX_A/irq_ctrl.h new file mode 100644 index 00000000000..4299c2831c3 --- /dev/null +++ b/cmsis/TARGET_CORTEX_A/irq_ctrl.h @@ -0,0 +1,180 @@ +/**************************************************************************//** + * @file irq_ctrl.h + * @brief Interrupt Controller API header file + * @version V1.0.0 + * @date 23. June 2017 + ******************************************************************************/ +/* + * Copyright (c) 2017 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 + * + * 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 IRQ_CTRL_H_ +#define IRQ_CTRL_H_ + +#include + +#ifndef IRQHANDLER_T +#define IRQHANDLER_T +/// Interrupt handler data type +typedef void (*IRQHandler_t) (void); +#endif + +#ifndef IRQN_ID_T +#define IRQN_ID_T +/// Interrupt ID number data type +typedef int32_t IRQn_ID_t; +#endif + +/* Interrupt mode bit-masks */ +#define IRQ_MODE_TRIG_Pos (0U) +#define IRQ_MODE_TRIG_Msk (0x07UL /*<< IRQ_MODE_TRIG_Pos*/) +#define IRQ_MODE_TRIG_LEVEL (0x00UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: level triggered interrupt +#define IRQ_MODE_TRIG_LEVEL_LOW (0x01UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: low level triggered interrupt +#define IRQ_MODE_TRIG_LEVEL_HIGH (0x02UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: high level triggered interrupt +#define IRQ_MODE_TRIG_EDGE (0x04UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: edge triggered interrupt +#define IRQ_MODE_TRIG_EDGE_RISING (0x05UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: rising edge triggered interrupt +#define IRQ_MODE_TRIG_EDGE_FALLING (0x06UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: falling edge triggered interrupt +#define IRQ_MODE_TRIG_EDGE_BOTH (0x07UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: rising and falling edge triggered interrupt + +#define IRQ_MODE_TYPE_Pos (3U) +#define IRQ_MODE_TYPE_Msk (0x01UL << IRQ_MODE_TYPE_Pos) +#define IRQ_MODE_TYPE_IRQ (0x00UL << IRQ_MODE_TYPE_Pos) ///< Type: interrupt source triggers CPU IRQ line +#define IRQ_MODE_TYPE_FIQ (0x01UL << IRQ_MODE_TYPE_Pos) ///< Type: interrupt source triggers CPU FIQ line + +#define IRQ_MODE_DOMAIN_Pos (4U) +#define IRQ_MODE_DOMAIN_Msk (0x01UL << IRQ_MODE_DOMAIN_Pos) +#define IRQ_MODE_DOMAIN_NONSECURE (0x00UL << IRQ_MODE_DOMAIN_Pos) ///< Domain: interrupt is targeting non-secure domain +#define IRQ_MODE_DOMAIN_SECURE (0x01UL << IRQ_MODE_DOMAIN_Pos) ///< Domain: interrupt is targeting secure domain + +#define IRQ_MODE_CPU_Pos (5U) +#define IRQ_MODE_CPU_Msk (0xFFUL << IRQ_MODE_CPU_Pos) +#define IRQ_MODE_CPU_ALL (0x00UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets all CPUs +#define IRQ_MODE_CPU_0 (0x01UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 0 +#define IRQ_MODE_CPU_1 (0x02UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 1 +#define IRQ_MODE_CPU_2 (0x04UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 2 +#define IRQ_MODE_CPU_3 (0x08UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 3 +#define IRQ_MODE_CPU_4 (0x10UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 4 +#define IRQ_MODE_CPU_5 (0x20UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 5 +#define IRQ_MODE_CPU_6 (0x40UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 6 +#define IRQ_MODE_CPU_7 (0x80UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 7 + +#define IRQ_MODE_ERROR (0x80000000UL) ///< Bit indicating mode value error + +/* Interrupt priority bit-masks */ +#define IRQ_PRIORITY_Msk (0x0000FFFFUL) ///< Interrupt priority value bit-mask +#define IRQ_PRIORITY_ERROR (0x80000000UL) ///< Bit indicating priority value error + +/// Initialize interrupt controller. +/// \return 0 on success, -1 on error. +int32_t IRQ_Initialize (void); + +/// Register interrupt handler. +/// \param[in] irqn interrupt ID number +/// \param[in] handler interrupt handler function address +/// \return 0 on success, -1 on error. +int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler); + +/// Get the registered interrupt handler. +/// \param[in] irqn interrupt ID number +/// \return registered interrupt handler function address. +IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn); + +/// Enable interrupt. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_Enable (IRQn_ID_t irqn); + +/// Disable interrupt. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_Disable (IRQn_ID_t irqn); + +/// Get interrupt enable state. +/// \param[in] irqn interrupt ID number +/// \return 0 - interrupt is disabled, 1 - interrupt is enabled. +uint32_t IRQ_GetEnableState (IRQn_ID_t irqn); + +/// Configure interrupt request mode. +/// \param[in] irqn interrupt ID number +/// \param[in] mode mode configuration +/// \return 0 on success, -1 on error. +int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode); + +/// Get interrupt mode configuration. +/// \param[in] irqn interrupt ID number +/// \return current interrupt mode configuration with optional IRQ_MODE_ERROR bit set. +uint32_t IRQ_GetMode (IRQn_ID_t irqn); + +/// Get ID number of current interrupt request (IRQ). +/// \return interrupt ID number. +IRQn_ID_t IRQ_GetActiveIRQ (void); + +/// Get ID number of current fast interrupt request (FIQ). +/// \return interrupt ID number. +IRQn_ID_t IRQ_GetActiveFIQ (void); + +/// Signal end of interrupt processing. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn); + +/// Set interrupt pending flag. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_SetPending (IRQn_ID_t irqn); + +/// Get interrupt pending flag. +/// \param[in] irqn interrupt ID number +/// \return 0 - interrupt is not pending, 1 - interrupt is pending. +uint32_t IRQ_GetPending (IRQn_ID_t irqn); + +/// Clear interrupt pending flag. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_ClearPending (IRQn_ID_t irqn); + +/// Set interrupt priority value. +/// \param[in] irqn interrupt ID number +/// \param[in] priority interrupt priority value +/// \return 0 on success, -1 on error. +int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority); + +/// Get interrupt priority. +/// \param[in] irqn interrupt ID number +/// \return current interrupt priority value with optional IRQ_PRIORITY_ERROR bit set. +uint32_t IRQ_GetPriority (IRQn_ID_t irqn); + +/// Set priority masking threshold. +/// \param[in] priority priority masking threshold value +/// \return 0 on success, -1 on error. +int32_t IRQ_SetPriorityMask (uint32_t priority); + +/// Get priority masking threshold +/// \return current priority masking threshold value with optional IRQ_PRIORITY_ERROR bit set. +uint32_t IRQ_GetPriorityMask (void); + +/// Set priority grouping field split point +/// \param[in] bits number of MSB bits included in the group priority field comparison +/// \return 0 on success, -1 on error. +int32_t IRQ_SetPriorityGroupBits (uint32_t bits); + +/// Get priority grouping field split point +/// \return current number of MSB bits included in the group priority field comparison with +/// optional IRQ_PRIORITY_ERROR bit set. +uint32_t IRQ_GetPriorityGroupBits (void); + +#endif // IRQ_CTRL_H_ diff --git a/cmsis/TARGET_CORTEX_A/irq_ctrl_gic.c b/cmsis/TARGET_CORTEX_A/irq_ctrl_gic.c new file mode 100644 index 00000000000..1db4d8b4f89 --- /dev/null +++ b/cmsis/TARGET_CORTEX_A/irq_ctrl_gic.c @@ -0,0 +1,404 @@ +/**************************************************************************//** + * @file irq_ctrl_gic.c + * @brief Interrupt controller handling implementation for GIC + * @version V1.0.0 + * @date 30. June 2017 + ******************************************************************************/ +/* + * Copyright (c) 2017 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 + * + * 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 + +#include "RTE_Components.h" +#include CMSIS_device_header + +#include "irq_ctrl.h" + +#if defined(__GIC_PRESENT) && (__GIC_PRESENT == 1U) + +/// Number of implemented interrupt lines +#ifndef IRQ_GIC_LINE_COUNT +#define IRQ_GIC_LINE_COUNT (1020U) +#endif + +static IRQHandler_t IRQTable[IRQ_GIC_LINE_COUNT] = { 0U }; +static uint32_t IRQ_ID0; + +/// Initialize interrupt controller. +__WEAK int32_t IRQ_Initialize (void) { + uint32_t i; + + for (i = 0U; i < IRQ_GIC_LINE_COUNT; i++) { + IRQTable[i] = (IRQHandler_t)NULL; + } + GIC_Enable(); + return (0); +} + + +/// Register interrupt handler. +__WEAK int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler) { + int32_t status; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + IRQTable[irqn] = handler; + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Get the registered interrupt handler. +__WEAK IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn) { + IRQHandler_t h; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + h = IRQTable[irqn]; + } else { + h = (IRQHandler_t)0; + } + + return (h); +} + + +/// Enable interrupt. +__WEAK int32_t IRQ_Enable (IRQn_ID_t irqn) { + int32_t status; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_EnableIRQ ((IRQn_Type)irqn); + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Disable interrupt. +__WEAK int32_t IRQ_Disable (IRQn_ID_t irqn) { + int32_t status; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_DisableIRQ ((IRQn_Type)irqn); + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Get interrupt enable state. +__WEAK uint32_t IRQ_GetEnableState (IRQn_ID_t irqn) { + uint32_t enable; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + enable = GIC_GetEnableIRQ((IRQn_Type)irqn); + } else { + enable = 0U; + } + + return (enable); +} + + +/// Configure interrupt request mode. +__WEAK int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode) { + int32_t status; + uint32_t val; + uint8_t cfg; + uint8_t secure; + uint8_t cpu; + + status = 0; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + // Check triggering mode + val = (mode & IRQ_MODE_TRIG_Msk); + + if (val == IRQ_MODE_TRIG_LEVEL) { + cfg = 0x00U; + } else if (val == IRQ_MODE_TRIG_EDGE) { + cfg = 0x02U; + } else { + status = -1; + } + + // Check interrupt type + val = mode & IRQ_MODE_TYPE_Msk; + + if (val != IRQ_MODE_TYPE_IRQ) { + status = -1; + } + + // Check interrupt domain + val = mode & IRQ_MODE_DOMAIN_Msk; + + if (val == IRQ_MODE_DOMAIN_NONSECURE) { + secure = 0; + } else { + // Check security extensions support + val = GIC_DistributorInfo() & (1UL << 10U); + + if (val != 0U) { + // Security extensions are supported + secure = 1; + } else { + status = -1; + } + } + + // Check interrupt CPU targets + val = mode & IRQ_MODE_CPU_Msk; + + if (val == IRQ_MODE_CPU_ALL) { + cpu = 0xFF; + } else { + cpu = val >> IRQ_MODE_CPU_Pos; + } + + // Apply configuration if no mode error + if (status == 0) { + GIC_SetConfiguration((IRQn_Type)irqn, cfg); + GIC_SetTarget ((IRQn_Type)irqn, cpu); + + if (secure != 0U) { + GIC_SetGroup ((IRQn_Type)irqn, secure); + } + } + } + + return (status); +} + + +/// Get interrupt mode configuration. +__WEAK uint32_t IRQ_GetMode (IRQn_ID_t irqn) { + uint32_t mode; + uint32_t val; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + mode = IRQ_MODE_TYPE_IRQ; + + // Get trigger mode + val = GIC_GetConfiguration((IRQn_Type)irqn); + + if ((val & 2U) != 0U) { + // Corresponding interrupt is edge triggered + mode |= IRQ_MODE_TRIG_EDGE; + } else { + // Corresponding interrupt is level triggered + mode |= IRQ_MODE_TRIG_LEVEL; + } + + // Get interrupt CPU targets + mode |= GIC_GetTarget ((IRQn_Type)irqn) << IRQ_MODE_CPU_Pos; + + } else { + mode = IRQ_MODE_ERROR; + } + + return (mode); +} + + +/// Get ID number of current interrupt request (IRQ). +__WEAK IRQn_ID_t IRQ_GetActiveIRQ (void) { + IRQn_ID_t irqn; + uint32_t prio; + + /* Dummy read to avoid GIC 390 errata 801120 */ + GIC_GetHighPendingIRQ(); + + irqn = GIC_AcknowledgePending(); + + __DSB(); + + /* Workaround GIC 390 errata 733075 (GIC-390_Errata_Notice_v6.pdf, 09-Jul-2014) */ + /* The following workaround code is for a single-core system. It would be */ + /* different in a multi-core system. */ + /* If the ID is 0 or 0x3FE or 0x3FF, then the GIC CPU interface may be locked-up */ + /* so unlock it, otherwise service the interrupt as normal. */ + /* Special IDs 1020=0x3FC and 1021=0x3FD are reserved values in GICv1 and GICv2 */ + /* so will not occur here. */ + + if ((irqn == 0) || (irqn >= 0x3FE)) { + /* Unlock the CPU interface with a dummy write to Interrupt Priority Register */ + prio = GIC_GetPriority((IRQn_Type)0); + GIC_SetPriority ((IRQn_Type)0, prio); + + __DSB(); + + if ((irqn == 0U) && ((GIC_GetIRQStatus ((IRQn_Type)irqn) & 1U) != 0U) && (IRQ_ID0 == 0U)) { + /* If the ID is 0, is active and has not been seen before */ + IRQ_ID0 = 1U; + } + /* End of Workaround GIC 390 errata 733075 */ + } + + return (irqn); +} + + +/// Get ID number of current fast interrupt request (FIQ). +__WEAK IRQn_ID_t IRQ_GetActiveFIQ (void) { + return ((IRQn_ID_t)-1); +} + + +/// Signal end of interrupt processing. +__WEAK int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn) { + int32_t status; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_EndInterrupt ((IRQn_Type)irqn); + + if (irqn == 0) { + IRQ_ID0 = 0U; + } + + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Set interrupt pending flag. +__WEAK int32_t IRQ_SetPending (IRQn_ID_t irqn) { + int32_t status; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_SetPendingIRQ ((IRQn_Type)irqn); + status = 0; + } else { + status = -1; + } + + return (status); +} + +/// Get interrupt pending flag. +__WEAK uint32_t IRQ_GetPending (IRQn_ID_t irqn) { + uint32_t pending; + + if ((irqn >= 16) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + pending = GIC_GetPendingIRQ ((IRQn_Type)irqn); + } else { + pending = 0U; + } + + return (pending & 1U); +} + + +/// Clear interrupt pending flag. +__WEAK int32_t IRQ_ClearPending (IRQn_ID_t irqn) { + int32_t status; + + if ((irqn >= 16) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_ClearPendingIRQ ((IRQn_Type)irqn); + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Set interrupt priority value. +__WEAK int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority) { + int32_t status; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_SetPriority ((IRQn_Type)irqn, priority); + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Get interrupt priority. +__WEAK uint32_t IRQ_GetPriority (IRQn_ID_t irqn) { + uint32_t priority; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + priority = GIC_GetPriority ((IRQn_Type)irqn); + } else { + priority = IRQ_PRIORITY_ERROR; + } + + return (priority); +} + + +/// Set priority masking threshold. +__WEAK int32_t IRQ_SetPriorityMask (uint32_t priority) { + GIC_SetInterfacePriorityMask (priority); + return (0); +} + + +/// Get priority masking threshold +__WEAK uint32_t IRQ_GetPriorityMask (void) { + return GIC_GetInterfacePriorityMask(); +} + + +/// Set priority grouping field split point +__WEAK int32_t IRQ_SetPriorityGroupBits (uint32_t bits) { + int32_t status; + + if (bits == IRQ_PRIORITY_Msk) { + bits = 7U; + } + + if (bits < 8U) { + GIC_SetBinaryPoint (7U - bits); + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Get priority grouping field split point +__WEAK uint32_t IRQ_GetPriorityGroupBits (void) { + uint32_t bp; + + bp = GIC_GetBinaryPoint() & 0x07U; + + return (7U - bp); +} + +#endif diff --git a/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armcc.h b/cmsis/TARGET_CORTEX_M/cmsis_armcc.h similarity index 94% rename from cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armcc.h rename to cmsis/TARGET_CORTEX_M/cmsis_armcc.h index 7b2a2847e0e..c2ef0a5b8ca 100644 --- a/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armcc.h +++ b/cmsis/TARGET_CORTEX_M/cmsis_armcc.h @@ -73,6 +73,9 @@ #ifndef __PACKED_STRUCT #define __PACKED_STRUCT __packed struct #endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif #ifndef __UNALIGNED_UINT32 /* deprecated */ #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) #endif @@ -91,7 +94,9 @@ #ifndef __ALIGNED #define __ALIGNED(x) __attribute__((aligned(x))) #endif - +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif /* ########################### Core Function Access ########################### */ /** \ingroup CMSIS_Core_FunctionInterface @@ -456,7 +461,7 @@ __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) \return Reversed value */ #ifndef __NO_EMBEDDED_ASM -__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint16_t __REV16(uint16_t value) { rev16 r0, r0 bx lr @@ -471,7 +476,7 @@ __attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(u \return Reversed value */ #ifndef __NO_EMBEDDED_ASM -__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) { revsh r0, r0 bx lr @@ -512,17 +517,17 @@ __attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(in __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) { uint32_t result; - int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */ + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ result = value; /* r will be reversed bits of v; first get LSB of v */ - for (value >>= 1U; value; value >>= 1U) + for (value >>= 1U; value != 0U; value >>= 1U) { result <<= 1U; result |= value & 1U; s--; } result <<= s; /* shift when v's highest bits are zero */ - return(result); + return result; } #endif @@ -719,6 +724,50 @@ __attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint3 */ #define __STRT(value, ptr) __strt(value, ptr) +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) { + return max; + } else if (val < min) { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) { + return max; + } else if (val < 0) { + return 0U; + } + } + return (uint32_t)val; +} + #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ diff --git a/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armclang.h b/cmsis/TARGET_CORTEX_M/cmsis_armclang.h similarity index 95% rename from cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armclang.h rename to cmsis/TARGET_CORTEX_M/cmsis_armclang.h index 7c22d84096b..f13bb171f56 100644 --- a/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armclang.h +++ b/cmsis/TARGET_CORTEX_M/cmsis_armclang.h @@ -22,7 +22,7 @@ * limitations under the License. */ -//lint -esym(9058, IRQn) disable MISRA 2012 Rule 2.4 for IRQn +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ #ifndef __CMSIS_ARMCLANG_H #define __CMSIS_ARMCLANG_H @@ -56,10 +56,13 @@ #ifndef __PACKED_STRUCT #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) #endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif #ifndef __UNALIGNED_UINT32 /* deprecated */ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" -//lint -esym(9058, T_UINT32) disable MISRA 2012 Rule 2.4 for T_UINT32 +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ struct __attribute__((packed)) T_UINT32 { uint32_t v; }; #pragma clang diagnostic pop #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) @@ -67,7 +70,7 @@ #ifndef __UNALIGNED_UINT16_WRITE #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" -//lint -esym(9058, T_UINT16_WRITE) disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; #pragma clang diagnostic pop #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) @@ -75,7 +78,7 @@ #ifndef __UNALIGNED_UINT16_READ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" -//lint -esym(9058, T_UINT16_READ) disable MISRA 2012 Rule 2.4 for T_UINT16_READ +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; #pragma clang diagnostic pop #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) @@ -83,7 +86,7 @@ #ifndef __UNALIGNED_UINT32_WRITE #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" -//lint -esym(9058, T_UINT32_WRITE) disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; #pragma clang diagnostic pop #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) @@ -91,6 +94,7 @@ #ifndef __UNALIGNED_UINT32_READ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; #pragma clang diagnostic pop #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) @@ -98,6 +102,9 @@ #ifndef __ALIGNED #define __ALIGNED(x) __attribute__((aligned(x))) #endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif /* ########################### Core Function Access ########################### */ @@ -677,36 +684,24 @@ __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSPLIM_NS(uint32_t \details Returns the current value of the Floating Point Status/Control register. \return Floating Point Status/Control register value */ -/* #define __get_FPSCR __builtin_arm_get_fpscr */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void) -{ #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) - uint32_t result; - - __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); - return(result); +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr #else - return(0U); +#define __get_FPSCR() ((uint32_t)0U) #endif -} - /** \brief Set FPSCR \details Assigns the given value to the Floating Point Status/Control register. \param [in] fpscr Floating Point Status/Control value to set */ -/* #define __set_FPSCR __builtin_arm_set_fpscr */ -__attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) -{ #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) - __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "memory"); +#define __set_FPSCR __builtin_arm_set_fpscr #else - (void)fpscr; +#define __set_FPSCR(x) ((void)(x)) #endif -} #endif /* ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ @@ -791,7 +786,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) \param [in] value Value to reverse \return Reversed value */ -#define __REV __builtin_bswap32 +#define __REV (uint32_t)__builtin_bswap32 /** @@ -800,16 +795,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) \param [in] value Value to reverse \return Reversed value */ -#define __REV16 __builtin_bswap16 /* ToDo ARMCLANG: check if __builtin_bswap16 could be used */ -#if 0 -__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); -} -#endif +#define __REV16 (uint16_t)__builtin_bswap16 /** @@ -818,13 +804,13 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) \param [in] value Value to reverse \return Reversed value */ - /* ToDo ARMCLANG: check if __builtin_bswap16 could be used */ -__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) +__attribute__((always_inline)) __STATIC_INLINE int16_t __REVSH(int16_t value) { - int32_t result; + int16_t result; __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); + + return result; } @@ -848,7 +834,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint \param [in] value is ignored by the processor. If required, a debugger can use it to store additional information about the breakpoint. */ -#define __BKPT(value) __ASM volatile ("bkpt "#value) +#define __BKPT(value) __ASM volatile ("bkpt "#value) /** @@ -857,30 +843,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint \param [in] value Value to reverse \return Reversed value */ - /* ToDo ARMCLANG: check if __builtin_arm_rbit is supported */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) -{ - uint32_t result; - -#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ - (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ - (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) - __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); -#else - int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */ - - result = value; /* r will be reversed bits of v; first get LSB of v */ - for (value >>= 1U; value; value >>= 1U) - { - result <<= 1U; - result |= value & 1U; - s--; - } - result <<= s; /* shift when v's highest bits are zero */ -#endif - return(result); -} - +#define __RBIT (uint32_t)__builtin_arm_rbit /** \brief Count leading zeros @@ -970,6 +933,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + /** \brief Signed Saturate \details Saturates a signed value. @@ -1086,6 +1050,51 @@ __attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volat __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); } +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) { + return max; + } else if (val < min) { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) { + return max; + } else if (val < 0) { + return 0U; + } + } + return (uint32_t)val; +} + #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ diff --git a/cmsis/TARGET_CORTEX_M/cmsis_compiler.h b/cmsis/TARGET_CORTEX_M/cmsis_compiler.h index 9e87cfd74a4..5a9a222cdba 100644 --- a/cmsis/TARGET_CORTEX_M/cmsis_compiler.h +++ b/cmsis/TARGET_CORTEX_M/cmsis_compiler.h @@ -52,88 +52,9 @@ * IAR Compiler */ #elif defined ( __ICCARM__ ) + #include - #ifndef __ASM - #define __ASM __asm - #endif - #ifndef __INLINE - #define __INLINE inline - #endif - #ifndef __STATIC_INLINE - #define __STATIC_INLINE static inline - #endif - - #include - - /* CMSIS compiler control architecture macros */ - #if (__CORE__ == __ARM6M__) || (__CORE__ == __ARM6SM__) - #ifndef __ARM_ARCH_6M__ - #define __ARM_ARCH_6M__ 1 - #endif - #elif (__CORE__ == __ARM7M__) - #ifndef __ARM_ARCH_7M__ - #define __ARM_ARCH_7M__ 1 - #endif - #elif (__CORE__ == __ARM7EM__) - #ifndef __ARM_ARCH_7EM__ - #define __ARM_ARCH_7EM__ 1 - #endif - #elif (__CORE__ == __ARM8M_BASELINE__) - #ifndef __ARM_ARCH_8M_BASE__ - #define __ARM_ARCH_8M_BASE__ 1 - #endif - #elif (__CORE__ == __ARM8M_MAINLINE__) - #ifndef __ARM_ARCH_8M_MAIN__ - #define __ARM_ARCH_8M_MAIN__ 1 - #endif - #endif - - // IAR version 7.8.1 and earlier do not include __ALIGNED - #ifndef __ALIGNED - #define __ALIGNED(x) __attribute__((aligned(x))) - #endif - - #ifndef __NO_RETURN - #define __NO_RETURN __noreturn - #endif - #ifndef __USED - #define __USED __root - #endif - #ifndef __WEAK - #define __WEAK __weak - #endif - #ifndef __PACKED - #define __PACKED __packed - #endif - #ifndef __PACKED_STRUCT - #define __PACKED_STRUCT __packed struct - #endif - #ifndef __UNALIGNED_UINT32 /* deprecated */ - __packed struct T_UINT32 { uint32_t v; }; - #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) - #endif - #ifndef __UNALIGNED_UINT16_WRITE - __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; - #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) - #endif - #ifndef __UNALIGNED_UINT16_READ - __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; - #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) - #endif - #ifndef __UNALIGNED_UINT32_WRITE - __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; - #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) - #endif - #ifndef __UNALIGNED_UINT32_READ - __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; - #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) - #endif - #ifndef __ALIGNED - #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. - #define __ALIGNED(x) - #endif - - + /* * TI ARM Compiler */ @@ -164,6 +85,9 @@ #ifndef __PACKED_STRUCT #define __PACKED_STRUCT struct __attribute__((packed)) #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif #ifndef __UNALIGNED_UINT32 /* deprecated */ struct __attribute__((packed)) T_UINT32 { uint32_t v; }; #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) @@ -187,6 +111,10 @@ #ifndef __ALIGNED #define __ALIGNED(x) __attribute__((aligned(x))) #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif /* @@ -223,6 +151,9 @@ #ifndef __PACKED_STRUCT #define __PACKED_STRUCT struct __packed__ #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif #ifndef __UNALIGNED_UINT32 /* deprecated */ struct __packed__ T_UINT32 { uint32_t v; }; #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) @@ -246,6 +177,10 @@ #ifndef __ALIGNED #define __ALIGNED(x) __align(x) #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif /* @@ -280,6 +215,9 @@ #ifndef __PACKED_STRUCT #define __PACKED_STRUCT @packed struct #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif #ifndef __UNALIGNED_UINT32 /* deprecated */ @packed struct T_UINT32 { uint32_t v; }; #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) @@ -304,6 +242,10 @@ #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. #define __ALIGNED(x) #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif #else diff --git a/cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC/cmsis_gcc.h b/cmsis/TARGET_CORTEX_M/cmsis_gcc.h similarity index 95% rename from cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC/cmsis_gcc.h rename to cmsis/TARGET_CORTEX_M/cmsis_gcc.h index f023d77b230..4aef7af1e5b 100644 --- a/cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC/cmsis_gcc.h +++ b/cmsis/TARGET_CORTEX_M/cmsis_gcc.h @@ -31,6 +31,11 @@ #pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wunused-parameter" +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + /* CMSIS compiler specific defines */ #ifndef __ASM #define __ASM __asm @@ -56,6 +61,9 @@ #ifndef __PACKED_STRUCT #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) #endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif #ifndef __UNALIGNED_UINT32 /* deprecated */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpacked" @@ -99,6 +107,9 @@ #ifndef __ALIGNED #define __ALIGNED(x) __attribute__((aligned(x))) #endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif /* ########################### Core Function Access ########################### */ @@ -694,12 +705,17 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void) { #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else uint32_t result; __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); return(result); +#endif #else - return(0U); + return(0U); #endif } @@ -713,7 +729,12 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) { #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif #else (void)fpscr; #endif @@ -826,7 +847,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __DMB(void) /** \brief Reverse byte order (32 bit) - \details Reverses the byte order in integer value. + \details Reverses the byte order in unsigned integer value. \param [in] value Value to reverse \return Reversed value */ @@ -845,13 +866,13 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value) /** \brief Reverse byte order (16 bit) - \details Reverses the byte order in two unsigned short values. + \details Reverses the byte order in unsigned short value. \param [in] value Value to reverse \return Reversed value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) +__attribute__((always_inline)) __STATIC_INLINE uint16_t __REV16(uint16_t value) { - uint32_t result; + uint16_t result; __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); return(result); @@ -864,15 +885,15 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) \param [in] value Value to reverse \return Reversed value */ -__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) +__attribute__((always_inline)) __STATIC_INLINE int16_t __REVSH(int16_t value) { #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - return (short)__builtin_bswap16(value); + return (int16_t)__builtin_bswap16(value); #else - int32_t result; + int16_t result; __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); + return result; #endif } @@ -915,10 +936,10 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); #else - int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */ + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ result = value; /* r will be reversed bits of v; first get LSB of v */ - for (value >>= 1U; value; value >>= 1U) + for (value >>= 1U; value != 0U; value >>= 1U) { result <<= 1U; result |= value & 1U; @@ -926,7 +947,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) } result <<= s; /* shift when v's highest bits are zero */ #endif - return(result); + return result; } @@ -1074,11 +1095,12 @@ __attribute__((always_inline)) __STATIC_INLINE void __CLREX(void) /** \brief Signed Saturate \details Saturates a signed value. - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (1..32) + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) \return Saturated value */ #define __SSAT(ARG1,ARG2) \ +__extension__ \ ({ \ int32_t __RES, __ARG1 = (ARG1); \ __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ @@ -1089,11 +1111,12 @@ __attribute__((always_inline)) __STATIC_INLINE void __CLREX(void) /** \brief Unsigned Saturate \details Saturates an unsigned value. - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (0..31) + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) \return Saturated value */ #define __USAT(ARG1,ARG2) \ + __extension__ \ ({ \ uint32_t __RES, __ARG1 = (ARG1); \ __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ @@ -1211,6 +1234,51 @@ __attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volat __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); } +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) { + return max; + } else if (val < min) { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) { + return max; + } else if (val < 0) { + return 0U; + } + } + return (uint32_t)val; +} + #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ diff --git a/cmsis/TARGET_CORTEX_M/cmsis_iccarm.h b/cmsis/TARGET_CORTEX_M/cmsis_iccarm.h new file mode 100644 index 00000000000..01612854bbd --- /dev/null +++ b/cmsis/TARGET_CORTEX_M/cmsis_iccarm.h @@ -0,0 +1,771 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR compiler) header file + * @version V5.0.3 + * @date 29. August 2017 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017 IAR Systems +// +// 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 __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ +/* Macros already defined */ +#else + #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' + #if __ARM_ARCH == 6 + #define __ARM_ARCH_6M__ 1 + #elif __ARM_ARCH == 7 + #if __ARM_FEATURE_DSP + #define __ARM_ARCH_7EM__ 1 + #else + #define __ARM_ARCH_7M__ 1 + #endif + #endif /* __ARM_ARCH */ + #endif /* __ARM_ARCH_PROFILE == 'M' */ +#endif + +/* Alternativ core deduction for older ICCARM's */ +#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ + !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) + #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) + #define __ARM_ARCH_6M__ 1 + #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) + #define __ARM_ARCH_7M__ 1 + #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) + #define __ARM_ARCH_7EM__ 1 + #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #else + #error "Unknown target." + #endif +#endif + + + +#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 + #define __IAR_M0_FAMILY 1 +#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 + #define __IAR_M0_FAMILY 1 +#else + #define __IAR_M0_FAMILY 0 +#endif + + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((noreturn)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #define __RESTRICT restrict +#endif + + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __UNALIGNED_UINT16_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint16_t __iar_uint16_read(void const *ptr) { + return *(__packed uint16_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) { + *(__packed uint16_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint32_t __iar_uint32_read(void const *ptr) { + return *(__packed uint32_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) { + *(__packed uint32_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32 /* deprecated */ +#pragma language=save +#pragma language=extended +__packed struct __iar_u32 { uint32_t v; }; +#pragma language=restore +#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __enable_irq __iar_builtin_enable_interrupt + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + + #define __get_APSR() (__arm_rsr("APSR")) + #define __get_BASEPRI() (__arm_rsr("BASEPRI")) + #define __get_CONTROL() (__arm_rsr("CONTROL")) + #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) + + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) + #else + #define __get_FPSCR() ( 0 ) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #define __get_IPSR() (__arm_rsr("IPSR")) + #define __get_MSP() (__arm_rsr("MSP")) + #define __get_MSPLIM() (__arm_rsr("MSPLIM")) + #define __get_PRIMASK() (__arm_rsr("PRIMASK")) + #define __get_PSP() (__arm_rsr("PSP")) + #define __get_PSPLIM() (__arm_rsr("PSPLIM")) + #define __get_xPSR() (__arm_rsr("xPSR")) + + #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) + #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) + #define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE))) + #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) + #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) + #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) + #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) + #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) + #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) + + #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) + #define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE))) + #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) + #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) + #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) + #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) + #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) + #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) + #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) + #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) + #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) + #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) + #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) + #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) + #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) + #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) + #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) + #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) + + #define __NOP __iar_builtin_no_operation + + __IAR_FT uint8_t __CLZ(uint32_t val) { + return __iar_builtin_CLZ(val); + } + + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int32_t __REVSH(int32_t val) { + return __iar_builtin_REVSH((int16_t)val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #if !__IAR_M0_FAMILY + #define __SSAT __iar_builtin_SSAT + #endif + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #if !__IAR_M0_FAMILY + #define __USAT __iar_builtin_USAT + #endif + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #if __ARM_MEDIA__ + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + #endif + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #define __CLZ __cmsis_iar_clz_not_active + #define __SSAT __cmsis_iar_ssat_not_active + #define __USAT __cmsis_iar_usat_not_active + #define __RBIT __cmsis_iar_rbit_not_active + #define __get_APSR __cmsis_iar_get_APSR_not_active + #endif + + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #define __set_FPSCR __cmsis_iar_set_FPSR_not_active + #endif + + #include + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #undef __CLZ + #undef __SSAT + #undef __USAT + #undef __RBIT + #undef __get_APSR + + __STATIC_INLINE uint8_t __CLZ(uint32_t data) { + if (data == 0u) { return 32u; } + + uint32_t count = 0; + uint32_t mask = 0x80000000; + + while ((data & mask) == 0) + { + count += 1u; + mask = mask >> 1u; + } + return (count); + } + + __STATIC_INLINE uint32_t __RBIT(uint32_t v) { + uint8_t sc = 31; + uint32_t r = v; + for (v >>= 1U; v; v >>= 1U) + { + r <<= 1U; + r |= v & 1U; + sc--; + } + return (r << sc); + } + + __STATIC_INLINE uint32_t __get_APSR(void) { + uint32_t res; + __asm("MRS %0,APSR" : "=r" (res)); + return res; + } + + #endif + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #undef __get_FPSCR + #undef __set_FPSCR + #define __get_FPSCR() (0) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) { + return __STREX(value, (unsigned long *)ptr); + } + #endif + + + /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + #if (__CORTEX_M >= 0x03) + + __IAR_FT uint32_t __RRX(uint32_t value) { + uint32_t result; + __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); + return(result); + } + + __IAR_FT void __set_BASEPRI_MAX(uint32_t value) { + __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); + } + + + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + + + #endif /* (__CORTEX_M >= 0x03) */ + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) { + uint32_t res; + __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) { + __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSP_NS(void) { + uint32_t res; + __asm volatile("MRS %0,PSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PSP_NS(uint32_t value) { + __asm volatile("MSR PSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSP_NS(void) { + uint32_t res; + __asm volatile("MRS %0,MSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSP_NS(uint32_t value) { + __asm volatile("MSR MSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_SP_NS(void) { + uint32_t res; + __asm volatile("MRS %0,SP_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_SP_NS(uint32_t value) { + __asm volatile("MSR SP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) { + uint32_t res; + __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) { + __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) { + uint32_t res; + __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) { + __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) { + uint32_t res; + __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) { + __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) { + uint32_t res; + __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) { + __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) { + uint32_t res; + __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) { + __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); + } + + #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + +#if __IAR_M0_FAMILY + __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) { + if ((sat >= 1U) && (sat <= 32U)) { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) { + return max; + } else if (val < min) { + return min; + } + } + return val; + } + + __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) { + if (sat <= 31U) { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) { + return max; + } else if (val < 0) { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + + __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) { + uint32_t res; + __ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) { + uint32_t res; + __ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) { + uint32_t res; + __ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return res; + } + + __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) { + __ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) { + __ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) { + __ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); + } + +#endif /* (__CORTEX_M >= 0x03) */ + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + + __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) { + uint32_t res; + __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) { + uint32_t res; + __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) { + uint32_t res; + __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return res; + } + + __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) { + __ASM volatile ("STLB %1, [%0]" :: "r" (*ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) { + __ASM volatile ("STLH %1, [%0]" :: "r" (*ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) { + __ASM volatile ("STL %1, [%0]" :: "r" (*ptr), "r" (value) : "memory"); + } + + __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) { + uint32_t res; + __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) { + uint32_t res; + __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) { + uint32_t res; + __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) { + uint32_t res; + __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (*ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) { + uint32_t res; + __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (*ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) { + uint32_t res; + __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (*ptr), "r" (value) : "memory"); + return res; + } + +#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#undef __IAR_FT +#undef __IAR_M0_FAMILY +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/cmsis/TARGET_CORTEX_M/cmsis_version.h b/cmsis/TARGET_CORTEX_M/cmsis_version.h new file mode 100644 index 00000000000..d458a6c8599 --- /dev/null +++ b/cmsis/TARGET_CORTEX_M/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.2 + * @date 19. April 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/cmsis/core_armv8mbl.h b/cmsis/TARGET_CORTEX_M/core_armv8mbl.h similarity index 99% rename from cmsis/core_armv8mbl.h rename to cmsis/TARGET_CORTEX_M/core_armv8mbl.h index d03935201ce..917b16e1a32 100644 --- a/cmsis/core_armv8mbl.h +++ b/cmsis/TARGET_CORTEX_M/core_armv8mbl.h @@ -1,8 +1,8 @@ /**************************************************************************//** * @file core_armv8mbl.h * @brief CMSIS ARMv8MBL Core Peripheral Access Layer Header File - * @version V5.0.2 - * @date 13. February 2017 + * @version V5.0.3 + * @date 09. August 2017 ******************************************************************************/ /* * Copyright (c) 2009-2017 ARM Limited. All rights reserved. @@ -59,12 +59,14 @@ \ingroup Cortex_ARMv8MBL @{ */ + +#include "cmsis_version.h" -/* CMSIS cmGrebe definitions */ -#define __ARMv8MBL_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __ARMv8MBL_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +/* CMSIS definitions */ +#define __ARMv8MBL_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MBL_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __ARMv8MBL_CMSIS_VERSION ((__ARMv8MBL_CMSIS_VERSION_MAIN << 16U) | \ - __ARMv8MBL_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __ARMv8MBL_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M ( 2U) /*!< Cortex-M Core */ @@ -881,10 +883,17 @@ typedef struct __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; } MPU_Type; +#define MPU_TYPE_RALIASES 1U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -1627,6 +1636,10 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) { return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } + else + { + return(0U); + } } @@ -1729,6 +1742,13 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif /* ########################## FPU functions #################################### */ /** diff --git a/cmsis/core_armv8mml.h b/cmsis/TARGET_CORTEX_M/core_armv8mml.h similarity index 98% rename from cmsis/core_armv8mml.h rename to cmsis/TARGET_CORTEX_M/core_armv8mml.h index 286322f75c4..afea7588c75 100644 --- a/cmsis/core_armv8mml.h +++ b/cmsis/TARGET_CORTEX_M/core_armv8mml.h @@ -1,8 +1,8 @@ /**************************************************************************//** * @file core_armv8mml.h * @brief CMSIS ARMv8MML Core Peripheral Access Layer Header File - * @version V5.0.2 - * @date 13. February 2017 + * @version V5.0.3 + * @date 09. August 2017 ******************************************************************************/ /* * Copyright (c) 2009-2017 ARM Limited. All rights reserved. @@ -60,11 +60,13 @@ @{ */ +#include "cmsis_version.h" + /* CMSIS ARMv8MML definitions */ -#define __ARMv8MML_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __ARMv8MML_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __ARMv8MML_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MML_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __ARMv8MML_CMSIS_VERSION ((__ARMv8MML_CMSIS_VERSION_MAIN << 16U) | \ - __ARMv8MML_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __ARMv8MML_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (81U) /*!< Cortex-M Core */ @@ -83,6 +85,17 @@ #define __FPU_USED 0U #endif + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_PCS_VFP #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) @@ -95,6 +108,17 @@ #define __FPU_USED 0U #endif + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) @@ -106,7 +130,18 @@ #else #define __FPU_USED 0U #endif - + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) @@ -119,6 +154,17 @@ #define __FPU_USED 0U #endif + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + #elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) @@ -480,7 +526,7 @@ typedef struct uint32_t RESERVED4[15U]; __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ - __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ uint32_t RESERVED5[1U]; __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ uint32_t RESERVED6[1U]; @@ -1505,10 +1551,17 @@ typedef struct __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; } MPU_Type; +#define MPU_TYPE_RALIASES 4U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -2661,6 +2714,13 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif /* ########################## FPU functions #################################### */ /** diff --git a/cmsis/core_cm0.h b/cmsis/TARGET_CORTEX_M/core_cm0.h similarity index 99% rename from cmsis/core_cm0.h rename to cmsis/TARGET_CORTEX_M/core_cm0.h index f1fbbe9c172..2f63b68610b 100644 --- a/cmsis/core_cm0.h +++ b/cmsis/TARGET_CORTEX_M/core_cm0.h @@ -2,7 +2,7 @@ * @file core_cm0.h * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File * @version V5.0.2 - * @date 13. February 2017 + * @date 19. April 2017 ******************************************************************************/ /* * Copyright (c) 2009-2017 ARM Limited. All rights reserved. @@ -60,11 +60,13 @@ @{ */ +#include "cmsis_version.h" + /* CMSIS CM0 definitions */ -#define __CM0_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __CM0_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ - __CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (0U) /*!< Cortex-M Core */ diff --git a/cmsis/core_cm0plus.h b/cmsis/TARGET_CORTEX_M/core_cm0plus.h similarity index 98% rename from cmsis/core_cm0plus.h rename to cmsis/TARGET_CORTEX_M/core_cm0plus.h index 2dca31a3cf1..84f32813fd2 100644 --- a/cmsis/core_cm0plus.h +++ b/cmsis/TARGET_CORTEX_M/core_cm0plus.h @@ -1,8 +1,8 @@ /**************************************************************************//** * @file core_cm0plus.h * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File - * @version V5.0.2 - * @date 13. February 2017 + * @version V5.0.3 + * @date 09. August 2017 ******************************************************************************/ /* * Copyright (c) 2009-2017 ARM Limited. All rights reserved. @@ -60,11 +60,13 @@ @{ */ +#include "cmsis_version.h" + /* CMSIS CM0+ definitions */ -#define __CM0PLUS_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __CM0PLUS_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \ - __CM0PLUS_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __CM0PLUS_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (0U) /*!< Cortex-M Core */ @@ -528,6 +530,8 @@ typedef struct __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ } MPU_Type; +#define MPU_TYPE_RALIASES 1U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -932,6 +936,13 @@ __STATIC_INLINE void __NVIC_SystemReset(void) /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif /* ########################## FPU functions #################################### */ /** diff --git a/cmsis/core_cm23.h b/cmsis/TARGET_CORTEX_M/core_cm23.h similarity index 99% rename from cmsis/core_cm23.h rename to cmsis/TARGET_CORTEX_M/core_cm23.h index 378c69beeb2..1852efbb54c 100644 --- a/cmsis/core_cm23.h +++ b/cmsis/TARGET_CORTEX_M/core_cm23.h @@ -1,8 +1,8 @@ /**************************************************************************//** * @file core_cm23.h * @brief CMSIS Cortex-M23 Core Peripheral Access Layer Header File - * @version V5.0.2 - * @date 13. February 2017 + * @version V5.0.3 + * @date 09. August 2017 ******************************************************************************/ /* * Copyright (c) 2009-2017 ARM Limited. All rights reserved. @@ -60,11 +60,13 @@ @{ */ -/* CMSIS cmGrebe definitions */ -#define __CM23_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __CM23_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#include "cmsis_version.h" + +/* CMSIS definitions */ +#define __CM23_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM23_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM23_CMSIS_VERSION ((__CM23_CMSIS_VERSION_MAIN << 16U) | \ - __CM23_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __CM23_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (23U) /*!< Cortex-M Core */ @@ -881,10 +883,17 @@ typedef struct __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; } MPU_Type; +#define MPU_TYPE_RALIASES 1U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -1627,6 +1636,10 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) { return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } + else + { + return(0U); + } } @@ -1729,6 +1742,13 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif /* ########################## FPU functions #################################### */ /** diff --git a/cmsis/core_cm3.h b/cmsis/TARGET_CORTEX_M/core_cm3.h similarity index 99% rename from cmsis/core_cm3.h rename to cmsis/TARGET_CORTEX_M/core_cm3.h index cfeb58bea91..3809f716c52 100644 --- a/cmsis/core_cm3.h +++ b/cmsis/TARGET_CORTEX_M/core_cm3.h @@ -1,8 +1,8 @@ /**************************************************************************//** * @file core_cm3.h * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File - * @version V5.0.2 - * @date 13. February 2017 + * @version V5.0.3 + * @date 09. August 2017 ******************************************************************************/ /* * Copyright (c) 2009-2017 ARM Limited. All rights reserved. @@ -60,11 +60,13 @@ @{ */ +#include "cmsis_version.h" + /* CMSIS CM3 definitions */ -#define __CM3_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __CM3_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \ - __CM3_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __CM3_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (3U) /*!< Cortex-M Core */ @@ -1162,6 +1164,8 @@ typedef struct __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ } MPU_Type; +#define MPU_TYPE_RALIASES 4U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -1761,6 +1765,13 @@ __STATIC_INLINE void __NVIC_SystemReset(void) /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif /* ########################## FPU functions #################################### */ /** diff --git a/cmsis/core_cm33.h b/cmsis/TARGET_CORTEX_M/core_cm33.h similarity index 98% rename from cmsis/core_cm33.h rename to cmsis/TARGET_CORTEX_M/core_cm33.h index 9e880ae7dc9..ef0b7c7c530 100644 --- a/cmsis/core_cm33.h +++ b/cmsis/TARGET_CORTEX_M/core_cm33.h @@ -1,8 +1,8 @@ /**************************************************************************//** * @file core_cm33.h * @brief CMSIS Cortex-M33 Core Peripheral Access Layer Header File - * @version V5.0.2 - * @date 13. February 2017 + * @version V5.0.3 + * @date 09. August 2017 ******************************************************************************/ /* * Copyright (c) 2009-2017 ARM Limited. All rights reserved. @@ -60,11 +60,13 @@ @{ */ +#include "cmsis_version.h" + /* CMSIS CM33 definitions */ -#define __CM33_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __CM33_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __CM33_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM33_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM33_CMSIS_VERSION ((__CM33_CMSIS_VERSION_MAIN << 16U) | \ - __CM33_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __CM33_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (33U) /*!< Cortex-M Core */ @@ -83,6 +85,17 @@ #define __FPU_USED 0U #endif + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_PCS_VFP #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) @@ -95,6 +108,17 @@ #define __FPU_USED 0U #endif + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) @@ -107,6 +131,17 @@ #define __FPU_USED 0U #endif + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) @@ -119,6 +154,17 @@ #define __FPU_USED 0U #endif + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + #elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) @@ -480,7 +526,7 @@ typedef struct uint32_t RESERVED4[15U]; __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ - __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ uint32_t RESERVED5[1U]; __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ uint32_t RESERVED6[1U]; @@ -1505,10 +1551,17 @@ typedef struct __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; } MPU_Type; +#define MPU_TYPE_RALIASES 4U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -1534,8 +1587,8 @@ typedef struct #define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ -#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: ADDR Mask */ #define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ #define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ @@ -2557,6 +2610,10 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) { return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } + else + { + return(0U); + } } @@ -2657,6 +2714,13 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif /* ########################## FPU functions #################################### */ /** diff --git a/cmsis/core_cm4.h b/cmsis/TARGET_CORTEX_M/core_cm4.h similarity index 99% rename from cmsis/core_cm4.h rename to cmsis/TARGET_CORTEX_M/core_cm4.h index bdaedcf9f31..1c12d4e51cc 100644 --- a/cmsis/core_cm4.h +++ b/cmsis/TARGET_CORTEX_M/core_cm4.h @@ -1,8 +1,8 @@ /**************************************************************************//** * @file core_cm4.h * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File - * @version V5.0.2 - * @date 13. February 2017 + * @version V5.0.3 + * @date 09. August 2017 ******************************************************************************/ /* * Copyright (c) 2009-2017 ARM Limited. All rights reserved. @@ -60,11 +60,13 @@ @{ */ -/* CMSIS CM4 definitions */ -#define __CM4_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __CM4_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#include "cmsis_version.h" + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ - __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __CM4_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (4U) /*!< Cortex-M Core */ @@ -1227,6 +1229,8 @@ typedef struct __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ } MPU_Type; +#define MPU_TYPE_RALIASES 4U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -1935,6 +1939,14 @@ __STATIC_INLINE void __NVIC_SystemReset(void) /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + /* ########################## FPU functions #################################### */ /** diff --git a/cmsis/core_cm7.h b/cmsis/TARGET_CORTEX_M/core_cm7.h similarity index 99% rename from cmsis/core_cm7.h rename to cmsis/TARGET_CORTEX_M/core_cm7.h index fee3d0c977a..65fa60fc85b 100644 --- a/cmsis/core_cm7.h +++ b/cmsis/TARGET_CORTEX_M/core_cm7.h @@ -1,8 +1,8 @@ /**************************************************************************//** * @file core_cm7.h * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File - * @version V5.0.2 - * @date 13. February 2017 + * @version V5.0.3 + * @date 09. August 2017 ******************************************************************************/ /* * Copyright (c) 2009-2017 ARM Limited. All rights reserved. @@ -60,11 +60,13 @@ @{ */ +#include "cmsis_version.h" + /* CMSIS CM7 definitions */ -#define __CM7_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __CM7_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __CM7_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM7_CMSIS_VERSION_SUB ( __CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ - __CM7_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __CM7_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (7U) /*!< Cortex-M Core */ @@ -482,7 +484,7 @@ typedef struct uint32_t RESERVED4[15U]; __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ - __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ uint32_t RESERVED5[1U]; __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ uint32_t RESERVED6[1U]; @@ -1432,6 +1434,8 @@ typedef struct __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ } MPU_Type; +#define MPU_TYPE_RALIASES 4U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -2143,6 +2147,13 @@ __STATIC_INLINE void __NVIC_SystemReset(void) /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif /* ########################## FPU functions #################################### */ /** diff --git a/cmsis/core_sc000.h b/cmsis/TARGET_CORTEX_M/core_sc000.h similarity index 99% rename from cmsis/core_sc000.h rename to cmsis/TARGET_CORTEX_M/core_sc000.h index 53dfaadd8b3..bd26eaa0db9 100644 --- a/cmsis/core_sc000.h +++ b/cmsis/TARGET_CORTEX_M/core_sc000.h @@ -2,7 +2,7 @@ * @file core_sc000.h * @brief CMSIS SC000 Core Peripheral Access Layer Header File * @version V5.0.2 - * @date 13. February 2017 + * @date 19. April 2017 ******************************************************************************/ /* * Copyright (c) 2009-2017 ARM Limited. All rights reserved. @@ -60,11 +60,13 @@ @{ */ +#include "cmsis_version.h" + /* CMSIS SC000 definitions */ -#define __SC000_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __SC000_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __SC000_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __SC000_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \ - __SC000_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __SC000_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_SC (000U) /*!< Cortex secure core */ diff --git a/cmsis/core_sc300.h b/cmsis/TARGET_CORTEX_M/core_sc300.h similarity index 99% rename from cmsis/core_sc300.h rename to cmsis/TARGET_CORTEX_M/core_sc300.h index 78450e0f7c5..780372a350c 100644 --- a/cmsis/core_sc300.h +++ b/cmsis/TARGET_CORTEX_M/core_sc300.h @@ -2,7 +2,7 @@ * @file core_sc300.h * @brief CMSIS SC300 Core Peripheral Access Layer Header File * @version V5.0.2 - * @date 13. February 2017 + * @date 19. April 2017 ******************************************************************************/ /* * Copyright (c) 2009-2017 ARM Limited. All rights reserved. @@ -60,11 +60,13 @@ @{ */ +#include "cmsis_version.h" + /* CMSIS SC300 definitions */ -#define __SC300_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __SC300_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __SC300_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __SC300_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16U) | \ - __SC300_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __SC300_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_SC (300U) /*!< Cortex secure core */ diff --git a/cmsis/TARGET_CORTEX_M/mpu_armv7.h b/cmsis/TARGET_CORTEX_M/mpu_armv7.h new file mode 100644 index 00000000000..44d0930cc3f --- /dev/null +++ b/cmsis/TARGET_CORTEX_M/mpu_armv7.h @@ -0,0 +1,191 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for ARMv7 MPU + * @version V5.0.3 + * @date 09. August 2017 + ******************************************************************************/ +/* + * Copyright (c) 2017 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 + * + * 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 ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) + +#define ARM_MPU_AP_NONE 0U +#define ARM_MPU_AP_PRIV 1U +#define ARM_MPU_AP_URO 2U +#define ARM_MPU_AP_FULL 3U +#define ARM_MPU_AP_PRO 5U +#define ARM_MPU_AP_RO 6U + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Region Attribut and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ((((DisableExec ) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((TypeExtField ) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable ) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable ) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable ) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk) | \ + (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ + (((Size ) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ + (MPU_RASR_ENABLE_Msk)) + + +/** +* Struct for a single MPU Region +*/ +typedef struct _ARM_MPU_Region_t { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + static const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + if (cnt > MPU_TYPE_RALIASES) { + orderedCpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + ARM_MPU_Load(table+MPU_TYPE_RALIASES, cnt-MPU_TYPE_RALIASES); + } else { + orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); + } +} + +#endif diff --git a/cmsis/TARGET_CORTEX_M/mpu_armv8.h b/cmsis/TARGET_CORTEX_M/mpu_armv8.h new file mode 100644 index 00000000000..69452e0d0b3 --- /dev/null +++ b/cmsis/TARGET_CORTEX_M/mpu_armv8.h @@ -0,0 +1,323 @@ +/****************************************************************************** + * @file mpu_armv8.h + * @brief CMSIS MPU API for ARMv8 MPU + * @version V5.0.3 + * @date 09. August 2017 + ******************************************************************************/ +/* + * Copyright (c) 2017 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 + * + * 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 ARM_MPU_ARMV8_H +#define ARM_MPU_ARMV8_H + +/** \brief Attribute for device memory (outer only) */ +#define ARM_MPU_ATTR_DEVICE ( 0U ) + +/** \brief Attribute for non-cacheable, normal memory */ +#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U ) + +/** \brief Attribute for normal memory (outer and inner) +* \param NT Non-Transient: Set to 1 for non-transient data. +* \param WB Write-Back: Set to 1 to use write-back update policy. +* \param RA Read Allocation: Set to 1 to use cache allocation on read miss. +* \param WA Write Allocation: Set to 1 to use cache allocation on write miss. +*/ +#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ + (((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U)) + +/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) + +/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRE (1U) + +/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGRE (2U) + +/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_GRE (3U) + +/** \brief Memory Attribute +* \param O Outer memory attributes +* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes +*/ +#define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U))) + +/** \brief Normal memory non-shareable */ +#define ARM_MPU_SH_NON (0U) + +/** \brief Normal memory outer shareable */ +#define ARM_MPU_SH_OUTER (2U) + +/** \brief Normal memory inner shareable */ +#define ARM_MPU_SH_INNER (3U) + +/** \brief Memory access permissions +* \param RO Read-Only: Set to 1 for read-only memory. +* \param NP Non-Privileged: Set to 1 for non-privileged memory. +*/ +#define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U)) + +/** \brief Region Base Address Register value +* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned. +* \param SH Defines the Shareability domain for this memory region. +* \param RO Read-Only: Set to 1 for a read-only memory region. +* \param NP Non-Privileged: Set to 1 for a non-privileged memory region. +* \oaram XN eXecute Never: Set to 1 for a non-executable memory region. +*/ +#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ + ((BASE & MPU_RBAR_BASE_Pos) | \ + ((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \ + ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \ + ((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) + +/** \brief Region Limit Address Register value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR(LIMIT, IDX) \ + ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ + ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +/** +* Struct for a single MPU Region +*/ +typedef struct _ARM_MPU_Region_t { + uint32_t RBAR; /*!< Region Base Address Register value */ + uint32_t RLAR; /*!< Region Limit Address Register value */ +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +#ifdef MPU_NS +/** Enable the Non-secure MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the Non-secure MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable_NS(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} +#endif + +/** Set the memory attribute encoding to the given MPU. +* \param mpu Pointer to the MPU to be configured. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) +{ + const uint8_t reg = idx / 4U; + const uint32_t pos = ((idx % 4U) * 8U); + const uint32_t mask = 0xFFU << pos; + + if (reg >= (sizeof(MPU->MAIR) / sizeof(MPU->MAIR[0]))) { + return; // invalid index + } + + MPU->MAIR[reg] = ((MPU->MAIR[reg] & ~mask) | ((attr << pos) & mask)); +} + +/** Set the memory attribute encoding. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU, idx, attr); +} + +#ifdef MPU_NS +/** Set the memory attribute encoding to the Non-secure MPU. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); +} +#endif + +/** Clear and disable the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RLAR = 0U; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU, rnr); +} + +#ifdef MPU_NS +/** Clear and disable the given Non-secure MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU_NS, rnr); +} +#endif + +/** Configure the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RLAR = rlar; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); +} + +#ifdef MPU_NS +/** Configure the given Non-secure MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar); +} +#endif + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table to the given MPU. +* \param mpu Pointer to the MPU registers to be used. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + static const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + if (cnt == 1U) { + mpu->RNR = rnr; + orderedCpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); + } else { + uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U); + uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; + + mpu->RNR = rnrBase; + if ((rnrOffset + cnt) > MPU_TYPE_RALIASES) { + uint32_t c = MPU_TYPE_RALIASES - rnrOffset; + orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize); + ARM_MPU_LoadEx(mpu, rnr + c, table + c, cnt - c); + } else { + orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize); + } + } +} + +/** Load the given number of MPU regions from a table. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU, rnr, table, cnt); +} + +#ifdef MPU_NS +/** Load the given number of MPU regions from a table to the Non-secure MPU. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); +} +#endif + +#endif + diff --git a/cmsis/tz_context.h b/cmsis/TARGET_CORTEX_M/tz_context.h similarity index 100% rename from cmsis/tz_context.h rename to cmsis/TARGET_CORTEX_M/tz_context.h diff --git a/cmsis/TOOLCHAIN_GCC/TARGET_CORTEX_A/cache.S b/cmsis/TOOLCHAIN_GCC/TARGET_CORTEX_A/cache.S deleted file mode 100644 index d37f889191d..00000000000 --- a/cmsis/TOOLCHAIN_GCC/TARGET_CORTEX_A/cache.S +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright (c) 2009 - 2012 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - .text - .global __v7_all_cache -/* - * __STATIC_ASM void __v7_all_cache(uint32_t op) { - */ -__v7_all_cache: - .arm - - PUSH {R4-R11} - - MRC p15, 1, R6, c0, c0, 1 /* Read CLIDR */ - ANDS R3, R6, #0x07000000 /* Extract coherency level */ - MOV R3, R3, LSR #23 /* Total cache levels << 1 */ - BEQ Finished /* If 0, no need to clean */ - - MOV R10, #0 /* R10 holds current cache level << 1 */ -Loop1: ADD R2, R10, R10, LSR #1 /* R2 holds cache "Set" position */ - MOV R1, R6, LSR R2 /* Bottom 3 bits are the Cache-type for this level */ - AND R1, R1, #7 /* Isolate those lower 3 bits */ - CMP R1, #2 - BLT Skip /* No cache or only instruction cache at this level */ - - MCR p15, 2, R10, c0, c0, 0 /* Write the Cache Size selection register */ - ISB /* ISB to sync the change to the CacheSizeID reg */ - MRC p15, 1, R1, c0, c0, 0 /* Reads current Cache Size ID register */ - AND R2, R1, #7 /* Extract the line length field */ - ADD R2, R2, #4 /* Add 4 for the line length offset (log2 16 bytes) */ - LDR R4, =0x3FF - ANDS R4, R4, R1, LSR #3 /* R4 is the max number on the way size (right aligned) */ - CLZ R5, R4 /* R5 is the bit position of the way size increment */ - LDR R7, =0x7FFF - ANDS R7, R7, R1, LSR #13 /* R7 is the max number of the index size (right aligned) */ - -Loop2: MOV R9, R4 /* R9 working copy of the max way size (right aligned) */ - -Loop3: ORR R11, R10, R9, LSL R5 /* Factor in the Way number and cache number into R11 */ - ORR R11, R11, R7, LSL R2 /* Factor in the Set number */ - CMP R0, #0 - BNE Dccsw - MCR p15, 0, R11, c7, c6, 2 /* DCISW. Invalidate by Set/Way */ - B cont -Dccsw: CMP R0, #1 - BNE Dccisw - MCR p15, 0, R11, c7, c10, 2 /* DCCSW. Clean by Set/Way */ - B cont -Dccisw: MCR p15, 0, R11, c7, c14, 2 /* DCCISW, Clean and Invalidate by Set/Way */ -cont: SUBS R9, R9, #1 /* Decrement the Way number */ - BGE Loop3 - SUBS R7, R7, #1 /* Decrement the Set number */ - BGE Loop2 -Skip: ADD R10, R10, #2 /* increment the cache number */ - CMP R3, R10 - BGT Loop1 - -Finished: - DSB - POP {R4-R11} - BX lr - - - .END -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/cmsis/TOOLCHAIN_IAR/TARGET_CORTEX_A/cache.S b/cmsis/TOOLCHAIN_IAR/TARGET_CORTEX_A/cache.S deleted file mode 100644 index 00352787a20..00000000000 --- a/cmsis/TOOLCHAIN_IAR/TARGET_CORTEX_A/cache.S +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright (c) 2009 - 2012 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - SECTION `.text`:CODE:NOROOT(2) - arm - PUBLIC __v7_all_cache -/* - * __STATIC_ASM void __v7_all_cache(uint32_t op) { - */ - -__v7_all_cache: - - - PUSH {R4-R11} - - MRC p15, 1, R6, c0, c0, 1 /* Read CLIDR */ - ANDS R3, R6, #0x07000000 /* Extract coherency level */ - MOV R3, R3, LSR #23 /* Total cache levels << 1 */ - BEQ Finished /* If 0, no need to clean */ - - MOV R10, #0 /* R10 holds current cache level << 1 */ -Loop1: ADD R2, R10, R10, LSR #1 /* R2 holds cache "Set" position */ - MOV R1, R6, LSR R2 /* Bottom 3 bits are the Cache-type for this level */ - AND R1, R1, #7 /* Isolate those lower 3 bits */ - CMP R1, #2 - BLT Skip /* No cache or only instruction cache at this level */ - - MCR p15, 2, R10, c0, c0, 0 /* Write the Cache Size selection register */ - ISB /* ISB to sync the change to the CacheSizeID reg */ - MRC p15, 1, R1, c0, c0, 0 /* Reads current Cache Size ID register */ - AND R2, R1, #7 /* Extract the line length field */ - ADD R2, R2, #4 /* Add 4 for the line length offset (log2 16 bytes) */ - LDR R4, =0x3FF - ANDS R4, R4, R1, LSR #3 /* R4 is the max number on the way size (right aligned) */ - CLZ R5, R4 /* R5 is the bit position of the way size increment */ - LDR R7, =0x7FFF - ANDS R7, R7, R1, LSR #13 /* R7 is the max number of the index size (right aligned) */ - -Loop2: MOV R9, R4 /* R9 working copy of the max way size (right aligned) */ - -Loop3: ORR R11, R10, R9, LSL R5 /* Factor in the Way number and cache number into R11 */ - ORR R11, R11, R7, LSL R2 /* Factor in the Set number */ - CMP R0, #0 - BNE Dccsw - MCR p15, 0, R11, c7, c6, 2 /* DCISW. Invalidate by Set/Way */ - B cont -Dccsw: CMP R0, #1 - BNE Dccisw - MCR p15, 0, R11, c7, c10, 2 /* DCCSW. Clean by Set/Way */ - B cont -Dccisw: MCR p15, 0, R11, c7, c14, 2 /* DCCISW, Clean and Invalidate by Set/Way */ -cont: SUBS R9, R9, #1 /* Decrement the Way number */ - BGE Loop3 - SUBS R7, R7, #1 /* Decrement the Set number */ - BGE Loop2 -Skip: ADD R10, R10, #2 /* increment the cache number */ - CMP R3, R10 - BGT Loop1 - -Finished: - DSB - POP {R4-R11} - BX lr - - - END -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - diff --git a/cmsis/TOOLCHAIN_IAR/cmain.S b/cmsis/TOOLCHAIN_IAR/cmain.S deleted file mode 100644 index 0da55009b38..00000000000 --- a/cmsis/TOOLCHAIN_IAR/cmain.S +++ /dev/null @@ -1,101 +0,0 @@ -/************************************************** - * - * Part two of the system initialization code, contains C-level - * initialization, thumb-2 only variant. - * - * $Revision: 59783 $ - * - **************************************************/ -/* Copyright 2008-2017, IAR Systems AB. - This source code is the property of IAR Systems. The source code may only - be used together with the IAR Embedded Workbench. Redistribution and use - in source and binary forms, with or without modification, is permitted - provided that the following conditions are met: - - Redistributions of source code, in whole or in part, must retain the - above copyright notice, this list of conditions and the disclaimer below. - - IAR Systems name may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -; -------------------------------------------------- -; Module ?cmain, C-level initialization. -; - - - SECTION SHT$$PREINIT_ARRAY:CONST:NOROOT(2) - SECTION SHT$$INIT_ARRAY:CONST:NOROOT(2) - - SECTION .text:CODE:NOROOT(2) - - PUBLIC __cmain - ;; Keep ?main for legacy reasons, it is accessed in countless instances of cstartup.s around the world... - PUBLIC ?main - EXTWEAK __iar_data_init3 - EXTWEAK __iar_argc_argv - EXTERN __low_level_init - EXTERN __call_ctors - EXTERN main - EXTERN exit - EXTERN __iar_dynamic_initialization - EXTERN mbed_sdk_init - EXTERN mbed_main - EXTERN SystemInit - - THUMB -__cmain: -?main: - -; Initialize segments. -; __segment_init and __low_level_init are assumed to use the same -; instruction set and to be reachable by BL from the ICODE segment -; (it is safest to link them in segment ICODE). - - FUNCALL __cmain, __low_level_init - bl __low_level_init - cmp r0,#0 - beq ?l1 - FUNCALL __cmain, __iar_data_init3 - bl __iar_data_init3 - MOVS r0,#0 ; No parameters - FUNCALL __cmain, mbed_sdk_init - BL mbed_sdk_init - MOVS r0,#0 ; No parameters - FUNCALL __cmain, __iar_dynamic_initialization - BL __iar_dynamic_initialization ; C++ dynamic initialization - -?l1: - REQUIRE ?l3 - - SECTION .text:CODE:NOROOT(2) - - PUBLIC _main - PUBLIC _call_main - THUMB - -__iar_init$$done: ; Copy initialization is done - -?l3: -_call_main: - MOVS r0,#0 ; No parameters - FUNCALL __cmain, __iar_argc_argv - BL __iar_argc_argv ; Maybe setup command line - - MOVS r0,#0 ; No parameters - FUNCALL __cmain, mbed_main - BL mbed_main - - FUNCALL __cmain, main - BL main -_main: - FUNCALL __cmain, exit - BL exit - - END diff --git a/cmsis/arm_math.h b/cmsis/arm_math.h deleted file mode 100644 index 6d754018966..00000000000 --- a/cmsis/arm_math.h +++ /dev/null @@ -1,7257 +0,0 @@ -/* ---------------------------------------------------------------------- - * Project: CMSIS DSP Library - * Title: arm_math.h - * Description: Public header file for CMSIS DSP Library - * - * $Date: 27. January 2017 - * $Revision: V.1.5.1 - * - * Target Processor: Cortex-M cores - * -------------------------------------------------------------------- */ -/* - * Copyright (C) 2010-2017 ARM Limited or its affiliates. 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 - * - * 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. - */ - -/** - \mainpage CMSIS DSP Software Library - * - * Introduction - * ------------ - * - * This user manual describes the CMSIS DSP software library, - * a suite of common signal processing functions for use on Cortex-M processor based devices. - * - * The library is divided into a number of functions each covering a specific category: - * - Basic math functions - * - Fast math functions - * - Complex math functions - * - Filters - * - Matrix functions - * - Transforms - * - Motor control functions - * - Statistical functions - * - Support functions - * - Interpolation functions - * - * The library has separate functions for operating on 8-bit integers, 16-bit integers, - * 32-bit integer and 32-bit floating-point values. - * - * Using the Library - * ------------ - * - * The library installer contains prebuilt versions of the libraries in the Lib folder. - * - arm_cortexM7lfdp_math.lib (Cortex-M7, Little endian, Double Precision Floating Point Unit) - * - arm_cortexM7bfdp_math.lib (Cortex-M7, Big endian, Double Precision Floating Point Unit) - * - arm_cortexM7lfsp_math.lib (Cortex-M7, Little endian, Single Precision Floating Point Unit) - * - arm_cortexM7bfsp_math.lib (Cortex-M7, Big endian and Single Precision Floating Point Unit on) - * - arm_cortexM7l_math.lib (Cortex-M7, Little endian) - * - arm_cortexM7b_math.lib (Cortex-M7, Big endian) - * - arm_cortexM4lf_math.lib (Cortex-M4, Little endian, Floating Point Unit) - * - arm_cortexM4bf_math.lib (Cortex-M4, Big endian, Floating Point Unit) - * - arm_cortexM4l_math.lib (Cortex-M4, Little endian) - * - arm_cortexM4b_math.lib (Cortex-M4, Big endian) - * - arm_cortexM3l_math.lib (Cortex-M3, Little endian) - * - arm_cortexM3b_math.lib (Cortex-M3, Big endian) - * - arm_cortexM0l_math.lib (Cortex-M0 / Cortex-M0+, Little endian) - * - arm_cortexM0b_math.lib (Cortex-M0 / Cortex-M0+, Big endian) - * - arm_ARMv8MBLl_math.lib (ARMv8M Baseline, Little endian) - * - arm_ARMv8MMLl_math.lib (ARMv8M Mainline, Little endian) - * - arm_ARMv8MMLlfsp_math.lib (ARMv8M Mainline, Little endian, Single Precision Floating Point Unit) - * - arm_ARMv8MMLld_math.lib (ARMv8M Mainline, Little endian, DSP instructions) - * - arm_ARMv8MMLldfsp_math.lib (ARMv8M Mainline, Little endian, DSP instructions, Single Precision Floating Point Unit) - * - * The library functions are declared in the public file arm_math.h which is placed in the Include folder. - * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single - * public header file arm_math.h for Cortex-M cores with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. - * Define the appropriate pre processor MACRO ARM_MATH_CM7 or ARM_MATH_CM4 or ARM_MATH_CM3 or - * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application. - * For ARMv8M cores define pre processor MACRO ARM_MATH_ARMV8MBL or ARM_MATH_ARMV8MML. - * Set Pre processor MACRO __DSP_PRESENT if ARMv8M Mainline core supports DSP instructions. - * - * - * Examples - * -------- - * - * The library ships with a number of examples which demonstrate how to use the library functions. - * - * Toolchain Support - * ------------ - * - * The library has been developed and tested with MDK-ARM version 5.14.0.0 - * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. - * - * Building the Library - * ------------ - * - * The library installer contains a project file to re build libraries on MDK-ARM Tool chain in the CMSIS\\DSP_Lib\\Source\\ARM folder. - * - arm_cortexM_math.uvprojx - * - * - * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional pre processor MACROs detailed above. - * - * Pre-processor Macros - * ------------ - * - * Each library project have differant pre-processor macros. - * - * - UNALIGNED_SUPPORT_DISABLE: - * - * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access - * - * - ARM_MATH_BIG_ENDIAN: - * - * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. - * - * - ARM_MATH_MATRIX_CHECK: - * - * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices - * - * - ARM_MATH_ROUNDING: - * - * Define macro ARM_MATH_ROUNDING for rounding on support functions - * - * - ARM_MATH_CMx: - * - * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target - * and ARM_MATH_CM0 for building library on Cortex-M0 target, ARM_MATH_CM0PLUS for building library on Cortex-M0+ target, and - * ARM_MATH_CM7 for building the library on cortex-M7. - * - * - ARM_MATH_ARMV8MxL: - * - * Define macro ARM_MATH_ARMV8MBL for building the library on ARMv8M Baseline target, ARM_MATH_ARMV8MBL for building library - * on ARMv8M Mainline target. - * - * - __FPU_PRESENT: - * - * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for floating point libraries. - * - * - __DSP_PRESENT: - * - * Initialize macro __DSP_PRESENT = 1 when ARMv8M Mainline core supports DSP instructions. - * - *
- * CMSIS-DSP in ARM::CMSIS Pack - * ----------------------------- - * - * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: - * |File/Folder |Content | - * |------------------------------|------------------------------------------------------------------------| - * |\b CMSIS\\Documentation\\DSP | This documentation | - * |\b CMSIS\\DSP_Lib | Software license agreement (license.txt) | - * |\b CMSIS\\DSP_Lib\\Examples | Example projects demonstrating the usage of the library functions | - * |\b CMSIS\\DSP_Lib\\Source | Source files for rebuilding the library | - * - *
- * Revision History of CMSIS-DSP - * ------------ - * Please refer to \ref ChangeLog_pg. - * - * Copyright Notice - * ------------ - * - * Copyright (C) 2010-2015 ARM Limited. All rights reserved. - */ - - -/** - * @defgroup groupMath Basic Math Functions - */ - -/** - * @defgroup groupFastMath Fast Math Functions - * This set of functions provides a fast approximation to sine, cosine, and square root. - * As compared to most of the other functions in the CMSIS math library, the fast math functions - * operate on individual values and not arrays. - * There are separate functions for Q15, Q31, and floating-point data. - * - */ - -/** - * @defgroup groupCmplxMath Complex Math Functions - * This set of functions operates on complex data vectors. - * The data in the complex arrays is stored in an interleaved fashion - * (real, imag, real, imag, ...). - * In the API functions, the number of samples in a complex array refers - * to the number of complex values; the array contains twice this number of - * real values. - */ - -/** - * @defgroup groupFilters Filtering Functions - */ - -/** - * @defgroup groupMatrix Matrix Functions - * - * This set of functions provides basic matrix math operations. - * The functions operate on matrix data structures. For example, - * the type - * definition for the floating-point matrix structure is shown - * below: - *
- *     typedef struct
- *     {
- *       uint16_t numRows;     // number of rows of the matrix.
- *       uint16_t numCols;     // number of columns of the matrix.
- *       float32_t *pData;     // points to the data of the matrix.
- *     } arm_matrix_instance_f32;
- * 
- * There are similar definitions for Q15 and Q31 data types. - * - * The structure specifies the size of the matrix and then points to - * an array of data. The array is of size numRows X numCols - * and the values are arranged in row order. That is, the - * matrix element (i, j) is stored at: - *
- *     pData[i*numCols + j]
- * 
- * - * \par Init Functions - * There is an associated initialization function for each type of matrix - * data structure. - * The initialization function sets the values of the internal structure fields. - * Refer to the function arm_mat_init_f32(), arm_mat_init_q31() - * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. - * - * \par - * Use of the initialization function is optional. However, if initialization function is used - * then the instance structure cannot be placed into a const data section. - * To place the instance structure in a const data - * section, manually initialize the data structure. For example: - *
- * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
- * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
- * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
- * 
- * where nRows specifies the number of rows, nColumns - * specifies the number of columns, and pData points to the - * data array. - * - * \par Size Checking - * By default all of the matrix functions perform size checking on the input and - * output matrices. For example, the matrix addition function verifies that the - * two input matrices and the output matrix all have the same number of rows and - * columns. If the size check fails the functions return: - *
- *     ARM_MATH_SIZE_MISMATCH
- * 
- * Otherwise the functions return - *
- *     ARM_MATH_SUCCESS
- * 
- * There is some overhead associated with this matrix size checking. - * The matrix size checking is enabled via the \#define - *
- *     ARM_MATH_MATRIX_CHECK
- * 
- * within the library project settings. By default this macro is defined - * and size checking is enabled. By changing the project settings and - * undefining this macro size checking is eliminated and the functions - * run a bit faster. With size checking disabled the functions always - * return ARM_MATH_SUCCESS. - */ - -/** - * @defgroup groupTransforms Transform Functions - */ - -/** - * @defgroup groupController Controller Functions - */ - -/** - * @defgroup groupStats Statistics Functions - */ -/** - * @defgroup groupSupport Support Functions - */ - -/** - * @defgroup groupInterpolation Interpolation Functions - * These functions perform 1- and 2-dimensional interpolation of data. - * Linear interpolation is used for 1-dimensional data and - * bilinear interpolation is used for 2-dimensional data. - */ - -/** - * @defgroup groupExamples Examples - */ -#ifndef _ARM_MATH_H -#define _ARM_MATH_H - -/* Compiler specific diagnostic adjustment */ -#if defined ( __CC_ARM ) - -#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) - -#elif defined ( __GNUC__ ) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wunused-parameter" - -#elif defined ( __ICCARM__ ) - -#elif defined ( __TI_ARM__ ) - -#elif defined ( __CSMC__ ) - -#elif defined ( __TASKING__ ) - -#else - #error Unknown compiler -#endif - - -#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ - -#if defined(ARM_MATH_CM7) - #include "core_cm7.h" - #define ARM_MATH_DSP -#elif defined (ARM_MATH_CM4) - #include "core_cm4.h" - #define ARM_MATH_DSP -#elif defined (ARM_MATH_CM3) - #include "core_cm3.h" -#elif defined (ARM_MATH_CM0) - #include "core_cm0.h" - #define ARM_MATH_CM0_FAMILY -#elif defined (ARM_MATH_CM0PLUS) - #include "core_cm0plus.h" - #define ARM_MATH_CM0_FAMILY -#elif defined (ARM_MATH_ARMV8MBL) - #include "core_armv8mbl.h" - #define ARM_MATH_CM0_FAMILY -#elif defined (ARM_MATH_ARMV8MML) - #include "core_armv8mml.h" - #if (defined (__DSP_PRESENT) && (__DSP_PRESENT == 1)) - #define ARM_MATH_DSP - #endif -#else - #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS, ARM_MATH_CM0, ARM_MATH_ARMV8MBL, ARM_MATH_ARMV8MML" -#endif - -#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ -#include "string.h" -#include "math.h" -#ifdef __cplusplus -extern "C" -{ -#endif - - - /** - * @brief Macros required for reciprocal calculation in Normalized LMS - */ - -#define DELTA_Q31 (0x100) -#define DELTA_Q15 0x5 -#define INDEX_MASK 0x0000003F -#ifndef PI - #define PI 3.14159265358979f -#endif - - /** - * @brief Macros required for SINE and COSINE Fast math approximations - */ - -#define FAST_MATH_TABLE_SIZE 512 -#define FAST_MATH_Q31_SHIFT (32 - 10) -#define FAST_MATH_Q15_SHIFT (16 - 10) -#define CONTROLLER_Q31_SHIFT (32 - 9) -#define TABLE_SPACING_Q31 0x400000 -#define TABLE_SPACING_Q15 0x80 - - /** - * @brief Macros required for SINE and COSINE Controller functions - */ - /* 1.31(q31) Fixed value of 2/360 */ - /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ -#define INPUT_SPACING 0xB60B61 - - /** - * @brief Macro for Unaligned Support - */ -#ifndef UNALIGNED_SUPPORT_DISABLE - #define ALIGN4 -#else - #if defined (__GNUC__) - #define ALIGN4 __attribute__((aligned(4))) - #else - #define ALIGN4 __align(4) - #endif -#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ - - /** - * @brief Error status returned by some functions in the library. - */ - - typedef enum - { - ARM_MATH_SUCCESS = 0, /**< No error */ - ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ - ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ - ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ - ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ - ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ - ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ - } arm_status; - - /** - * @brief 8-bit fractional data type in 1.7 format. - */ - typedef int8_t q7_t; - - /** - * @brief 16-bit fractional data type in 1.15 format. - */ - typedef int16_t q15_t; - - /** - * @brief 32-bit fractional data type in 1.31 format. - */ - typedef int32_t q31_t; - - /** - * @brief 64-bit fractional data type in 1.63 format. - */ - typedef int64_t q63_t; - - /** - * @brief 32-bit floating-point type definition. - */ - typedef float float32_t; - - /** - * @brief 64-bit floating-point type definition. - */ - typedef double float64_t; - - /** - * @brief definition to read/write two 16 bit values. - */ -#if defined ( __CC_ARM ) - #define __SIMD32_TYPE int32_t __packed - #define CMSIS_UNUSED __attribute__((unused)) - #define CMSIS_INLINE __attribute__((always_inline)) - -#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) - #define __SIMD32_TYPE int32_t - #define CMSIS_UNUSED __attribute__((unused)) - #define CMSIS_INLINE __attribute__((always_inline)) - -#elif defined ( __GNUC__ ) - #define __SIMD32_TYPE int32_t - #define CMSIS_UNUSED __attribute__((unused)) - #define CMSIS_INLINE __attribute__((always_inline)) - -#elif defined ( __ICCARM__ ) - #define __SIMD32_TYPE int32_t __packed - #define CMSIS_UNUSED - #define CMSIS_INLINE - -#elif defined ( __TI_ARM__ ) - #define __SIMD32_TYPE int32_t - #define CMSIS_UNUSED __attribute__((unused)) - #define CMSIS_INLINE - -#elif defined ( __CSMC__ ) - #define __SIMD32_TYPE int32_t - #define CMSIS_UNUSED - #define CMSIS_INLINE - -#elif defined ( __TASKING__ ) - #define __SIMD32_TYPE __unaligned int32_t - #define CMSIS_UNUSED - #define CMSIS_INLINE - -#else - #error Unknown compiler -#endif - -#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) -#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr)) -#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr)) -#define __SIMD64(addr) (*(int64_t **) & (addr)) - -/* #if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ -#if !defined (ARM_MATH_DSP) - /** - * @brief definition to pack two 16 bit values. - */ -#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ - (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) -#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ - (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) - -/* #endif // defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ -#endif /* !defined (ARM_MATH_DSP) */ - - /** - * @brief definition to pack four 8 bit values. - */ -#ifndef ARM_MATH_BIG_ENDIAN - -#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ - (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ - (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ - (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) -#else - -#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ - (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ - (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ - (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) - -#endif - - - /** - * @brief Clips Q63 to Q31 values. - */ - CMSIS_INLINE __STATIC_INLINE q31_t clip_q63_to_q31( - q63_t x) - { - return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? - ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; - } - - /** - * @brief Clips Q63 to Q15 values. - */ - CMSIS_INLINE __STATIC_INLINE q15_t clip_q63_to_q15( - q63_t x) - { - return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? - ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); - } - - /** - * @brief Clips Q31 to Q7 values. - */ - CMSIS_INLINE __STATIC_INLINE q7_t clip_q31_to_q7( - q31_t x) - { - return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? - ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; - } - - /** - * @brief Clips Q31 to Q15 values. - */ - CMSIS_INLINE __STATIC_INLINE q15_t clip_q31_to_q15( - q31_t x) - { - return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? - ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; - } - - /** - * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. - */ - - CMSIS_INLINE __STATIC_INLINE q63_t mult32x64( - q63_t x, - q31_t y) - { - return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + - (((q63_t) (x >> 32) * y))); - } - -/* - #if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM ) - #define __CLZ __clz - #endif - */ -/* note: function can be removed when all toolchain support __CLZ for Cortex-M0 */ -#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) ) - CMSIS_INLINE __STATIC_INLINE uint32_t __CLZ( - q31_t data); - - CMSIS_INLINE __STATIC_INLINE uint32_t __CLZ( - q31_t data) - { - uint32_t count = 0; - uint32_t mask = 0x80000000; - - while ((data & mask) == 0) - { - count += 1u; - mask = mask >> 1u; - } - - return (count); - } -#endif - - /** - * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. - */ - - CMSIS_INLINE __STATIC_INLINE uint32_t arm_recip_q31( - q31_t in, - q31_t * dst, - q31_t * pRecipTable) - { - q31_t out; - uint32_t tempVal; - uint32_t index, i; - uint32_t signBits; - - if (in > 0) - { - signBits = ((uint32_t) (__CLZ( in) - 1)); - } - else - { - signBits = ((uint32_t) (__CLZ(-in) - 1)); - } - - /* Convert input sample to 1.31 format */ - in = (in << signBits); - - /* calculation of index for initial approximated Val */ - index = (uint32_t)(in >> 24); - index = (index & INDEX_MASK); - - /* 1.31 with exp 1 */ - out = pRecipTable[index]; - - /* calculation of reciprocal value */ - /* running approximation for two iterations */ - for (i = 0u; i < 2u; i++) - { - tempVal = (uint32_t) (((q63_t) in * out) >> 31); - tempVal = 0x7FFFFFFFu - tempVal; - /* 1.31 with exp 1 */ - /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */ - out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30); - } - - /* write output */ - *dst = out; - - /* return num of signbits of out = 1/in value */ - return (signBits + 1u); - } - - - /** - * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. - */ - CMSIS_INLINE __STATIC_INLINE uint32_t arm_recip_q15( - q15_t in, - q15_t * dst, - q15_t * pRecipTable) - { - q15_t out = 0; - uint32_t tempVal = 0; - uint32_t index = 0, i = 0; - uint32_t signBits = 0; - - if (in > 0) - { - signBits = ((uint32_t)(__CLZ( in) - 17)); - } - else - { - signBits = ((uint32_t)(__CLZ(-in) - 17)); - } - - /* Convert input sample to 1.15 format */ - in = (in << signBits); - - /* calculation of index for initial approximated Val */ - index = (uint32_t)(in >> 8); - index = (index & INDEX_MASK); - - /* 1.15 with exp 1 */ - out = pRecipTable[index]; - - /* calculation of reciprocal value */ - /* running approximation for two iterations */ - for (i = 0u; i < 2u; i++) - { - tempVal = (uint32_t) (((q31_t) in * out) >> 15); - tempVal = 0x7FFFu - tempVal; - /* 1.15 with exp 1 */ - out = (q15_t) (((q31_t) out * tempVal) >> 14); - /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */ - } - - /* write output */ - *dst = out; - - /* return num of signbits of out = 1/in value */ - return (signBits + 1); - } - - - /* - * @brief C custom defined intrinisic function for only M0 processors - */ -#if defined(ARM_MATH_CM0_FAMILY) - CMSIS_INLINE __STATIC_INLINE q31_t __SSAT( - q31_t x, - uint32_t y) - { - int32_t posMax, negMin; - uint32_t i; - - posMax = 1; - for (i = 0; i < (y - 1); i++) - { - posMax = posMax * 2; - } - - if (x > 0) - { - posMax = (posMax - 1); - - if (x > posMax) - { - x = posMax; - } - } - else - { - negMin = -posMax; - - if (x < negMin) - { - x = negMin; - } - } - return (x); - } -#endif /* end of ARM_MATH_CM0_FAMILY */ - - - /* - * @brief C custom defined intrinsic function for M3 and M0 processors - */ -/* #if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ -#if !defined (ARM_MATH_DSP) - - /* - * @brief C custom defined QADD8 for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __QADD8( - uint32_t x, - uint32_t y) - { - q31_t r, s, t, u; - - r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; - s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; - t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; - u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; - - return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); - } - - - /* - * @brief C custom defined QSUB8 for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __QSUB8( - uint32_t x, - uint32_t y) - { - q31_t r, s, t, u; - - r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; - s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; - t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; - u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; - - return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); - } - - - /* - * @brief C custom defined QADD16 for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __QADD16( - uint32_t x, - uint32_t y) - { -/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */ - q31_t r = 0, s = 0; - - r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; - s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; - - return ((uint32_t)((s << 16) | (r ))); - } - - - /* - * @brief C custom defined SHADD16 for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SHADD16( - uint32_t x, - uint32_t y) - { - q31_t r, s; - - r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; - s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; - - return ((uint32_t)((s << 16) | (r ))); - } - - - /* - * @brief C custom defined QSUB16 for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __QSUB16( - uint32_t x, - uint32_t y) - { - q31_t r, s; - - r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; - s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; - - return ((uint32_t)((s << 16) | (r ))); - } - - - /* - * @brief C custom defined SHSUB16 for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SHSUB16( - uint32_t x, - uint32_t y) - { - q31_t r, s; - - r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; - s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; - - return ((uint32_t)((s << 16) | (r ))); - } - - - /* - * @brief C custom defined QASX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __QASX( - uint32_t x, - uint32_t y) - { - q31_t r, s; - - r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; - s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; - - return ((uint32_t)((s << 16) | (r ))); - } - - - /* - * @brief C custom defined SHASX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SHASX( - uint32_t x, - uint32_t y) - { - q31_t r, s; - - r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; - s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; - - return ((uint32_t)((s << 16) | (r ))); - } - - - /* - * @brief C custom defined QSAX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __QSAX( - uint32_t x, - uint32_t y) - { - q31_t r, s; - - r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; - s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; - - return ((uint32_t)((s << 16) | (r ))); - } - - - /* - * @brief C custom defined SHSAX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SHSAX( - uint32_t x, - uint32_t y) - { - q31_t r, s; - - r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; - s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; - - return ((uint32_t)((s << 16) | (r ))); - } - - - /* - * @brief C custom defined SMUSDX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SMUSDX( - uint32_t x, - uint32_t y) - { - return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - - ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); - } - - /* - * @brief C custom defined SMUADX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SMUADX( - uint32_t x, - uint32_t y) - { - return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + - ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); - } - - - /* - * @brief C custom defined QADD for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE int32_t __QADD( - int32_t x, - int32_t y) - { - return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y))); - } - - - /* - * @brief C custom defined QSUB for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE int32_t __QSUB( - int32_t x, - int32_t y) - { - return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y))); - } - - - /* - * @brief C custom defined SMLAD for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SMLAD( - uint32_t x, - uint32_t y, - uint32_t sum) - { - return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + - ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + - ( ((q31_t)sum ) ) )); - } - - - /* - * @brief C custom defined SMLADX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SMLADX( - uint32_t x, - uint32_t y, - uint32_t sum) - { - return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + - ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + - ( ((q31_t)sum ) ) )); - } - - - /* - * @brief C custom defined SMLSDX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SMLSDX( - uint32_t x, - uint32_t y, - uint32_t sum) - { - return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - - ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + - ( ((q31_t)sum ) ) )); - } - - - /* - * @brief C custom defined SMLALD for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint64_t __SMLALD( - uint32_t x, - uint32_t y, - uint64_t sum) - { -/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */ - return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + - ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + - ( ((q63_t)sum ) ) )); - } - - - /* - * @brief C custom defined SMLALDX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint64_t __SMLALDX( - uint32_t x, - uint32_t y, - uint64_t sum) - { -/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */ - return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + - ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + - ( ((q63_t)sum ) ) )); - } - - - /* - * @brief C custom defined SMUAD for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SMUAD( - uint32_t x, - uint32_t y) - { - return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + - ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); - } - - - /* - * @brief C custom defined SMUSD for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SMUSD( - uint32_t x, - uint32_t y) - { - return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) - - ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); - } - - - /* - * @brief C custom defined SXTB16 for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SXTB16( - uint32_t x) - { - return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) | - ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) )); - } - - /* - * @brief C custom defined SMMLA for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE int32_t __SMMLA( - int32_t x, - int32_t y, - int32_t sum) - { - return (sum + (int32_t) (((int64_t) x * y) >> 32)); - } - -#if 0 - /* - * @brief C custom defined PKHBT for unavailable DSP extension - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __PKHBT( - uint32_t x, - uint32_t y, - uint32_t leftshift) - { - return ( ((x ) & 0x0000FFFFUL) | - ((y << leftshift) & 0xFFFF0000UL) ); - } - - /* - * @brief C custom defined PKHTB for unavailable DSP extension - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __PKHTB( - uint32_t x, - uint32_t y, - uint32_t rightshift) - { - return ( ((x ) & 0xFFFF0000UL) | - ((y >> rightshift) & 0x0000FFFFUL) ); - } -#endif - -/* #endif // defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ -#endif /* !defined (ARM_MATH_DSP) */ - - - /** - * @brief Instance structure for the Q7 FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - } arm_fir_instance_q7; - - /** - * @brief Instance structure for the Q15 FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - } arm_fir_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - } arm_fir_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - } arm_fir_instance_f32; - - - /** - * @brief Processing function for the Q7 FIR filter. - * @param[in] S points to an instance of the Q7 FIR filter structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_fir_q7( - const arm_fir_instance_q7 * S, - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q7 FIR filter. - * @param[in,out] S points to an instance of the Q7 FIR structure. - * @param[in] numTaps Number of filter coefficients in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of samples that are processed. - */ - void arm_fir_init_q7( - arm_fir_instance_q7 * S, - uint16_t numTaps, - q7_t * pCoeffs, - q7_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q15 FIR filter. - * @param[in] S points to an instance of the Q15 FIR structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_fir_q15( - const arm_fir_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4. - * @param[in] S points to an instance of the Q15 FIR filter structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_fir_fast_q15( - const arm_fir_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q15 FIR filter. - * @param[in,out] S points to an instance of the Q15 FIR filter structure. - * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of samples that are processed at a time. - * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if - * numTaps is not a supported value. - */ - arm_status arm_fir_init_q15( - arm_fir_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 FIR filter. - * @param[in] S points to an instance of the Q31 FIR filter structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_fir_q31( - const arm_fir_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4. - * @param[in] S points to an instance of the Q31 FIR structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_fir_fast_q31( - const arm_fir_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 FIR filter. - * @param[in,out] S points to an instance of the Q31 FIR structure. - * @param[in] numTaps Number of filter coefficients in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of samples that are processed at a time. - */ - void arm_fir_init_q31( - arm_fir_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the floating-point FIR filter. - * @param[in] S points to an instance of the floating-point FIR structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_fir_f32( - const arm_fir_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point FIR filter. - * @param[in,out] S points to an instance of the floating-point FIR filter structure. - * @param[in] numTaps Number of filter coefficients in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of samples that are processed at a time. - */ - void arm_fir_init_f32( - arm_fir_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q15 Biquad cascade filter. - */ - typedef struct - { - int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ - q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ - int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ - } arm_biquad_casd_df1_inst_q15; - - /** - * @brief Instance structure for the Q31 Biquad cascade filter. - */ - typedef struct - { - uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ - q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ - uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ - } arm_biquad_casd_df1_inst_q31; - - /** - * @brief Instance structure for the floating-point Biquad cascade filter. - */ - typedef struct - { - uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ - float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ - } arm_biquad_casd_df1_inst_f32; - - - /** - * @brief Processing function for the Q15 Biquad cascade filter. - * @param[in] S points to an instance of the Q15 Biquad cascade structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cascade_df1_q15( - const arm_biquad_casd_df1_inst_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q15 Biquad cascade filter. - * @param[in,out] S points to an instance of the Q15 Biquad cascade structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format - */ - void arm_biquad_cascade_df1_init_q15( - arm_biquad_casd_df1_inst_q15 * S, - uint8_t numStages, - q15_t * pCoeffs, - q15_t * pState, - int8_t postShift); - - - /** - * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. - * @param[in] S points to an instance of the Q15 Biquad cascade structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cascade_df1_fast_q15( - const arm_biquad_casd_df1_inst_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 Biquad cascade filter - * @param[in] S points to an instance of the Q31 Biquad cascade structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cascade_df1_q31( - const arm_biquad_casd_df1_inst_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. - * @param[in] S points to an instance of the Q31 Biquad cascade structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cascade_df1_fast_q31( - const arm_biquad_casd_df1_inst_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 Biquad cascade filter. - * @param[in,out] S points to an instance of the Q31 Biquad cascade structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format - */ - void arm_biquad_cascade_df1_init_q31( - arm_biquad_casd_df1_inst_q31 * S, - uint8_t numStages, - q31_t * pCoeffs, - q31_t * pState, - int8_t postShift); - - - /** - * @brief Processing function for the floating-point Biquad cascade filter. - * @param[in] S points to an instance of the floating-point Biquad cascade structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cascade_df1_f32( - const arm_biquad_casd_df1_inst_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point Biquad cascade filter. - * @param[in,out] S points to an instance of the floating-point Biquad cascade structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - */ - void arm_biquad_cascade_df1_init_f32( - arm_biquad_casd_df1_inst_f32 * S, - uint8_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - - /** - * @brief Instance structure for the floating-point matrix structure. - */ - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - float32_t *pData; /**< points to the data of the matrix. */ - } arm_matrix_instance_f32; - - - /** - * @brief Instance structure for the floating-point matrix structure. - */ - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - float64_t *pData; /**< points to the data of the matrix. */ - } arm_matrix_instance_f64; - - /** - * @brief Instance structure for the Q15 matrix structure. - */ - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - q15_t *pData; /**< points to the data of the matrix. */ - } arm_matrix_instance_q15; - - /** - * @brief Instance structure for the Q31 matrix structure. - */ - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - q31_t *pData; /**< points to the data of the matrix. */ - } arm_matrix_instance_q31; - - - /** - * @brief Floating-point matrix addition. - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_add_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - - /** - * @brief Q15 matrix addition. - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_add_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst); - - - /** - * @brief Q31 matrix addition. - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_add_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point, complex, matrix multiplication. - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_cmplx_mult_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - - /** - * @brief Q15, complex, matrix multiplication. - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_cmplx_mult_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst, - q15_t * pScratch); - - - /** - * @brief Q31, complex, matrix multiplication. - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_cmplx_mult_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix transpose. - * @param[in] pSrc points to the input matrix - * @param[out] pDst points to the output matrix - * @return The function returns either ARM_MATH_SIZE_MISMATCH - * or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_trans_f32( - const arm_matrix_instance_f32 * pSrc, - arm_matrix_instance_f32 * pDst); - - - /** - * @brief Q15 matrix transpose. - * @param[in] pSrc points to the input matrix - * @param[out] pDst points to the output matrix - * @return The function returns either ARM_MATH_SIZE_MISMATCH - * or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_trans_q15( - const arm_matrix_instance_q15 * pSrc, - arm_matrix_instance_q15 * pDst); - - - /** - * @brief Q31 matrix transpose. - * @param[in] pSrc points to the input matrix - * @param[out] pDst points to the output matrix - * @return The function returns either ARM_MATH_SIZE_MISMATCH - * or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_trans_q31( - const arm_matrix_instance_q31 * pSrc, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix multiplication - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_mult_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - - /** - * @brief Q15 matrix multiplication - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @param[in] pState points to the array for storing intermediate results - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_mult_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst, - q15_t * pState); - - - /** - * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @param[in] pState points to the array for storing intermediate results - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_mult_fast_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst, - q15_t * pState); - - - /** - * @brief Q31 matrix multiplication - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_mult_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_mult_fast_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix subtraction - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_sub_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - - /** - * @brief Q15 matrix subtraction - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_sub_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst); - - - /** - * @brief Q31 matrix subtraction - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_sub_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix scaling. - * @param[in] pSrc points to the input matrix - * @param[in] scale scale factor - * @param[out] pDst points to the output matrix - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_scale_f32( - const arm_matrix_instance_f32 * pSrc, - float32_t scale, - arm_matrix_instance_f32 * pDst); - - - /** - * @brief Q15 matrix scaling. - * @param[in] pSrc points to input matrix - * @param[in] scaleFract fractional portion of the scale factor - * @param[in] shift number of bits to shift the result by - * @param[out] pDst points to output matrix - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_scale_q15( - const arm_matrix_instance_q15 * pSrc, - q15_t scaleFract, - int32_t shift, - arm_matrix_instance_q15 * pDst); - - - /** - * @brief Q31 matrix scaling. - * @param[in] pSrc points to input matrix - * @param[in] scaleFract fractional portion of the scale factor - * @param[in] shift number of bits to shift the result by - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_scale_q31( - const arm_matrix_instance_q31 * pSrc, - q31_t scaleFract, - int32_t shift, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Q31 matrix initialization. - * @param[in,out] S points to an instance of the floating-point matrix structure. - * @param[in] nRows number of rows in the matrix. - * @param[in] nColumns number of columns in the matrix. - * @param[in] pData points to the matrix data array. - */ - void arm_mat_init_q31( - arm_matrix_instance_q31 * S, - uint16_t nRows, - uint16_t nColumns, - q31_t * pData); - - - /** - * @brief Q15 matrix initialization. - * @param[in,out] S points to an instance of the floating-point matrix structure. - * @param[in] nRows number of rows in the matrix. - * @param[in] nColumns number of columns in the matrix. - * @param[in] pData points to the matrix data array. - */ - void arm_mat_init_q15( - arm_matrix_instance_q15 * S, - uint16_t nRows, - uint16_t nColumns, - q15_t * pData); - - - /** - * @brief Floating-point matrix initialization. - * @param[in,out] S points to an instance of the floating-point matrix structure. - * @param[in] nRows number of rows in the matrix. - * @param[in] nColumns number of columns in the matrix. - * @param[in] pData points to the matrix data array. - */ - void arm_mat_init_f32( - arm_matrix_instance_f32 * S, - uint16_t nRows, - uint16_t nColumns, - float32_t * pData); - - - - /** - * @brief Instance structure for the Q15 PID Control. - */ - typedef struct - { - q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ -#if !defined (ARM_MATH_DSP) - q15_t A1; - q15_t A2; -#else - q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ -#endif - q15_t state[3]; /**< The state array of length 3. */ - q15_t Kp; /**< The proportional gain. */ - q15_t Ki; /**< The integral gain. */ - q15_t Kd; /**< The derivative gain. */ - } arm_pid_instance_q15; - - /** - * @brief Instance structure for the Q31 PID Control. - */ - typedef struct - { - q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ - q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ - q31_t A2; /**< The derived gain, A2 = Kd . */ - q31_t state[3]; /**< The state array of length 3. */ - q31_t Kp; /**< The proportional gain. */ - q31_t Ki; /**< The integral gain. */ - q31_t Kd; /**< The derivative gain. */ - } arm_pid_instance_q31; - - /** - * @brief Instance structure for the floating-point PID Control. - */ - typedef struct - { - float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ - float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ - float32_t A2; /**< The derived gain, A2 = Kd . */ - float32_t state[3]; /**< The state array of length 3. */ - float32_t Kp; /**< The proportional gain. */ - float32_t Ki; /**< The integral gain. */ - float32_t Kd; /**< The derivative gain. */ - } arm_pid_instance_f32; - - - - /** - * @brief Initialization function for the floating-point PID Control. - * @param[in,out] S points to an instance of the PID structure. - * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. - */ - void arm_pid_init_f32( - arm_pid_instance_f32 * S, - int32_t resetStateFlag); - - - /** - * @brief Reset function for the floating-point PID Control. - * @param[in,out] S is an instance of the floating-point PID Control structure - */ - void arm_pid_reset_f32( - arm_pid_instance_f32 * S); - - - /** - * @brief Initialization function for the Q31 PID Control. - * @param[in,out] S points to an instance of the Q15 PID structure. - * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. - */ - void arm_pid_init_q31( - arm_pid_instance_q31 * S, - int32_t resetStateFlag); - - - /** - * @brief Reset function for the Q31 PID Control. - * @param[in,out] S points to an instance of the Q31 PID Control structure - */ - - void arm_pid_reset_q31( - arm_pid_instance_q31 * S); - - - /** - * @brief Initialization function for the Q15 PID Control. - * @param[in,out] S points to an instance of the Q15 PID structure. - * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. - */ - void arm_pid_init_q15( - arm_pid_instance_q15 * S, - int32_t resetStateFlag); - - - /** - * @brief Reset function for the Q15 PID Control. - * @param[in,out] S points to an instance of the q15 PID Control structure - */ - void arm_pid_reset_q15( - arm_pid_instance_q15 * S); - - - /** - * @brief Instance structure for the floating-point Linear Interpolate function. - */ - typedef struct - { - uint32_t nValues; /**< nValues */ - float32_t x1; /**< x1 */ - float32_t xSpacing; /**< xSpacing */ - float32_t *pYData; /**< pointer to the table of Y values */ - } arm_linear_interp_instance_f32; - - /** - * @brief Instance structure for the floating-point bilinear interpolation function. - */ - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - float32_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_f32; - - /** - * @brief Instance structure for the Q31 bilinear interpolation function. - */ - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - q31_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_q31; - - /** - * @brief Instance structure for the Q15 bilinear interpolation function. - */ - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - q15_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_q15; - - /** - * @brief Instance structure for the Q15 bilinear interpolation function. - */ - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - q7_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_q7; - - - /** - * @brief Q7 vector multiplication. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_mult_q7( - q7_t * pSrcA, - q7_t * pSrcB, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q15 vector multiplication. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_mult_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q31 vector multiplication. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_mult_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Floating-point vector multiplication. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_mult_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q15 CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix2_instance_q15; - -/* Deprecated */ - arm_status arm_cfft_radix2_init_q15( - arm_cfft_radix2_instance_q15 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix2_q15( - const arm_cfft_radix2_instance_q15 * S, - q15_t * pSrc); - - - /** - * @brief Instance structure for the Q15 CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q15_t *pTwiddle; /**< points to the twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix4_instance_q15; - -/* Deprecated */ - arm_status arm_cfft_radix4_init_q15( - arm_cfft_radix4_instance_q15 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix4_q15( - const arm_cfft_radix4_instance_q15 * S, - q15_t * pSrc); - - /** - * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q31_t *pTwiddle; /**< points to the Twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix2_instance_q31; - -/* Deprecated */ - arm_status arm_cfft_radix2_init_q31( - arm_cfft_radix2_instance_q31 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix2_q31( - const arm_cfft_radix2_instance_q31 * S, - q31_t * pSrc); - - /** - * @brief Instance structure for the Q31 CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q31_t *pTwiddle; /**< points to the twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix4_instance_q31; - -/* Deprecated */ - void arm_cfft_radix4_q31( - const arm_cfft_radix4_instance_q31 * S, - q31_t * pSrc); - -/* Deprecated */ - arm_status arm_cfft_radix4_init_q31( - arm_cfft_radix4_instance_q31 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Instance structure for the floating-point CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - float32_t *pTwiddle; /**< points to the Twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - float32_t onebyfftLen; /**< value of 1/fftLen. */ - } arm_cfft_radix2_instance_f32; - -/* Deprecated */ - arm_status arm_cfft_radix2_init_f32( - arm_cfft_radix2_instance_f32 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix2_f32( - const arm_cfft_radix2_instance_f32 * S, - float32_t * pSrc); - - /** - * @brief Instance structure for the floating-point CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - float32_t *pTwiddle; /**< points to the Twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - float32_t onebyfftLen; /**< value of 1/fftLen. */ - } arm_cfft_radix4_instance_f32; - -/* Deprecated */ - arm_status arm_cfft_radix4_init_f32( - arm_cfft_radix4_instance_f32 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix4_f32( - const arm_cfft_radix4_instance_f32 * S, - float32_t * pSrc); - - /** - * @brief Instance structure for the fixed-point CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ - const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t bitRevLength; /**< bit reversal table length. */ - } arm_cfft_instance_q15; - -void arm_cfft_q15( - const arm_cfft_instance_q15 * S, - q15_t * p1, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Instance structure for the fixed-point CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ - const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t bitRevLength; /**< bit reversal table length. */ - } arm_cfft_instance_q31; - -void arm_cfft_q31( - const arm_cfft_instance_q31 * S, - q31_t * p1, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Instance structure for the floating-point CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ - const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t bitRevLength; /**< bit reversal table length. */ - } arm_cfft_instance_f32; - - void arm_cfft_f32( - const arm_cfft_instance_f32 * S, - float32_t * p1, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Instance structure for the Q15 RFFT/RIFFT function. - */ - typedef struct - { - uint32_t fftLenReal; /**< length of the real FFT. */ - uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ - uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ - uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ - q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ - const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ - } arm_rfft_instance_q15; - - arm_status arm_rfft_init_q15( - arm_rfft_instance_q15 * S, - uint32_t fftLenReal, - uint32_t ifftFlagR, - uint32_t bitReverseFlag); - - void arm_rfft_q15( - const arm_rfft_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst); - - /** - * @brief Instance structure for the Q31 RFFT/RIFFT function. - */ - typedef struct - { - uint32_t fftLenReal; /**< length of the real FFT. */ - uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ - uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ - uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ - q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ - const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ - } arm_rfft_instance_q31; - - arm_status arm_rfft_init_q31( - arm_rfft_instance_q31 * S, - uint32_t fftLenReal, - uint32_t ifftFlagR, - uint32_t bitReverseFlag); - - void arm_rfft_q31( - const arm_rfft_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst); - - /** - * @brief Instance structure for the floating-point RFFT/RIFFT function. - */ - typedef struct - { - uint32_t fftLenReal; /**< length of the real FFT. */ - uint16_t fftLenBy2; /**< length of the complex FFT. */ - uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ - uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ - uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ - float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ - arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ - } arm_rfft_instance_f32; - - arm_status arm_rfft_init_f32( - arm_rfft_instance_f32 * S, - arm_cfft_radix4_instance_f32 * S_CFFT, - uint32_t fftLenReal, - uint32_t ifftFlagR, - uint32_t bitReverseFlag); - - void arm_rfft_f32( - const arm_rfft_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst); - - /** - * @brief Instance structure for the floating-point RFFT/RIFFT function. - */ -typedef struct - { - arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ - uint16_t fftLenRFFT; /**< length of the real sequence */ - float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ - } arm_rfft_fast_instance_f32 ; - -arm_status arm_rfft_fast_init_f32 ( - arm_rfft_fast_instance_f32 * S, - uint16_t fftLen); - -void arm_rfft_fast_f32( - arm_rfft_fast_instance_f32 * S, - float32_t * p, float32_t * pOut, - uint8_t ifftFlag); - - /** - * @brief Instance structure for the floating-point DCT4/IDCT4 function. - */ - typedef struct - { - uint16_t N; /**< length of the DCT4. */ - uint16_t Nby2; /**< half of the length of the DCT4. */ - float32_t normalize; /**< normalizing factor. */ - float32_t *pTwiddle; /**< points to the twiddle factor table. */ - float32_t *pCosFactor; /**< points to the cosFactor table. */ - arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ - arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ - } arm_dct4_instance_f32; - - - /** - * @brief Initialization function for the floating-point DCT4/IDCT4. - * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure. - * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure. - * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure. - * @param[in] N length of the DCT4. - * @param[in] Nby2 half of the length of the DCT4. - * @param[in] normalize normalizing factor. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. - */ - arm_status arm_dct4_init_f32( - arm_dct4_instance_f32 * S, - arm_rfft_instance_f32 * S_RFFT, - arm_cfft_radix4_instance_f32 * S_CFFT, - uint16_t N, - uint16_t Nby2, - float32_t normalize); - - - /** - * @brief Processing function for the floating-point DCT4/IDCT4. - * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure. - * @param[in] pState points to state buffer. - * @param[in,out] pInlineBuffer points to the in-place input and output buffer. - */ - void arm_dct4_f32( - const arm_dct4_instance_f32 * S, - float32_t * pState, - float32_t * pInlineBuffer); - - - /** - * @brief Instance structure for the Q31 DCT4/IDCT4 function. - */ - typedef struct - { - uint16_t N; /**< length of the DCT4. */ - uint16_t Nby2; /**< half of the length of the DCT4. */ - q31_t normalize; /**< normalizing factor. */ - q31_t *pTwiddle; /**< points to the twiddle factor table. */ - q31_t *pCosFactor; /**< points to the cosFactor table. */ - arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ - arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ - } arm_dct4_instance_q31; - - - /** - * @brief Initialization function for the Q31 DCT4/IDCT4. - * @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure. - * @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure - * @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure - * @param[in] N length of the DCT4. - * @param[in] Nby2 half of the length of the DCT4. - * @param[in] normalize normalizing factor. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. - */ - arm_status arm_dct4_init_q31( - arm_dct4_instance_q31 * S, - arm_rfft_instance_q31 * S_RFFT, - arm_cfft_radix4_instance_q31 * S_CFFT, - uint16_t N, - uint16_t Nby2, - q31_t normalize); - - - /** - * @brief Processing function for the Q31 DCT4/IDCT4. - * @param[in] S points to an instance of the Q31 DCT4 structure. - * @param[in] pState points to state buffer. - * @param[in,out] pInlineBuffer points to the in-place input and output buffer. - */ - void arm_dct4_q31( - const arm_dct4_instance_q31 * S, - q31_t * pState, - q31_t * pInlineBuffer); - - - /** - * @brief Instance structure for the Q15 DCT4/IDCT4 function. - */ - typedef struct - { - uint16_t N; /**< length of the DCT4. */ - uint16_t Nby2; /**< half of the length of the DCT4. */ - q15_t normalize; /**< normalizing factor. */ - q15_t *pTwiddle; /**< points to the twiddle factor table. */ - q15_t *pCosFactor; /**< points to the cosFactor table. */ - arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ - arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ - } arm_dct4_instance_q15; - - - /** - * @brief Initialization function for the Q15 DCT4/IDCT4. - * @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure. - * @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure. - * @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure. - * @param[in] N length of the DCT4. - * @param[in] Nby2 half of the length of the DCT4. - * @param[in] normalize normalizing factor. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. - */ - arm_status arm_dct4_init_q15( - arm_dct4_instance_q15 * S, - arm_rfft_instance_q15 * S_RFFT, - arm_cfft_radix4_instance_q15 * S_CFFT, - uint16_t N, - uint16_t Nby2, - q15_t normalize); - - - /** - * @brief Processing function for the Q15 DCT4/IDCT4. - * @param[in] S points to an instance of the Q15 DCT4 structure. - * @param[in] pState points to state buffer. - * @param[in,out] pInlineBuffer points to the in-place input and output buffer. - */ - void arm_dct4_q15( - const arm_dct4_instance_q15 * S, - q15_t * pState, - q15_t * pInlineBuffer); - - - /** - * @brief Floating-point vector addition. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_add_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q7 vector addition. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_add_q7( - q7_t * pSrcA, - q7_t * pSrcB, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q15 vector addition. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_add_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q31 vector addition. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_add_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Floating-point vector subtraction. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_sub_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q7 vector subtraction. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_sub_q7( - q7_t * pSrcA, - q7_t * pSrcB, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q15 vector subtraction. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_sub_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q31 vector subtraction. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_sub_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Multiplies a floating-point vector by a scalar. - * @param[in] pSrc points to the input vector - * @param[in] scale scale factor to be applied - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_scale_f32( - float32_t * pSrc, - float32_t scale, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Multiplies a Q7 vector by a scalar. - * @param[in] pSrc points to the input vector - * @param[in] scaleFract fractional portion of the scale value - * @param[in] shift number of bits to shift the result by - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_scale_q7( - q7_t * pSrc, - q7_t scaleFract, - int8_t shift, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Multiplies a Q15 vector by a scalar. - * @param[in] pSrc points to the input vector - * @param[in] scaleFract fractional portion of the scale value - * @param[in] shift number of bits to shift the result by - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_scale_q15( - q15_t * pSrc, - q15_t scaleFract, - int8_t shift, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Multiplies a Q31 vector by a scalar. - * @param[in] pSrc points to the input vector - * @param[in] scaleFract fractional portion of the scale value - * @param[in] shift number of bits to shift the result by - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_scale_q31( - q31_t * pSrc, - q31_t scaleFract, - int8_t shift, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q7 vector absolute value. - * @param[in] pSrc points to the input buffer - * @param[out] pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - */ - void arm_abs_q7( - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Floating-point vector absolute value. - * @param[in] pSrc points to the input buffer - * @param[out] pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - */ - void arm_abs_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q15 vector absolute value. - * @param[in] pSrc points to the input buffer - * @param[out] pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - */ - void arm_abs_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q31 vector absolute value. - * @param[in] pSrc points to the input buffer - * @param[out] pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - */ - void arm_abs_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Dot product of floating-point vectors. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] result output result returned here - */ - void arm_dot_prod_f32( - float32_t * pSrcA, - float32_t * pSrcB, - uint32_t blockSize, - float32_t * result); - - - /** - * @brief Dot product of Q7 vectors. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] result output result returned here - */ - void arm_dot_prod_q7( - q7_t * pSrcA, - q7_t * pSrcB, - uint32_t blockSize, - q31_t * result); - - - /** - * @brief Dot product of Q15 vectors. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] result output result returned here - */ - void arm_dot_prod_q15( - q15_t * pSrcA, - q15_t * pSrcB, - uint32_t blockSize, - q63_t * result); - - - /** - * @brief Dot product of Q31 vectors. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] result output result returned here - */ - void arm_dot_prod_q31( - q31_t * pSrcA, - q31_t * pSrcB, - uint32_t blockSize, - q63_t * result); - - - /** - * @brief Shifts the elements of a Q7 vector a specified number of bits. - * @param[in] pSrc points to the input vector - * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_shift_q7( - q7_t * pSrc, - int8_t shiftBits, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Shifts the elements of a Q15 vector a specified number of bits. - * @param[in] pSrc points to the input vector - * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_shift_q15( - q15_t * pSrc, - int8_t shiftBits, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Shifts the elements of a Q31 vector a specified number of bits. - * @param[in] pSrc points to the input vector - * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_shift_q31( - q31_t * pSrc, - int8_t shiftBits, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Adds a constant offset to a floating-point vector. - * @param[in] pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_offset_f32( - float32_t * pSrc, - float32_t offset, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Adds a constant offset to a Q7 vector. - * @param[in] pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_offset_q7( - q7_t * pSrc, - q7_t offset, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Adds a constant offset to a Q15 vector. - * @param[in] pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_offset_q15( - q15_t * pSrc, - q15_t offset, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Adds a constant offset to a Q31 vector. - * @param[in] pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_offset_q31( - q31_t * pSrc, - q31_t offset, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Negates the elements of a floating-point vector. - * @param[in] pSrc points to the input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_negate_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Negates the elements of a Q7 vector. - * @param[in] pSrc points to the input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_negate_q7( - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Negates the elements of a Q15 vector. - * @param[in] pSrc points to the input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_negate_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Negates the elements of a Q31 vector. - * @param[in] pSrc points to the input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_negate_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Copies the elements of a floating-point vector. - * @param[in] pSrc input pointer - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_copy_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Copies the elements of a Q7 vector. - * @param[in] pSrc input pointer - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_copy_q7( - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Copies the elements of a Q15 vector. - * @param[in] pSrc input pointer - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_copy_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Copies the elements of a Q31 vector. - * @param[in] pSrc input pointer - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_copy_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Fills a constant value into a floating-point vector. - * @param[in] value input value to be filled - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_fill_f32( - float32_t value, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Fills a constant value into a Q7 vector. - * @param[in] value input value to be filled - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_fill_q7( - q7_t value, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Fills a constant value into a Q15 vector. - * @param[in] value input value to be filled - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_fill_q15( - q15_t value, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Fills a constant value into a Q31 vector. - * @param[in] value input value to be filled - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_fill_q31( - q31_t value, - q31_t * pDst, - uint32_t blockSize); - - -/** - * @brief Convolution of floating-point sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. - */ - void arm_conv_f32( - float32_t * pSrcA, - uint32_t srcALen, - float32_t * pSrcB, - uint32_t srcBLen, - float32_t * pDst); - - - /** - * @brief Convolution of Q15 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. - * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - */ - void arm_conv_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - q15_t * pScratch1, - q15_t * pScratch2); - - -/** - * @brief Convolution of Q15 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. - */ - void arm_conv_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - - /** - * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. - */ - void arm_conv_fast_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - - /** - * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. - * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - */ - void arm_conv_fast_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - q15_t * pScratch1, - q15_t * pScratch2); - - - /** - * @brief Convolution of Q31 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. - */ - void arm_conv_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - - /** - * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. - */ - void arm_conv_fast_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - - /** - * @brief Convolution of Q7 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. - * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). - */ - void arm_conv_opt_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - q15_t * pScratch1, - q15_t * pScratch2); - - - /** - * @brief Convolution of Q7 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. - */ - void arm_conv_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst); - - - /** - * @brief Partial convolution of floating-point sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_f32( - float32_t * pSrcA, - uint32_t srcALen, - float32_t * pSrcB, - uint32_t srcBLen, - float32_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q15 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints, - q15_t * pScratch1, - q15_t * pScratch2); - - - /** - * @brief Partial convolution of Q15 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_fast_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_fast_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints, - q15_t * pScratch1, - q15_t * pScratch2); - - - /** - * @brief Partial convolution of Q31 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_fast_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q7 sequences - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_opt_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - uint32_t firstIndex, - uint32_t numPoints, - q15_t * pScratch1, - q15_t * pScratch2); - - -/** - * @brief Partial convolution of Q7 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Instance structure for the Q15 FIR decimator. - */ - typedef struct - { - uint8_t M; /**< decimation factor. */ - uint16_t numTaps; /**< number of coefficients in the filter. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - } arm_fir_decimate_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR decimator. - */ - typedef struct - { - uint8_t M; /**< decimation factor. */ - uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - } arm_fir_decimate_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR decimator. - */ - typedef struct - { - uint8_t M; /**< decimation factor. */ - uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - } arm_fir_decimate_instance_f32; - - - /** - * @brief Processing function for the floating-point FIR decimator. - * @param[in] S points to an instance of the floating-point FIR decimator structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_decimate_f32( - const arm_fir_decimate_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point FIR decimator. - * @param[in,out] S points to an instance of the floating-point FIR decimator structure. - * @param[in] numTaps number of coefficients in the filter. - * @param[in] M decimation factor. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * blockSize is not a multiple of M. - */ - arm_status arm_fir_decimate_init_f32( - arm_fir_decimate_instance_f32 * S, - uint16_t numTaps, - uint8_t M, - float32_t * pCoeffs, - float32_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q15 FIR decimator. - * @param[in] S points to an instance of the Q15 FIR decimator structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_decimate_q15( - const arm_fir_decimate_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. - * @param[in] S points to an instance of the Q15 FIR decimator structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_decimate_fast_q15( - const arm_fir_decimate_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q15 FIR decimator. - * @param[in,out] S points to an instance of the Q15 FIR decimator structure. - * @param[in] numTaps number of coefficients in the filter. - * @param[in] M decimation factor. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * blockSize is not a multiple of M. - */ - arm_status arm_fir_decimate_init_q15( - arm_fir_decimate_instance_q15 * S, - uint16_t numTaps, - uint8_t M, - q15_t * pCoeffs, - q15_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 FIR decimator. - * @param[in] S points to an instance of the Q31 FIR decimator structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_decimate_q31( - const arm_fir_decimate_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. - * @param[in] S points to an instance of the Q31 FIR decimator structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_decimate_fast_q31( - arm_fir_decimate_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 FIR decimator. - * @param[in,out] S points to an instance of the Q31 FIR decimator structure. - * @param[in] numTaps number of coefficients in the filter. - * @param[in] M decimation factor. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * blockSize is not a multiple of M. - */ - arm_status arm_fir_decimate_init_q31( - arm_fir_decimate_instance_q31 * S, - uint16_t numTaps, - uint8_t M, - q31_t * pCoeffs, - q31_t * pState, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q15 FIR interpolator. - */ - typedef struct - { - uint8_t L; /**< upsample factor. */ - uint16_t phaseLength; /**< length of each polyphase filter component. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ - } arm_fir_interpolate_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR interpolator. - */ - typedef struct - { - uint8_t L; /**< upsample factor. */ - uint16_t phaseLength; /**< length of each polyphase filter component. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ - } arm_fir_interpolate_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR interpolator. - */ - typedef struct - { - uint8_t L; /**< upsample factor. */ - uint16_t phaseLength; /**< length of each polyphase filter component. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ - } arm_fir_interpolate_instance_f32; - - - /** - * @brief Processing function for the Q15 FIR interpolator. - * @param[in] S points to an instance of the Q15 FIR interpolator structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_interpolate_q15( - const arm_fir_interpolate_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q15 FIR interpolator. - * @param[in,out] S points to an instance of the Q15 FIR interpolator structure. - * @param[in] L upsample factor. - * @param[in] numTaps number of filter coefficients in the filter. - * @param[in] pCoeffs points to the filter coefficient buffer. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * the filter length numTaps is not a multiple of the interpolation factor L. - */ - arm_status arm_fir_interpolate_init_q15( - arm_fir_interpolate_instance_q15 * S, - uint8_t L, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 FIR interpolator. - * @param[in] S points to an instance of the Q15 FIR interpolator structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_interpolate_q31( - const arm_fir_interpolate_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 FIR interpolator. - * @param[in,out] S points to an instance of the Q31 FIR interpolator structure. - * @param[in] L upsample factor. - * @param[in] numTaps number of filter coefficients in the filter. - * @param[in] pCoeffs points to the filter coefficient buffer. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * the filter length numTaps is not a multiple of the interpolation factor L. - */ - arm_status arm_fir_interpolate_init_q31( - arm_fir_interpolate_instance_q31 * S, - uint8_t L, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the floating-point FIR interpolator. - * @param[in] S points to an instance of the floating-point FIR interpolator structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_interpolate_f32( - const arm_fir_interpolate_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point FIR interpolator. - * @param[in,out] S points to an instance of the floating-point FIR interpolator structure. - * @param[in] L upsample factor. - * @param[in] numTaps number of filter coefficients in the filter. - * @param[in] pCoeffs points to the filter coefficient buffer. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * the filter length numTaps is not a multiple of the interpolation factor L. - */ - arm_status arm_fir_interpolate_init_f32( - arm_fir_interpolate_instance_f32 * S, - uint8_t L, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - uint32_t blockSize); - - - /** - * @brief Instance structure for the high precision Q31 Biquad cascade filter. - */ - typedef struct - { - uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ - q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ - } arm_biquad_cas_df1_32x64_ins_q31; - - - /** - * @param[in] S points to an instance of the high precision Q31 Biquad cascade filter structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cas_df1_32x64_q31( - const arm_biquad_cas_df1_32x64_ins_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @param[in,out] S points to an instance of the high precision Q31 Biquad cascade filter structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format - */ - void arm_biquad_cas_df1_32x64_init_q31( - arm_biquad_cas_df1_32x64_ins_q31 * S, - uint8_t numStages, - q31_t * pCoeffs, - q63_t * pState, - uint8_t postShift); - - - /** - * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. - */ - typedef struct - { - uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ - float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - } arm_biquad_cascade_df2T_instance_f32; - - /** - * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. - */ - typedef struct - { - uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ - float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - } arm_biquad_cascade_stereo_df2T_instance_f32; - - /** - * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. - */ - typedef struct - { - uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ - float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - } arm_biquad_cascade_df2T_instance_f64; - - - /** - * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in] S points to an instance of the filter data structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cascade_df2T_f32( - const arm_biquad_cascade_df2T_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels - * @param[in] S points to an instance of the filter data structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cascade_stereo_df2T_f32( - const arm_biquad_cascade_stereo_df2T_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in] S points to an instance of the filter data structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cascade_df2T_f64( - const arm_biquad_cascade_df2T_instance_f64 * S, - float64_t * pSrc, - float64_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in,out] S points to an instance of the filter data structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - */ - void arm_biquad_cascade_df2T_init_f32( - arm_biquad_cascade_df2T_instance_f32 * S, - uint8_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - - /** - * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in,out] S points to an instance of the filter data structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - */ - void arm_biquad_cascade_stereo_df2T_init_f32( - arm_biquad_cascade_stereo_df2T_instance_f32 * S, - uint8_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - - /** - * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in,out] S points to an instance of the filter data structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - */ - void arm_biquad_cascade_df2T_init_f64( - arm_biquad_cascade_df2T_instance_f64 * S, - uint8_t numStages, - float64_t * pCoeffs, - float64_t * pState); - - - /** - * @brief Instance structure for the Q15 FIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of filter stages. */ - q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ - } arm_fir_lattice_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of filter stages. */ - q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ - } arm_fir_lattice_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of filter stages. */ - float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ - } arm_fir_lattice_instance_f32; - - - /** - * @brief Initialization function for the Q15 FIR lattice filter. - * @param[in] S points to an instance of the Q15 FIR lattice structure. - * @param[in] numStages number of filter stages. - * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. - * @param[in] pState points to the state buffer. The array is of length numStages. - */ - void arm_fir_lattice_init_q15( - arm_fir_lattice_instance_q15 * S, - uint16_t numStages, - q15_t * pCoeffs, - q15_t * pState); - - - /** - * @brief Processing function for the Q15 FIR lattice filter. - * @param[in] S points to an instance of the Q15 FIR lattice structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_fir_lattice_q15( - const arm_fir_lattice_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 FIR lattice filter. - * @param[in] S points to an instance of the Q31 FIR lattice structure. - * @param[in] numStages number of filter stages. - * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. - * @param[in] pState points to the state buffer. The array is of length numStages. - */ - void arm_fir_lattice_init_q31( - arm_fir_lattice_instance_q31 * S, - uint16_t numStages, - q31_t * pCoeffs, - q31_t * pState); - - - /** - * @brief Processing function for the Q31 FIR lattice filter. - * @param[in] S points to an instance of the Q31 FIR lattice structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of samples to process. - */ - void arm_fir_lattice_q31( - const arm_fir_lattice_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - -/** - * @brief Initialization function for the floating-point FIR lattice filter. - * @param[in] S points to an instance of the floating-point FIR lattice structure. - * @param[in] numStages number of filter stages. - * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. - * @param[in] pState points to the state buffer. The array is of length numStages. - */ - void arm_fir_lattice_init_f32( - arm_fir_lattice_instance_f32 * S, - uint16_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - - /** - * @brief Processing function for the floating-point FIR lattice filter. - * @param[in] S points to an instance of the floating-point FIR lattice structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of samples to process. - */ - void arm_fir_lattice_f32( - const arm_fir_lattice_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q15 IIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of stages in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ - q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ - } arm_iir_lattice_instance_q15; - - /** - * @brief Instance structure for the Q31 IIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of stages in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ - q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ - } arm_iir_lattice_instance_q31; - - /** - * @brief Instance structure for the floating-point IIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of stages in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ - float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ - } arm_iir_lattice_instance_f32; - - - /** - * @brief Processing function for the floating-point IIR lattice filter. - * @param[in] S points to an instance of the floating-point IIR lattice structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_iir_lattice_f32( - const arm_iir_lattice_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point IIR lattice filter. - * @param[in] S points to an instance of the floating-point IIR lattice structure. - * @param[in] numStages number of stages in the filter. - * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. - * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. - * @param[in] pState points to the state buffer. The array is of length numStages+blockSize-1. - * @param[in] blockSize number of samples to process. - */ - void arm_iir_lattice_init_f32( - arm_iir_lattice_instance_f32 * S, - uint16_t numStages, - float32_t * pkCoeffs, - float32_t * pvCoeffs, - float32_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 IIR lattice filter. - * @param[in] S points to an instance of the Q31 IIR lattice structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_iir_lattice_q31( - const arm_iir_lattice_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 IIR lattice filter. - * @param[in] S points to an instance of the Q31 IIR lattice structure. - * @param[in] numStages number of stages in the filter. - * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. - * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. - * @param[in] pState points to the state buffer. The array is of length numStages+blockSize. - * @param[in] blockSize number of samples to process. - */ - void arm_iir_lattice_init_q31( - arm_iir_lattice_instance_q31 * S, - uint16_t numStages, - q31_t * pkCoeffs, - q31_t * pvCoeffs, - q31_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q15 IIR lattice filter. - * @param[in] S points to an instance of the Q15 IIR lattice structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_iir_lattice_q15( - const arm_iir_lattice_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - -/** - * @brief Initialization function for the Q15 IIR lattice filter. - * @param[in] S points to an instance of the fixed-point Q15 IIR lattice structure. - * @param[in] numStages number of stages in the filter. - * @param[in] pkCoeffs points to reflection coefficient buffer. The array is of length numStages. - * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. - * @param[in] pState points to state buffer. The array is of length numStages+blockSize. - * @param[in] blockSize number of samples to process per call. - */ - void arm_iir_lattice_init_q15( - arm_iir_lattice_instance_q15 * S, - uint16_t numStages, - q15_t * pkCoeffs, - q15_t * pvCoeffs, - q15_t * pState, - uint32_t blockSize); - - - /** - * @brief Instance structure for the floating-point LMS filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - float32_t mu; /**< step size that controls filter coefficient updates. */ - } arm_lms_instance_f32; - - - /** - * @brief Processing function for floating-point LMS filter. - * @param[in] S points to an instance of the floating-point LMS filter structure. - * @param[in] pSrc points to the block of input data. - * @param[in] pRef points to the block of reference data. - * @param[out] pOut points to the block of output data. - * @param[out] pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - */ - void arm_lms_f32( - const arm_lms_instance_f32 * S, - float32_t * pSrc, - float32_t * pRef, - float32_t * pOut, - float32_t * pErr, - uint32_t blockSize); - - - /** - * @brief Initialization function for floating-point LMS filter. - * @param[in] S points to an instance of the floating-point LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] pCoeffs points to the coefficient buffer. - * @param[in] pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - */ - void arm_lms_init_f32( - arm_lms_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - float32_t mu, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q15 LMS filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q15_t mu; /**< step size that controls filter coefficient updates. */ - uint32_t postShift; /**< bit shift applied to coefficients. */ - } arm_lms_instance_q15; - - - /** - * @brief Initialization function for the Q15 LMS filter. - * @param[in] S points to an instance of the Q15 LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] pCoeffs points to the coefficient buffer. - * @param[in] pState points to the state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - */ - void arm_lms_init_q15( - arm_lms_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - q15_t mu, - uint32_t blockSize, - uint32_t postShift); - - - /** - * @brief Processing function for Q15 LMS filter. - * @param[in] S points to an instance of the Q15 LMS filter structure. - * @param[in] pSrc points to the block of input data. - * @param[in] pRef points to the block of reference data. - * @param[out] pOut points to the block of output data. - * @param[out] pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - */ - void arm_lms_q15( - const arm_lms_instance_q15 * S, - q15_t * pSrc, - q15_t * pRef, - q15_t * pOut, - q15_t * pErr, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q31 LMS filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q31_t mu; /**< step size that controls filter coefficient updates. */ - uint32_t postShift; /**< bit shift applied to coefficients. */ - } arm_lms_instance_q31; - - - /** - * @brief Processing function for Q31 LMS filter. - * @param[in] S points to an instance of the Q15 LMS filter structure. - * @param[in] pSrc points to the block of input data. - * @param[in] pRef points to the block of reference data. - * @param[out] pOut points to the block of output data. - * @param[out] pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - */ - void arm_lms_q31( - const arm_lms_instance_q31 * S, - q31_t * pSrc, - q31_t * pRef, - q31_t * pOut, - q31_t * pErr, - uint32_t blockSize); - - - /** - * @brief Initialization function for Q31 LMS filter. - * @param[in] S points to an instance of the Q31 LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] pCoeffs points to coefficient buffer. - * @param[in] pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - */ - void arm_lms_init_q31( - arm_lms_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - q31_t mu, - uint32_t blockSize, - uint32_t postShift); - - - /** - * @brief Instance structure for the floating-point normalized LMS filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - float32_t mu; /**< step size that control filter coefficient updates. */ - float32_t energy; /**< saves previous frame energy. */ - float32_t x0; /**< saves previous input sample. */ - } arm_lms_norm_instance_f32; - - - /** - * @brief Processing function for floating-point normalized LMS filter. - * @param[in] S points to an instance of the floating-point normalized LMS filter structure. - * @param[in] pSrc points to the block of input data. - * @param[in] pRef points to the block of reference data. - * @param[out] pOut points to the block of output data. - * @param[out] pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - */ - void arm_lms_norm_f32( - arm_lms_norm_instance_f32 * S, - float32_t * pSrc, - float32_t * pRef, - float32_t * pOut, - float32_t * pErr, - uint32_t blockSize); - - - /** - * @brief Initialization function for floating-point normalized LMS filter. - * @param[in] S points to an instance of the floating-point LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] pCoeffs points to coefficient buffer. - * @param[in] pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - */ - void arm_lms_norm_init_f32( - arm_lms_norm_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - float32_t mu, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q31 normalized LMS filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q31_t mu; /**< step size that controls filter coefficient updates. */ - uint8_t postShift; /**< bit shift applied to coefficients. */ - q31_t *recipTable; /**< points to the reciprocal initial value table. */ - q31_t energy; /**< saves previous frame energy. */ - q31_t x0; /**< saves previous input sample. */ - } arm_lms_norm_instance_q31; - - - /** - * @brief Processing function for Q31 normalized LMS filter. - * @param[in] S points to an instance of the Q31 normalized LMS filter structure. - * @param[in] pSrc points to the block of input data. - * @param[in] pRef points to the block of reference data. - * @param[out] pOut points to the block of output data. - * @param[out] pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - */ - void arm_lms_norm_q31( - arm_lms_norm_instance_q31 * S, - q31_t * pSrc, - q31_t * pRef, - q31_t * pOut, - q31_t * pErr, - uint32_t blockSize); - - - /** - * @brief Initialization function for Q31 normalized LMS filter. - * @param[in] S points to an instance of the Q31 normalized LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] pCoeffs points to coefficient buffer. - * @param[in] pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - */ - void arm_lms_norm_init_q31( - arm_lms_norm_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - q31_t mu, - uint32_t blockSize, - uint8_t postShift); - - - /** - * @brief Instance structure for the Q15 normalized LMS filter. - */ - typedef struct - { - uint16_t numTaps; /**< Number of coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q15_t mu; /**< step size that controls filter coefficient updates. */ - uint8_t postShift; /**< bit shift applied to coefficients. */ - q15_t *recipTable; /**< Points to the reciprocal initial value table. */ - q15_t energy; /**< saves previous frame energy. */ - q15_t x0; /**< saves previous input sample. */ - } arm_lms_norm_instance_q15; - - - /** - * @brief Processing function for Q15 normalized LMS filter. - * @param[in] S points to an instance of the Q15 normalized LMS filter structure. - * @param[in] pSrc points to the block of input data. - * @param[in] pRef points to the block of reference data. - * @param[out] pOut points to the block of output data. - * @param[out] pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - */ - void arm_lms_norm_q15( - arm_lms_norm_instance_q15 * S, - q15_t * pSrc, - q15_t * pRef, - q15_t * pOut, - q15_t * pErr, - uint32_t blockSize); - - - /** - * @brief Initialization function for Q15 normalized LMS filter. - * @param[in] S points to an instance of the Q15 normalized LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] pCoeffs points to coefficient buffer. - * @param[in] pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - */ - void arm_lms_norm_init_q15( - arm_lms_norm_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - q15_t mu, - uint32_t blockSize, - uint8_t postShift); - - - /** - * @brief Correlation of floating-point sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - */ - void arm_correlate_f32( - float32_t * pSrcA, - uint32_t srcALen, - float32_t * pSrcB, - uint32_t srcBLen, - float32_t * pDst); - - - /** - * @brief Correlation of Q15 sequences - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - */ - void arm_correlate_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - q15_t * pScratch); - - - /** - * @brief Correlation of Q15 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - */ - - void arm_correlate_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - - /** - * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - */ - - void arm_correlate_fast_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - - /** - * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - */ - void arm_correlate_fast_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - q15_t * pScratch); - - - /** - * @brief Correlation of Q31 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - */ - void arm_correlate_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - - /** - * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - */ - void arm_correlate_fast_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - - /** - * @brief Correlation of Q7 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). - */ - void arm_correlate_opt_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - q15_t * pScratch1, - q15_t * pScratch2); - - - /** - * @brief Correlation of Q7 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - */ - void arm_correlate_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst); - - - /** - * @brief Instance structure for the floating-point sparse FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_f32; - - /** - * @brief Instance structure for the Q31 sparse FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_q31; - - /** - * @brief Instance structure for the Q15 sparse FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_q15; - - /** - * @brief Instance structure for the Q7 sparse FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_q7; - - - /** - * @brief Processing function for the floating-point sparse FIR filter. - * @param[in] S points to an instance of the floating-point sparse FIR structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] pScratchIn points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_sparse_f32( - arm_fir_sparse_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - float32_t * pScratchIn, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point sparse FIR filter. - * @param[in,out] S points to an instance of the floating-point sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] pCoeffs points to the array of filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - */ - void arm_fir_sparse_init_f32( - arm_fir_sparse_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 sparse FIR filter. - * @param[in] S points to an instance of the Q31 sparse FIR structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] pScratchIn points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_sparse_q31( - arm_fir_sparse_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - q31_t * pScratchIn, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 sparse FIR filter. - * @param[in,out] S points to an instance of the Q31 sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] pCoeffs points to the array of filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - */ - void arm_fir_sparse_init_q31( - arm_fir_sparse_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q15 sparse FIR filter. - * @param[in] S points to an instance of the Q15 sparse FIR structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] pScratchIn points to a temporary buffer of size blockSize. - * @param[in] pScratchOut points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_sparse_q15( - arm_fir_sparse_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - q15_t * pScratchIn, - q31_t * pScratchOut, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q15 sparse FIR filter. - * @param[in,out] S points to an instance of the Q15 sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] pCoeffs points to the array of filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - */ - void arm_fir_sparse_init_q15( - arm_fir_sparse_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q7 sparse FIR filter. - * @param[in] S points to an instance of the Q7 sparse FIR structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] pScratchIn points to a temporary buffer of size blockSize. - * @param[in] pScratchOut points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_sparse_q7( - arm_fir_sparse_instance_q7 * S, - q7_t * pSrc, - q7_t * pDst, - q7_t * pScratchIn, - q31_t * pScratchOut, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q7 sparse FIR filter. - * @param[in,out] S points to an instance of the Q7 sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] pCoeffs points to the array of filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - */ - void arm_fir_sparse_init_q7( - arm_fir_sparse_instance_q7 * S, - uint16_t numTaps, - q7_t * pCoeffs, - q7_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - - /** - * @brief Floating-point sin_cos function. - * @param[in] theta input value in degrees - * @param[out] pSinVal points to the processed sine output. - * @param[out] pCosVal points to the processed cos output. - */ - void arm_sin_cos_f32( - float32_t theta, - float32_t * pSinVal, - float32_t * pCosVal); - - - /** - * @brief Q31 sin_cos function. - * @param[in] theta scaled input value in degrees - * @param[out] pSinVal points to the processed sine output. - * @param[out] pCosVal points to the processed cosine output. - */ - void arm_sin_cos_q31( - q31_t theta, - q31_t * pSinVal, - q31_t * pCosVal); - - - /** - * @brief Floating-point complex conjugate. - * @param[in] pSrc points to the input vector - * @param[out] pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - */ - void arm_cmplx_conj_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t numSamples); - - /** - * @brief Q31 complex conjugate. - * @param[in] pSrc points to the input vector - * @param[out] pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - */ - void arm_cmplx_conj_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t numSamples); - - - /** - * @brief Q15 complex conjugate. - * @param[in] pSrc points to the input vector - * @param[out] pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - */ - void arm_cmplx_conj_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t numSamples); - - - /** - * @brief Floating-point complex magnitude squared - * @param[in] pSrc points to the complex input vector - * @param[out] pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - */ - void arm_cmplx_mag_squared_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t numSamples); - - - /** - * @brief Q31 complex magnitude squared - * @param[in] pSrc points to the complex input vector - * @param[out] pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - */ - void arm_cmplx_mag_squared_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t numSamples); - - - /** - * @brief Q15 complex magnitude squared - * @param[in] pSrc points to the complex input vector - * @param[out] pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - */ - void arm_cmplx_mag_squared_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t numSamples); - - - /** - * @ingroup groupController - */ - - /** - * @defgroup PID PID Motor Control - * - * A Proportional Integral Derivative (PID) controller is a generic feedback control - * loop mechanism widely used in industrial control systems. - * A PID controller is the most commonly used type of feedback controller. - * - * This set of functions implements (PID) controllers - * for Q15, Q31, and floating-point data types. The functions operate on a single sample - * of data and each call to the function returns a single processed value. - * S points to an instance of the PID control data structure. in - * is the input sample value. The functions return the output value. - * - * \par Algorithm: - *
-   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
-   *    A0 = Kp + Ki + Kd
-   *    A1 = (-Kp ) - (2 * Kd )
-   *    A2 = Kd  
- * - * \par - * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant - * - * \par - * \image html PID.gif "Proportional Integral Derivative Controller" - * - * \par - * The PID controller calculates an "error" value as the difference between - * the measured output and the reference input. - * The controller attempts to minimize the error by adjusting the process control inputs. - * The proportional value determines the reaction to the current error, - * the integral value determines the reaction based on the sum of recent errors, - * and the derivative value determines the reaction based on the rate at which the error has been changing. - * - * \par Instance Structure - * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. - * A separate instance structure must be defined for each PID Controller. - * There are separate instance structure declarations for each of the 3 supported data types. - * - * \par Reset Functions - * There is also an associated reset function for each data type which clears the state array. - * - * \par Initialization Functions - * There is also an associated initialization function for each data type. - * The initialization function performs the following operations: - * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. - * - Zeros out the values in the state buffer. - * - * \par - * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. - * - * \par Fixed-Point Behavior - * Care must be taken when using the fixed-point versions of the PID Controller functions. - * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup PID - * @{ - */ - - /** - * @brief Process function for the floating-point PID Control. - * @param[in,out] S is an instance of the floating-point PID Control structure - * @param[in] in input sample to process - * @return out processed output sample. - */ - CMSIS_INLINE __STATIC_INLINE float32_t arm_pid_f32( - arm_pid_instance_f32 * S, - float32_t in) - { - float32_t out; - - /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ - out = (S->A0 * in) + - (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); - - /* Update state */ - S->state[1] = S->state[0]; - S->state[0] = in; - S->state[2] = out; - - /* return to application */ - return (out); - - } - - /** - * @brief Process function for the Q31 PID Control. - * @param[in,out] S points to an instance of the Q31 PID Control structure - * @param[in] in input sample to process - * @return out processed output sample. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 64-bit accumulator. - * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. - * Thus, if the accumulator result overflows it wraps around rather than clip. - * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. - * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. - */ - CMSIS_INLINE __STATIC_INLINE q31_t arm_pid_q31( - arm_pid_instance_q31 * S, - q31_t in) - { - q63_t acc; - q31_t out; - - /* acc = A0 * x[n] */ - acc = (q63_t) S->A0 * in; - - /* acc += A1 * x[n-1] */ - acc += (q63_t) S->A1 * S->state[0]; - - /* acc += A2 * x[n-2] */ - acc += (q63_t) S->A2 * S->state[1]; - - /* convert output to 1.31 format to add y[n-1] */ - out = (q31_t) (acc >> 31u); - - /* out += y[n-1] */ - out += S->state[2]; - - /* Update state */ - S->state[1] = S->state[0]; - S->state[0] = in; - S->state[2] = out; - - /* return to application */ - return (out); - } - - - /** - * @brief Process function for the Q15 PID Control. - * @param[in,out] S points to an instance of the Q15 PID Control structure - * @param[in] in input sample to process - * @return out processed output sample. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using a 64-bit internal accumulator. - * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. - * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. - * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. - * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. - * Lastly, the accumulator is saturated to yield a result in 1.15 format. - */ - CMSIS_INLINE __STATIC_INLINE q15_t arm_pid_q15( - arm_pid_instance_q15 * S, - q15_t in) - { - q63_t acc; - q15_t out; - -#if defined (ARM_MATH_DSP) - __SIMD32_TYPE *vstate; - - /* Implementation of PID controller */ - - /* acc = A0 * x[n] */ - acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in); - - /* acc += A1 * x[n-1] + A2 * x[n-2] */ - vstate = __SIMD32_CONST(S->state); - acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)*vstate, (uint64_t)acc); -#else - /* acc = A0 * x[n] */ - acc = ((q31_t) S->A0) * in; - - /* acc += A1 * x[n-1] + A2 * x[n-2] */ - acc += (q31_t) S->A1 * S->state[0]; - acc += (q31_t) S->A2 * S->state[1]; -#endif - - /* acc += y[n-1] */ - acc += (q31_t) S->state[2] << 15; - - /* saturate the output */ - out = (q15_t) (__SSAT((acc >> 15), 16)); - - /* Update state */ - S->state[1] = S->state[0]; - S->state[0] = in; - S->state[2] = out; - - /* return to application */ - return (out); - } - - /** - * @} end of PID group - */ - - - /** - * @brief Floating-point matrix inverse. - * @param[in] src points to the instance of the input floating-point matrix structure. - * @param[out] dst points to the instance of the output floating-point matrix structure. - * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. - * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. - */ - arm_status arm_mat_inverse_f32( - const arm_matrix_instance_f32 * src, - arm_matrix_instance_f32 * dst); - - - /** - * @brief Floating-point matrix inverse. - * @param[in] src points to the instance of the input floating-point matrix structure. - * @param[out] dst points to the instance of the output floating-point matrix structure. - * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. - * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. - */ - arm_status arm_mat_inverse_f64( - const arm_matrix_instance_f64 * src, - arm_matrix_instance_f64 * dst); - - - - /** - * @ingroup groupController - */ - - /** - * @defgroup clarke Vector Clarke Transform - * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. - * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents - * in the two-phase orthogonal stator axis Ialpha and Ibeta. - * When Ialpha is superposed with Ia as shown in the figure below - * \image html clarke.gif Stator current space vector and its components in (a,b). - * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta - * can be calculated using only Ia and Ib. - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html clarkeFormula.gif - * where Ia and Ib are the instantaneous stator phases and - * pIalpha and pIbeta are the two coordinates of time invariant vector. - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Clarke transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup clarke - * @{ - */ - - /** - * - * @brief Floating-point Clarke transform - * @param[in] Ia input three-phase coordinate a - * @param[in] Ib input three-phase coordinate b - * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] pIbeta points to output two-phase orthogonal vector axis beta - */ - CMSIS_INLINE __STATIC_INLINE void arm_clarke_f32( - float32_t Ia, - float32_t Ib, - float32_t * pIalpha, - float32_t * pIbeta) - { - /* Calculate pIalpha using the equation, pIalpha = Ia */ - *pIalpha = Ia; - - /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ - *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); - } - - - /** - * @brief Clarke transform for Q31 version - * @param[in] Ia input three-phase coordinate a - * @param[in] Ib input three-phase coordinate b - * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] pIbeta points to output two-phase orthogonal vector axis beta - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the addition, hence there is no risk of overflow. - */ - CMSIS_INLINE __STATIC_INLINE void arm_clarke_q31( - q31_t Ia, - q31_t Ib, - q31_t * pIalpha, - q31_t * pIbeta) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - - /* Calculating pIalpha from Ia by equation pIalpha = Ia */ - *pIalpha = Ia; - - /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ - product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); - - /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ - product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); - - /* pIbeta is calculated by adding the intermediate products */ - *pIbeta = __QADD(product1, product2); - } - - /** - * @} end of clarke group - */ - - /** - * @brief Converts the elements of the Q7 vector to Q31 vector. - * @param[in] pSrc input pointer - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_q7_to_q31( - q7_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - - /** - * @ingroup groupController - */ - - /** - * @defgroup inv_clarke Vector Inverse Clarke Transform - * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html clarkeInvFormula.gif - * where pIa and pIb are the instantaneous stator phases and - * Ialpha and Ibeta are the two coordinates of time invariant vector. - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Clarke transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup inv_clarke - * @{ - */ - - /** - * @brief Floating-point Inverse Clarke transform - * @param[in] Ialpha input two-phase orthogonal vector axis alpha - * @param[in] Ibeta input two-phase orthogonal vector axis beta - * @param[out] pIa points to output three-phase coordinate a - * @param[out] pIb points to output three-phase coordinate b - */ - CMSIS_INLINE __STATIC_INLINE void arm_inv_clarke_f32( - float32_t Ialpha, - float32_t Ibeta, - float32_t * pIa, - float32_t * pIb) - { - /* Calculating pIa from Ialpha by equation pIa = Ialpha */ - *pIa = Ialpha; - - /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ - *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta; - } - - - /** - * @brief Inverse Clarke transform for Q31 version - * @param[in] Ialpha input two-phase orthogonal vector axis alpha - * @param[in] Ibeta input two-phase orthogonal vector axis beta - * @param[out] pIa points to output three-phase coordinate a - * @param[out] pIb points to output three-phase coordinate b - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the subtraction, hence there is no risk of overflow. - */ - CMSIS_INLINE __STATIC_INLINE void arm_inv_clarke_q31( - q31_t Ialpha, - q31_t Ibeta, - q31_t * pIa, - q31_t * pIb) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - - /* Calculating pIa from Ialpha by equation pIa = Ialpha */ - *pIa = Ialpha; - - /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ - product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); - - /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ - product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); - - /* pIb is calculated by subtracting the products */ - *pIb = __QSUB(product2, product1); - } - - /** - * @} end of inv_clarke group - */ - - /** - * @brief Converts the elements of the Q7 vector to Q15 vector. - * @param[in] pSrc input pointer - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_q7_to_q15( - q7_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - - /** - * @ingroup groupController - */ - - /** - * @defgroup park Vector Park Transform - * - * Forward Park transform converts the input two-coordinate vector to flux and torque components. - * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents - * from the stationary to the moving reference frame and control the spatial relationship between - * the stator vector current and rotor flux vector. - * If we consider the d axis aligned with the rotor flux, the diagram below shows the - * current vector and the relationship from the two reference frames: - * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html parkFormula.gif - * where Ialpha and Ibeta are the stator vector components, - * pId and pIq are rotor vector components and cosVal and sinVal are the - * cosine and sine values of theta (rotor flux position). - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Park transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup park - * @{ - */ - - /** - * @brief Floating-point Park transform - * @param[in] Ialpha input two-phase vector coordinate alpha - * @param[in] Ibeta input two-phase vector coordinate beta - * @param[out] pId points to output rotor reference frame d - * @param[out] pIq points to output rotor reference frame q - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * - * The function implements the forward Park transform. - * - */ - CMSIS_INLINE __STATIC_INLINE void arm_park_f32( - float32_t Ialpha, - float32_t Ibeta, - float32_t * pId, - float32_t * pIq, - float32_t sinVal, - float32_t cosVal) - { - /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ - *pId = Ialpha * cosVal + Ibeta * sinVal; - - /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ - *pIq = -Ialpha * sinVal + Ibeta * cosVal; - } - - - /** - * @brief Park transform for Q31 version - * @param[in] Ialpha input two-phase vector coordinate alpha - * @param[in] Ibeta input two-phase vector coordinate beta - * @param[out] pId points to output rotor reference frame d - * @param[out] pIq points to output rotor reference frame q - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the addition and subtraction, hence there is no risk of overflow. - */ - CMSIS_INLINE __STATIC_INLINE void arm_park_q31( - q31_t Ialpha, - q31_t Ibeta, - q31_t * pId, - q31_t * pIq, - q31_t sinVal, - q31_t cosVal) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - q31_t product3, product4; /* Temporary variables used to store intermediate results */ - - /* Intermediate product is calculated by (Ialpha * cosVal) */ - product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); - - /* Intermediate product is calculated by (Ibeta * sinVal) */ - product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); - - - /* Intermediate product is calculated by (Ialpha * sinVal) */ - product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); - - /* Intermediate product is calculated by (Ibeta * cosVal) */ - product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); - - /* Calculate pId by adding the two intermediate products 1 and 2 */ - *pId = __QADD(product1, product2); - - /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ - *pIq = __QSUB(product4, product3); - } - - /** - * @} end of park group - */ - - /** - * @brief Converts the elements of the Q7 vector to floating-point vector. - * @param[in] pSrc is input pointer - * @param[out] pDst is output pointer - * @param[in] blockSize is the number of samples to process - */ - void arm_q7_to_float( - q7_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @ingroup groupController - */ - - /** - * @defgroup inv_park Vector Inverse Park transform - * Inverse Park transform converts the input flux and torque components to two-coordinate vector. - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html parkInvFormula.gif - * where pIalpha and pIbeta are the stator vector components, - * Id and Iq are rotor vector components and cosVal and sinVal are the - * cosine and sine values of theta (rotor flux position). - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Park transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup inv_park - * @{ - */ - - /** - * @brief Floating-point Inverse Park transform - * @param[in] Id input coordinate of rotor reference frame d - * @param[in] Iq input coordinate of rotor reference frame q - * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] pIbeta points to output two-phase orthogonal vector axis beta - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - */ - CMSIS_INLINE __STATIC_INLINE void arm_inv_park_f32( - float32_t Id, - float32_t Iq, - float32_t * pIalpha, - float32_t * pIbeta, - float32_t sinVal, - float32_t cosVal) - { - /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ - *pIalpha = Id * cosVal - Iq * sinVal; - - /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ - *pIbeta = Id * sinVal + Iq * cosVal; - } - - - /** - * @brief Inverse Park transform for Q31 version - * @param[in] Id input coordinate of rotor reference frame d - * @param[in] Iq input coordinate of rotor reference frame q - * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] pIbeta points to output two-phase orthogonal vector axis beta - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the addition, hence there is no risk of overflow. - */ - CMSIS_INLINE __STATIC_INLINE void arm_inv_park_q31( - q31_t Id, - q31_t Iq, - q31_t * pIalpha, - q31_t * pIbeta, - q31_t sinVal, - q31_t cosVal) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - q31_t product3, product4; /* Temporary variables used to store intermediate results */ - - /* Intermediate product is calculated by (Id * cosVal) */ - product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); - - /* Intermediate product is calculated by (Iq * sinVal) */ - product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); - - - /* Intermediate product is calculated by (Id * sinVal) */ - product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); - - /* Intermediate product is calculated by (Iq * cosVal) */ - product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); - - /* Calculate pIalpha by using the two intermediate products 1 and 2 */ - *pIalpha = __QSUB(product1, product2); - - /* Calculate pIbeta by using the two intermediate products 3 and 4 */ - *pIbeta = __QADD(product4, product3); - } - - /** - * @} end of Inverse park group - */ - - - /** - * @brief Converts the elements of the Q31 vector to floating-point vector. - * @param[in] pSrc is input pointer - * @param[out] pDst is output pointer - * @param[in] blockSize is the number of samples to process - */ - void arm_q31_to_float( - q31_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @ingroup groupInterpolation - */ - - /** - * @defgroup LinearInterpolate Linear Interpolation - * - * Linear interpolation is a method of curve fitting using linear polynomials. - * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line - * - * \par - * \image html LinearInterp.gif "Linear interpolation" - * - * \par - * A Linear Interpolate function calculates an output value(y), for the input(x) - * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) - * - * \par Algorithm: - *
-   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
-   *       where x0, x1 are nearest values of input x
-   *             y0, y1 are nearest values to output y
-   * 
- * - * \par - * This set of functions implements Linear interpolation process - * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single - * sample of data and each call to the function returns a single processed value. - * S points to an instance of the Linear Interpolate function data structure. - * x is the input sample value. The functions returns the output value. - * - * \par - * if x is outside of the table boundary, Linear interpolation returns first value of the table - * if x is below input range and returns last value of table if x is above range. - */ - - /** - * @addtogroup LinearInterpolate - * @{ - */ - - /** - * @brief Process function for the floating-point Linear Interpolation Function. - * @param[in,out] S is an instance of the floating-point Linear Interpolation structure - * @param[in] x input sample to process - * @return y processed output sample. - * - */ - CMSIS_INLINE __STATIC_INLINE float32_t arm_linear_interp_f32( - arm_linear_interp_instance_f32 * S, - float32_t x) - { - float32_t y; - float32_t x0, x1; /* Nearest input values */ - float32_t y0, y1; /* Nearest output values */ - float32_t xSpacing = S->xSpacing; /* spacing between input values */ - int32_t i; /* Index variable */ - float32_t *pYData = S->pYData; /* pointer to output table */ - - /* Calculation of index */ - i = (int32_t) ((x - S->x1) / xSpacing); - - if (i < 0) - { - /* Iniatilize output for below specified range as least output value of table */ - y = pYData[0]; - } - else if ((uint32_t)i >= S->nValues) - { - /* Iniatilize output for above specified range as last output value of table */ - y = pYData[S->nValues - 1]; - } - else - { - /* Calculation of nearest input values */ - x0 = S->x1 + i * xSpacing; - x1 = S->x1 + (i + 1) * xSpacing; - - /* Read of nearest output values */ - y0 = pYData[i]; - y1 = pYData[i + 1]; - - /* Calculation of output */ - y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); - - } - - /* returns output value */ - return (y); - } - - - /** - * - * @brief Process function for the Q31 Linear Interpolation Function. - * @param[in] pYData pointer to Q31 Linear Interpolation table - * @param[in] x input sample to process - * @param[in] nValues number of table values - * @return y processed output sample. - * - * \par - * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. - * This function can support maximum of table size 2^12. - * - */ - CMSIS_INLINE __STATIC_INLINE q31_t arm_linear_interp_q31( - q31_t * pYData, - q31_t x, - uint32_t nValues) - { - q31_t y; /* output */ - q31_t y0, y1; /* Nearest output values */ - q31_t fract; /* fractional part */ - int32_t index; /* Index to read nearest output values */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - index = ((x & (q31_t)0xFFF00000) >> 20); - - if (index >= (int32_t)(nValues - 1)) - { - return (pYData[nValues - 1]); - } - else if (index < 0) - { - return (pYData[0]); - } - else - { - /* 20 bits for the fractional part */ - /* shift left by 11 to keep fract in 1.31 format */ - fract = (x & 0x000FFFFF) << 11; - - /* Read two nearest output values from the index in 1.31(q31) format */ - y0 = pYData[index]; - y1 = pYData[index + 1]; - - /* Calculation of y0 * (1-fract) and y is in 2.30 format */ - y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); - - /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ - y += ((q31_t) (((q63_t) y1 * fract) >> 32)); - - /* Convert y to 1.31 format */ - return (y << 1u); - } - } - - - /** - * - * @brief Process function for the Q15 Linear Interpolation Function. - * @param[in] pYData pointer to Q15 Linear Interpolation table - * @param[in] x input sample to process - * @param[in] nValues number of table values - * @return y processed output sample. - * - * \par - * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. - * This function can support maximum of table size 2^12. - * - */ - CMSIS_INLINE __STATIC_INLINE q15_t arm_linear_interp_q15( - q15_t * pYData, - q31_t x, - uint32_t nValues) - { - q63_t y; /* output */ - q15_t y0, y1; /* Nearest output values */ - q31_t fract; /* fractional part */ - int32_t index; /* Index to read nearest output values */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - index = ((x & (int32_t)0xFFF00000) >> 20); - - if (index >= (int32_t)(nValues - 1)) - { - return (pYData[nValues - 1]); - } - else if (index < 0) - { - return (pYData[0]); - } - else - { - /* 20 bits for the fractional part */ - /* fract is in 12.20 format */ - fract = (x & 0x000FFFFF); - - /* Read two nearest output values from the index */ - y0 = pYData[index]; - y1 = pYData[index + 1]; - - /* Calculation of y0 * (1-fract) and y is in 13.35 format */ - y = ((q63_t) y0 * (0xFFFFF - fract)); - - /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ - y += ((q63_t) y1 * (fract)); - - /* convert y to 1.15 format */ - return (q15_t) (y >> 20); - } - } - - - /** - * - * @brief Process function for the Q7 Linear Interpolation Function. - * @param[in] pYData pointer to Q7 Linear Interpolation table - * @param[in] x input sample to process - * @param[in] nValues number of table values - * @return y processed output sample. - * - * \par - * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. - * This function can support maximum of table size 2^12. - */ - CMSIS_INLINE __STATIC_INLINE q7_t arm_linear_interp_q7( - q7_t * pYData, - q31_t x, - uint32_t nValues) - { - q31_t y; /* output */ - q7_t y0, y1; /* Nearest output values */ - q31_t fract; /* fractional part */ - uint32_t index; /* Index to read nearest output values */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - if (x < 0) - { - return (pYData[0]); - } - index = (x >> 20) & 0xfff; - - if (index >= (nValues - 1)) - { - return (pYData[nValues - 1]); - } - else - { - /* 20 bits for the fractional part */ - /* fract is in 12.20 format */ - fract = (x & 0x000FFFFF); - - /* Read two nearest output values from the index and are in 1.7(q7) format */ - y0 = pYData[index]; - y1 = pYData[index + 1]; - - /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ - y = ((y0 * (0xFFFFF - fract))); - - /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ - y += (y1 * fract); - - /* convert y to 1.7(q7) format */ - return (q7_t) (y >> 20); - } - } - - /** - * @} end of LinearInterpolate group - */ - - /** - * @brief Fast approximation to the trigonometric sine function for floating-point data. - * @param[in] x input value in radians. - * @return sin(x). - */ - float32_t arm_sin_f32( - float32_t x); - - - /** - * @brief Fast approximation to the trigonometric sine function for Q31 data. - * @param[in] x Scaled input value in radians. - * @return sin(x). - */ - q31_t arm_sin_q31( - q31_t x); - - - /** - * @brief Fast approximation to the trigonometric sine function for Q15 data. - * @param[in] x Scaled input value in radians. - * @return sin(x). - */ - q15_t arm_sin_q15( - q15_t x); - - - /** - * @brief Fast approximation to the trigonometric cosine function for floating-point data. - * @param[in] x input value in radians. - * @return cos(x). - */ - float32_t arm_cos_f32( - float32_t x); - - - /** - * @brief Fast approximation to the trigonometric cosine function for Q31 data. - * @param[in] x Scaled input value in radians. - * @return cos(x). - */ - q31_t arm_cos_q31( - q31_t x); - - - /** - * @brief Fast approximation to the trigonometric cosine function for Q15 data. - * @param[in] x Scaled input value in radians. - * @return cos(x). - */ - q15_t arm_cos_q15( - q15_t x); - - - /** - * @ingroup groupFastMath - */ - - - /** - * @defgroup SQRT Square Root - * - * Computes the square root of a number. - * There are separate functions for Q15, Q31, and floating-point data types. - * The square root function is computed using the Newton-Raphson algorithm. - * This is an iterative algorithm of the form: - *
-   *      x1 = x0 - f(x0)/f'(x0)
-   * 
- * where x1 is the current estimate, - * x0 is the previous estimate, and - * f'(x0) is the derivative of f() evaluated at x0. - * For the square root function, the algorithm reduces to: - *
-   *     x0 = in/2                         [initial guess]
-   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
-   * 
- */ - - - /** - * @addtogroup SQRT - * @{ - */ - - /** - * @brief Floating-point square root function. - * @param[in] in input value. - * @param[out] pOut square root of input value. - * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if - * in is negative value and returns zero output for negative values. - */ - CMSIS_INLINE __STATIC_INLINE arm_status arm_sqrt_f32( - float32_t in, - float32_t * pOut) - { - if (in >= 0.0f) - { - -#if (__FPU_USED == 1) && defined ( __CC_ARM ) - *pOut = __sqrtf(in); -#elif (__FPU_USED == 1) && (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) - *pOut = __builtin_sqrtf(in); -#elif (__FPU_USED == 1) && defined(__GNUC__) - *pOut = __builtin_sqrtf(in); -#elif (__FPU_USED == 1) && defined ( __ICCARM__ ) && (__VER__ >= 6040000) - __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in)); -#else - *pOut = sqrtf(in); -#endif - - return (ARM_MATH_SUCCESS); - } - else - { - *pOut = 0.0f; - return (ARM_MATH_ARGUMENT_ERROR); - } - } - - - /** - * @brief Q31 square root function. - * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF. - * @param[out] pOut square root of input value. - * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if - * in is negative value and returns zero output for negative values. - */ - arm_status arm_sqrt_q31( - q31_t in, - q31_t * pOut); - - - /** - * @brief Q15 square root function. - * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF. - * @param[out] pOut square root of input value. - * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if - * in is negative value and returns zero output for negative values. - */ - arm_status arm_sqrt_q15( - q15_t in, - q15_t * pOut); - - /** - * @} end of SQRT group - */ - - - /** - * @brief floating-point Circular write function. - */ - CMSIS_INLINE __STATIC_INLINE void arm_circularWrite_f32( - int32_t * circBuffer, - int32_t L, - uint16_t * writeOffset, - int32_t bufferInc, - const int32_t * src, - int32_t srcInc, - uint32_t blockSize) - { - uint32_t i = 0u; - int32_t wOffset; - - /* Copy the value of Index pointer that points - * to the current location where the input samples to be copied */ - wOffset = *writeOffset; - - /* Loop over the blockSize */ - i = blockSize; - - while (i > 0u) - { - /* copy the input sample to the circular buffer */ - circBuffer[wOffset] = *src; - - /* Update the input pointer */ - src += srcInc; - - /* Circularly update wOffset. Watch out for positive and negative value */ - wOffset += bufferInc; - if (wOffset >= L) - wOffset -= L; - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *writeOffset = (uint16_t)wOffset; - } - - - - /** - * @brief floating-point Circular Read function. - */ - CMSIS_INLINE __STATIC_INLINE void arm_circularRead_f32( - int32_t * circBuffer, - int32_t L, - int32_t * readOffset, - int32_t bufferInc, - int32_t * dst, - int32_t * dst_base, - int32_t dst_length, - int32_t dstInc, - uint32_t blockSize) - { - uint32_t i = 0u; - int32_t rOffset, dst_end; - - /* Copy the value of Index pointer that points - * to the current location from where the input samples to be read */ - rOffset = *readOffset; - dst_end = (int32_t) (dst_base + dst_length); - - /* Loop over the blockSize */ - i = blockSize; - - while (i > 0u) - { - /* copy the sample from the circular buffer to the destination buffer */ - *dst = circBuffer[rOffset]; - - /* Update the input pointer */ - dst += dstInc; - - if (dst == (int32_t *) dst_end) - { - dst = dst_base; - } - - /* Circularly update rOffset. Watch out for positive and negative value */ - rOffset += bufferInc; - - if (rOffset >= L) - { - rOffset -= L; - } - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *readOffset = rOffset; - } - - - /** - * @brief Q15 Circular write function. - */ - CMSIS_INLINE __STATIC_INLINE void arm_circularWrite_q15( - q15_t * circBuffer, - int32_t L, - uint16_t * writeOffset, - int32_t bufferInc, - const q15_t * src, - int32_t srcInc, - uint32_t blockSize) - { - uint32_t i = 0u; - int32_t wOffset; - - /* Copy the value of Index pointer that points - * to the current location where the input samples to be copied */ - wOffset = *writeOffset; - - /* Loop over the blockSize */ - i = blockSize; - - while (i > 0u) - { - /* copy the input sample to the circular buffer */ - circBuffer[wOffset] = *src; - - /* Update the input pointer */ - src += srcInc; - - /* Circularly update wOffset. Watch out for positive and negative value */ - wOffset += bufferInc; - if (wOffset >= L) - wOffset -= L; - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *writeOffset = (uint16_t)wOffset; - } - - - /** - * @brief Q15 Circular Read function. - */ - CMSIS_INLINE __STATIC_INLINE void arm_circularRead_q15( - q15_t * circBuffer, - int32_t L, - int32_t * readOffset, - int32_t bufferInc, - q15_t * dst, - q15_t * dst_base, - int32_t dst_length, - int32_t dstInc, - uint32_t blockSize) - { - uint32_t i = 0; - int32_t rOffset, dst_end; - - /* Copy the value of Index pointer that points - * to the current location from where the input samples to be read */ - rOffset = *readOffset; - - dst_end = (int32_t) (dst_base + dst_length); - - /* Loop over the blockSize */ - i = blockSize; - - while (i > 0u) - { - /* copy the sample from the circular buffer to the destination buffer */ - *dst = circBuffer[rOffset]; - - /* Update the input pointer */ - dst += dstInc; - - if (dst == (q15_t *) dst_end) - { - dst = dst_base; - } - - /* Circularly update wOffset. Watch out for positive and negative value */ - rOffset += bufferInc; - - if (rOffset >= L) - { - rOffset -= L; - } - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *readOffset = rOffset; - } - - - /** - * @brief Q7 Circular write function. - */ - CMSIS_INLINE __STATIC_INLINE void arm_circularWrite_q7( - q7_t * circBuffer, - int32_t L, - uint16_t * writeOffset, - int32_t bufferInc, - const q7_t * src, - int32_t srcInc, - uint32_t blockSize) - { - uint32_t i = 0u; - int32_t wOffset; - - /* Copy the value of Index pointer that points - * to the current location where the input samples to be copied */ - wOffset = *writeOffset; - - /* Loop over the blockSize */ - i = blockSize; - - while (i > 0u) - { - /* copy the input sample to the circular buffer */ - circBuffer[wOffset] = *src; - - /* Update the input pointer */ - src += srcInc; - - /* Circularly update wOffset. Watch out for positive and negative value */ - wOffset += bufferInc; - if (wOffset >= L) - wOffset -= L; - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *writeOffset = (uint16_t)wOffset; - } - - - /** - * @brief Q7 Circular Read function. - */ - CMSIS_INLINE __STATIC_INLINE void arm_circularRead_q7( - q7_t * circBuffer, - int32_t L, - int32_t * readOffset, - int32_t bufferInc, - q7_t * dst, - q7_t * dst_base, - int32_t dst_length, - int32_t dstInc, - uint32_t blockSize) - { - uint32_t i = 0; - int32_t rOffset, dst_end; - - /* Copy the value of Index pointer that points - * to the current location from where the input samples to be read */ - rOffset = *readOffset; - - dst_end = (int32_t) (dst_base + dst_length); - - /* Loop over the blockSize */ - i = blockSize; - - while (i > 0u) - { - /* copy the sample from the circular buffer to the destination buffer */ - *dst = circBuffer[rOffset]; - - /* Update the input pointer */ - dst += dstInc; - - if (dst == (q7_t *) dst_end) - { - dst = dst_base; - } - - /* Circularly update rOffset. Watch out for positive and negative value */ - rOffset += bufferInc; - - if (rOffset >= L) - { - rOffset -= L; - } - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *readOffset = rOffset; - } - - - /** - * @brief Sum of the squares of the elements of a Q31 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_power_q31( - q31_t * pSrc, - uint32_t blockSize, - q63_t * pResult); - - - /** - * @brief Sum of the squares of the elements of a floating-point vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_power_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - - /** - * @brief Sum of the squares of the elements of a Q15 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_power_q15( - q15_t * pSrc, - uint32_t blockSize, - q63_t * pResult); - - - /** - * @brief Sum of the squares of the elements of a Q7 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_power_q7( - q7_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - - /** - * @brief Mean value of a Q7 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_mean_q7( - q7_t * pSrc, - uint32_t blockSize, - q7_t * pResult); - - - /** - * @brief Mean value of a Q15 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_mean_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult); - - - /** - * @brief Mean value of a Q31 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_mean_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - - /** - * @brief Mean value of a floating-point vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_mean_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - - /** - * @brief Variance of the elements of a floating-point vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_var_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - - /** - * @brief Variance of the elements of a Q31 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_var_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - - /** - * @brief Variance of the elements of a Q15 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_var_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult); - - - /** - * @brief Root Mean Square of the elements of a floating-point vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_rms_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - - /** - * @brief Root Mean Square of the elements of a Q31 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_rms_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - - /** - * @brief Root Mean Square of the elements of a Q15 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_rms_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult); - - - /** - * @brief Standard deviation of the elements of a floating-point vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_std_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - - /** - * @brief Standard deviation of the elements of a Q31 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_std_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - - /** - * @brief Standard deviation of the elements of a Q15 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_std_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult); - - - /** - * @brief Floating-point complex magnitude - * @param[in] pSrc points to the complex input vector - * @param[out] pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - */ - void arm_cmplx_mag_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t numSamples); - - - /** - * @brief Q31 complex magnitude - * @param[in] pSrc points to the complex input vector - * @param[out] pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - */ - void arm_cmplx_mag_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t numSamples); - - - /** - * @brief Q15 complex magnitude - * @param[in] pSrc points to the complex input vector - * @param[out] pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - */ - void arm_cmplx_mag_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t numSamples); - - - /** - * @brief Q15 complex dot product - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[in] numSamples number of complex samples in each vector - * @param[out] realResult real part of the result returned here - * @param[out] imagResult imaginary part of the result returned here - */ - void arm_cmplx_dot_prod_q15( - q15_t * pSrcA, - q15_t * pSrcB, - uint32_t numSamples, - q31_t * realResult, - q31_t * imagResult); - - - /** - * @brief Q31 complex dot product - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[in] numSamples number of complex samples in each vector - * @param[out] realResult real part of the result returned here - * @param[out] imagResult imaginary part of the result returned here - */ - void arm_cmplx_dot_prod_q31( - q31_t * pSrcA, - q31_t * pSrcB, - uint32_t numSamples, - q63_t * realResult, - q63_t * imagResult); - - - /** - * @brief Floating-point complex dot product - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[in] numSamples number of complex samples in each vector - * @param[out] realResult real part of the result returned here - * @param[out] imagResult imaginary part of the result returned here - */ - void arm_cmplx_dot_prod_f32( - float32_t * pSrcA, - float32_t * pSrcB, - uint32_t numSamples, - float32_t * realResult, - float32_t * imagResult); - - - /** - * @brief Q15 complex-by-real multiplication - * @param[in] pSrcCmplx points to the complex input vector - * @param[in] pSrcReal points to the real input vector - * @param[out] pCmplxDst points to the complex output vector - * @param[in] numSamples number of samples in each vector - */ - void arm_cmplx_mult_real_q15( - q15_t * pSrcCmplx, - q15_t * pSrcReal, - q15_t * pCmplxDst, - uint32_t numSamples); - - - /** - * @brief Q31 complex-by-real multiplication - * @param[in] pSrcCmplx points to the complex input vector - * @param[in] pSrcReal points to the real input vector - * @param[out] pCmplxDst points to the complex output vector - * @param[in] numSamples number of samples in each vector - */ - void arm_cmplx_mult_real_q31( - q31_t * pSrcCmplx, - q31_t * pSrcReal, - q31_t * pCmplxDst, - uint32_t numSamples); - - - /** - * @brief Floating-point complex-by-real multiplication - * @param[in] pSrcCmplx points to the complex input vector - * @param[in] pSrcReal points to the real input vector - * @param[out] pCmplxDst points to the complex output vector - * @param[in] numSamples number of samples in each vector - */ - void arm_cmplx_mult_real_f32( - float32_t * pSrcCmplx, - float32_t * pSrcReal, - float32_t * pCmplxDst, - uint32_t numSamples); - - - /** - * @brief Minimum value of a Q7 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] result is output pointer - * @param[in] index is the array index of the minimum value in the input buffer. - */ - void arm_min_q7( - q7_t * pSrc, - uint32_t blockSize, - q7_t * result, - uint32_t * index); - - - /** - * @brief Minimum value of a Q15 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output pointer - * @param[in] pIndex is the array index of the minimum value in the input buffer. - */ - void arm_min_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult, - uint32_t * pIndex); - - - /** - * @brief Minimum value of a Q31 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output pointer - * @param[out] pIndex is the array index of the minimum value in the input buffer. - */ - void arm_min_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult, - uint32_t * pIndex); - - - /** - * @brief Minimum value of a floating-point vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output pointer - * @param[out] pIndex is the array index of the minimum value in the input buffer. - */ - void arm_min_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult, - uint32_t * pIndex); - - -/** - * @brief Maximum value of a Q7 vector. - * @param[in] pSrc points to the input buffer - * @param[in] blockSize length of the input vector - * @param[out] pResult maximum value returned here - * @param[out] pIndex index of maximum value returned here - */ - void arm_max_q7( - q7_t * pSrc, - uint32_t blockSize, - q7_t * pResult, - uint32_t * pIndex); - - -/** - * @brief Maximum value of a Q15 vector. - * @param[in] pSrc points to the input buffer - * @param[in] blockSize length of the input vector - * @param[out] pResult maximum value returned here - * @param[out] pIndex index of maximum value returned here - */ - void arm_max_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult, - uint32_t * pIndex); - - -/** - * @brief Maximum value of a Q31 vector. - * @param[in] pSrc points to the input buffer - * @param[in] blockSize length of the input vector - * @param[out] pResult maximum value returned here - * @param[out] pIndex index of maximum value returned here - */ - void arm_max_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult, - uint32_t * pIndex); - - -/** - * @brief Maximum value of a floating-point vector. - * @param[in] pSrc points to the input buffer - * @param[in] blockSize length of the input vector - * @param[out] pResult maximum value returned here - * @param[out] pIndex index of maximum value returned here - */ - void arm_max_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult, - uint32_t * pIndex); - - - /** - * @brief Q15 complex-by-complex multiplication - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - */ - void arm_cmplx_mult_cmplx_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t numSamples); - - - /** - * @brief Q31 complex-by-complex multiplication - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - */ - void arm_cmplx_mult_cmplx_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t numSamples); - - - /** - * @brief Floating-point complex-by-complex multiplication - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - */ - void arm_cmplx_mult_cmplx_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t numSamples); - - - /** - * @brief Converts the elements of the floating-point vector to Q31 vector. - * @param[in] pSrc points to the floating-point input vector - * @param[out] pDst points to the Q31 output vector - * @param[in] blockSize length of the input vector - */ - void arm_float_to_q31( - float32_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the floating-point vector to Q15 vector. - * @param[in] pSrc points to the floating-point input vector - * @param[out] pDst points to the Q15 output vector - * @param[in] blockSize length of the input vector - */ - void arm_float_to_q15( - float32_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the floating-point vector to Q7 vector. - * @param[in] pSrc points to the floating-point input vector - * @param[out] pDst points to the Q7 output vector - * @param[in] blockSize length of the input vector - */ - void arm_float_to_q7( - float32_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the Q31 vector to Q15 vector. - * @param[in] pSrc is input pointer - * @param[out] pDst is output pointer - * @param[in] blockSize is the number of samples to process - */ - void arm_q31_to_q15( - q31_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the Q31 vector to Q7 vector. - * @param[in] pSrc is input pointer - * @param[out] pDst is output pointer - * @param[in] blockSize is the number of samples to process - */ - void arm_q31_to_q7( - q31_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the Q15 vector to floating-point vector. - * @param[in] pSrc is input pointer - * @param[out] pDst is output pointer - * @param[in] blockSize is the number of samples to process - */ - void arm_q15_to_float( - q15_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the Q15 vector to Q31 vector. - * @param[in] pSrc is input pointer - * @param[out] pDst is output pointer - * @param[in] blockSize is the number of samples to process - */ - void arm_q15_to_q31( - q15_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the Q15 vector to Q7 vector. - * @param[in] pSrc is input pointer - * @param[out] pDst is output pointer - * @param[in] blockSize is the number of samples to process - */ - void arm_q15_to_q7( - q15_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @ingroup groupInterpolation - */ - - /** - * @defgroup BilinearInterpolate Bilinear Interpolation - * - * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. - * The underlying function f(x, y) is sampled on a regular grid and the interpolation process - * determines values between the grid points. - * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. - * Bilinear interpolation is often used in image processing to rescale images. - * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. - * - * Algorithm - * \par - * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. - * For floating-point, the instance structure is defined as: - *
-   *   typedef struct
-   *   {
-   *     uint16_t numRows;
-   *     uint16_t numCols;
-   *     float32_t *pData;
-   * } arm_bilinear_interp_instance_f32;
-   * 
- * - * \par - * where numRows specifies the number of rows in the table; - * numCols specifies the number of columns in the table; - * and pData points to an array of size numRows*numCols values. - * The data table pTable is organized in row order and the supplied data values fall on integer indexes. - * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. - * - * \par - * Let (x, y) specify the desired interpolation point. Then define: - *
-   *     XF = floor(x)
-   *     YF = floor(y)
-   * 
- * \par - * The interpolated output point is computed as: - *
-   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
-   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
-   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
-   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
-   * 
- * Note that the coordinates (x, y) contain integer and fractional components. - * The integer components specify which portion of the table to use while the - * fractional components control the interpolation processor. - * - * \par - * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. - */ - - /** - * @addtogroup BilinearInterpolate - * @{ - */ - - - /** - * - * @brief Floating-point bilinear interpolation. - * @param[in,out] S points to an instance of the interpolation structure. - * @param[in] X interpolation coordinate. - * @param[in] Y interpolation coordinate. - * @return out interpolated value. - */ - CMSIS_INLINE __STATIC_INLINE float32_t arm_bilinear_interp_f32( - const arm_bilinear_interp_instance_f32 * S, - float32_t X, - float32_t Y) - { - float32_t out; - float32_t f00, f01, f10, f11; - float32_t *pData = S->pData; - int32_t xIndex, yIndex, index; - float32_t xdiff, ydiff; - float32_t b1, b2, b3, b4; - - xIndex = (int32_t) X; - yIndex = (int32_t) Y; - - /* Care taken for table outside boundary */ - /* Returns zero output when values are outside table boundary */ - if (xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1)) - { - return (0); - } - - /* Calculation of index for two nearest points in X-direction */ - index = (xIndex - 1) + (yIndex - 1) * S->numCols; - - - /* Read two nearest points in X-direction */ - f00 = pData[index]; - f01 = pData[index + 1]; - - /* Calculation of index for two nearest points in Y-direction */ - index = (xIndex - 1) + (yIndex) * S->numCols; - - - /* Read two nearest points in Y-direction */ - f10 = pData[index]; - f11 = pData[index + 1]; - - /* Calculation of intermediate values */ - b1 = f00; - b2 = f01 - f00; - b3 = f10 - f00; - b4 = f00 - f01 - f10 + f11; - - /* Calculation of fractional part in X */ - xdiff = X - xIndex; - - /* Calculation of fractional part in Y */ - ydiff = Y - yIndex; - - /* Calculation of bi-linear interpolated output */ - out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; - - /* return to application */ - return (out); - } - - - /** - * - * @brief Q31 bilinear interpolation. - * @param[in,out] S points to an instance of the interpolation structure. - * @param[in] X interpolation coordinate in 12.20 format. - * @param[in] Y interpolation coordinate in 12.20 format. - * @return out interpolated value. - */ - CMSIS_INLINE __STATIC_INLINE q31_t arm_bilinear_interp_q31( - arm_bilinear_interp_instance_q31 * S, - q31_t X, - q31_t Y) - { - q31_t out; /* Temporary output */ - q31_t acc = 0; /* output */ - q31_t xfract, yfract; /* X, Y fractional parts */ - q31_t x1, x2, y1, y2; /* Nearest output values */ - int32_t rI, cI; /* Row and column indices */ - q31_t *pYData = S->pData; /* pointer to output table values */ - uint32_t nCols = S->numCols; /* num of rows */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - rI = ((X & (q31_t)0xFFF00000) >> 20); - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - cI = ((Y & (q31_t)0xFFF00000) >> 20); - - /* Care taken for table outside boundary */ - /* Returns zero output when values are outside table boundary */ - if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) - { - return (0); - } - - /* 20 bits for the fractional part */ - /* shift left xfract by 11 to keep 1.31 format */ - xfract = (X & 0x000FFFFF) << 11u; - - /* Read two nearest output values from the index */ - x1 = pYData[(rI) + (int32_t)nCols * (cI) ]; - x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1]; - - /* 20 bits for the fractional part */ - /* shift left yfract by 11 to keep 1.31 format */ - yfract = (Y & 0x000FFFFF) << 11u; - - /* Read two nearest output values from the index */ - y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ]; - y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1]; - - /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ - out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); - acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); - - /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ - out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); - acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); - - /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ - out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); - acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); - - /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ - out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); - acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); - - /* Convert acc to 1.31(q31) format */ - return ((q31_t)(acc << 2)); - } - - - /** - * @brief Q15 bilinear interpolation. - * @param[in,out] S points to an instance of the interpolation structure. - * @param[in] X interpolation coordinate in 12.20 format. - * @param[in] Y interpolation coordinate in 12.20 format. - * @return out interpolated value. - */ - CMSIS_INLINE __STATIC_INLINE q15_t arm_bilinear_interp_q15( - arm_bilinear_interp_instance_q15 * S, - q31_t X, - q31_t Y) - { - q63_t acc = 0; /* output */ - q31_t out; /* Temporary output */ - q15_t x1, x2, y1, y2; /* Nearest output values */ - q31_t xfract, yfract; /* X, Y fractional parts */ - int32_t rI, cI; /* Row and column indices */ - q15_t *pYData = S->pData; /* pointer to output table values */ - uint32_t nCols = S->numCols; /* num of rows */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - rI = ((X & (q31_t)0xFFF00000) >> 20); - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - cI = ((Y & (q31_t)0xFFF00000) >> 20); - - /* Care taken for table outside boundary */ - /* Returns zero output when values are outside table boundary */ - if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) - { - return (0); - } - - /* 20 bits for the fractional part */ - /* xfract should be in 12.20 format */ - xfract = (X & 0x000FFFFF); - - /* Read two nearest output values from the index */ - x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; - x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; - - /* 20 bits for the fractional part */ - /* yfract should be in 12.20 format */ - yfract = (Y & 0x000FFFFF); - - /* Read two nearest output values from the index */ - y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; - y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; - - /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ - - /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ - /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ - out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u); - acc = ((q63_t) out * (0xFFFFF - yfract)); - - /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ - out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u); - acc += ((q63_t) out * (xfract)); - - /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ - out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u); - acc += ((q63_t) out * (yfract)); - - /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ - out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u); - acc += ((q63_t) out * (yfract)); - - /* acc is in 13.51 format and down shift acc by 36 times */ - /* Convert out to 1.15 format */ - return ((q15_t)(acc >> 36)); - } - - - /** - * @brief Q7 bilinear interpolation. - * @param[in,out] S points to an instance of the interpolation structure. - * @param[in] X interpolation coordinate in 12.20 format. - * @param[in] Y interpolation coordinate in 12.20 format. - * @return out interpolated value. - */ - CMSIS_INLINE __STATIC_INLINE q7_t arm_bilinear_interp_q7( - arm_bilinear_interp_instance_q7 * S, - q31_t X, - q31_t Y) - { - q63_t acc = 0; /* output */ - q31_t out; /* Temporary output */ - q31_t xfract, yfract; /* X, Y fractional parts */ - q7_t x1, x2, y1, y2; /* Nearest output values */ - int32_t rI, cI; /* Row and column indices */ - q7_t *pYData = S->pData; /* pointer to output table values */ - uint32_t nCols = S->numCols; /* num of rows */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - rI = ((X & (q31_t)0xFFF00000) >> 20); - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - cI = ((Y & (q31_t)0xFFF00000) >> 20); - - /* Care taken for table outside boundary */ - /* Returns zero output when values are outside table boundary */ - if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) - { - return (0); - } - - /* 20 bits for the fractional part */ - /* xfract should be in 12.20 format */ - xfract = (X & (q31_t)0x000FFFFF); - - /* Read two nearest output values from the index */ - x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; - x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; - - /* 20 bits for the fractional part */ - /* yfract should be in 12.20 format */ - yfract = (Y & (q31_t)0x000FFFFF); - - /* Read two nearest output values from the index */ - y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; - y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; - - /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ - out = ((x1 * (0xFFFFF - xfract))); - acc = (((q63_t) out * (0xFFFFF - yfract))); - - /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ - out = ((x2 * (0xFFFFF - yfract))); - acc += (((q63_t) out * (xfract))); - - /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ - out = ((y1 * (0xFFFFF - xfract))); - acc += (((q63_t) out * (yfract))); - - /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ - out = ((y2 * (yfract))); - acc += (((q63_t) out * (xfract))); - - /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ - return ((q7_t)(acc >> 40)); - } - - /** - * @} end of BilinearInterpolate group - */ - - -/* SMMLAR */ -#define multAcc_32x32_keep32_R(a, x, y) \ - a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) - -/* SMMLSR */ -#define multSub_32x32_keep32_R(a, x, y) \ - a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) - -/* SMMULR */ -#define mult_32x32_keep32_R(a, x, y) \ - a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) - -/* SMMLA */ -#define multAcc_32x32_keep32(a, x, y) \ - a += (q31_t) (((q63_t) x * y) >> 32) - -/* SMMLS */ -#define multSub_32x32_keep32(a, x, y) \ - a -= (q31_t) (((q63_t) x * y) >> 32) - -/* SMMUL */ -#define mult_32x32_keep32(a, x, y) \ - a = (q31_t) (((q63_t) x * y ) >> 32) - - -#if defined ( __CC_ARM ) - /* Enter low optimization region - place directly above function definition */ - #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) - #define LOW_OPTIMIZATION_ENTER \ - _Pragma ("push") \ - _Pragma ("O1") - #else - #define LOW_OPTIMIZATION_ENTER - #endif - - /* Exit low optimization region - place directly after end of function definition */ - #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) - #define LOW_OPTIMIZATION_EXIT \ - _Pragma ("pop") - #else - #define LOW_OPTIMIZATION_EXIT - #endif - - /* Enter low optimization region - place directly above function definition */ - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - - /* Exit low optimization region - place directly after end of function definition */ - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined (__ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) - #define LOW_OPTIMIZATION_ENTER - #define LOW_OPTIMIZATION_EXIT - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined ( __GNUC__ ) - #define LOW_OPTIMIZATION_ENTER \ - __attribute__(( optimize("-O1") )) - #define LOW_OPTIMIZATION_EXIT - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined ( __ICCARM__ ) - /* Enter low optimization region - place directly above function definition */ - #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) - #define LOW_OPTIMIZATION_ENTER \ - _Pragma ("optimize=low") - #else - #define LOW_OPTIMIZATION_ENTER - #endif - - /* Exit low optimization region - place directly after end of function definition */ - #define LOW_OPTIMIZATION_EXIT - - /* Enter low optimization region - place directly above function definition */ - #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ - _Pragma ("optimize=low") - #else - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - #endif - - /* Exit low optimization region - place directly after end of function definition */ - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined ( __TI_ARM__ ) - #define LOW_OPTIMIZATION_ENTER - #define LOW_OPTIMIZATION_EXIT - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined ( __CSMC__ ) - #define LOW_OPTIMIZATION_ENTER - #define LOW_OPTIMIZATION_EXIT - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined ( __TASKING__ ) - #define LOW_OPTIMIZATION_ENTER - #define LOW_OPTIMIZATION_EXIT - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#endif - - -#ifdef __cplusplus -} -#endif - -/* Compiler specific diagnostic adjustment */ -#if defined ( __CC_ARM ) - -#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) - -#elif defined ( __GNUC__ ) -#pragma GCC diagnostic pop - -#elif defined ( __ICCARM__ ) - -#elif defined ( __TI_ARM__ ) - -#elif defined ( __CSMC__ ) - -#elif defined ( __TASKING__ ) - -#else - #error Unknown compiler -#endif - -#endif /* _ARM_MATH_H */ - -/** - * - * End of file. - */ diff --git a/cmsis/core_cmSecureAccess.h b/cmsis/core_cmSecureAccess.h deleted file mode 100644 index 4903efdff68..00000000000 --- a/cmsis/core_cmSecureAccess.h +++ /dev/null @@ -1,201 +0,0 @@ -/**************************************************************************//** - * @file core_cmSecureAccess.h - * @brief CMSIS Cortex-M Core Secure Access Header File - * @version XXX - * @date 10. June 2016 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2016 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#ifndef __CORE_CM_SECURE_ACCESS_H -#define __CORE_CM_SECURE_ACCESS_H - - -/* ########################### Core Secure Access ########################### */ - -#ifdef FEATURE_UVISOR -#include "uvisor-lib/uvisor-lib.h" - -/* Secure uVisor implementation. */ - -/** Set the value at the target address. - * - * Equivalent to: `*address = value`. - * @param address[in] Target address - * @param value[in] Value to write at the address location. - */ -#define SECURE_WRITE(address, value) \ - uvisor_write(public_box, UVISOR_RGW_SHARED, address, value, UVISOR_RGW_OP_WRITE, 0xFFFFFFFFUL) - -/** Get the value at the target address. - * - * @param address[in] Target address - * @returns The value `*address`. - */ -#define SECURE_READ(address) \ - uvisor_read(public_box, UVISOR_RGW_SHARED, address, UVISOR_RGW_OP_READ, 0xFFFFFFFFUL) - -/** Get the selected bits at the target address. - * - * @param address[in] Target address - * @param mask[in] Bits to select out of the target address - * @returns The value `*address & mask`. - */ -#define SECURE_BITS_GET(address, mask) \ - UVISOR_BITS_GET(public_box, UVISOR_RGW_SHARED, address, mask) - -/** Check the selected bits at the target address. - * - * @param address[in] Address at which to check the bits - * @param mask[in] Bits to select out of the target address - * @returns The value `((*address & mask) == mask)`. - */ -#define SECURE_BITS_CHECK(address, mask) \ - UVISOR_BITS_CHECK(public_box, UVISOR_RGW_SHARED, address, mask) - -/** Set the selected bits to 1 at the target address. - * - * Equivalent to: `*address |= mask`. - * @param address[in] Target address - * @param mask[in] Bits to select out of the target address - */ -#define SECURE_BITS_SET(address, mask) \ - UVISOR_BITS_SET(public_box, UVISOR_RGW_SHARED, address, mask) - -/** Clear the selected bits at the target address. - * - * Equivalent to: `*address &= ~mask`. - * @param address[in] Target address - * @param mask[in] Bits to select out of the target address - */ -#define SECURE_BITS_CLEAR(address, mask) \ - UVISOR_BITS_CLEAR(public_box, UVISOR_RGW_SHARED, address, mask) - -/** Set the selected bits at the target address to the given value. - * - * Equivalent to: `*address = (*address & ~mask) | (value & mask)`. - * @param address[in] Target address - * @param mask[in] Bits to select out of the target address - * @param value[in] Value to write at the address location. Note: The value - * must be already shifted to the correct bit position - */ -#define SECURE_BITS_SET_VALUE(address, mask, value) \ - UVISOR_BITS_SET_VALUE(public_box, UVISOR_RGW_SHARED, address, mask, value) - -/** Toggle the selected bits at the target address. - * - * Equivalent to: `*address ^= mask`. - * @param address[in] Target address - * @param mask[in] Bits to select out of the target address - */ -#define SECURE_BITS_TOGGLE(address, mask) \ - UVISOR_BITS_TOGGLE(public_box, UVISOR_RGW_SHARED, address, mask) - -#else - -/* Insecure fallback implementation. */ - -/** Set the value at the target address. - * - * Equivalent to: `*address = value`. - * @param address[in] Target address - * @param value[in] Value to write at the address location. - */ -#define SECURE_WRITE(address, value) \ - *(address) = (value) - -/** Get the value at the target address. - * - * @param address[in] Target address - * @returns The value `*address`. - */ -#define SECURE_READ(address) \ - (*(address)) - -/** Get the selected bits at the target address. - * - * @param address[in] Target address - * @param mask[in] Bits to select out of the target address - * @returns The value `*address & mask`. - */ -#define SECURE_BITS_GET(address, mask) \ - (*(address) & (mask)) - -/** Check the selected bits at the target address. - * - * @param address[in] Address at which to check the bits - * @param mask[in] Bits to select out of the target address - * @returns The value `((*address & mask) == mask)`. - */ -#define SECURE_BITS_CHECK(address, mask) \ - ((*(address) & (mask)) == (mask)) - -/** Set the selected bits to 1 at the target address. - * - * Equivalent to: `*address |= mask`. - * @param address[in] Target address - * @param mask[in] Bits to select out of the target address - */ -#define SECURE_BITS_SET(address, mask) \ - *(address) |= (mask) - -/** Clear the selected bits at the target address. - * - * Equivalent to: `*address &= ~mask`. - * @param address[in] Target address - * @param mask[in] Bits to select out of the target address - */ -#define SECURE_BITS_CLEAR(address, mask) \ - *(address) &= ~(mask) - -/** Set the selected bits at the target address to the given value. - * - * Equivalent to: `*address = (*address & ~mask) | (value & mask)`. - * @param address[in] Target address - * @param mask[in] Bits to select out of the target address - * @param value[in] Value to write at the address location. Note: The value - * must be already shifted to the correct bit position - */ -#define SECURE_BITS_SET_VALUE(address, mask, value) \ - *(address) = (*(address) & ~(mask)) | ((value) & (mask)) - -/** Toggle the selected bits at the target address. - * - * Equivalent to: `*address ^= mask`. - * @param address[in] Target address - * @param mask[in] Bits to select out of the target address - */ -#define SECURE_BITS_TOGGLE(address, mask) \ - *(address) ^= (mask) - -#endif - -#endif /* __CORE_CM_SECURE_ACCESS_H */ diff --git a/rtos/TARGET_CORTEX/rtx4/cmsis_os.h b/rtos/TARGET_CORTEX/rtx4/cmsis_os.h index 4f7ba115df9..a5601622f09 100644 --- a/rtos/TARGET_CORTEX/rtx4/cmsis_os.h +++ b/rtos/TARGET_CORTEX/rtx4/cmsis_os.h @@ -17,8 +17,8 @@ * * ---------------------------------------------------------------------- * - * $Date: 10. January 2017 - * $Revision: V2.1.0 + * $Date: 9. June 2017 + * $Revision: V2.1.1 * * Project: CMSIS-RTOS API * Title: cmsis_os.h RTX header file @@ -118,6 +118,11 @@ * - added: osKernelRestoreLock * Updated Thread and Event Flags: * - changed flags parameter and return type from int32_t to uint32_t + * Version 2.1.1 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osKernelGetTickCount, osKernelGetTickFreq + * Changed Kernel Tick type to uint32_t: + * - updated: osKernelGetTickCount, osDelayUntil *---------------------------------------------------------------------------*/ #ifndef CMSIS_OS_H_ @@ -433,23 +438,23 @@ uint32_t osKernelSysTick (void); /// \param instances number of possible thread instances. /// \param stacksz stack size (in bytes) requirements for the thread function. #if defined (osObjectsExternal) // object is external -#define osThreadDef(name, priority, stacksz) \ +#define osThreadDef(name, priority, instances, stacksz) \ extern const osThreadDef_t os_thread_def_##name #else // define the object #if (osCMSIS < 0x20000U) -#define osThreadDef(name, priority, stacksz) \ +#define osThreadDef(name, priority, instances, stacksz) \ const osThreadDef_t os_thread_def_##name = \ -{ (name), (priority), (1), (stacksz) } +{ (name), (priority), (instances), (stacksz) } #else -#define osThreadDef(name, priority, stacksz) \ -uint64_t os_thread_stack##name[(stacksz)?(((stacksz+7)/8)):1] __attribute__((section(".bss.os.thread.stack"))); \ +#define osThreadDef(name, priority, instances, stacksz) \ +static uint64_t os_thread_stack##name[(stacksz)?(((stacksz+7)/8)):1] __attribute__((section(".bss.os.thread.stack"))); \ static osRtxThread_t os_thread_cb_##name __attribute__((section(".bss.os.thread.cb"))); \ const osThreadDef_t os_thread_def_##name = \ { (name), \ { NULL, osThreadDetached, \ - (&os_thread_cb_##name),\ - osRtxThreadCbSize, \ - (stacksz) ? (&os_thread_stack##name) : NULL, \ + (instances == 1) ? (&os_thread_cb_##name) : NULL,\ + (instances == 1) ? osRtxThreadCbSize : 0U, \ + ((stacksz) && (instances == 1)) ? (&os_thread_stack##name) : NULL, \ 8*((stacksz+7)/8), \ (priority), 0U, 0U } } #endif diff --git a/rtos/TARGET_CORTEX/rtx5/cmsis_os2.h b/rtos/TARGET_CORTEX/rtx5/Include/cmsis_os2.h similarity index 96% rename from rtos/TARGET_CORTEX/rtx5/cmsis_os2.h rename to rtos/TARGET_CORTEX/rtx5/Include/cmsis_os2.h index 6ae65137b7c..73fee84d3c4 100644 --- a/rtos/TARGET_CORTEX/rtx5/cmsis_os2.h +++ b/rtos/TARGET_CORTEX/rtx5/Include/cmsis_os2.h @@ -1,5 +1,3 @@ -/** \addtogroup rtos */ -/** @{*/ /* * Copyright (c) 2013-2017 ARM Limited. All rights reserved. * @@ -19,12 +17,17 @@ * * ---------------------------------------------------------------------- * - * $Date: 10. January 2017 - * $Revision: V2.1.0 + * $Date: 9. June 2017 + * $Revision: V2.1.1 * * Project: CMSIS-RTOS2 API * Title: cmsis_os2.h header file * + * Version 2.1.1 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osKernelGetTickCount, osKernelGetTickFreq + * Changed Kernel Tick type to uint32_t: + * - updated: osKernelGetTickCount, osDelayUntil * Version 2.1.0 * Support for critical and uncritical sections (nesting safe): * - updated: osKernelLock, osKernelUnlock @@ -151,7 +154,7 @@ typedef enum { /// Entry point of a thread. typedef void (*osThreadFunc_t) (void *argument); -/// Entry point of a timer call back function. +/// Timer callback function. typedef void (*osTimerFunc_t) (void *argument); /// Timer type. @@ -160,15 +163,15 @@ typedef enum { osTimerPeriodic = 1 ///< Repeating timer. } osTimerType_t; -/// Timeout value. +// Timeout value. #define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value. -/// Flags options (\ref osThreadFlagsWait and \ref osEventFlagsWait). +// Flags options (\ref osThreadFlagsWait and \ref osEventFlagsWait). #define osFlagsWaitAny 0x00000000U ///< Wait for any flag (default). #define osFlagsWaitAll 0x00000001U ///< Wait for all flags. #define osFlagsNoClear 0x00000002U ///< Do not clear flags which have been specified to wait for. -/// Flags errors (returned by osThreadFlagsXxxx and osEventFlagsXxxx). +// Flags errors (returned by osThreadFlagsXxxx and osEventFlagsXxxx). #define osFlagsError 0x80000000U ///< Error indicator. #define osFlagsErrorUnknown 0xFFFFFFFFU ///< osError (-1). #define osFlagsErrorTimeout 0xFFFFFFFEU ///< osErrorTimeout (-2). @@ -176,11 +179,11 @@ typedef enum { #define osFlagsErrorParameter 0xFFFFFFFCU ///< osErrorParameter (-4). #define osFlagsErrorISR 0xFFFFFFFAU ///< osErrorISR (-6). -/// Thread attributes (attr_bits in \ref osThreadAttr_t). -#define osThreadDetached 0x00000000U ///< Thread created in detached state (default) -#define osThreadJoinable 0x00000001U ///< Thread created in joinable state +// Thread attributes (attr_bits in \ref osThreadAttr_t). +#define osThreadDetached 0x00000000U ///< Thread created in detached mode (default) +#define osThreadJoinable 0x00000001U ///< Thread created in joinable mode -/// Mutex attributes (attr_bits in \ref osMutexAttr_t). +// Mutex attributes (attr_bits in \ref osMutexAttr_t). #define osMutexRecursive 0x00000001U ///< Recursive mutex. #define osMutexPrioInherit 0x00000002U ///< Priority inherit protocol. #define osMutexRobust 0x00000008U ///< Robust mutex. @@ -337,10 +340,10 @@ void osKernelResume (uint32_t sleep_ticks); /// Get the RTOS kernel tick count. /// \return RTOS kernel current tick count. -uint64_t osKernelGetTickCount (void); +uint32_t osKernelGetTickCount (void); /// Get the RTOS kernel tick frequency. -/// \return frequency of the kernel tick. +/// \return frequency of the kernel tick in hertz, i.e. kernel ticks per second. uint32_t osKernelGetTickFreq (void); /// Get the RTOS kernel system timer count. @@ -348,7 +351,7 @@ uint32_t osKernelGetTickFreq (void); uint32_t osKernelGetSysTimerCount (void); /// Get the RTOS kernel system timer frequency. -/// \return frequency of the system timer. +/// \return frequency of the system timer in hertz, i.e. timer ticks per second. uint32_t osKernelGetSysTimerFreq (void); @@ -360,7 +363,6 @@ uint32_t osKernelGetSysTimerFreq (void); /// \param[in] attr thread attributes; NULL: default values. /// \return thread ID for reference by other functions or NULL in case of error. osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); -osThreadId_t osThreadContextNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr, void *context); /// Get name of a thread. /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. @@ -475,15 +477,15 @@ osStatus_t osDelay (uint32_t ticks); /// Wait until specified time. /// \param[in] ticks absolute time in ticks /// \return status code that indicates the execution status of the function. -osStatus_t osDelayUntil (uint64_t ticks); +osStatus_t osDelayUntil (uint32_t ticks); // ==== Timer Management Functions ==== /// Create and Initialize a timer. -/// \param[in] func start address of a timer call back function. -/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. -/// \param[in] argument argument to the timer call back function. +/// \param[in] func function pointer to callback function. +/// \param[in] type \ref osTimerOnce for one-shot or \ref osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer callback function. /// \param[in] attr timer attributes; NULL: default values. /// \return timer ID for reference by other functions or NULL in case of error. osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr); @@ -612,7 +614,7 @@ const char *osSemaphoreGetName (osSemaphoreId_t semaphore_id); /// \return status code that indicates the execution status of the function. osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout); -/// Release a Semaphore token that was acquired by \ref osSemaphoreAcquire. +/// Release a Semaphore token up to the initial maximum count. /// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. /// \return status code that indicates the execution status of the function. osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id); @@ -746,5 +748,3 @@ osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id); #endif #endif // CMSIS_OS2_H_ - -/** @}*/ diff --git a/rtos/TARGET_CORTEX/rtx5/Include/os_tick.h b/rtos/TARGET_CORTEX/rtx5/Include/os_tick.h new file mode 100644 index 00000000000..391f729ca06 --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/Include/os_tick.h @@ -0,0 +1,74 @@ +/**************************************************************************//** + * @file os_tick.h + * @brief CMSIS OS Tick header file + * @version V1.0.0 + * @date 05. June 2017 + ******************************************************************************/ +/* + * Copyright (c) 2017-2017 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 + * + * 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 OS_TICK_H +#define OS_TICK_H + +#include + +/// IRQ Handler. +#ifndef IRQHANDLER_T +#define IRQHANDLER_T +typedef void (*IRQHandler_t) (void); +#endif + +/// Setup OS Tick. +/// \param[in] freq tick frequency in Hz +/// \param[in] handler tick IRQ handler +/// \return 0 on success, -1 on error. +int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler); + +/// Enable OS Tick. +/// \return 0 on success, -1 on error. +int32_t OS_Tick_Enable (void); + +/// Disable OS Tick. +/// \return 0 on success, -1 on error. +int32_t OS_Tick_Disable (void); + +/// Acknowledge OS Tick IRQ. +/// \return 0 on success, -1 on error. +int32_t OS_Tick_AcknowledgeIRQ (void); + +/// Get OS Tick IRQ number. +/// \return OS Tick IRQ number. +int32_t OS_Tick_GetIRQn (void); + +/// Get OS Tick clock. +/// \return OS Tick clock in Hz. +uint32_t OS_Tick_GetClock (void); + +/// Get OS Tick interval. +/// \return OS Tick interval. +uint32_t OS_Tick_GetInterval (void); + +/// Get OS Tick count value. +/// \return OS Tick count value. +uint32_t OS_Tick_GetCount (void); + +/// Get OS Tick overflow status. +/// \return OS Tick overflow status (1 - overflow, 0 - no overflow). +uint32_t OS_Tick_GetOverflow (void); + +#endif /* OS_TICK_H */ diff --git a/rtos/TARGET_CORTEX/rtx5/RTX_Config.c b/rtos/TARGET_CORTEX/rtx5/RTX/Config/RTX_Config.c similarity index 99% rename from rtos/TARGET_CORTEX/rtx5/RTX_Config.c rename to rtos/TARGET_CORTEX/rtx5/RTX/Config/RTX_Config.c index 6572cf0a498..69c8179dfb1 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX_Config.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Config/RTX_Config.c @@ -24,7 +24,7 @@ * * ----------------------------------------------------------------------------- */ - + #include "cmsis_compiler.h" #include "rtx_os.h" diff --git a/rtos/TARGET_CORTEX/rtx5/RTX_Config.h b/rtos/TARGET_CORTEX/rtx5/RTX/Config/RTX_Config.h similarity index 99% rename from rtos/TARGET_CORTEX/rtx5/RTX_Config.h rename to rtos/TARGET_CORTEX/rtx5/RTX/Config/RTX_Config.h index 1a0ea44b782..6cacee82488 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX_Config.h +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Config/RTX_Config.h @@ -1,5 +1,3 @@ -/** \addtogroup rtos */ -/** @{*/ /* * Copyright (c) 2013-2017 ARM Limited. All rights reserved. * @@ -29,9 +27,7 @@ #ifndef RTX_CONFIG_H_ #define RTX_CONFIG_H_ - -#include "mbed_rtx_conf.h" - + //-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- // System Configuration @@ -381,4 +377,3 @@ //------------- <<< end of configuration section >>> --------------------------- #endif // RTX_CONFIG_H_ -/** @}*/ diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Config/TARGET_CORTEX_A/handlers.c b/rtos/TARGET_CORTEX/rtx5/RTX/Config/TARGET_CORTEX_A/handlers.c new file mode 100644 index 00000000000..6afdccc8d26 --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Config/TARGET_CORTEX_A/handlers.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2013-2017 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 + * + * 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Exception handlers (C functions) + * + * ----------------------------------------------------------------------------- + */ +#include "RTE_Components.h" +#include CMSIS_device_header + + +//Fault Status Register (IFSR/DFSR) definitions +#define FSR_ALIGNMENT_FAULT 0x01 //DFSR only. Fault on first lookup +#define FSR_INSTRUCTION_CACHE_MAINTENANCE 0x04 //DFSR only - async/external +#define FSR_SYNC_EXT_TTB_WALK_FIRST 0x0c //sync/external +#define FSR_SYNC_EXT_TTB_WALK_SECOND 0x0e //sync/external +#define FSR_SYNC_PARITY_TTB_WALK_FIRST 0x1c //sync/external +#define FSR_SYNC_PARITY_TTB_WALK_SECOND 0x1e //sync/external +#define FSR_TRANSLATION_FAULT_FIRST 0x05 //MMU Fault - internal +#define FSR_TRANSLATION_FAULT_SECOND 0x07 //MMU Fault - internal +#define FSR_ACCESS_FLAG_FAULT_FIRST 0x03 //MMU Fault - internal +#define FSR_ACCESS_FLAG_FAULT_SECOND 0x06 //MMU Fault - internal +#define FSR_DOMAIN_FAULT_FIRST 0x09 //MMU Fault - internal +#define FSR_DOMAIN_FAULT_SECOND 0x0b //MMU Fault - internal +#define FSR_PERMISSION_FAULT_FIRST 0x0f //MMU Fault - internal +#define FSR_PERMISSION_FAULT_SECOND 0x0d //MMU Fault - internal +#define FSR_DEBUG_EVENT 0x02 //internal +#define FSR_SYNC_EXT_ABORT 0x08 //sync/external +#define FSR_TLB_CONFLICT_ABORT 0x10 //sync/external +#define FSR_LOCKDOWN 0x14 //internal +#define FSR_COPROCESSOR_ABORT 0x1a //internal +#define FSR_SYNC_PARITY_ERROR 0x19 //sync/external +#define FSR_ASYNC_EXTERNAL_ABORT 0x16 //DFSR only - async/external +#define FSR_ASYNC_PARITY_ERROR 0x18 //DFSR only - async/external + +void CDAbtHandler(uint32_t DFSR, uint32_t DFAR, uint32_t LR) { + uint32_t FS = (DFSR & (1 << 10)) >> 6 | (DFSR & 0x0f); //Store Fault Status + + switch(FS) { + //Synchronous parity errors - retry + case FSR_SYNC_PARITY_ERROR: + case FSR_SYNC_PARITY_TTB_WALK_FIRST: + case FSR_SYNC_PARITY_TTB_WALK_SECOND: + return; + + //Your code here. Value in DFAR is invalid for some fault statuses. + case FSR_ALIGNMENT_FAULT: + case FSR_INSTRUCTION_CACHE_MAINTENANCE: + case FSR_SYNC_EXT_TTB_WALK_FIRST: + case FSR_SYNC_EXT_TTB_WALK_SECOND: + case FSR_TRANSLATION_FAULT_FIRST: + case FSR_TRANSLATION_FAULT_SECOND: + case FSR_ACCESS_FLAG_FAULT_FIRST: + case FSR_ACCESS_FLAG_FAULT_SECOND: + case FSR_DOMAIN_FAULT_FIRST: + case FSR_DOMAIN_FAULT_SECOND: + case FSR_PERMISSION_FAULT_FIRST: + case FSR_PERMISSION_FAULT_SECOND: + case FSR_DEBUG_EVENT: + case FSR_SYNC_EXT_ABORT: + case FSR_TLB_CONFLICT_ABORT: + case FSR_LOCKDOWN: + case FSR_COPROCESSOR_ABORT: + case FSR_ASYNC_EXTERNAL_ABORT: //DFAR invalid + case FSR_ASYNC_PARITY_ERROR: //DFAR invalid + default: + while(1); + } +} + +void CPAbtHandler(uint32_t IFSR, uint32_t IFAR, uint32_t LR) { + uint32_t FS = (IFSR & (1 << 10)) >> 6 | (IFSR & 0x0f); //Store Fault Status + + switch(FS) { + //Synchronous parity errors - retry + case FSR_SYNC_PARITY_ERROR: + case FSR_SYNC_PARITY_TTB_WALK_FIRST: + case FSR_SYNC_PARITY_TTB_WALK_SECOND: + return; + + //Your code here. Value in IFAR is invalid for some fault statuses. + case FSR_SYNC_EXT_TTB_WALK_FIRST: + case FSR_SYNC_EXT_TTB_WALK_SECOND: + case FSR_TRANSLATION_FAULT_FIRST: + case FSR_TRANSLATION_FAULT_SECOND: + case FSR_ACCESS_FLAG_FAULT_FIRST: + case FSR_ACCESS_FLAG_FAULT_SECOND: + case FSR_DOMAIN_FAULT_FIRST: + case FSR_DOMAIN_FAULT_SECOND: + case FSR_PERMISSION_FAULT_FIRST: + case FSR_PERMISSION_FAULT_SECOND: + case FSR_DEBUG_EVENT: //IFAR invalid + case FSR_SYNC_EXT_ABORT: + case FSR_TLB_CONFLICT_ABORT: + case FSR_LOCKDOWN: + case FSR_COPROCESSOR_ABORT: + default: + while(1); + } +} + + +//returns amount to decrement lr by +//this will be 0 when we have emulated the instruction and want to execute the next instruction +//this will be 2 when we have performed some maintenance and want to retry the instruction in Thumb (state == 2) +//this will be 4 when we have performed some maintenance and want to retry the instruction in ARM (state == 4) +uint32_t CUndefHandler(uint32_t opcode, uint32_t state, uint32_t LR) { + const int THUMB = 2; + const int ARM = 4; + //Lazy VFP/NEON initialisation and switching + + // (ARM ARM section A7.5) VFP data processing instruction? + // (ARM ARM section A7.6) VFP/NEON register load/store instruction? + // (ARM ARM section A7.8) VFP/NEON register data transfer instruction? + // (ARM ARM section A7.9) VFP/NEON 64-bit register data transfer instruction? + if ((state == ARM && ((opcode & 0x0C000000) >> 26 == 0x03)) || + (state == THUMB && ((opcode & 0xEC000000) >> 26 == 0x3B))) { + if (((opcode & 0x00000E00) >> 9) == 5) { + __FPU_Enable(); + return state; + } + } + + // (ARM ARM section A7.4) NEON data processing instruction? + if ((state == ARM && ((opcode & 0xFE000000) >> 24 == 0xF2)) || + (state == THUMB && ((opcode & 0xEF000000) >> 24 == 0xEF)) || + // (ARM ARM section A7.7) NEON load/store instruction? + (state == ARM && ((opcode >> 24) == 0xF4)) || + (state == THUMB && ((opcode >> 24) == 0xF9))) { + __FPU_Enable(); + return state; + } + + //Add code here for other Undef cases + while(1); +} diff --git a/rtos/TARGET_CORTEX/rtx5/rtx_evr.h b/rtos/TARGET_CORTEX/rtx5/RTX/Include/rtx_evr.h similarity index 99% rename from rtos/TARGET_CORTEX/rtx5/rtx_evr.h rename to rtos/TARGET_CORTEX/rtx5/RTX/Include/rtx_evr.h index 5bc4baa89fe..897d4de63ae 100644 --- a/rtos/TARGET_CORTEX/rtx5/rtx_evr.h +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Include/rtx_evr.h @@ -1,5 +1,3 @@ -/** \addtogroup rtos */ -/** @{*/ /* * Copyright (c) 2013-2017 ARM Limited. All rights reserved. * @@ -310,7 +308,7 @@ extern void EvrRtxKernelResumed (void); \param[in] count RTOS kernel current tick count. */ #if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_TICK_COUNT_DISABLE)) -extern void EvrRtxKernelGetTickCount (uint64_t count); +extern void EvrRtxKernelGetTickCount (uint32_t count); #else #define EvrRtxKernelGetTickCount(count) #endif @@ -762,7 +760,7 @@ extern void EvrRtxThreadDelay (uint32_t ticks); \param[in] ticks absolute time in ticks */ #if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DELAY_UNTIL_DISABLE)) -extern void EvrRtxThreadDelayUntil (uint64_t ticks); +extern void EvrRtxThreadDelayUntil (uint32_t ticks); #else #define EvrRtxThreadDelayUntil(ticks) #endif @@ -1844,4 +1842,3 @@ extern void EvrRtxMessageQueueDestroyed (osMessageQueueId_t mq_id); #endif // RTX_EVR_H_ -/** @}*/ diff --git a/rtos/TARGET_CORTEX/rtx5/rtx_os.h b/rtos/TARGET_CORTEX/rtx5/RTX/Include/rtx_os.h similarity index 94% rename from rtos/TARGET_CORTEX/rtx5/rtx_os.h rename to rtos/TARGET_CORTEX/rtx5/RTX/Include/rtx_os.h index fbc243c4194..cbb3f6a3dd8 100644 --- a/rtos/TARGET_CORTEX/rtx5/rtx_os.h +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Include/rtx_os.h @@ -37,9 +37,9 @@ extern "C" /// Kernel Information -#define osRtxVersionAPI 20010000 ///< API version (2.1.0) -#define osRtxVersionKernel 50010001 ///< Kernel version (5.1.1) -#define osRtxKernelId "RTX V5.1.1" ///< Kernel identification string +#define osRtxVersionAPI 20010001 ///< API version (2.1.1) +#define osRtxVersionKernel 50020002 ///< Kernel version (5.2.2) +#define osRtxKernelId "RTX V5.2.2" ///< Kernel identification string // ==== Common definitions ==== @@ -127,7 +127,6 @@ typedef struct osRtxThread_s { uint32_t sp; ///< Current Stack Pointer uint32_t thread_addr; ///< Thread entry address uint32_t tz_memory; ///< TrustZone Memory Identifier - void *context; ///< Context for OsEventObserver objects } osRtxThread_t; @@ -283,10 +282,9 @@ typedef struct { struct { ///< Kernel Info uint8_t state; ///< State volatile uint8_t blocked; ///< Blocked - uint8_t pendISR; ///< Pending ISR (SV and SysTick) uint8_t pendSV; ///< Pending SV - uint32_t sys_freq; ///< System Frequency - uint64_t tick; ///< Tick counter + uint8_t reserved; + uint32_t tick; ///< Tick counter } kernel; int32_t tick_irqn; ///< Tick Timer IRQ Number struct { ///< Thread Info @@ -341,7 +339,6 @@ typedef struct { osRtxMpInfo_t *memory_pool; ///< Memory Pool Control Blocks osRtxMpInfo_t *message_queue; ///< Message Queue Control Blocks } mpi; - uint32_t padding; } osRtxInfo_t; extern osRtxInfo_t osRtxInfo; ///< OS Runtime Information @@ -398,30 +395,6 @@ extern void PendSV_Handler (void); extern void SysTick_Handler (void); -/// OS System Timer functions (default implementation uses SysTick) - -/// Setup System Timer. -/// \return system timer IRQ number. -extern int32_t osRtxSysTimerSetup (void); - -/// Enable System Timer. -extern void osRtxSysTimerEnable (void); - -/// Disable System Timer. -extern void osRtxSysTimerDisable (void); - -/// Acknowledge System Timer IRQ. -extern void osRtxSysTimerAckIRQ (void); - -/// Get System Timer count. -/// \return system timer count. -extern uint32_t osRtxSysTimerGetCount (void); - -/// Get System Timer frequency. -/// \return system timer frequency. -extern uint32_t osRtxSysTimerGetFreq (void); - - // ==== OS External Configuration ==== /// OS Configuration flags diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_CORTEX_A/irq_ca.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_CORTEX_A/irq_ca.s new file mode 100644 index 00000000000..7963fdefc09 --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_CORTEX_A/irq_ca.s @@ -0,0 +1,447 @@ +;/* +; * Copyright (c) 2013-2017 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 +; * +; * 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. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-A Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + +MODE_FIQ EQU 0x11 +MODE_IRQ EQU 0x12 +MODE_SVC EQU 0x13 +MODE_ABT EQU 0x17 +MODE_UND EQU 0x1B + +CPSR_BIT_T EQU 0x20 + +K_STATE_RUNNING EQU 2 ; osKernelState_t::osKernelRunning +I_K_STATE_OFS EQU 8 ; osRtxInfo.kernel.state offset +I_TICK_IRQN_OFS EQU 16 ; osRtxInfo.tick_irqn offset +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset +TCB_SP_FRAME EQU 34 ; osRtxThread_t.stack_frame offset +TCB_SP_OFS EQU 56 ; osRtxThread_t.sp offset + + + PRESERVE8 + ARM + + + AREA |.constdata|, DATA, READONLY + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + AREA |.data|, DATA, READWRITE + EXPORT IRQ_PendSV +IRQ_NestLevel DCD 0 ; IRQ nesting level counter +IRQ_PendSV DCB 0 ; Pending SVC flag +SVC_Active DCB 0 ; SVC handler execution active flag + + + AREA |.text|, CODE, READONLY + + +Undef_Handler\ + PROC + EXPORT Undef_Handler + IMPORT CUndefHandler + + SRSFD SP!, #MODE_UND + PUSH {R0-R4, R12} ; Save APCS corruptible registers to UND mode stack + + MRS R0, SPSR + TST R0, #CPSR_BIT_T ; Check mode + MOVEQ R1, #4 ; R1 = 4 ARM mode + MOVNE R1, #2 ; R1 = 2 Thumb mode + SUB R0, LR, R1 + LDREQ R0, [R0] ; ARM mode - R0 points to offending instruction + BEQ Undef_Cont + + ; Thumb instruction + ; Determine if it is a 32-bit Thumb instruction + LDRH R0, [R0] + MOV R2, #0x1C + CMP R2, R0, LSR #11 + BHS Undef_Cont ; 16-bit Thumb instruction + + ; 32-bit Thumb instruction. Unaligned - reconstruct the offending instruction + LDRH R2, [LR] + ORR R0, R2, R0, LSL #16 +Undef_Cont + MOV R2, LR ; Set LR to third argument + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR + + ; R0 =Offending instruction, R1 =2(Thumb) or =4(ARM) + BL CUndefHandler + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + LDR LR, [SP, #24] ; Restore stacked LR and possibly adjust for retry + SUB LR, LR, R0 + LDR R0, [SP, #28] ; Restore stacked SPSR + MSR SPSR_CXSF, R0 + POP {R0-R4, R12} ; Restore stacked APCS registers + ADD SP, SP, #8 ; Adjust SP for already-restored banked registers + MOVS PC, LR + + ENDP + + +PAbt_Handler\ + PROC + EXPORT PAbt_Handler + IMPORT CPAbtHandler + + SUB LR, LR, #4 ; Pre-adjust LR + SRSFD SP!, #MODE_ABT ; Save LR and SPRS to ABT mode stack + PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack + MRC p15, 0, R0, c5, c0, 1 ; IFSR + MRC p15, 0, R1, c6, c0, 2 ; IFAR + + MOV R2, LR ; Set LR to third argument + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR + + BL CPAbtHandler + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + POP {R0-R4, R12} ; Restore stack APCS registers + RFEFD SP! ; Return from exception + + ENDP + + +DAbt_Handler\ + PROC + EXPORT DAbt_Handler + IMPORT CDAbtHandler + + SUB LR, LR, #8 ; Pre-adjust LR + SRSFD SP!, #MODE_ABT ; Save LR and SPRS to ABT mode stack + PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack + CLREX ; State of exclusive monitors unknown after taken data abort + MRC p15, 0, R0, c5, c0, 0 ; DFSR + MRC p15, 0, R1, c6, c0, 0 ; DFAR + + MOV R2, LR ; Set LR to third argument + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR + + BL CDAbtHandler + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + POP {R0-R4, R12} ; Restore stacked APCS registers + RFEFD SP! ; Return from exception + + ENDP + + +IRQ_Handler\ + PROC + EXPORT IRQ_Handler + IMPORT osRtxInfo + IMPORT IRQ_GetActiveIRQ + IMPORT IRQ_GetHandler + IMPORT IRQ_EndOfInterrupt + + SUB LR, LR, #4 ; Pre-adjust LR + SRSFD SP!, #MODE_SVC ; Save LR_irq and SPRS_irq on to the SVC stack + CPS #MODE_SVC ; Change to SVC mode + PUSH {R0-R3, R12, LR} ; Save APCS corruptible registers + + MOV R3, SP ; Move SP into R3 + AND R3, R3, #4 ; Get stack adjustment to ensure 8-byte alignment + SUB SP, SP, R3 ; Adjust stack + PUSH {R3, R4} ; Store stack adjustment(R3) and user data(R4) + + BLX IRQ_GetActiveIRQ ; Retrieve interrupt ID into R0 + MOV R4, R0 ; Move interrupt ID to R4 + + LDR R1, =IRQ_NestLevel + LDR R3, [R1] ; Load IRQ nest level and increment it + ADD R3, R3, #1 + STR R3, [R1] + + BLX IRQ_GetHandler ; Retrieve interrupt handler address for current ID + CMP R0, #0 ; Check if handler address is 0 + BEQ IRQ_End ; If 0, end interrupt and return + + CPSIE i ; Re-enable interrupts + BLX R0 ; Call IRQ handler + CPSID i ; Disable interrupts + +IRQ_End + MOV R0, R4 ; Move interrupt ID to R0 + BLX IRQ_EndOfInterrupt ; Signal end of interrupt + + LDR R2, =IRQ_NestLevel + LDR R1, [R2] ; Load IRQ nest level and + SUBS R1, R1, #1 ; decrement it + STR R1, [R2] + BNE IRQ_Exit ; Not zero, exit from IRQ handler + + LDR R0, =SVC_Active + LDRB R0, [R0] ; Load SVC_Active flag + CMP R0, #0 + BNE IRQ_SwitchCheck ; Skip post processing when SVC active + + ; RTX IRQ post processing check + PUSH {R5, R6} ; Save user R5 and R6 + MOV R6, #0 + LDR R5, =IRQ_PendSV ; Load address of IRQ_PendSV flag + B IRQ_PendCheck +IRQ_PendExec + STRB R6, [R5] ; Clear PendSV flag + CPSIE i ; Re-enable interrupts + BLX osRtxPendSV_Handler ; Post process pending objects + CPSID i ; Disable interrupts +IRQ_PendCheck + LDRB R0, [R5] ; Load PendSV flag + CMP R0, #1 ; Compare PendSV value + BEQ IRQ_PendExec ; Branch to IRQ_PendExec if PendSV is set + POP {R5, R6} ; Restore user R5 and R6 + +IRQ_SwitchCheck + ; RTX IRQ context switch check + LDR R12, =osRtxInfo+I_T_RUN_OFS ; Load address of osRtxInfo.run + LDM R12, {R0, R1} ; Load osRtxInfo.thread.run: curr & next + CMP R0, R1 ; Check if context switch is required + BEQ IRQ_Exit + + POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4) + ADD SP, SP, R3 ; Unadjust stack + B osRtxContextSwitch + +IRQ_Exit + POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4) + ADD SP, SP, R3 ; Unadjust stack + + POP {R0-R3, R12, LR} ; Restore stacked APCS registers + RFEFD SP! ; Return from IRQ handler + + ENDP + + +SVC_Handler\ + PROC + EXPORT SVC_Handler + IMPORT IRQ_Disable + IMPORT IRQ_Enable + IMPORT osRtxPendSV_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + + SRSFD SP!, #MODE_SVC ; Store SPSR_svc and LR_svc onto SVC stack + PUSH {R12, LR} + + MRS R12, SPSR ; Load SPSR + TST R12, #CPSR_BIT_T ; Thumb bit set? + LDRHNE R12, [LR,#-2] ; Thumb: load halfword + BICNE R12, R12, #0xFF00 ; extract SVC number + LDREQ R12, [LR,#-4] ; ARM: load word + BICEQ R12, R12, #0xFF000000 ; extract SVC number + CMP R12, #0 ; Compare SVC number + BNE SVC_User ; Branch if User SVC + + PUSH {R0-R3} + + LDR R3, =osRtxInfo + LDR R1, [R3, #I_K_STATE_OFS] ; Load RTX5 kernel state + CMP R1, #K_STATE_RUNNING ; Check osKernelRunning + BLT SVC_FuncCall ; Continue if kernel is not running + LDR R0, [R3, #I_TICK_IRQN_OFS] ; Load OS Tick irqn + BLX IRQ_Disable ; Disable OS Tick interrupt +SVC_FuncCall + LDR R0, =SVC_Active + MOV R1, #1 + STRB R1, [R0] ; Set SVC_Active flag + POP {R0-R3} + + LDR R12, [SP] ; Reload R12 from stack + + CPSIE i ; Re-enable interrupts + BLX R12 ; Branch to SVC function + CPSID i ; Disable interrupts + + SUB SP, SP, #4 ; Adjust SP + STM SP, {SP}^ ; Store SP_usr onto stack + POP {R12} ; Pop SP_usr into R12 + SUB R12, R12, #16 ; Adjust pointer to SP_usr + LDMDB R12, {R2,R3} ; Load return values from SVC function + PUSH {R0-R3} ; Push return values to stack + + PUSH {R4, R5} ; Save R4 and R5 + MOV R5, #0 + LDR R4, =IRQ_PendSV ; Load address of IRQ_PendSV + B SVC_PendCheck +SVC_PendExec + STRB R5, [R4] ; Clear IRQ_PendSV flag + CPSIE i ; Re-enable interrupts + BLX osRtxPendSV_Handler ; Post process pending objects + CPSID i ; Disable interrupts +SVC_PendCheck + LDRB R0, [R4] ; Load IRQ_PendSV flag + CMP R0, #1 ; Compare IRQ_PendSV value + BEQ SVC_PendExec ; Branch to SVC_PendExec if IRQ_PendSV is set + POP {R4, R5} ; Restore R4 and R5 + + LDR R0, =SVC_Active + MOV R1, #0 + STRB R1, [R0] ; Clear SVC_Active flag + + LDR R12, =osRtxInfo + LDR R1, [R12, #I_K_STATE_OFS] ; Load RTX5 kernel state + CMP R1, #K_STATE_RUNNING ; Check osKernelRunning + BLT SVC_ContextCheck ; Continue if kernel is not running + LDR R0, [R12, #I_TICK_IRQN_OFS] ; Load OS Tick irqn + BLX IRQ_Enable ; Enable OS Tick interrupt +SVC_ContextCheck + ADD R12, R12, #I_T_RUN_OFS ; Load address of osRtxInfo.thread.run + LDM R12, {R0, R1} ; Load osRtxInfo.thread.run: curr & next + CMP R0, R1 ; Check if context switch is required + BEQ osRtxContextExit ; Exit if curr and next are equal + B osRtxContextSwitch ; Continue in context switcher + +SVC_User + PUSH {R4, R5} + LDR R5,=osRtxUserSVC ; Load address of SVC table + LDR R4,[R5] ; Load SVC maximum number + CMP R12,R4 ; Check SVC number range + BHI SVC_Done ; Branch if out of range + + LDR R12,[R5,R12,LSL #2] ; Load SVC Function Address + BLX R12 ; Call SVC Function + +SVC_Done + POP {R4, R5, R12, LR} + RFEFD SP! ; Return from exception + + ENDP + + +osRtxContextSwitch\ + PROC + EXPORT osRtxContextSwitch + + ; R0 = osRtxInfo.thread.run.curr + ; R1 = osRtxInfo.thread.run.next + ; R12 = &osRtxInfo.thread.run + + CMP R0, #0 ; Is osRtxInfo.thread.run.curr == 0 + ADDEQ SP, SP, #32 ; Equal, curr deleted, adjust current SP + BEQ osRtxContextRestore ; Restore context, run.curr = run.next; + +osRtxContextSave + SUB SP, SP, #4 + STM SP, {SP}^ ; Save SP_usr to current stack + POP {R3} ; Pop SP_usr into R3 + + SUB R3, R3, #64 ; Adjust user sp to end of basic frame (R4) + STMIA R3!, {R4-R11} ; Save R4-R11 to user + POP {R4-R8} ; Pop current R0-R12 into R4-R8 + STMIA R3!, {R4-R8} ; Store them to user stack + STM R3, {LR}^ ; Store LR_usr directly + ADD R3, R3, #4 ; Adjust user sp to PC + POP {R4-R6} ; Pop current LR, PC, CPSR + STMIA R3!, {R5-R6} ; Restore user PC and CPSR + + SUB R3, R3, #64 ; Adjust user sp to R4 + + ; Check if VFP state need to be saved + MRC p15, 0, R2, c1, c0, 2 ; VFP/NEON access enabled? (CPACR) + AND R2, R2, #0x00F00000 + CMP R2, #0x00F00000 + BNE osRtxContextSave1 ; Continue, no VFP + + VMRS R2, FPSCR + STMDB R3!, {R2,R12} ; Push FPSCR, maintain 8-byte alignment + IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 16 + VSTMDB R3!, {D0-D15} + LDRB R2, [R0, #TCB_SP_FRAME] ; Record in TCB that VFP/D16 state is stacked + ORR R2, R2, #2 + STRB R2, [R0, #TCB_SP_FRAME] + ENDIF + IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 + VSTMDB R3!, {D0-D15} + VSTMDB R3!, {D16-D31} + LDRB R2, [R0, #TCB_SP_FRAME] ; Record in TCB that NEON/D32 state is stacked + ORR R2, R2, #4 + STRB R2, [R0, #TCB_SP_FRAME] + ENDIF + +osRtxContextSave1 + STR R3, [R0, #TCB_SP_OFS] ; Store user sp to osRtxInfo.thread.run.curr + +osRtxContextRestore + STR R1, [R12] ; Store run.next to run.curr + LDR R3, [R1, #TCB_SP_OFS] ; Load next osRtxThread_t.sp + LDRB R2, [R1, #TCB_SP_FRAME] ; Load next osRtxThread_t.stack_frame + + ANDS R2, R2, #0x6 ; Check stack frame for VFP context + MRC p15, 0, R2, c1, c0, 2 ; Read CPACR + ANDEQ R2, R2, #0xFF0FFFFF ; Disable VFP/NEON access if incoming task does not have stacked VFP/NEON state + ORRNE R2, R2, #0x00F00000 ; Enable VFP/NEON access if incoming task does have stacked VFP/NEON state + MCR p15, 0, R2, c1, c0, 2 ; Write CPACR + BEQ osRtxContextRestore1 ; No VFP + ISB ; Only sync if we enabled VFP, otherwise we will context switch before next VFP instruction anyway + IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 + VLDMIA R3!, {D16-D31} + ENDIF + VLDMIA R3!, {D0-D15} + LDR R2, [R3] + VMSR FPSCR, R2 + ADD R3, R3, #8 + +osRtxContextRestore1 + LDMIA R3!, {R4-R11} ; Restore R4-R11 + MOV R12, R3 ; Move sp pointer to R12 + ADD R3, R3, #32 ; Adjust sp + PUSH {R3} ; Push sp onto stack + LDMIA SP, {SP}^ ; Restore SP_usr + ADD SP, SP, #4 ; Adjust SP_svc + LDMIA R12!, {R0-R3} ; Restore User R0-R3 + LDR LR, [R12, #12] ; Load SPSR into LR + MSR SPSR_CXSF, LR ; Restore SPSR + ADD R12, R12, #4 ; Adjust pointer to LR + LDM R12, {LR}^ ; Restore LR_usr directly into LR + LDR LR, [R12, #4] ; Restore LR + LDR R12, [R12, #-4] ; Restore R12 + + MOVS PC, LR ; Return from exception + +osRtxContextExit + POP {R0-R3, R12, LR} ; Restore stacked APCS registers + RFEFD SP! ; Return from exception + + ENDP + + END diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_M0/TOOLCHAIN_ARM/irq_cm0.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M0/irq_cm0.s similarity index 98% rename from rtos/TARGET_CORTEX/rtx5/TARGET_M0/TOOLCHAIN_ARM/irq_cm0.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M0/irq_cm0.s index 74c8a84a45c..8fab32aabe7 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_M0/TOOLCHAIN_ARM/irq_cm0.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M0/irq_cm0.s @@ -24,7 +24,7 @@ ; */ -I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset TCB_SP_OFS EQU 56 ; TCB.SP offset diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_M0P/TOOLCHAIN_ARM/irq_cm0.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M0P/irq_cm0.s similarity index 98% rename from rtos/TARGET_CORTEX/rtx5/TARGET_M0P/TOOLCHAIN_ARM/irq_cm0.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M0P/irq_cm0.s index 74c8a84a45c..8fab32aabe7 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_M0P/TOOLCHAIN_ARM/irq_cm0.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M0P/irq_cm0.s @@ -24,7 +24,7 @@ ; */ -I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset TCB_SP_OFS EQU 56 ; TCB.SP offset diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_M23/TOOLCHAIN_ARM/irq_armv8mbl.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl.s similarity index 94% rename from rtos/TARGET_CORTEX/rtx5/TARGET_M23/TOOLCHAIN_ARM/irq_armv8mbl.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl.s index 41e4beb713f..1586a95549d 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_M23/TOOLCHAIN_ARM/irq_armv8mbl.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl.s @@ -23,7 +23,12 @@ ; * ----------------------------------------------------------------------------- ; */ -I_T_RUN_OFS EQU 28 ; osInfo.thread.run offset + + IF :LNOT::DEF:__DOMAIN_NS +__DOMAIN_NS EQU 0 + ENDIF + +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset TCB_SM_OFS EQU 48 ; TCB.stack_mem offset TCB_SP_OFS EQU 56 ; TCB.SP offset TCB_SF_OFS EQU 34 ; TCB.stack_frame offset @@ -46,10 +51,10 @@ SVC_Handler PROC EXPORT SVC_Handler IMPORT osRtxUserSVC IMPORT osRtxInfo -#ifdef __DOMAIN_NS + IF __DOMAIN_NS = 1 IMPORT TZ_LoadContext_S IMPORT TZ_StoreContext_S -#endif + ENDIF MRS R0,PSP ; Get PSP LDR R1,[R0,#24] ; Load saved PC from stack @@ -74,7 +79,7 @@ SVC_Context CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted SVC_ContextSave -#ifdef __DOMAIN_NS + IF __DOMAIN_NS = 1 LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier CBZ R0,SVC_ContextSave1 ; Branch if there is no secure context PUSH {R1,R2,R3,R7} ; Save registers @@ -82,7 +87,7 @@ SVC_ContextSave BL TZ_StoreContext_S ; Store secure context MOV LR,R7 ; Set EXC_RETURN POP {R1,R2,R3,R7} ; Restore registers -#endif + ENDIF SVC_ContextSave1 MRS R0,PSP ; Get PSP @@ -105,13 +110,13 @@ SVC_ContextSwitch STR R2,[R3] ; osRtxInfo.thread.run: curr = next SVC_ContextRestore -#ifdef __DOMAIN_NS + IF __DOMAIN_NS = 1 LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier CBZ R0,SVC_ContextRestore1 ; Branch if there is no secure context PUSH {R2,R3} ; Save registers BL TZ_LoadContext_S ; Load secure context POP {R2,R3} ; Restore registers -#endif + ENDIF SVC_ContextRestore1 MOV R1,R2 @@ -122,16 +127,16 @@ SVC_ContextRestore1 ORRS R0,R1 MOV LR,R0 ; Set EXC_RETURN -#ifdef __DOMAIN_NS + IF __DOMAIN_NS = 1 LSLS R0,R0,#25 ; Check domain of interrupted thread BPL SVC_ContextRestore2 ; Branch if non-secure LDR R0,[R2,#TCB_SP_OFS] ; Load SP MSR PSP,R0 ; Set PSP BX LR ; Exit from handler -#else + ELSE LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base MSR PSPLIM,R0 ; Set PSPLIM -#endif + ENDIF SVC_ContextRestore2 LDR R0,[R2,#TCB_SP_OFS] ; Load SP @@ -201,10 +206,10 @@ SysTick_Handler PROC Sys_Context PROC EXPORT Sys_Context IMPORT osRtxInfo -#ifdef __DOMAIN_NS + IF __DOMAIN_NS = 1 IMPORT TZ_LoadContext_S IMPORT TZ_StoreContext_S -#endif + ENDIF LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run LDM R3!,{R1,R2} ; Load osRtxInfo.thread.run: curr & next @@ -212,7 +217,7 @@ Sys_Context PROC BEQ Sys_ContextExit ; Branch when threads are the same Sys_ContextSave -#ifdef __DOMAIN_NS + IF __DOMAIN_NS = 1 LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier CBZ R0,Sys_ContextSave1 ; Branch if there is no secure context PUSH {R1,R2,R3,R7} ; Save registers @@ -225,7 +230,7 @@ Sys_ContextSave MRS R0,PSP ; Get PSP STR R0,[R1,#TCB_SP_OFS] ; Store SP B Sys_ContextSave2 -#endif + ENDIF Sys_ContextSave1 MRS R0,PSP ; Get PSP @@ -248,13 +253,13 @@ Sys_ContextSwitch STR R2,[R3] ; osRtxInfo.run: curr = next Sys_ContextRestore -#ifdef __DOMAIN_NS + IF __DOMAIN_NS = 1 LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier CBZ R0,Sys_ContextRestore1 ; Branch if there is no secure context PUSH {R2,R3} ; Save registers BL TZ_LoadContext_S ; Load secure context POP {R2,R3} ; Restore registers -#endif + ENDIF Sys_ContextRestore1 MOV R1,R2 @@ -265,16 +270,16 @@ Sys_ContextRestore1 ORRS R0,R1 MOV LR,R0 ; Set EXC_RETURN -#ifdef __DOMAIN_NS + IF __DOMAIN_NS = 1 LSLS R0,R0,#25 ; Check domain of interrupted thread BPL Sys_ContextRestore2 ; Branch if non-secure LDR R0,[R2,#TCB_SP_OFS] ; Load SP MSR PSP,R0 ; Set PSP BX LR ; Exit from handler -#else + ELSE LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base MSR PSPLIM,R0 ; Set PSPLIM -#endif + ENDIF Sys_ContextRestore2 LDR R0,[R2,#TCB_SP_OFS] ; Load SP @@ -295,4 +300,4 @@ Sys_ContextExit ENDP - END \ No newline at end of file + END diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl_ns.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl_ns.s new file mode 100644 index 00000000000..10d31709212 --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl_ns.s @@ -0,0 +1,3 @@ +__DOMAIN_NS EQU 1 + INCLUDE irq_armv8mbl.s + END diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_M3/TOOLCHAIN_ARM/irq_cm3.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M3/irq_cm3.s similarity index 98% rename from rtos/TARGET_CORTEX/rtx5/TARGET_M3/TOOLCHAIN_ARM/irq_cm3.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M3/irq_cm3.s index b951538c826..2fd6618f03a 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_M3/TOOLCHAIN_ARM/irq_cm3.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M3/irq_cm3.s @@ -24,7 +24,7 @@ ; */ -I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset TCB_SP_OFS EQU 56 ; TCB.SP offset diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_M33/TOOLCHAIN_ARM/irq_armv8mml.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml.s similarity index 89% rename from rtos/TARGET_CORTEX/rtx5/TARGET_M33/TOOLCHAIN_ARM/irq_armv8mml.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml.s index 1adeffa5570..b8b25a1a324 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_M33/TOOLCHAIN_ARM/irq_armv8mml.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml.s @@ -24,7 +24,17 @@ ; */ -I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset + IF :LNOT::DEF:__DOMAIN_NS +__DOMAIN_NS EQU 0 + ENDIF + + IF ({FPU}="FPv5-SP") || ({FPU}="FPv5_D16") +__FPU_USED EQU 1 + ELSE +__FPU_USED EQU 0 + ENDIF + +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset TCB_SM_OFS EQU 48 ; TCB.stack_mem offset TCB_SP_OFS EQU 56 ; TCB.SP offset TCB_SF_OFS EQU 34 ; TCB.stack_frame offset @@ -47,10 +57,10 @@ SVC_Handler PROC EXPORT SVC_Handler IMPORT osRtxUserSVC IMPORT osRtxInfo -#ifdef __DOMAIN_NS + IF __DOMAIN_NS = 1 IMPORT TZ_LoadContext_S IMPORT TZ_StoreContext_S -#endif + ENDIF MRS R0,PSP ; Get PSP LDR R1,[R0,#24] ; Load saved PC from stack @@ -70,7 +80,7 @@ SVC_Context CMP R1,R2 ; Check if thread switch is required BXEQ LR ; Exit when threads are the same -#ifdef __FPU_USED + IF __FPU_USED = 1 CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted TST LR,#0x10 ; Check if extended stack frame BNE SVC_ContextSwitch @@ -79,26 +89,26 @@ SVC_Context BIC R0,#1 ; Clear LSPACT (Lazy state) STR R0,[R1] ; Store FPCCR B SVC_ContextSwitch -#else + ELSE CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted -#endif + ENDIF SVC_ContextSave -#ifdef __DOMAIN_NS + IF __DOMAIN_NS = 1 LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier CBZ R0,SVC_ContextSave1 ; Branch if there is no secure context PUSH {R1,R2,R3,LR} ; Save registers and EXC_RETURN BL TZ_StoreContext_S ; Store secure context POP {R1,R2,R3,LR} ; Restore registers and EXC_RETURN -#endif + ENDIF SVC_ContextSave1 MRS R0,PSP ; Get PSP STMDB R0!,{R4-R11} ; Save R4..R11 -#ifdef __FPU_USED + IF __FPU_USED = 1 TST LR,#0x10 ; Check if extended stack frame VSTMDBEQ R0!,{S16-S31} ; Save VFP S16.S31 -#endif + ENDIF SVC_ContextSave2 STR R0,[R1,#TCB_SP_OFS] ; Store SP @@ -108,13 +118,13 @@ SVC_ContextSwitch STR R2,[R3] ; osRtxInfo.thread.run: curr = next SVC_ContextRestore -#ifdef __DOMAIN_NS + IF __DOMAIN_NS = 1 LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier CBZ R0,SVC_ContextRestore1 ; Branch if there is no secure context PUSH {R2,R3} ; Save registers BL TZ_LoadContext_S ; Load secure context POP {R2,R3} ; Restore registers -#endif + ENDIF SVC_ContextRestore1 LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base @@ -123,15 +133,15 @@ SVC_ContextRestore1 LDR R0,[R2,#TCB_SP_OFS] ; Load SP ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN -#ifdef __DOMAIN_NS + IF __DOMAIN_NS = 1 TST LR,#0x40 ; Check domain of interrupted thread BNE SVC_ContextRestore2 ; Branch if secure -#endif + ENDIF -#ifdef __FPU_USED + IF __FPU_USED = 1 TST LR,#0x10 ; Check if extended stack frame VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 -#endif + ENDIF LDMIA R0!,{R4-R11} ; Restore R4..R11 SVC_ContextRestore2 @@ -190,10 +200,10 @@ SysTick_Handler PROC Sys_Context PROC EXPORT Sys_Context IMPORT osRtxInfo -#ifdef __DOMAIN_NS + IF __DOMAIN_NS = 1 IMPORT TZ_LoadContext_S IMPORT TZ_StoreContext_S -#endif + ENDIF LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next @@ -201,7 +211,7 @@ Sys_Context PROC BXEQ LR ; Exit when threads are the same Sys_ContextSave -#ifdef __DOMAIN_NS + IF __DOMAIN_NS = 1 LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier CBZ R0,Sys_ContextSave1 ; Branch if there is no secure context PUSH {R1,R2,R3,LR} ; Save registers and EXC_RETURN @@ -210,15 +220,15 @@ Sys_ContextSave TST LR,#0x40 ; Check domain of interrupted thread MRSNE R0,PSP ; Get PSP BNE Sys_ContextSave2 ; Branch if secure -#endif + ENDIF Sys_ContextSave1 MRS R0,PSP ; Get PSP STMDB R0!,{R4-R11} ; Save R4..R11 -#ifdef __FPU_USED + IF __FPU_USED = 1 TST LR,#0x10 ; Check if extended stack frame VSTMDBEQ R0!,{S16-S31} ; Save VFP S16.S31 -#endif + ENDIF Sys_ContextSave2 STR R0,[R1,#TCB_SP_OFS] ; Store SP @@ -228,13 +238,13 @@ Sys_ContextSwitch STR R2,[R3] ; osRtxInfo.run: curr = next Sys_ContextRestore -#ifdef __DOMAIN_NS + IF __DOMAIN_NS = 1 LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier CBZ R0,Sys_ContextRestore1 ; Branch if there is no secure context PUSH {R2,R3} ; Save registers BL TZ_LoadContext_S ; Load secure context POP {R2,R3} ; Restore registers -#endif + ENDIF Sys_ContextRestore1 LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base @@ -243,15 +253,15 @@ Sys_ContextRestore1 LDR R0,[R2,#TCB_SP_OFS] ; Load SP ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN -#ifdef __DOMAIN_NS + IF __DOMAIN_NS = 1 TST LR,#0x40 ; Check domain of interrupted thread BNE Sys_ContextRestore2 ; Branch if secure -#endif + ENDIF -#ifdef __FPU_USED + IF __FPU_USED = 1 TST LR,#0x10 ; Check if extended stack frame VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 -#endif + ENDIF LDMIA R0!,{R4-R11} ; Restore R4..R11 Sys_ContextRestore2 @@ -264,4 +274,4 @@ Sys_ContextExit ENDP - END \ No newline at end of file + END diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml_ns.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml_ns.s new file mode 100644 index 00000000000..b868bab6a31 --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml_ns.s @@ -0,0 +1,3 @@ +__DOMAIN_NS EQU 1 + INCLUDE irq_armv8mml.s + END diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/irq_cm4f.s similarity index 97% rename from rtos/TARGET_CORTEX/rtx5/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/irq_cm4f.s index 84ad0b53618..f0df8aaa040 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/irq_cm4f.s @@ -24,7 +24,7 @@ ; */ -I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset TCB_SP_OFS EQU 56 ; TCB.SP offset TCB_SF_OFS EQU 34 ; TCB.stack_frame offset @@ -66,20 +66,16 @@ SVC_Context CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted TST LR,#0x10 ; Check if extended stack frame BNE SVC_ContextSwitch -#ifdef __FPU_PRESENT LDR R1,=0xE000EF34 ; FPCCR Address LDR R0,[R1] ; Load FPCCR BIC R0,#1 ; Clear LSPACT (Lazy state) STR R0,[R1] ; Store FPCCR B SVC_ContextSwitch -#endif SVC_ContextSave STMDB R12!,{R4-R11} ; Save R4..R11 -#ifdef __FPU_PRESENT TST LR,#0x10 ; Check if extended stack frame VSTMDBEQ R12!,{S16-S31} ; Save VFP S16.S31 -#endif STR R12,[R1,#TCB_SP_OFS] ; Store SP STRB LR, [R1,#TCB_SF_OFS] ; Store stack frame information @@ -92,10 +88,8 @@ SVC_ContextRestore LDR R0,[R2,#TCB_SP_OFS] ; Load SP ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN -#ifdef __FPU_PRESENT TST LR,#0x10 ; Check if extended stack frame VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 -#endif LDMIA R0!,{R4-R11} ; Restore R4..R11 MSR PSP,R0 ; Set PSP diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_CORTEX_A/irq_ca.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_CORTEX_A/irq_ca.S new file mode 100644 index 00000000000..aa40e0d3649 --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_CORTEX_A/irq_ca.S @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2013-2017 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 + * + * 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Cortex-A Exception handlers + * + * ----------------------------------------------------------------------------- + */ + + .file "irq_ca.S" + .syntax unified + + .equ MODE_FIQ, 0x11 + .equ MODE_IRQ, 0x12 + .equ MODE_SVC, 0x13 + .equ MODE_ABT, 0x17 + .equ MODE_UND, 0x1B + + .equ CPSR_BIT_T, 0x20 + + .equ K_STATE_RUNNING, 2 // osKernelState_t::osKernelRunning + .equ I_K_STATE_OFS, 8 // osRtxInfo.kernel.state offset + .equ I_TICK_IRQN_OFS, 16 // osRtxInfo.tick_irqn offset + .equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset + .equ TCB_SP_FRAME, 34 // osRtxThread_t.stack_frame offset + .equ TCB_SP_OFS, 56 // osRtxThread_t.sp offset + + + .section ".rodata" + .global irqRtxLib // Non weak library reference +irqRtxLib: + .byte 0 + + .section ".data" + .global IRQ_PendSV +IRQ_NestLevel: + .word 0 // IRQ nesting level counter +IRQ_PendSV: + .byte 0 // Pending SVC flag +SVC_Active: + .byte 0 // SVC handler execution active flag + + .arm + .section ".text" + .align 4 + + + .type Undef_Handler, %function + .global Undef_Handler + .fnstart + .cantunwind +Undef_Handler: + + SRSFD SP!, #MODE_UND + PUSH {R0-R4, R12} // Save APCS corruptible registers to UND mode stack + + MRS R0, SPSR + TST R0, #CPSR_BIT_T // Check mode + MOVEQ R1, #4 // R1 = 4 ARM mode + MOVNE R1, #2 // R1 = 2 Thumb mode + SUB R0, LR, R1 + LDREQ R0, [R0] // ARM mode - R0 points to offending instruction + BEQ Undef_Cont + + // Thumb instruction + // Determine if it is a 32-bit Thumb instruction + LDRH R0, [R0] + MOV R2, #0x1C + CMP R2, R0, LSR #11 + BHS Undef_Cont // 16-bit Thumb instruction + + // 32-bit Thumb instruction. Unaligned - reconstruct the offending instruction + LDRH R2, [LR] + ORR R0, R2, R0, LSL #16 +Undef_Cont: + MOV R2, LR // Set LR to third argument + + AND R12, SP, #4 // Ensure stack is 8-byte aligned + SUB SP, SP, R12 // Adjust stack + PUSH {R12, LR} // Store stack adjustment and dummy LR + + // R0 =Offending instruction, R1 =2(Thumb) or =4(ARM) + BL CUndefHandler + + POP {R12, LR} // Get stack adjustment & discard dummy LR + ADD SP, SP, R12 // Unadjust stack + + LDR LR, [SP, #24] // Restore stacked LR and possibly adjust for retry + SUB LR, LR, R0 + LDR R0, [SP, #28] // Restore stacked SPSR + MSR SPSR_cxsf, R0 + POP {R0-R4, R12} // Restore stacked APCS registers + ADD SP, SP, #8 // Adjust SP for already-restored banked registers + MOVS PC, LR + + .fnend + .size Undef_Handler, .-Undef_Handler + + + .type PAbt_Handler, %function + .global PAbt_Handler + .fnstart + .cantunwind +PAbt_Handler: + + SUB LR, LR, #4 // Pre-adjust LR + SRSFD SP!, #MODE_ABT // Save LR and SPRS to ABT mode stack + PUSH {R0-R4, R12} // Save APCS corruptible registers to ABT mode stack + MRC p15, 0, R0, c5, c0, 1 // IFSR + MRC p15, 0, R1, c6, c0, 2 // IFAR + + MOV R2, LR // Set LR to third argument + + AND R12, SP, #4 // Ensure stack is 8-byte aligned + SUB SP, SP, R12 // Adjust stack + PUSH {R12, LR} // Store stack adjustment and dummy LR + + BL CPAbtHandler + + POP {R12, LR} // Get stack adjustment & discard dummy LR + ADD SP, SP, R12 // Unadjust stack + + POP {R0-R4, R12} // Restore stack APCS registers + RFEFD SP! // Return from exception + + .fnend + .size PAbt_Handler, .-PAbt_Handler + + + .type DAbt_Handler, %function + .global DAbt_Handler + .fnstart + .cantunwind +DAbt_Handler: + SUB LR, LR, #8 // Pre-adjust LR + SRSFD SP!, #MODE_ABT // Save LR and SPRS to ABT mode stack + PUSH {R0-R4, R12} // Save APCS corruptible registers to ABT mode stack + CLREX // State of exclusive monitors unknown after taken data abort + MRC p15, 0, R0, c5, c0, 0 // DFSR + MRC p15, 0, R1, c6, c0, 0 // DFAR + + MOV R2, LR // Set LR to third argument + + AND R12, SP, #4 // Ensure stack is 8-byte aligned + SUB SP, SP, R12 // Adjust stack + PUSH {R12, LR} // Store stack adjustment and dummy LR + + BL CDAbtHandler + + POP {R12, LR} // Get stack adjustment & discard dummy LR + ADD SP, SP, R12 // Unadjust stack + + POP {R0-R4, R12} // Restore stacked APCS registers + RFEFD SP! // Return from exception + + .fnend + .size DAbt_Handler, .-DAbt_Handler + + + .type IRQ_Handler, %function + .global IRQ_Handler + .fnstart + .cantunwind +IRQ_Handler: + + SUB LR, LR, #4 // Pre-adjust LR + SRSFD SP!, #MODE_SVC // Save LR_irq and SPRS_irq on to the SVC stack + CPS #MODE_SVC // Change to SVC mode + PUSH {R0-R3, R12, LR} // Save APCS corruptible registers + + MOV R3, SP // Move SP into R3 + AND R3, R3, #4 // Get stack adjustment to ensure 8-byte alignment + SUB SP, SP, R3 // Adjust stack + PUSH {R3, R4} // Store stack adjustment(R3) and user data(R4) + + BLX IRQ_GetActiveIRQ // Retrieve interrupt ID into R0 + MOV R4, R0 // Move interrupt ID to R4 + + LDR R1, =IRQ_NestLevel + LDR R3, [R1] // Load IRQ nest level and increment it + ADD R3, R3, #1 + STR R3, [R1] + + BLX IRQ_GetHandler // Retrieve interrupt handler address for current ID + CMP R0, #0 // Check if handler address is 0 + BEQ IRQ_End // If 0, end interrupt and return + + CPSIE i // Re-enable interrupts + BLX R0 // Call IRQ handler + CPSID i // Disable interrupts + +IRQ_End: + MOV R0, R4 // Move interrupt ID to R0 + BLX IRQ_EndOfInterrupt // Signal end of interrupt + + LDR R2, =IRQ_NestLevel + LDR R1, [R2] // Load IRQ nest level and + SUBS R1, R1, #1 // decrement it + STR R1, [R2] + BNE IRQ_Exit // Not zero, exit from IRQ handler + + LDR R0, =SVC_Active + LDRB R0, [R0] // Load SVC_Active flag + CMP R0, #0 + BNE IRQ_SwitchCheck // Skip post processing when SVC active + + // RTX IRQ post processing check + PUSH {R5, R6} // Save user R5 and R6 + MOV R6, #0 + LDR R5, =IRQ_PendSV // Load address of IRQ_PendSV flag + B IRQ_PendCheck +IRQ_PendExec: + STRB R6, [R5] // Clear PendSV flag + CPSIE i // Re-enable interrupts + BLX osRtxPendSV_Handler // Post process pending objects + CPSID i // Disable interrupts +IRQ_PendCheck: + LDRB R0, [R5] // Load PendSV flag + CMP R0, #1 // Compare PendSV value + BEQ IRQ_PendExec // Branch to IRQ_PendExec if PendSV is set + POP {R5, R6} // Restore user R5 and R6 + +IRQ_SwitchCheck: + // RTX IRQ context switch check + LDR R12, =osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run + LDM R12, {R0, R1} // Load osRtxInfo.thread.run: curr & next + CMP R0, R1 // Check if context switch is required + BEQ IRQ_Exit + + POP {R3, R4} // Restore stack adjustment(R3) and user data(R4) + ADD SP, SP, R3 // Unadjust stack + B osRtxContextSwitch + +IRQ_Exit: + POP {R3, R4} // Restore stack adjustment(R3) and user data(R4) + ADD SP, SP, R3 // Unadjust stack + + POP {R0-R3, R12, LR} // Restore stacked APCS registers + RFEFD SP! // Return from IRQ handler + + .fnend + .size IRQ_Handler, .-IRQ_Handler + + + .type SVC_Handler, %function + .global SVC_Handler + .fnstart + .cantunwind +SVC_Handler: + + SRSFD SP!, #MODE_SVC // Store SPSR_svc and LR_svc onto SVC stack + PUSH {R12, LR} + + MRS R12, SPSR // Load SPSR + TST R12, #CPSR_BIT_T // Thumb bit set? + LDRHNE R12, [LR,#-2] // Thumb: load halfword + BICNE R12, R12, #0xFF00 // extract SVC number + LDREQ R12, [LR,#-4] // ARM: load word + BICEQ R12, R12, #0xFF000000 // extract SVC number + CMP R12, #0 // Compare SVC number + BNE SVC_User // Branch if User SVC + + PUSH {R0-R3} + + LDR R3, =osRtxInfo + LDR R1, [R3, #I_K_STATE_OFS] // Load RTX5 kernel state + CMP R1, #K_STATE_RUNNING // Check osKernelRunning + BLT SVC_FuncCall // Continue if kernel is not running + LDR R0, [R3, #I_TICK_IRQN_OFS] // Load OS Tick irqn + BLX IRQ_Disable // Disable OS Tick interrupt +SVC_FuncCall: + LDR R0, =SVC_Active + MOV R1, #1 + STRB R1, [R0] // Set SVC_Active flag + POP {R0-R3} + + LDR R12, [SP] // Reload R12 from stack + + CPSIE i // Re-enable interrupts + BLX R12 // Branch to SVC function + CPSID i // Disable interrupts + + SUB SP, SP, #4 // Adjust SP + STM SP, {SP}^ // Store SP_usr onto stack + POP {R12} // Pop SP_usr into R12 + SUB R12, R12, #16 // Adjust pointer to SP_usr + LDMDB R12, {R2,R3} // Load return values from SVC function + PUSH {R0-R3} // Push return values to stack + + PUSH {R4, R5} // Save R4 and R5 + MOV R5, #0 + LDR R4, =IRQ_PendSV // Load address of IRQ_PendSV + B SVC_PendCheck +SVC_PendExec: + STRB R5, [R4] // Clear IRQ_PendSV flag + CPSIE i // Re-enable interrupts + BLX osRtxPendSV_Handler // Post process pending objects + CPSID i // Disable interrupts +SVC_PendCheck: + LDRB R0, [R4] // Load IRQ_PendSV flag + CMP R0, #1 // Compare IRQ_PendSV value + BEQ SVC_PendExec // Branch to SVC_PendExec if IRQ_PendSV is set + POP {R4, R5} // Restore R4 and R5 + + LDR R0, =SVC_Active + MOV R1, #0 + STRB R1, [R0] // Clear SVC_Active flag + + LDR R12, =osRtxInfo + LDR R1, [R12, #I_K_STATE_OFS] // Load RTX5 kernel state + CMP R1, #K_STATE_RUNNING // Check osKernelRunning + BLT SVC_ContextCheck // Continue if kernel is not running + LDR R0, [R12, #I_TICK_IRQN_OFS] // Load OS Tick irqn + BLX IRQ_Enable // Enable OS Tick interrupt +SVC_ContextCheck: + ADD R12, R12, #I_T_RUN_OFS // Load address of osRtxInfo.thread.run + LDM R12, {R0, R1} // Load osRtxInfo.thread.run: curr & next + CMP R0, R1 // Check if context switch is required + BEQ osRtxContextExit // Exit if curr and next are equal + B osRtxContextSwitch // Continue in context switcher + +SVC_User: + PUSH {R4, R5} + LDR R5,=osRtxUserSVC // Load address of SVC table + LDR R4,[R5] // Load SVC maximum number + CMP R12,R4 // Check SVC number range + BHI SVC_Done // Branch if out of range + + LDR R12,[R5,R12,LSL #2] // Load SVC Function Address + BLX R12 // Call SVC Function + +SVC_Done: + POP {R4, R5, R12, LR} + RFEFD SP! // Return from exception + + .fnend + .size SVC_Handler, .-SVC_Handler + + + .type osRtxContextSwitch, %function + .global osRtxContextSwitch + .fnstart + .cantunwind +osRtxContextSwitch: + + // R0 = osRtxInfo.thread.run.curr + // R1 = osRtxInfo.thread.run.next + // R12 = &osRtxInfo.thread.run + + CMP R0, #0 // Is osRtxInfo.thread.run.curr == 0 + ADDEQ SP, SP, #32 // Equal, curr deleted, adjust current SP + BEQ osRtxContextRestore // Restore context, run.curr = run.next; + +osRtxContextSave: + SUB SP, SP, #4 + STM SP, {SP}^ // Save SP_usr to current stack + POP {R3} // Pop SP_usr into R3 + + SUB R3, R3, #64 // Adjust user sp to end of basic frame (R4) + STMIA R3!, {R4-R11} // Save R4-R11 to user + POP {R4-R8} // Pop current R0-R12 into R4-R8 + STMIA R3!, {R4-R8} // Store them to user stack + STM R3, {LR}^ // Store LR_usr directly + ADD R3, R3, #4 // Adjust user sp to PC + POP {R4-R6} // Pop current LR, PC, CPSR + STMIA R3!, {R5-R6} // Restore user PC and CPSR + + SUB R3, R3, #64 // Adjust user sp to R4 + + // Check if VFP state need to be saved + MRC p15, 0, R2, c1, c0, 2 // VFP/NEON access enabled? (CPACR) + AND R2, R2, #0x00F00000 + CMP R2, #0x00F00000 + BNE osRtxContextSave1 // Continue, no VFP + + VMRS R2, FPSCR + STMDB R3!, {R2,R12} // Push FPSCR, maintain 8-byte alignment + #if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 16 + VSTMDB R3!, {D0-D15} + LDRB R2, [R0, #TCB_SP_FRAME] // Record in TCB that VFP/D16 state is stacked + ORR R2, R2, #2 + STRB R2, [R0, #TCB_SP_FRAME] + #endif + #if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 32 + VSTMDB R3!, {D0-D15} + VSTMDB R3!, {D16-D31} + LDRB R2, [R0, #TCB_SP_FRAME] // Record in TCB that NEON/D32 state is stacked + ORR R2, R2, #4 + STRB R2, [R0, #TCB_SP_FRAME] + #endif + +osRtxContextSave1: + STR R3, [R0, #TCB_SP_OFS] // Store user sp to osRtxInfo.thread.run.curr + +osRtxContextRestore: + STR R1, [R12] // Store run.next to run.curr + LDR R3, [R1, #TCB_SP_OFS] // Load next osRtxThread_t.sp + LDRB R2, [R1, #TCB_SP_FRAME] // Load next osRtxThread_t.stack_frame + + ANDS R2, R2, #0x6 // Check stack frame for VFP context + MRC p15, 0, R2, c1, c0, 2 // Read CPACR + ANDEQ R2, R2, #0xFF0FFFFF // Disable VFP/NEON access if incoming task does not have stacked VFP/NEON state + ORRNE R2, R2, #0x00F00000 // Enable VFP/NEON access if incoming task does have stacked VFP/NEON state + MCR p15, 0, R2, c1, c0, 2 // Write CPACR + BEQ osRtxContextRestore1 // No VFP + ISB // Only sync if we enabled VFP, otherwise we will context switch before next VFP instruction anyway + #if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 32 + VLDMIA R3!, {D16-D31} + #endif + VLDMIA R3!, {D0-D15} + LDR R2, [R3] + VMSR FPSCR, R2 + ADD R3, R3, #8 + +osRtxContextRestore1: + LDMIA R3!, {R4-R11} // Restore R4-R11 + MOV R12, R3 // Move sp pointer to R12 + ADD R3, R3, #32 // Adjust sp + PUSH {R3} // Push sp onto stack + LDMIA SP, {SP}^ // Restore SP_usr + ADD SP, SP, #4 // Adjust SP_svc + LDMIA R12!, {R0-R3} // Restore User R0-R3 + LDR LR, [R12, #12] // Load SPSR into LR + MSR SPSR_cxsf, LR // Restore SPSR + ADD R12, R12, #4 // Adjust pointer to LR + LDM R12, {LR}^ // Restore LR_usr directly into LR + LDR LR, [R12, #4] // Restore LR + LDR R12, [R12, #-4] // Restore R12 + + MOVS PC, LR // Return from exception + +osRtxContextExit: + POP {R0-R3, R12, LR} // Restore stacked APCS registers + RFEFD SP! // Return from exception + + .fnend + .size osRtxContextSwitch, .-osRtxContextSwitch + + .end diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_M0P/TOOLCHAIN_GCC/irq_cm0.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M0/irq_cm0.S similarity index 98% rename from rtos/TARGET_CORTEX/rtx5/TARGET_M0P/TOOLCHAIN_GCC/irq_cm0.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M0/irq_cm0.S index 5362c196960..59288e24336 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_M0P/TOOLCHAIN_GCC/irq_cm0.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M0/irq_cm0.S @@ -27,7 +27,7 @@ .file "irq_cm0.S" .syntax unified - .equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset + .equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset .equ TCB_SP_OFS, 56 // TCB.SP offset .section ".rodata" diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_M0/TOOLCHAIN_GCC/irq_cm0.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M0P/irq_cm0.S similarity index 98% rename from rtos/TARGET_CORTEX/rtx5/TARGET_M0/TOOLCHAIN_GCC/irq_cm0.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M0P/irq_cm0.S index 5362c196960..59288e24336 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_M0/TOOLCHAIN_GCC/irq_cm0.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M0P/irq_cm0.S @@ -27,7 +27,7 @@ .file "irq_cm0.S" .syntax unified - .equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset + .equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset .equ TCB_SP_OFS, 56 // TCB.SP offset .section ".rodata" diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_M23/TOOLCHAIN_GCC/irq_armv8mbl.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M23/irq_armv8mbl.S similarity index 95% rename from rtos/TARGET_CORTEX/rtx5/TARGET_M23/TOOLCHAIN_GCC/irq_armv8mbl.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M23/irq_armv8mbl.S index 1b6b119e536..497e5c917f1 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_M23/TOOLCHAIN_GCC/irq_armv8mbl.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M23/irq_armv8mbl.S @@ -27,7 +27,11 @@ .file "irq_armv8mbl.S" .syntax unified - .equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset + .ifndef __DOMAIN_NS + .equ __DOMAIN_NS, 0 + .endif + + .equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset .equ TCB_SM_OFS, 48 // TCB.stack_mem offset .equ TCB_SP_OFS, 56 // TCB.SP offset .equ TCB_SF_OFS, 34 // TCB.stack_frame offset @@ -50,6 +54,7 @@ irqRtxLib: .fnstart .cantunwind SVC_Handler: + MRS R0,PSP // Get PSP LDR R1,[R0,#24] // Load saved PC from stack SUBS R1,R1,#2 // Point to SVC instruction @@ -73,7 +78,7 @@ SVC_Context: CBZ R1,SVC_ContextSwitch // Branch if running thread is deleted SVC_ContextSave: -#ifdef __DOMAIN_NS + .if __DOMAIN_NS == 1 LDR R0,[R1,#TCB_TZM_OFS] // Load TrustZone memory identifier CBZ R0,SVC_ContextSave1 // Branch if there is no secure context PUSH {R1,R2,R3,R7} // Save registers @@ -81,7 +86,7 @@ SVC_ContextSave: BL TZ_StoreContext_S // Store secure context MOV LR,R7 // Set EXC_RETURN POP {R1,R2,R3,R7} // Restore registers -#endif + .endif SVC_ContextSave1: MRS R0,PSP // Get PSP @@ -104,13 +109,13 @@ SVC_ContextSwitch: STR R2,[R3] // osRtxInfo.thread.run: curr = next SVC_ContextRestore: -#ifdef __DOMAIN_NS + .if __DOMAIN_NS == 1 LDR R0,[R2,#TCB_TZM_OFS] // Load TrustZone memory identifier CBZ R0,SVC_ContextRestore1 // Branch if there is no secure context PUSH {R2,R3} // Save registers BL TZ_LoadContext_S // Load secure context POP {R2,R3} // Restore registers -#endif + .endif SVC_ContextRestore1: MOV R1,R2 @@ -121,16 +126,16 @@ SVC_ContextRestore1: ORRS R0,R1 MOV LR,R0 // Set EXC_RETURN -#ifdef __DOMAIN_NS + .if __DOMAIN_NS == 1 LSLS R0,R0,#25 // Check domain of interrupted thread BPL SVC_ContextRestore2 // Branch if non-secure LDR R0,[R2,#TCB_SP_OFS] // Load SP MSR PSP,R0 // Set PSP BX LR // Exit from handler -#else + .else LDR R0,[R2,#TCB_SM_OFS] // Load stack memory base MSR PSPLIM,R0 // Set PSPLIM -#endif + .endif SVC_ContextRestore2: LDR R0,[R2,#TCB_SP_OFS] // Load SP @@ -216,7 +221,7 @@ Sys_Context: BEQ Sys_ContextExit // Branch when threads are the same Sys_ContextSave: -#ifdef __DOMAIN_NS + .if __DOMAIN_NS == 1 LDR R0,[R1,#TCB_TZM_OFS] // Load TrustZone memory identifier CBZ R0,Sys_ContextSave1 // Branch if there is no secure context PUSH {R1,R2,R3,R7} // Save registers @@ -229,7 +234,7 @@ Sys_ContextSave: MRS R0,PSP // Get PSP STR R0,[R1,#TCB_SP_OFS] // Store SP B Sys_ContextSave2 -#endif + .endif Sys_ContextSave1: MRS R0,PSP // Get PSP @@ -252,13 +257,13 @@ Sys_ContextSwitch: STR R2,[R3] // osRtxInfo.run: curr = next Sys_ContextRestore: -#ifdef __DOMAIN_NS + .if __DOMAIN_NS == 1 LDR R0,[R2,#TCB_TZM_OFS] // Load TrustZone memory identifier CBZ R0,Sys_ContextRestore1 // Branch if there is no secure context PUSH {R2,R3} // Save registers BL TZ_LoadContext_S // Load secure context POP {R2,R3} // Restore registers -#endif + .endif Sys_ContextRestore1: MOV R1,R2 @@ -269,16 +274,16 @@ Sys_ContextRestore1: ORRS R0,R1 MOV LR,R0 // Set EXC_RETURN -#ifdef __DOMAIN_NS + .if __DOMAIN_NS == 1 LSLS R0,R0,#25 // Check domain of interrupted thread BPL Sys_ContextRestore2 // Branch if non-secure LDR R0,[R2,#TCB_SP_OFS] // Load SP MSR PSP,R0 // Set PSP BX LR // Exit from handler -#else + .else LDR R0,[R2,#TCB_SM_OFS] // Load stack memory base MSR PSPLIM,R0 // Set PSPLIM -#endif + .endif Sys_ContextRestore2: LDR R0,[R2,#TCB_SP_OFS] // Load SP diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M23/irq_armv8mbl_ns.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M23/irq_armv8mbl_ns.S new file mode 100644 index 00000000000..b8bd9c4a49e --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M23/irq_armv8mbl_ns.S @@ -0,0 +1,3 @@ + .equ __DOMAIN_NS, 1 + .include "../Source/GCC/irq_armv8mbl.S" + .end diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_M3/TOOLCHAIN_GCC/irq_cm3.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M3/irq_cm3.S similarity index 84% rename from rtos/TARGET_CORTEX/rtx5/TARGET_M3/TOOLCHAIN_GCC/irq_cm3.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M3/irq_cm3.S index f8684da2e41..0bdf091d319 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_M3/TOOLCHAIN_GCC/irq_cm3.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M3/irq_cm3.S @@ -27,7 +27,7 @@ .file "irq_cm3.S" .syntax unified - .equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset + .equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset .equ TCB_SP_OFS, 56 // TCB.SP offset .section ".rodata" @@ -73,27 +73,12 @@ SVC_ContextSave: STR R12,[R1,#TCB_SP_OFS] // Store SP SVC_ContextSwitch: -#ifdef FEATURE_UVISOR - CPSID I // The call to the thread switch helper and PSP loading must be atomic. -#endif - /* The call to thread_switch_helper can clobber R2 and R3, but we don't - * want to clobber R2 or R3. We can't save R2 and R3 to the stack (as - * the stack we save them onto is likely to be inaccessible after the - * call to thread_switch_helper). So, we just re-obtain the values from - * osRtxInfo again. */ - BL thread_switch_helper - LDR R3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run - LDM R3,{R1,R2} // Load osRtxInfo.thread.run: curr & next - STR R2,[R3] // osRtxInfo.thread.run: curr = next SVC_ContextRestore: LDR R0,[R2,#TCB_SP_OFS] // Load SP LDMIA R0!,{R4-R11} // Restore R4..R11 MSR PSP,R0 // Set PSP -#ifdef FEATURE_UVISOR - CPSIE I // The PSP has been set. Re-enable interrupts. -#endif MVN LR,#~0xFFFFFFFD // Set EXC_RETURN value SVC_Exit: diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_M33/TOOLCHAIN_GCC/irq_armv8mml.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M33/irq_armv8mml.S similarity index 92% rename from rtos/TARGET_CORTEX/rtx5/TARGET_M33/TOOLCHAIN_GCC/irq_armv8mml.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M33/irq_armv8mml.S index 49f80cf9b13..3248b9eb3b1 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_M33/TOOLCHAIN_GCC/irq_armv8mml.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M33/irq_armv8mml.S @@ -27,7 +27,15 @@ .file "irq_armv8mml.S" .syntax unified - .equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset + .ifndef __DOMAIN_NS + .equ __DOMAIN_NS, 0 + .endif + + .ifndef __FPU_USED + .equ __FPU_USED, 0 + .endif + + .equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset .equ TCB_SM_OFS, 48 // TCB.stack_mem offset .equ TCB_SP_OFS, 56 // TCB.SP offset .equ TCB_SF_OFS, 34 // TCB.stack_frame offset @@ -70,7 +78,7 @@ SVC_Context: IT EQ BXEQ LR // Exit when threads are the same -#ifdef __FPU_USED + .if __FPU_USED == 1 CBNZ R1,SVC_ContextSave // Branch if running thread is not deleted TST LR,#0x10 // Check if extended stack frame BNE SVC_ContextSwitch @@ -79,27 +87,27 @@ SVC_Context: BIC R0,#1 // Clear LSPACT (Lazy state) STR R0,[R1] // Store FPCCR B SVC_ContextSwitch -#else + .else CBZ R1,SVC_ContextSwitch // Branch if running thread is deleted -#endif + .endif SVC_ContextSave: -#ifdef __DOMAIN_NS + .if __DOMAIN_NS == 1 LDR R0,[R1,#TCB_TZM_OFS] // Load TrustZone memory identifier CBZ R0,SVC_ContextSave1 // Branch if there is no secure context PUSH {R1,R2,R3,LR} // Save registers and EXC_RETURN BL TZ_StoreContext_S // Store secure context POP {R1,R2,R3,LR} // Restore registers and EXC_RETURN -#endif + .endif SVC_ContextSave1: MRS R0,PSP // Get PSP STMDB R0!,{R4-R11} // Save R4..R11 -#ifdef __FPU_USED + .if __FPU_USED == 1 TST LR,#0x10 // Check if extended stack frame IT EQ VSTMDBEQ R0!,{S16-S31} // Save VFP S16.S31 -#endif + .endif SVC_ContextSave2: STR R0,[R1,#TCB_SP_OFS] // Store SP @@ -109,13 +117,13 @@ SVC_ContextSwitch: STR R2,[R3] // osRtxInfo.thread.run: curr = next SVC_ContextRestore: -#ifdef __DOMAIN_NS + .if __DOMAIN_NS == 1 LDR R0,[R2,#TCB_TZM_OFS] // Load TrustZone memory identifier CBZ R0,SVC_ContextRestore1 // Branch if there is no secure context PUSH {R2,R3} // Save registers BL TZ_LoadContext_S // Load secure context POP {R2,R3} // Restore registers -#endif + .endif SVC_ContextRestore1: LDR R0,[R2,#TCB_SM_OFS] // Load stack memory base @@ -124,16 +132,16 @@ SVC_ContextRestore1: LDR R0,[R2,#TCB_SP_OFS] // Load SP ORR LR,R1,#0xFFFFFF00 // Set EXC_RETURN -#ifdef __DOMAIN_NS + .if __DOMAIN_NS == 1 TST LR,#0x40 // Check domain of interrupted thread BNE SVC_ContextRestore2 // Branch if secure -#endif + .endif -#ifdef __FPU_USED + .if __FPU_USED == 1 TST LR,#0x10 // Check if extended stack frame IT EQ VLDMIAEQ R0!,{S16-S31} // Restore VFP S16..S31 -#endif + .endif LDMIA R0!,{R4-R11} // Restore R4..R11 SVC_ContextRestore2: @@ -209,7 +217,7 @@ Sys_Context: BXEQ LR // Exit when threads are the same Sys_ContextSave: -#ifdef __DOMAIN_NS + .if __DOMAIN_NS == 1 LDR R0,[R1,#TCB_TZM_OFS] // Load TrustZone memory identifier CBZ R0,Sys_ContextSave1 // Branch if there is no secure context PUSH {R1,R2,R3,LR} // Save registers and EXC_RETURN @@ -219,16 +227,16 @@ Sys_ContextSave: IT NE MRSNE R0,PSP // Get PSP BNE Sys_ContextSave2 // Branch if secure -#endif + .endif Sys_ContextSave1: MRS R0,PSP // Get PSP STMDB R0!,{R4-R11} // Save R4..R11 -#ifdef __FPU_USED + .if __FPU_USED == 1 TST LR,#0x10 // Check if extended stack frame IT EQ VSTMDBEQ R0!,{S16-S31} // Save VFP S16.S31 -#endif + .endif Sys_ContextSave2: STR R0,[R1,#TCB_SP_OFS] // Store SP @@ -238,13 +246,13 @@ Sys_ContextSwitch: STR R2,[R3] // osRtxInfo.run: curr = next Sys_ContextRestore: -#ifdef __DOMAIN_NS + .if __DOMAIN_NS == 1 LDR R0,[R2,#TCB_TZM_OFS] // Load TrustZone memory identifier CBZ R0,Sys_ContextRestore1 // Branch if there is no secure context PUSH {R2,R3} // Save registers BL TZ_LoadContext_S // Load secure context POP {R2,R3} // Restore registers -#endif + .endif Sys_ContextRestore1: LDR R0,[R2,#TCB_SM_OFS] // Load stack memory base @@ -253,16 +261,16 @@ Sys_ContextRestore1: LDR R0,[R2,#TCB_SP_OFS] // Load SP ORR LR,R1,#0xFFFFFF00 // Set EXC_RETURN -#ifdef __DOMAIN_NS + .if __DOMAIN_NS == 1 TST LR,#0x40 // Check domain of interrupted thread BNE Sys_ContextRestore2 // Branch if secure -#endif + .endif -#ifdef __FPU_USED + .if __FPU_USED == 1 TST LR,#0x10 // Check if extended stack frame IT EQ VLDMIAEQ R0!,{S16-S31} // Restore VFP S16..S31 -#endif + .endif LDMIA R0!,{R4-R11} // Restore R4..R11 Sys_ContextRestore2: diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M33/irq_armv8mml_fp.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M33/irq_armv8mml_fp.S new file mode 100644 index 00000000000..4e78031ed42 --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M33/irq_armv8mml_fp.S @@ -0,0 +1,3 @@ + .equ __FPU_USED, 1 + .include "../Source/GCC/irq_armv8mml.S" + .end diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M33/irq_armv8mml_fp_ns.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M33/irq_armv8mml_fp_ns.S new file mode 100644 index 00000000000..3f7c7243324 --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M33/irq_armv8mml_fp_ns.S @@ -0,0 +1,4 @@ + .equ __FPU_USED, 1 + .equ __DOMAIN_NS, 1 + .include "../Source/GCC/irq_armv8mml.S" + .end diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M33/irq_armv8mml_ns.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M33/irq_armv8mml_ns.S new file mode 100644 index 00000000000..fdd030e6472 --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M33/irq_armv8mml_ns.S @@ -0,0 +1,3 @@ + .equ __DOMAIN_NS, 1 + .include "../Source/GCC/irq_armv8mml.S" + .end diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/irq_cm4f.S similarity index 85% rename from rtos/TARGET_CORTEX/rtx5/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/irq_cm4f.S index fd57b7fd58e..8d10213d119 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/irq_cm4f.S @@ -27,7 +27,7 @@ .file "irq_cm4f.S" .syntax unified - .equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset + .equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset .equ TCB_SP_OFS, 56 // TCB.SP offset .equ TCB_SF_OFS, 34 // TCB.stack_frame offset @@ -70,39 +70,22 @@ SVC_Context: CBNZ R1,SVC_ContextSave // Branch if running thread is not deleted TST LR,#0x10 // Check if extended stack frame BNE SVC_ContextSwitch -#ifdef __FPU_PRESENT LDR R1,=0xE000EF34 // FPCCR Address LDR R0,[R1] // Load FPCCR BIC R0,#1 // Clear LSPACT (Lazy state) STR R0,[R1] // Store FPCCR B SVC_ContextSwitch -#endif SVC_ContextSave: STMDB R12!,{R4-R11} // Save R4..R11 - -#ifdef __FPU_PRESENT TST LR,#0x10 // Check if extended stack frame IT EQ VSTMDBEQ R12!,{S16-S31} // Save VFP S16.S31 -#endif STR R12,[R1,#TCB_SP_OFS] // Store SP STRB LR, [R1,#TCB_SF_OFS] // Store stack frame information SVC_ContextSwitch: -#ifdef FEATURE_UVISOR - CPSID I // The call to the thread switch helper and PSP loading must be atomic. -#endif - /* The call to thread_switch_helper can clobber R2 and R3, but we don't - * want to clobber R2 or R3. We can't save R2 and R3 to the stack (as - * the stack we save them onto is likely to be inaccessible after the - * call to thread_switch_helper). So, we just re-obtain the values from - * osRtxInfo again. */ - BL thread_switch_helper - LDR R3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run - LDM R3,{R1,R2} // Load osRtxInfo.thread.run: curr & next - STR R2,[R3] // osRtxInfo.thread.run: curr = next SVC_ContextRestore: @@ -110,16 +93,11 @@ SVC_ContextRestore: LDR R0,[R2,#TCB_SP_OFS] // Load SP ORR LR,R1,#0xFFFFFF00 // Set EXC_RETURN -#ifdef __FPU_PRESENT TST LR,#0x10 // Check if extended stack frame IT EQ VLDMIAEQ R0!,{S16-S31} // Restore VFP S16..S31 -#endif LDMIA R0!,{R4-R11} // Restore R4..R11 MSR PSP,R0 // Set PSP -#ifdef FEATURE_UVISOR - CPSIE I // The PSP has been set. Re-enable interrupts. -#endif SVC_Exit: BX LR // Exit from handler diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_CORTEX_A/irq_ca.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_CORTEX_A/irq_ca.s new file mode 100644 index 00000000000..acb2b12344d --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_CORTEX_A/irq_ca.s @@ -0,0 +1,431 @@ +;/* +; * Copyright (c) 2013-2017 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 +; * +; * 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. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-A Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + NAME irq_ca.s + +MODE_FIQ EQU 0x11 +MODE_IRQ EQU 0x12 +MODE_SVC EQU 0x13 +MODE_ABT EQU 0x17 +MODE_UND EQU 0x1B + +CPSR_BIT_T EQU 0x20 + +K_STATE_RUNNING EQU 2 ; osKernelState_t::osKernelRunning +I_K_STATE_OFS EQU 8 ; osRtxInfo.kernel.state offset +I_TICK_IRQN_OFS EQU 16 ; osRtxInfo.tick_irqn offset +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset +TCB_SP_FRAME EQU 34 ; osRtxThread_t.stack_frame offset +TCB_SP_OFS EQU 56 ; osRtxThread_t.sp offset + + + PRESERVE8 + ARM + + + SECTION .rodata:DATA:NOROOT(2) + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + SECTION .data:DATA:NOROOT(2) + EXPORT IRQ_PendSV +IRQ_NestLevel DCD 0 ; IRQ nesting level counter +IRQ_PendSV DCB 0 ; Pending SVC flag +SVC_Active DCB 0 ; SVC handler execution active flag + + + SECTION .text:CODE:NOROOT(2) + + +Undef_Handler + EXPORT Undef_Handler + IMPORT CUndefHandler + + SRSFD SP!, #MODE_UND + PUSH {R0-R4, R12} ; Save APCS corruptible registers to UND mode stack + + MRS R0, SPSR + TST R0, #CPSR_BIT_T ; Check mode + MOVEQ R1, #4 ; R1 = 4 ARM mode + MOVNE R1, #2 ; R1 = 2 Thumb mode + SUB R0, LR, R1 + LDREQ R0, [R0] ; ARM mode - R0 points to offending instruction + BEQ Undef_Cont + + ; Thumb instruction + ; Determine if it is a 32-bit Thumb instruction + LDRH R0, [R0] + MOV R2, #0x1C + CMP R2, R0, LSR #11 + BHS Undef_Cont ; 16-bit Thumb instruction + + ; 32-bit Thumb instruction. Unaligned - reconstruct the offending instruction + LDRH R2, [LR] + ORR R0, R2, R0, LSL #16 +Undef_Cont + MOV R2, LR ; Set LR to third argument + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR + + ; R0 =Offending instruction, R1 =2(Thumb) or =4(ARM) + BL CUndefHandler + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + LDR LR, [SP, #24] ; Restore stacked LR and possibly adjust for retry + SUB LR, LR, R0 + LDR R0, [SP, #28] ; Restore stacked SPSR + MSR SPSR_CXSF, R0 + POP {R0-R4, R12} ; Restore stacked APCS registers + ADD SP, SP, #8 ; Adjust SP for already-restored banked registers + MOVS PC, LR + + +PAbt_Handler + EXPORT PAbt_Handler + IMPORT CPAbtHandler + + SUB LR, LR, #4 ; Pre-adjust LR + SRSFD SP!, #MODE_ABT ; Save LR and SPRS to ABT mode stack + PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack + MRC p15, 0, R0, c5, c0, 1 ; IFSR + MRC p15, 0, R1, c6, c0, 2 ; IFAR + + MOV R2, LR ; Set LR to third argument + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR + + BL CPAbtHandler + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + POP {R0-R4, R12} ; Restore stack APCS registers + RFEFD SP! ; Return from exception + + +DAbt_Handler + EXPORT DAbt_Handler + IMPORT CDAbtHandler + + SUB LR, LR, #8 ; Pre-adjust LR + SRSFD SP!, #MODE_ABT ; Save LR and SPRS to ABT mode stack + PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack + CLREX ; State of exclusive monitors unknown after taken data abort + MRC p15, 0, R0, c5, c0, 0 ; DFSR + MRC p15, 0, R1, c6, c0, 0 ; DFAR + + MOV R2, LR ; Set LR to third argument + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR + + BL CDAbtHandler + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + POP {R0-R4, R12} ; Restore stacked APCS registers + RFEFD SP! ; Return from exception + + +IRQ_Handler + EXPORT IRQ_Handler + IMPORT osRtxInfo + IMPORT IRQ_GetActiveIRQ + IMPORT IRQ_GetHandler + IMPORT IRQ_EndOfInterrupt + + SUB LR, LR, #4 ; Pre-adjust LR + SRSFD SP!, #MODE_SVC ; Save LR_irq and SPRS_irq on to the SVC stack + CPS #MODE_SVC ; Change to SVC mode + PUSH {R0-R3, R12, LR} ; Save APCS corruptible registers + + MOV R3, SP ; Move SP into R3 + AND R3, R3, #4 ; Get stack adjustment to ensure 8-byte alignment + SUB SP, SP, R3 ; Adjust stack + PUSH {R3, R4} ; Store stack adjustment(R3) and user data(R4) + + BLX IRQ_GetActiveIRQ ; Retrieve interrupt ID into R0 + MOV R4, R0 ; Move interrupt ID to R4 + + LDR R1, =IRQ_NestLevel + LDR R3, [R1] ; Load IRQ nest level and increment it + ADD R3, R3, #1 + STR R3, [R1] + + BLX IRQ_GetHandler ; Retrieve interrupt handler address for current ID + CMP R0, #0 ; Check if handler address is 0 + BEQ IRQ_End ; If 0, end interrupt and return + + CPSIE i ; Re-enable interrupts + BLX R0 ; Call IRQ handler + CPSID i ; Disable interrupts + +IRQ_End + MOV R0, R4 ; Move interrupt ID to R0 + BLX IRQ_EndOfInterrupt ; Signal end of interrupt + + LDR R2, =IRQ_NestLevel + LDR R1, [R2] ; Load IRQ nest level and + SUBS R1, R1, #1 ; decrement it + STR R1, [R2] + BNE IRQ_Exit ; Not zero, exit from IRQ handler + + LDR R0, =SVC_Active + LDRB R0, [R0] ; Load SVC_Active flag + CMP R0, #0 + BNE IRQ_SwitchCheck ; Skip post processing when SVC active + + ; RTX IRQ post processing check + PUSH {R5, R6} ; Save user R5 and R6 + MOV R6, #0 + LDR R5, =IRQ_PendSV ; Load address of IRQ_PendSV flag + B IRQ_PendCheck +IRQ_PendExec + STRB R6, [R5] ; Clear PendSV flag + CPSIE i ; Re-enable interrupts + BLX osRtxPendSV_Handler ; Post process pending objects + CPSID i ; Disable interrupts +IRQ_PendCheck + LDRB R0, [R5] ; Load PendSV flag + CMP R0, #1 ; Compare PendSV value + BEQ IRQ_PendExec ; Branch to IRQ_PendExec if PendSV is set + POP {R5, R6} ; Restore user R5 and R6 + +IRQ_SwitchCheck + ; RTX IRQ context switch check + LDR R12, =osRtxInfo+I_T_RUN_OFS ; Load address of osRtxInfo.run + LDM R12, {R0, R1} ; Load osRtxInfo.thread.run: curr & next + CMP R0, R1 ; Check if context switch is required + BEQ IRQ_Exit + + POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4) + ADD SP, SP, R3 ; Unadjust stack + B osRtxContextSwitch + +IRQ_Exit + POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4) + ADD SP, SP, R3 ; Unadjust stack + + POP {R0-R3, R12, LR} ; Restore stacked APCS registers + RFEFD SP! ; Return from IRQ handler + + +SVC_Handler + EXPORT SVC_Handler + IMPORT IRQ_Disable + IMPORT IRQ_Enable + IMPORT osRtxPendSV_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + + SRSFD SP!, #MODE_SVC ; Store SPSR_svc and LR_svc onto SVC stack + PUSH {R12, LR} + + MRS R12, SPSR ; Load SPSR + TST R12, #CPSR_BIT_T ; Thumb bit set? + LDRHNE R12, [LR,#-2] ; Thumb: load halfword + BICNE R12, R12, #0xFF00 ; extract SVC number + LDREQ R12, [LR,#-4] ; ARM: load word + BICEQ R12, R12, #0xFF000000 ; extract SVC number + CMP R12, #0 ; Compare SVC number + BNE SVC_User ; Branch if User SVC + + PUSH {R0-R3} + + LDR R3, =osRtxInfo + LDR R1, [R3, #I_K_STATE_OFS] ; Load RTX5 kernel state + CMP R1, #K_STATE_RUNNING ; Check osKernelRunning + BLT SVC_FuncCall ; Continue if kernel is not running + LDR R0, [R3, #I_TICK_IRQN_OFS] ; Load OS Tick irqn + BLX IRQ_Disable ; Disable OS Tick interrupt +SVC_FuncCall + LDR R0, =SVC_Active + MOV R1, #1 + STRB R1, [R0] ; Set SVC_Active flag + POP {R0-R3} + + LDR R12, [SP] ; Reload R12 from stack + + CPSIE i ; Re-enable interrupts + BLX R12 ; Branch to SVC function + CPSID i ; Disable interrupts + + SUB SP, SP, #4 ; Adjust SP + STM SP, {SP}^ ; Store SP_usr onto stack + POP {R12} ; Pop SP_usr into R12 + SUB R12, R12, #16 ; Adjust pointer to SP_usr + LDMDB R12, {R2,R3} ; Load return values from SVC function + PUSH {R0-R3} ; Push return values to stack + + PUSH {R4, R5} ; Save R4 and R5 + MOV R5, #0 + LDR R4, =IRQ_PendSV ; Load address of IRQ_PendSV + B SVC_PendCheck +SVC_PendExec + STRB R5, [R4] ; Clear IRQ_PendSV flag + CPSIE i ; Re-enable interrupts + BLX osRtxPendSV_Handler ; Post process pending objects + CPSID i ; Disable interrupts +SVC_PendCheck + LDRB R0, [R4] ; Load IRQ_PendSV flag + CMP R0, #1 ; Compare IRQ_PendSV value + BEQ SVC_PendExec ; Branch to SVC_PendExec if IRQ_PendSV is set + POP {R4, R5} ; Restore R4 and R5 + + LDR R0, =SVC_Active + MOV R1, #0 + STRB R1, [R0] ; Clear SVC_Active flag + + LDR R12, =osRtxInfo + LDR R1, [R12, #I_K_STATE_OFS] ; Load RTX5 kernel state + CMP R1, #K_STATE_RUNNING ; Check osKernelRunning + BLT SVC_ContextCheck ; Continue if kernel is not running + LDR R0, [R12, #I_TICK_IRQN_OFS] ; Load OS Tick irqn + BLX IRQ_Enable ; Enable OS Tick interrupt +SVC_ContextCheck + ADD R12, R12, #I_T_RUN_OFS ; Load address of osRtxInfo.thread.run + LDM R12, {R0, R1} ; Load osRtxInfo.thread.run: curr & next + CMP R0, R1 ; Check if context switch is required + BEQ osRtxContextExit ; Exit if curr and next are equal + B osRtxContextSwitch ; Continue in context switcher + +SVC_User + PUSH {R4, R5} + LDR R5,=osRtxUserSVC ; Load address of SVC table + LDR R4,[R5] ; Load SVC maximum number + CMP R12,R4 ; Check SVC number range + BHI SVC_Done ; Branch if out of range + + LDR R12,[R5,R12,LSL #2] ; Load SVC Function Address + BLX R12 ; Call SVC Function + +SVC_Done + POP {R4, R5, R12, LR} + RFEFD SP! ; Return from exception + + +osRtxContextSwitch + EXPORT osRtxContextSwitch + + ; R0 = osRtxInfo.thread.run.curr + ; R1 = osRtxInfo.thread.run.next + ; R12 = &osRtxInfo.thread.run + + CMP R0, #0 ; Is osRtxInfo.thread.run.curr == 0 + ADDEQ SP, SP, #32 ; Equal, curr deleted, adjust current SP + BEQ osRtxContextRestore ; Restore context, run.curr = run.next; + +osRtxContextSave + SUB SP, SP, #4 + STM SP, {SP}^ ; Save SP_usr to current stack + POP {R3} ; Pop SP_usr into R3 + + SUB R3, R3, #64 ; Adjust user sp to end of basic frame (R4) + STMIA R3!, {R4-R11} ; Save R4-R11 to user + POP {R4-R8} ; Pop current R0-R12 into R4-R8 + STMIA R3!, {R4-R8} ; Store them to user stack + STM R3, {LR}^ ; Store LR_usr directly + ADD R3, R3, #4 ; Adjust user sp to PC + POP {R4-R6} ; Pop current LR, PC, CPSR + STMIA R3!, {R5-R6} ; Restore user PC and CPSR + + SUB R3, R3, #64 ; Adjust user sp to R4 + + ; Check if VFP state need to be saved + MRC p15, 0, R2, c1, c0, 2 ; VFP/NEON access enabled? (CPACR) + AND R2, R2, #0x00F00000 + CMP R2, #0x00F00000 + BNE osRtxContextSave1 ; Continue, no VFP + + VMRS R2, FPSCR + STMDB R3!, {R2,R12} ; Push FPSCR, maintain 8-byte alignment + IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 16 + VSTMDB R3!, {D0-D15} + LDRB R2, [R0, #TCB_SP_FRAME] ; Record in TCB that VFP/D16 state is stacked + ORR R2, R2, #2 + STRB R2, [R0, #TCB_SP_FRAME] + ENDIF + IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 + VSTMDB R3!, {D0-D15} + VSTMDB R3!, {D16-D31} + LDRB R2, [R0, #TCB_SP_FRAME] ; Record in TCB that NEON/D32 state is stacked + ORR R2, R2, #4 + STRB R2, [R0, #TCB_SP_FRAME] + ENDIF + +osRtxContextSave1 + STR R3, [R0, #TCB_SP_OFS] ; Store user sp to osRtxInfo.thread.run.curr + +osRtxContextRestore + STR R1, [R12] ; Store run.next to run.curr + LDR R3, [R1, #TCB_SP_OFS] ; Load next osRtxThread_t.sp + LDRB R2, [R1, #TCB_SP_FRAME] ; Load next osRtxThread_t.stack_frame + + ANDS R2, R2, #0x6 ; Check stack frame for VFP context + MRC p15, 0, R2, c1, c0, 2 ; Read CPACR + ANDEQ R2, R2, #0xFF0FFFFF ; Disable VFP/NEON access if incoming task does not have stacked VFP/NEON state + ORRNE R2, R2, #0x00F00000 ; Enable VFP/NEON access if incoming task does have stacked VFP/NEON state + MCR p15, 0, R2, c1, c0, 2 ; Write CPACR + BEQ osRtxContextRestore1 ; No VFP + ISB ; Only sync if we enabled VFP, otherwise we will context switch before next VFP instruction anyway + IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 + VLDMIA R3!, {D16-D31} + ENDIF + VLDMIA R3!, {D0-D15} + LDR R2, [R3] + VMSR FPSCR, R2 + ADD R3, R3, #8 + +osRtxContextRestore1 + LDMIA R3!, {R4-R11} ; Restore R4-R11 + MOV R12, R3 ; Move sp pointer to R12 + ADD R3, R3, #32 ; Adjust sp + PUSH {R3} ; Push sp onto stack + LDMIA SP, {SP}^ ; Restore SP_usr + ADD SP, SP, #4 ; Adjust SP_svc + LDMIA R12!, {R0-R3} ; Restore User R0-R3 + LDR LR, [R12, #12] ; Load SPSR into LR + MSR SPSR_CXSF, LR ; Restore SPSR + ADD R12, R12, #4 ; Adjust pointer to LR + LDM R12, {LR}^ ; Restore LR_usr directly into LR + LDR LR, [R12, #4] ; Restore LR + LDR R12, [R12, #-4] ; Restore R12 + + MOVS PC, LR ; Return from exception + +osRtxContextExit + POP {R0-R3, R12, LR} ; Restore stacked APCS registers + RFEFD SP! ; Return from exception + + END diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_M0/TOOLCHAIN_IAR/irq_cm0.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M0/irq_cm0.s similarity index 98% rename from rtos/TARGET_CORTEX/rtx5/TARGET_M0/TOOLCHAIN_IAR/irq_cm0.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M0/irq_cm0.s index 023aae3a9e7..9d116999318 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_M0/TOOLCHAIN_IAR/irq_cm0.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M0/irq_cm0.s @@ -27,7 +27,7 @@ NAME irq_cm0.s -I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset TCB_SP_OFS EQU 56 ; TCB.SP offset diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_M0P/TOOLCHAIN_IAR/irq_cm0.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M0P/irq_cm0.s similarity index 98% rename from rtos/TARGET_CORTEX/rtx5/TARGET_M0P/TOOLCHAIN_IAR/irq_cm0.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M0P/irq_cm0.s index 023aae3a9e7..9d116999318 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_M0P/TOOLCHAIN_IAR/irq_cm0.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M0P/irq_cm0.s @@ -27,7 +27,7 @@ NAME irq_cm0.s -I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset TCB_SP_OFS EQU 56 ; TCB.SP offset diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl.s new file mode 100644 index 00000000000..3b4e9f3652e --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl.s @@ -0,0 +1,5 @@ + NAME irq_armv8mbl.s +#define __DOMAIN_NS 0 + INCLUDE irq_armv8mbl_common.s + + END diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_M23/TOOLCHAIN_IAR/irq_armv8mbl.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl_common.s similarity index 96% rename from rtos/TARGET_CORTEX/rtx5/TARGET_M23/TOOLCHAIN_IAR/irq_armv8mbl.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl_common.s index 080814f1ec2..7cce8f567f5 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_M23/TOOLCHAIN_IAR/irq_armv8mbl.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl_common.s @@ -24,9 +24,11 @@ ; */ - NAME irq_armv8mbl.s +#ifndef __DOMAIN_NS +#define __DOMAIN_NS 0 +#endif -I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset TCB_SM_OFS EQU 48 ; TCB.stack_mem offset TCB_SP_OFS EQU 56 ; TCB.SP offset TCB_SF_OFS EQU 34 ; TCB.stack_frame offset @@ -34,21 +36,23 @@ TCB_TZM_OFS EQU 64 ; TCB.tz_memory offset PRESERVE8 - SECTION .rodata:DATA:NOROOT(2) + SECTION .rodata:DATA:NOROOT(2) EXPORT irqRtxLib irqRtxLib DCB 0 ; Non weak library reference + + SECTION .text:CODE:NOROOT(2) + THUMB - SECTION .text:CODE:NOROOT(2) SVC_Handler EXPORT SVC_Handler IMPORT osRtxUserSVC IMPORT osRtxInfo -#ifdef __DOMAIN_NS +#if (__DOMAIN_NS == 1) IMPORT TZ_LoadContext_S IMPORT TZ_StoreContext_S #endif @@ -76,7 +80,7 @@ SVC_Context CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted SVC_ContextSave -#ifdef __DOMAIN_NS +#if (__DOMAIN_NS == 1) LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier CBZ R0,SVC_ContextSave1 ; Branch if there is no secure context PUSH {R1,R2,R3,R7} ; Save registers @@ -107,7 +111,7 @@ SVC_ContextSwitch STR R2,[R3] ; osRtxInfo.thread.run: curr = next SVC_ContextRestore -#ifdef __DOMAIN_NS +#if (__DOMAIN_NS == 1) LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier CBZ R0,SVC_ContextRestore1 ; Branch if there is no secure context PUSH {R2,R3} ; Save registers @@ -124,7 +128,7 @@ SVC_ContextRestore1 ORRS R0,R1 MOV LR,R0 ; Set EXC_RETURN -#ifdef __DOMAIN_NS +#if (__DOMAIN_NS == 1) LSLS R0,R0,#25 ; Check domain of interrupted thread BPL SVC_ContextRestore2 ; Branch if non-secure LDR R0,[R2,#TCB_SP_OFS] ; Load SP @@ -191,10 +195,11 @@ SysTick_Handler B Sys_Context + Sys_Context EXPORT Sys_Context IMPORT osRtxInfo -#ifdef __DOMAIN_NS +#if (__DOMAIN_NS == 1) IMPORT TZ_LoadContext_S IMPORT TZ_StoreContext_S #endif @@ -204,9 +209,8 @@ Sys_Context CMP R1,R2 ; Check if thread switch is required BEQ Sys_ContextExit ; Branch when threads are the same - Sys_ContextSave -#ifdef __DOMAIN_NS +#if (__DOMAIN_NS == 1) LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier CBZ R0,Sys_ContextSave1 ; Branch if there is no secure context PUSH {R1,R2,R3,R7} ; Save registers @@ -242,7 +246,7 @@ Sys_ContextSwitch STR R2,[R3] ; osRtxInfo.run: curr = next Sys_ContextRestore -#ifdef __DOMAIN_NS +#if (__DOMAIN_NS == 1) LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier CBZ R0,Sys_ContextRestore1 ; Branch if there is no secure context PUSH {R2,R3} ; Save registers @@ -259,7 +263,7 @@ Sys_ContextRestore1 ORRS R0,R1 MOV LR,R0 ; Set EXC_RETURN -#ifdef __DOMAIN_NS +#if (__DOMAIN_NS == 1) LSLS R0,R0,#25 ; Check domain of interrupted thread BPL Sys_ContextRestore2 ; Branch if non-secure LDR R0,[R2,#TCB_SP_OFS] ; Load SP @@ -284,5 +288,3 @@ Sys_ContextRestore2 Sys_ContextExit BX LR ; Exit from handler - - END diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl_ns.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl_ns.s new file mode 100644 index 00000000000..7ee9d0465d8 --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl_ns.s @@ -0,0 +1,5 @@ + NAME irq_armv8mbl_ns.s +#define __DOMAIN_NS 1 + INCLUDE irq_armv8mbl_common.s + + END diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_M3/TOOLCHAIN_IAR/irq_cm3.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M3/irq_cm3.s similarity index 98% rename from rtos/TARGET_CORTEX/rtx5/TARGET_M3/TOOLCHAIN_IAR/irq_cm3.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M3/irq_cm3.s index bfc3b33d410..0bffcb34689 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_M3/TOOLCHAIN_IAR/irq_cm3.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M3/irq_cm3.s @@ -27,7 +27,7 @@ NAME irq_cm3.s -I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset TCB_SP_OFS EQU 56 ; TCB.SP offset diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml.s new file mode 100644 index 00000000000..8a8bd8a0f18 --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml.s @@ -0,0 +1,5 @@ + NAME irq_armv8mml.s +#define __DOMAIN_NS 0 + INCLUDE irq_armv8mml_common.s + END + diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_M33/TOOLCHAIN_IAR/irq_armv8mml.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml_common.s similarity index 93% rename from rtos/TARGET_CORTEX/rtx5/TARGET_M33/TOOLCHAIN_IAR/irq_armv8mml.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml_common.s index 20c041119f1..5edbf07bcf6 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_M33/TOOLCHAIN_IAR/irq_armv8mml.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml_common.s @@ -23,9 +23,19 @@ ; * ----------------------------------------------------------------------------- ; */ - NAME irq_armv8mml.S -I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset + +#ifndef __DOMAIN_NS +#define __DOMAIN_NS 0 +#endif + +#ifdef __ARMVFP__ +__FPU_USED EQU 1 +#else +__FPU_USED EQU 0 +#endif + +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset TCB_SM_OFS EQU 48 ; TCB.stack_mem offset TCB_SP_OFS EQU 56 ; TCB.SP offset TCB_SF_OFS EQU 34 ; TCB.stack_frame offset @@ -33,20 +43,22 @@ TCB_TZM_OFS EQU 64 ; TCB.tz_memory offset PRESERVE8 - SECTION .rodata:DATA:NOROOT(2) + + SECTION .rodata:DATA:NOROOT(2) EXPORT irqRtxLib irqRtxLib DCB 0 ; Non weak library reference + + SECTION .text:CODE:NOROOT(2) THUMB - SECTION .text:CODE:NOROOT(2) SVC_Handler EXPORT SVC_Handler IMPORT osRtxUserSVC IMPORT osRtxInfo -#ifdef __DOMAIN_NS +#if (__DOMAIN_NS == 1) IMPORT TZ_LoadContext_S IMPORT TZ_StoreContext_S #endif @@ -67,9 +79,10 @@ SVC_Context LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next CMP R1,R2 ; Check if thread switch is required + IT EQ BXEQ LR ; Exit when threads are the same -#ifdef __FPU_USED +#if (__FPU_USED == 1) CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted TST LR,#0x10 ; Check if extended stack frame BNE SVC_ContextSwitch @@ -83,7 +96,7 @@ SVC_Context #endif SVC_ContextSave -#ifdef __DOMAIN_NS +#if (__DOMAIN_NS == 1) LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier CBZ R0,SVC_ContextSave1 ; Branch if there is no secure context PUSH {R1,R2,R3,LR} ; Save registers and EXC_RETURN @@ -94,7 +107,7 @@ SVC_ContextSave SVC_ContextSave1 MRS R0,PSP ; Get PSP STMDB R0!,{R4-R11} ; Save R4..R11 -#ifdef __FPU_USED +#if (__FPU_USED == 1) TST LR,#0x10 ; Check if extended stack frame VSTMDBEQ R0!,{S16-S31} ; Save VFP S16.S31 #endif @@ -107,7 +120,7 @@ SVC_ContextSwitch STR R2,[R3] ; osRtxInfo.thread.run: curr = next SVC_ContextRestore -#ifdef __DOMAIN_NS +#if (__DOMAIN_NS == 1) LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier CBZ R0,SVC_ContextRestore1 ; Branch if there is no secure context PUSH {R2,R3} ; Save registers @@ -122,12 +135,12 @@ SVC_ContextRestore1 LDR R0,[R2,#TCB_SP_OFS] ; Load SP ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN -#ifdef __DOMAIN_NS +#if (__DOMAIN_NS == 1) TST LR,#0x40 ; Check domain of interrupted thread BNE SVC_ContextRestore2 ; Branch if secure #endif -#ifdef __FPU_USED +#if (__FPU_USED == 1) TST LR,#0x10 ; Check if extended stack frame VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 #endif @@ -177,10 +190,11 @@ SysTick_Handler B Sys_Context + Sys_Context EXPORT Sys_Context IMPORT osRtxInfo -#ifdef __DOMAIN_NS +#if (__DOMAIN_NS == 1) IMPORT TZ_LoadContext_S IMPORT TZ_StoreContext_S #endif @@ -188,16 +202,18 @@ Sys_Context LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next CMP R1,R2 ; Check if thread switch is required + IT EQ BXEQ LR ; Exit when threads are the same Sys_ContextSave -#ifdef __DOMAIN_NS +#if (__DOMAIN_NS == 1) LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier CBZ R0,Sys_ContextSave1 ; Branch if there is no secure context PUSH {R1,R2,R3,LR} ; Save registers and EXC_RETURN BL TZ_StoreContext_S ; Store secure context POP {R1,R2,R3,LR} ; Restore registers and EXC_RETURN TST LR,#0x40 ; Check domain of interrupted thread + IT NE MRSNE R0,PSP ; Get PSP BNE Sys_ContextSave2 ; Branch if secure #endif @@ -205,7 +221,7 @@ Sys_ContextSave Sys_ContextSave1 MRS R0,PSP ; Get PSP STMDB R0!,{R4-R11} ; Save R4..R11 -#ifdef __FPU_USED +#if (__FPU_USED == 1) TST LR,#0x10 ; Check if extended stack frame VSTMDBEQ R0!,{S16-S31} ; Save VFP S16.S31 #endif @@ -218,7 +234,7 @@ Sys_ContextSwitch STR R2,[R3] ; osRtxInfo.run: curr = next Sys_ContextRestore -#ifdef __DOMAIN_NS +#if (__DOMAIN_NS == 1) LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier CBZ R0,Sys_ContextRestore1 ; Branch if there is no secure context PUSH {R2,R3} ; Save registers @@ -233,12 +249,12 @@ Sys_ContextRestore1 LDR R0,[R2,#TCB_SP_OFS] ; Load SP ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN -#ifdef __DOMAIN_NS +#if (__DOMAIN_NS == 1) TST LR,#0x40 ; Check domain of interrupted thread BNE Sys_ContextRestore2 ; Branch if secure #endif -#ifdef __FPU_USED +#if (__FPU_USED == 1) TST LR,#0x10 ; Check if extended stack frame VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 #endif @@ -249,5 +265,3 @@ Sys_ContextRestore2 Sys_ContextExit BX LR ; Exit from handler - - END \ No newline at end of file diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml_ns.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml_ns.s new file mode 100644 index 00000000000..827abb49208 --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml_ns.s @@ -0,0 +1,5 @@ + NAME irq_armv8mml_ns.s +#define __DOMAIN_NS 1 + INCLUDE irq_armv8mml_common.s + END + diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/irq_cm4f.s similarity index 97% rename from rtos/TARGET_CORTEX/rtx5/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.S rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/irq_cm4f.s index e194af196c1..0d84409b392 100644 --- a/rtos/TARGET_CORTEX/rtx5/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/irq_cm4f.s @@ -27,7 +27,7 @@ NAME irq_cm4f.s -I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset TCB_SP_OFS EQU 56 ; TCB.SP offset TCB_SF_OFS EQU 34 ; TCB.stack_frame offset @@ -69,21 +69,17 @@ SVC_Context CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted TST LR,#0x10 ; Check if extended stack frame BNE SVC_ContextSwitch -#ifdef __FPU_PRESENT LDR R1,=0xE000EF34 ; FPCCR Address LDR R0,[R1] ; Load FPCCR BIC R0,R0,#1 ; Clear LSPACT (Lazy state) STR R0,[R1] ; Store FPCCR B SVC_ContextSwitch -#endif SVC_ContextSave STMDB R12!,{R4-R11} ; Save R4..R11 -#ifdef __FPU_PRESENT TST LR,#0x10 ; Check if extended stack frame IT EQ VSTMDBEQ R12!,{S16-S31} ; Save VFP S16.S31 -#endif STR R12,[R1,#TCB_SP_OFS] ; Store SP STRB LR, [R1,#TCB_SF_OFS] ; Store stack frame information @@ -96,11 +92,9 @@ SVC_ContextRestore LDR R0,[R2,#TCB_SP_OFS] ; Load SP ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN -#ifdef __FPU_PRESENT TST LR,#0x10 ; Check if extended stack frame IT EQ VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 -#endif LDMIA R0!,{R4-R11} ; Restore R4..R11 MSR PSP,R0 ; Set PSP diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_c.h b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_c.h new file mode 100644 index 00000000000..3e0ddd35294 --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_c.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2017 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 + * + * 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Cortex Core definitions + * + * ----------------------------------------------------------------------------- + */ + +#ifndef RTX_CORE_C_H_ +#define RTX_CORE_C_H_ + +#include "RTE_Components.h" +#include CMSIS_device_header + +#ifndef __ARM_ARCH_6M__ +#define __ARM_ARCH_6M__ 0U +#endif +#ifndef __ARM_ARCH_7A__ +#define __ARM_ARCH_7A__ 0U +#endif +#ifndef __ARM_ARCH_7M__ +#define __ARM_ARCH_7M__ 0U +#endif +#ifndef __ARM_ARCH_7EM__ +#define __ARM_ARCH_7EM__ 0U +#endif +#ifndef __ARM_ARCH_8M_BASE__ +#define __ARM_ARCH_8M_BASE__ 0U +#endif +#ifndef __ARM_ARCH_8M_MAIN__ +#define __ARM_ARCH_8M_MAIN__ 0U +#endif + +#if ((__ARM_ARCH_6M__ + \ + __ARM_ARCH_7A__ + \ + __ARM_ARCH_7M__ + \ + __ARM_ARCH_7EM__ + \ + __ARM_ARCH_8M_BASE__ + \ + __ARM_ARCH_8M_MAIN__) != 1U) +#error "Unknown ARM Architecture!" +#endif + +#if (__ARM_ARCH_7A__ != 0U) +#include "rtx_core_ca.h" +#else +#include "rtx_core_cm.h" +#endif + +#endif // RTX_CORE_C_H_ diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_ca.h b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_ca.h new file mode 100644 index 00000000000..f3a7a2addcc --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_ca.h @@ -0,0 +1,1100 @@ +/* + * Copyright (c) 2013-2017 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 + * + * 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Cortex-A Core definitions + * + * ----------------------------------------------------------------------------- + */ + +#ifndef RTX_CORE_CA_H_ +#define RTX_CORE_CA_H_ + +#include "RTE_Components.h" +#include CMSIS_device_header + +#define __DOMAIN_NS 0U +#define __EXCLUSIVE_ACCESS 1U + +/* CPSR bit definitions */ +#define CPSR_T_BIT 0x20U +#define CPSR_I_BIT 0x80U +#define CPSR_F_BIT 0x40U + +/* CPSR mode bitmasks */ +#define CPSR_MODE_USER 0x10U +#define CPSR_MODE_SYSTEM 0x1FU + +/* Determine privilege level */ +#define IS_PRIVILEGED() (__get_mode() != CPSR_MODE_USER) +#define IS_IRQ_MODE() ((__get_mode() != CPSR_MODE_USER) && (__get_mode() != CPSR_MODE_SYSTEM)) +#define IS_IRQ_MASKED() (0U) + +#define xPSR_INIT(privileged, thumb) \ + ((privileged) != 0U) ? (CPSR_MODE_SYSTEM | (((thumb) != 0U) ? CPSR_T_BIT : 0U)) : \ + (CPSR_MODE_USER | (((thumb) != 0U) ? CPSR_T_BIT : 0U)) + +#define STACK_FRAME_INIT 0x00U + +// Stack Frame: +// - VFP-D32: D16-31, D0-D15, FPSCR, Reserved, R4-R11, R0-R3, R12, LR, PC, CPSR +// - VFP-D16: D0-D15, FPSCR, Reserved, R4-R11, R0-R3, R12, LR, PC, CPSR +// - Basic: R4-R11, R0-R3, R12, LR, PC, CPSR +#define STACK_OFFSET_R0(stack_frame) \ + ((((stack_frame) & 0x04U) != 0U) ? ((32U*8U) + (2U*4U) + (8U*4U)) : \ + (((stack_frame) & 0x02U) != 0U) ? ((16U*8U) + (2U*4U) + (8U*4U)) : \ + (8U*4U)) + +#define OS_TICK_HANDLER osRtxTick_Handler + +/* Emulate M profile get_PSP: SP_usr - (8*4) */ +#if defined(__CC_ARM) +static __asm uint32_t __get_PSP (void) { + arm + sub sp, sp, #4 + stm sp, {sp}^ + pop {r0} + sub r0, r0, #32 + bx lr +} +#else +__STATIC_INLINE uint32_t __get_PSP (void) { + register uint32_t ret; + + __asm volatile ( + ".syntax unified\n\t" + ".arm\n\t" + "sub sp,sp,#4\n\t" + "stm sp,{sp}^\n\t" + "pop {%[ret]}\n\t" + "sub %[ret],%[ret],#32\n\t" + : [ret] "=&l" (ret) + : + : "memory" + ); + + return ret; +} +#endif + +__STATIC_INLINE void __set_CONTROL(uint32_t control) { +} + + +// ==== Service Calls definitions ==== + +#if defined(__CC_ARM) + +#define __SVC_INDIRECT(n) __svc_indirect(n) + +#define SVC0_0N(f,t) \ +__SVC_INDIRECT(0) t svc##f (t(*)()); \ + t svcRtx##f (void); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + svc##f(svcRtx##f); \ +} + +#define SVC0_0(f,t) \ +__SVC_INDIRECT(0) t svc##f (t(*)()); \ + t svcRtx##f (void); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + return svc##f(svcRtx##f); \ +} + +#define SVC0_1N(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1),t1); \ + t svcRtx##f (t1 a1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + svc##f(svcRtx##f,a1); \ +} + +#define SVC0_1(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1),t1); \ + t svcRtx##f (t1 a1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + return svc##f(svcRtx##f,a1); \ +} + +#define SVC0_2(f,t,t1,t2) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1,t2),t1,t2); \ + t svcRtx##f (t1 a1, t2 a2); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \ + return svc##f(svcRtx##f,a1,a2); \ +} + +#define SVC0_3(f,t,t1,t2,t3) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1,t2,t3),t1,t2,t3); \ + t svcRtx##f (t1 a1, t2 a2, t3 a3); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \ + return svc##f(svcRtx##f,a1,a2,a3); \ +} + +#define SVC0_4(f,t,t1,t2,t3,t4) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \ + t svcRtx##f (t1 a1, t2 a2, t3 a3, t4 a4); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + return svc##f(svcRtx##f,a1,a2,a3,a4); \ +} + +#define SVC0_0M SVC0_0 +#define SVC0_1M SVC0_1 +#define SVC0_2M SVC0_2 +#define SVC0_3M SVC0_3 +#define SVC0_4M SVC0_4 + +#elif defined(__ICCARM__) + +#define SVC_Setup(f) \ + __asm( \ + "mov r12,%0\n" \ + :: "r"(&f): "r12" \ + ); + +#define STRINGIFY(a) #a +#define __SVC_INDIRECT(n) _Pragma(STRINGIFY(swi_number = n)) __swi + +#define SVC0_0N(f,t) \ +__SVC_INDIRECT(0) t svc##f (); \ + t svcRtx##f (void); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_Setup(svcRtx##f); \ + svc##f(); \ +} + +#define SVC0_0(f,t) \ +__SVC_INDIRECT(0) t svc##f (); \ + t svcRtx##f (void); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_Setup(svcRtx##f); \ + return svc##f(); \ +} + +#define SVC0_1N(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t1 a1); \ + t svcRtx##f (t1 a1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_Setup(svcRtx##f); \ + svc##f(a1); \ +} + +#define SVC0_1(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t1 a1); \ + t svcRtx##f (t1 a1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_Setup(svcRtx##f); \ + return svc##f(a1); \ +} + +#define SVC0_2(f,t,t1,t2) \ +__SVC_INDIRECT(0) t svc##f (t1 a1, t2 a2); \ + t svcRtx##f (t1 a1, t2 a2); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \ + SVC_Setup(svcRtx##f); \ + return svc##f(a1,a2); \ +} + +#define SVC0_3(f,t,t1,t2,t3) \ +__SVC_INDIRECT(0) t svc##f (t1 a1, t2 a2, t3 a3); \ + t svcRtx##f (t1 a1, t2 a2, t3 a3); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \ + SVC_Setup(svcRtx##f); \ + return svc##f(a1,a2,a3); \ +} + +#define SVC0_4(f,t,t1,t2,t3,t4) \ +__SVC_INDIRECT(0) t svc##f (t1 a1, t2 a2, t3 a3, t4 a4); \ + t svcRtx##f (t1 a1, t2 a2, t3 a3, t4 a4); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_Setup(svcRtx##f); \ + return svc##f(a1,a2,a3,a4); \ +} + +#define SVC0_0M SVC0_0 +#define SVC0_1M SVC0_1 +#define SVC0_2M SVC0_2 +#define SVC0_3M SVC0_3 +#define SVC0_4M SVC0_4 + +#else // !(defined(__CC_ARM) || defined(__ICCARM__)) + +#define SVC_RegF "r12" + +#define SVC_ArgN(n) \ +register uint32_t __r##n __ASM("r"#n) + +#define SVC_ArgR(n,a) \ +register uint32_t __r##n __ASM("r"#n) = (uint32_t)a + +#define SVC_ArgF(f) \ +register uint32_t __rf __ASM(SVC_RegF) = (uint32_t)f + +#define SVC_In0 "r"(__rf) +#define SVC_In1 "r"(__rf),"r"(__r0) +#define SVC_In2 "r"(__rf),"r"(__r0),"r"(__r1) +#define SVC_In3 "r"(__rf),"r"(__r0),"r"(__r1),"r"(__r2) +#define SVC_In4 "r"(__rf),"r"(__r0),"r"(__r1),"r"(__r2),"r"(__r3) + +#define SVC_Out0 +#define SVC_Out1 "=r"(__r0) +#define SVC_Out2 "=r"(__r0),"=r"(__r1) + +#define SVC_CL0 +#define SVC_CL1 "r1" +#define SVC_CL2 "r0","r1" + +#define SVC_Call0(in, out, cl) \ + __ASM volatile ("svc 0" : out : in : cl) + +#define SVC0_0N(f,t) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In0, SVC_Out0, SVC_CL2); \ +} + +#define SVC0_0(f,t) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_ArgN(0); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In0, SVC_Out1, SVC_CL1); \ + return (t) __r0; \ +} + +#define SVC0_1N(f,t,t1) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_ArgR(0,a1); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In1, SVC_Out0, SVC_CL1); \ +} + +#define SVC0_1(f,t,t1) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_ArgR(0,a1); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In1, SVC_Out1, SVC_CL1); \ + return (t) __r0; \ +} + +#define SVC0_2(f,t,t1,t2) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \ + SVC_ArgR(0,a1); \ + SVC_ArgR(1,a2); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In2, SVC_Out1, SVC_CL0); \ + return (t) __r0; \ +} + +#define SVC0_3(f,t,t1,t2,t3) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \ + SVC_ArgR(0,a1); \ + SVC_ArgR(1,a2); \ + SVC_ArgR(2,a3); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In3, SVC_Out1, SVC_CL0); \ + return (t) __r0; \ +} + +#define SVC0_4(f,t,t1,t2,t3,t4) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_ArgR(0,a1); \ + SVC_ArgR(1,a2); \ + SVC_ArgR(2,a3); \ + SVC_ArgR(3,a4); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In4, SVC_Out1, SVC_CL0); \ + return (t) __r0; \ +} + +#define SVC0_0M SVC0_0 +#define SVC0_1M SVC0_1 +#define SVC0_2M SVC0_2 +#define SVC0_3M SVC0_3 +#define SVC0_4M SVC0_4 + +#endif + + +// ==== Core Peripherals functions ==== + +extern uint8_t IRQ_PendSV; + +/// Initialize SVC and PendSV System Service Calls (not needed on Cortex-A) +__STATIC_INLINE void SVC_Initialize (void) { +} + +/// Get Pending SV (Service Call) Flag +/// \return Pending SV Flag +__STATIC_INLINE uint8_t GetPendSV (void) { + return (IRQ_PendSV); +} + +/// Clear Pending SV (Service Call) Flag +__STATIC_INLINE void ClrPendSV (void) { + IRQ_PendSV = 0U; +} + +/// Set Pending SV (Service Call) Flag +__STATIC_INLINE void SetPendSV (void) { + IRQ_PendSV = 1U; +} + + +// ==== Exclusive Access Operation ==== + +#if (__EXCLUSIVE_ACCESS == 1U) + +/// Atomic Access Operation: Write (8-bit) +/// \param[in] mem Memory address +/// \param[in] val Value to write +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint8_t atomic_wr8 (uint8_t *mem, uint8_t val) { + mov r2,r0 +1 + ldrexb r0,[r2] + strexb r3,r1,[r2] + cmp r3,#0 + bne %B1 + bx lr +} +#else +__STATIC_INLINE uint8_t atomic_wr8 (uint8_t *mem, uint8_t val) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint8_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrexb %[ret],[%[mem]]\n\t" + "strexb %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n\t" + : [ret] "=&l" (ret), + [res] "=&l" (res) + : [mem] "l" (mem), + [val] "l" (val) + : "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Set bits (32-bit) +/// \param[in] mem Memory address +/// \param[in] bits Bit mask +/// \return New value +#if defined(__CC_ARM) +static __asm uint32_t atomic_set32 (uint32_t *mem, uint32_t bits) { + mov r2,r0 +1 + ldrex r0,[r2] + orr r0,r0,r1 + strex r3,r0,[r2] + cmp r3,#0 + bne %B1 + bx lr +} +#else +__STATIC_INLINE uint32_t atomic_set32 (uint32_t *mem, uint32_t bits) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[val],[%[mem]]\n\t" + "orr %[ret],%[val],%[bits]\n\t" + "strex %[res],%[ret],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [bits] "l" (bits) + : "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Clear bits (32-bit) +/// \param[in] mem Memory address +/// \param[in] bits Bit mask +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint32_t atomic_clr32 (uint32_t *mem, uint32_t bits) { + push {r4,lr} + mov r2,r0 +1 + ldrex r0,[r2] + bic r4,r0,r1 + strex r3,r4,[r2] + cmp r3,#0 + bne %B1 + pop {r4,pc} +} +#else +__STATIC_INLINE uint32_t atomic_clr32 (uint32_t *mem, uint32_t bits) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "bic %[val],%[ret],%[bits]\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [bits] "l" (bits) + : "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Check if all specified bits (32-bit) are active and clear them +/// \param[in] mem Memory address +/// \param[in] bits Bit mask +/// \return Active bits before clearing or 0 if not active +#if defined(__CC_ARM) +static __asm uint32_t atomic_chk32_all (uint32_t *mem, uint32_t bits) { + push {r4,lr} + mov r2,r0 +1 + ldrex r0,[r2] + and r4,r0,r1 + cmp r4,r1 + beq %F2 + clrex + movs r0,#0 + pop {r4,pc} +2 + bic r4,r0,r1 + strex r3,r4,[r2] + cmp r3,#0 + bne %B1 + pop {r4,pc} +} +#else +__STATIC_INLINE uint32_t atomic_chk32_all (uint32_t *mem, uint32_t bits) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "and %[val],%[ret],%[bits]\n\t" + "cmp %[val],%[bits]\n\t" + "beq 2f\n\t" + "clrex\n\t" + "movs %[ret],#0\n\t" + "b 3f\n" + "2:\n\t" + "bic %[val],%[ret],%[bits]\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [bits] "l" (bits) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Check if any specified bits (32-bit) are active and clear them +/// \param[in] mem Memory address +/// \param[in] bits Bit mask +/// \return Active bits before clearing or 0 if not active +#if defined(__CC_ARM) +static __asm uint32_t atomic_chk32_any (uint32_t *mem, uint32_t bits) { + push {r4,lr} + mov r2,r0 +1 + ldrex r0,[r2] + tst r0,r1 + bne %F2 + clrex + movs r0,#0 + pop {r4,pc} +2 + bic r4,r0,r1 + strex r3,r4,[r2] + cmp r3,#0 + bne %B1 + pop {r4,pc} +} +#else +__STATIC_INLINE uint32_t atomic_chk32_any (uint32_t *mem, uint32_t bits) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "tst %[ret],%[bits]\n\t" + "bne 2f\n\t" + "clrex\n\t" + "movs %[ret],#0\n\t" + "b 3f\n" + "2:\n\t" + "bic %[val],%[ret],%[bits]\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [bits] "l" (bits) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Increment (32-bit) +/// \param[in] mem Memory address +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint32_t atomic_inc32 (uint32_t *mem) { + mov r2,r0 +1 + ldrex r0,[r2] + adds r1,r0,#1 + strex r3,r1,[r2] + cmp r3,#0 + bne %B1 + bx lr +} +#else +__STATIC_INLINE uint32_t atomic_inc32 (uint32_t *mem) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "adds %[val],%[ret],#1\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// atomic Access Operation: Increment (32-bit) if Less Than +/// \param[in] mem Memory address +/// \param[in] max Maximum value +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint32_t atomic_inc32_lt (uint32_t *mem, uint32_t max) { + push {r4,lr} + mov r2,r0 +1 + ldrex r0,[r2] + cmp r1,r0 + bhi %F2 + clrex + pop {r4,pc} +2 + adds r4,r0,#1 + strex r3,r4,[r2] + cmp r3,#0 + bne %B1 + pop {r4,pc} +} +#else +__STATIC_INLINE uint32_t atomic_inc32_lt (uint32_t *mem, uint32_t max) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "cmp %[max],%[ret]\n\t" + "bhi 2f\n\t" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "adds %[val],%[ret],#1\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [max] "l" (max) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Increment (16-bit) if Less Than +/// \param[in] mem Memory address +/// \param[in] max Maximum value +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint16_t atomic_inc16_lt (uint16_t *mem, uint16_t max) { + push {r4,lr} + mov r2,r0 +1 + ldrexh r0,[r2] + cmp r1,r0 + bhi %F2 + clrex + pop {r4,pc} +2 + adds r4,r0,#1 + strexh r3,r4,[r2] + cmp r3,#0 + bne %B1 + pop {r4,pc} +} +#else +__STATIC_INLINE uint16_t atomic_inc16_lt (uint16_t *mem, uint16_t max) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint16_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrexh %[ret],[%[mem]]\n\t" + "cmp %[max],%[ret]\n\t" + "bhi 2f\n\t" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "adds %[val],%[ret],#1\n\t" + "strexh %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [max] "l" (max) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Increment (16-bit) and clear on Limit +/// \param[in] mem Memory address +/// \param[in] max Maximum value +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint16_t atomic_inc16_lim (uint16_t *mem, uint16_t lim) { + push {r4,lr} + mov r2,r0 +1 + ldrexh r0,[r2] + adds r4,r0,#1 + cmp r1,r4 + bhi %F2 + movs r4,#0 +2 + strexh r3,r4,[r2] + cmp r3,#0 + bne %B1 + pop {r4,pc} +} +#else +__STATIC_INLINE uint16_t atomic_inc16_lim (uint16_t *mem, uint16_t lim) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint16_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrexh %[ret],[%[mem]]\n\t" + "adds %[val],%[ret],#1\n\t" + "cmp %[lim],%[val]\n\t" + "bhi 2f\n\t" + "movs %[val],#0\n" + "2:\n\t" + "strexh %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [lim] "l" (lim) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Decrement (32-bit) if Not Zero +/// \param[in] mem Memory address +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint32_t atomic_dec32_nz (uint32_t *mem) { + mov r2,r0 +1 + ldrex r0,[r2] + cmp r0,#0 + bne %F2 + clrex + bx lr +2 + subs r1,r0,#1 + strex r3,r1,[r2] + cmp r3,#0 + bne %B1 + bx lr +} +#else +__STATIC_INLINE uint32_t atomic_dec32_nz (uint32_t *mem) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "cmp %[ret],#0\n\t" + "bne 2f\n" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "subs %[val],%[ret],#1\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Decrement (16-bit) if Not Zero +/// \param[in] mem Memory address +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint16_t atomic_dec16_nz (uint16_t *mem) { + mov r2,r0 +1 + ldrexh r0,[r2] + cmp r0,#0 + bne %F2 + clrex + bx lr +2 + subs r1,r0,#1 + strexh r3,r1,[r2] + cmp r3,#0 + bne %B1 + bx lr +} +#else +__STATIC_INLINE uint16_t atomic_dec16_nz (uint16_t *mem) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint16_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrexh %[ret],[%[mem]]\n\t" + "cmp %[ret],#0\n\t" + "bne 2f\n\t" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "subs %[val],%[ret],#1\n\t" + "strexh %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Link Get +/// \param[in] root Root address +/// \return Link +#if defined(__CC_ARM) +static __asm void *atomic_link_get (void **root) { + mov r2,r0 +1 + ldrex r0,[r2] + cmp r0,#0 + bne %F2 + clrex + bx lr +2 + ldr r1,[r0] + strex r3,r1,[r2] + cmp r3,#0 + bne %B1 + bx lr +} +#else +__STATIC_INLINE void *atomic_link_get (void **root) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register void *ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[root]]\n\t" + "cmp %[ret],#0\n\t" + "bne 2f\n\t" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "ldr %[val],[%[ret]]\n\t" + "strex %[res],%[val],[%[root]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [root] "l" (root) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Link Put +/// \param[in] root Root address +/// \param[in] lnk Link +#if defined(__CC_ARM) +static __asm void atomic_link_put (void **root, void *link) { +1 + ldr r2,[r0] + str r2,[r1] + dmb + ldrex r2,[r0] + ldr r3,[r1] + cmp r3,r2 + bne %B1 + strex r3,r1,[r0] + cmp r3,#0 + bne %B1 + bx lr +} +#else +__STATIC_INLINE void atomic_link_put (void **root, void *link) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val1, val2, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldr %[val1],[%[root]]\n\t" + "str %[val1],[%[link]]\n\t" + "dmb\n\t" + "ldrex %[val1],[%[root]]\n\t" + "ldr %[val2],[%[link]]\n\t" + "cmp %[val2],%[val1]\n\t" + "bne 1b\n\t" + "strex %[res],%[link],[%[root]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + : [val1] "=&l" (val1), + [val2] "=&l" (val2), + [res] "=&l" (res) + : [root] "l" (root), + [link] "l" (link) + : "cc", "memory" + ); +} +#endif + +#endif // (__EXCLUSIVE_ACCESS == 1U) + + +#endif // RTX_CORE_CA_H_ diff --git a/rtos/TARGET_CORTEX/rtx5/core_cm.h b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_cm.h similarity index 90% rename from rtos/TARGET_CORTEX/rtx5/core_cm.h rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_cm.h index 1590bd6c65a..3f2e8d1a4ba 100644 --- a/rtos/TARGET_CORTEX/rtx5/core_cm.h +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_cm.h @@ -1,5 +1,3 @@ -/** \addtogroup rtos */ -/** @{*/ /* * Copyright (c) 2013-2017 ARM Limited. All rights reserved. * @@ -25,37 +23,11 @@ * ----------------------------------------------------------------------------- */ -#ifndef CORE_CM_H_ -#define CORE_CM_H_ +#ifndef RTX_CORE_CM_H_ +#define RTX_CORE_CM_H_ -#include -#include "cmsis.h" -#include "cmsis_compiler.h" -#include "arm_math.h" - -#ifndef __ARM_ARCH_6M__ -#define __ARM_ARCH_6M__ 0U -#endif -#ifndef __ARM_ARCH_7M__ -#define __ARM_ARCH_7M__ 0U -#endif -#ifndef __ARM_ARCH_7EM__ -#define __ARM_ARCH_7EM__ 0U -#endif -#ifndef __ARM_ARCH_8M_BASE__ -#define __ARM_ARCH_8M_BASE__ 0U -#endif -#ifndef __ARM_ARCH_8M_MAIN__ -#define __ARM_ARCH_8M_MAIN__ 0U -#endif - -#if ((__ARM_ARCH_6M__ + \ - __ARM_ARCH_7M__ + \ - __ARM_ARCH_7EM__ + \ - __ARM_ARCH_8M_BASE__ + \ - __ARM_ARCH_8M_MAIN__) != 1U) -#error "Unknown ARM Architecture!" -#endif +#include "RTE_Components.h" +#include CMSIS_device_header #ifdef RTE_CMSIS_RTOS2_RTX5_ARMV8M_NS #define __DOMAIN_NS 1U @@ -81,7 +53,6 @@ #endif #endif - #define IS_PRIVILEGED() ((__get_CONTROL() & 1U) == 0U) #define IS_IRQ_MODE() (__get_IPSR() != 0U) @@ -94,7 +65,7 @@ #define IS_IRQ_MASKED() (__get_PRIMASK() != 0U) #endif -#define XPSR_INITIAL_VALUE 0x01000000U +#define xPSR_INIT(...) 0x01000000U #if (__DOMAIN_NS == 1U) #define STACK_FRAME_INIT 0xBCU @@ -102,7 +73,18 @@ #define STACK_FRAME_INIT 0xFDU #endif -#define IS_EXTENDED_STACK_FRAME(n) (((n) & 0x10U) == 0U) +// Stack Frame: +// - Extended: S16-S31, R4-R11, R0-R3, R12, LR, PC, xPSR, S0-S15, FPSCR +// - Basic: R4-R11, R0-R3, R12, LR, PC, xPSR +#if (__FPU_USED == 1U) +#define STACK_OFFSET_R0(stack_frame) \ + ((((stack_frame) & 0x10U) == 0U) ? ((16U+8U)*4U) : \ + (8U *4U)) +#else +#define STACK_OFFSET_R0(stack_frame) (8U *4U) +#endif + +#define OS_TICK_HANDLER SysTick_Handler // ==== Service Calls definitions ==== @@ -157,8 +139,6 @@ __STATIC_INLINE t __svc##f (void) { \ return svc##f(svcRtx##f); \ } -#define SVC0_0D SVC0_0 - #define SVC0_1N(f,t,t1) \ __SVC_INDIRECT(0) t svc##f (t(*)(t1),t1); \ t svcRtx##f (t1 a1); \ @@ -299,8 +279,6 @@ __STATIC_INLINE t __svc##f (void) { \ return svc##f(); \ } -#define SVC0_0D SVC0_0 - #define SVC0_1N(f,t,t1) \ __SVC_INDIRECT(0) t svc##f (t1 a1); \ t svcRtx##f (t1 a1); \ @@ -504,16 +482,6 @@ __STATIC_INLINE t __svc##f (void) { \ return (t) __r0; \ } -#define SVC0_0D(f,t) \ -__attribute__((always_inline)) \ -__STATIC_INLINE t __svc##f (void) { \ - SVC_ArgN(0); \ - SVC_ArgN(1); \ - SVC_ArgF(svcRtx##f); \ - SVC_Call0(SVC_In0, SVC_Out2, SVC_CL0); \ - return (((t) __r0) | (((t) __r1) << 32)); \ -} - #define SVC0_1N(f,t,t1) \ __attribute__((always_inline)) \ __STATIC_INLINE t __svc##f (t1 a1) { \ @@ -611,9 +579,6 @@ __STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ // ==== Core Peripherals functions ==== -extern uint32_t SystemCoreClock; // System Clock Frequency (Core Clock) - - /// Initialize SVC and PendSV System Service Calls __STATIC_INLINE void SVC_Initialize (void) { #if ((__ARM_ARCH_8M_MAIN__ == 1U) || (defined(__CORTEX_M) && (__CORTEX_M == 7U))) @@ -627,8 +592,11 @@ __STATIC_INLINE void SVC_Initialize (void) { } SCB->SHPR[7] = (uint8_t)(0xFEU << n); #elif (__ARM_ARCH_8M_BASE__ == 1U) + uint32_t n; + SCB->SHPR[1] |= 0x00FF0000U; - SCB->SHPR[0] |= (SCB->SHPR[1] << (8+1)) & 0xFC000000U; + n = SCB->SHPR[1]; + SCB->SHPR[0] |= (n << (8+1)) & 0xFC000000U; #elif ((__ARM_ARCH_7M__ == 1U) || \ (__ARM_ARCH_7EM__ == 1U)) uint32_t p, n; @@ -639,111 +607,22 @@ __STATIC_INLINE void SVC_Initialize (void) { if (p >= n) { n = p + 1U; } - -/* Only change the SVCall priority if uVisor is not present. */ -#if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)) SCB->SHP[7] = (uint8_t)(0xFEU << n); -#endif -#elif (__ARM_ARCH_6M__ == 1U) - SCB->SHP[1] |= 0x00FF0000U; - SCB->SHP[0] |= (SCB->SHP[1] << (8+1)) & 0xFC000000U; -#endif -} - -/// Setup SysTick Timer -/// \param[in] period Timer Load value -__STATIC_INLINE void SysTick_Setup (uint32_t period) { - SysTick->LOAD = period - 1U; - SysTick->VAL = 0U; -#if ((__ARM_ARCH_8M_MAIN__ == 1U) || (defined(__CORTEX_M) && (__CORTEX_M == 7U))) - SCB->SHPR[11] = 0xFFU; -#elif (__ARM_ARCH_8M_BASE__ == 1U) - SCB->SHPR[1] |= 0xFF000000U; -#elif ((__ARM_ARCH_7M__ == 1U) || \ - (__ARM_ARCH_7EM__ == 1U)) - SCB->SHP[11] = 0xFFU; #elif (__ARM_ARCH_6M__ == 1U) - SCB->SHP[1] |= 0xFF000000U; -#endif -} - -/// Get SysTick Period -/// \return SysTick Period -__STATIC_INLINE uint32_t SysTick_GetPeriod (void) { - return (SysTick->LOAD + 1U); -} - -/// Get SysTick Value -/// \return SysTick Value -__STATIC_INLINE uint32_t SysTick_GetVal (void) { - uint32_t load = SysTick->LOAD; - return (load - SysTick->VAL); -} - -/// Get SysTick Overflow (Auto Clear) -/// \return SysTick Overflow flag -__STATIC_INLINE uint32_t SysTick_GetOvf (void) { - return ((SysTick->CTRL >> 16) & 1U); -} - -/// Enable SysTick Timer -__STATIC_INLINE void SysTick_Enable (void) { - SysTick->CTRL = SysTick_CTRL_ENABLE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_CLKSOURCE_Msk; -} - -/// Disable SysTick Timer -__STATIC_INLINE void SysTick_Disable (void) { - SysTick->CTRL = 0U; -} + uint32_t n; -/// Setup External Tick Timer Interrupt -/// \param[in] irqn Interrupt number -__STATIC_INLINE void ExtTick_SetupIRQ (int32_t irqn) { -#if (__ARM_ARCH_8M_MAIN__ == 1U) - NVIC->IPR[irqn] = 0xFFU; -#elif (__ARM_ARCH_8M_BASE__ == 1U) - NVIC->IPR[irqn >> 2] = (NVIC->IPR[irqn >> 2] & ~(0xFFU << ((irqn & 3) << 3))) | - (0xFFU << ((irqn & 3) << 3)); -#elif ((__ARM_ARCH_7M__ == 1U) || \ - (__ARM_ARCH_7EM__ == 1U)) - NVIC->IP[irqn] = 0xFFU; -#elif (__ARM_ARCH_6M__ == 1U) - NVIC->IP[irqn >> 2] = (NVIC->IP[irqn >> 2] & ~(0xFFU << ((irqn & 3) << 3))) | - (0xFFU << ((irqn & 3) << 3)); + SCB->SHP[1] |= 0x00FF0000U; + n = SCB->SHP[1]; + SCB->SHP[0] |= (n << (8+1)) & 0xFC000000U; #endif } -/// Enable External Tick Timer Interrupt -/// \param[in] irqn Interrupt number -__STATIC_INLINE void ExtTick_EnableIRQ (int32_t irqn) { - NVIC->ISER[irqn >> 5] = 1U << (irqn & 0x1F); -} - -/// Disable External Tick Timer Interrupt -/// \param[in] irqn Interrupt number -__STATIC_INLINE void ExtTick_DisableIRQ (int32_t irqn) { - NVIC->ICER[irqn >> 5] = 1U << (irqn & 0x1F); -} - -/// Get Pending SV (Service Call) and ST (SysTick) Flags -/// \return Pending SV&ST Flags -__STATIC_INLINE uint8_t GetPendSV_ST (void) { - return ((uint8_t)((SCB->ICSR & (SCB_ICSR_PENDSVSET_Msk | SCB_ICSR_PENDSTSET_Msk)) >> 24)); -} - /// Get Pending SV (Service Call) Flag /// \return Pending SV Flag __STATIC_INLINE uint8_t GetPendSV (void) { return ((uint8_t)((SCB->ICSR & (SCB_ICSR_PENDSVSET_Msk)) >> 24)); } -/// Clear Pending SV (Service Call) and ST (SysTick) Flags -__STATIC_INLINE void ClrPendSV_ST (void) { - SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk; -} - /// Clear Pending SV (Service Call) Flag __STATIC_INLINE void ClrPendSV (void) { SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk; @@ -754,12 +633,6 @@ __STATIC_INLINE void SetPendSV (void) { SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; } -/// Set Pending Flags -/// \param[in] flags Flags to set -__STATIC_INLINE void SetPendFlags (uint8_t flags) { - SCB->ICSR = ((uint32_t)flags << 24); -} - // ==== Exclusive Access Operation ==== @@ -1529,6 +1402,4 @@ __STATIC_INLINE void atomic_link_put (void **root, void *link) { #endif // (__EXCLUSIVE_ACCESS == 1U) -#endif // CORE_CM_H_ - -/** @}*/ +#endif // RTX_CORE_CM_H_ diff --git a/rtos/TARGET_CORTEX/rtx5/rtx_delay.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_delay.c similarity index 83% rename from rtos/TARGET_CORTEX/rtx5/rtx_delay.c rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_delay.c index a7e71b7777b..17e90c28587 100644 --- a/rtos/TARGET_CORTEX/rtx5/rtx_delay.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_delay.c @@ -30,7 +30,7 @@ // Service Calls definitions SVC0_1(Delay, osStatus_t, uint32_t) -SVC0_2(DelayUntil, osStatus_t, uint32_t, uint32_t) +SVC0_1(DelayUntil, osStatus_t, uint32_t) /// Wait for Timeout (Time Delay). /// \note API identical to osDelay @@ -47,11 +47,10 @@ osStatus_t svcRtxDelay (uint32_t ticks) { /// Wait until specified time. /// \note API identical to osDelayUntil -osStatus_t svcRtxDelayUntil (uint32_t ticks_l, uint32_t ticks_h) { - uint64_t ticks = ((uint64_t)ticks_l) | ((uint64_t)ticks_h << 32); +osStatus_t svcRtxDelayUntil (uint32_t ticks) { ticks -= osRtxInfo.kernel.tick; - if (ticks >= 0xFFFFFFFFU) { + if (ticks == 0xFFFFFFFFU) { EvrRtxThreadError(NULL, osErrorParameter); return osErrorParameter; } @@ -59,7 +58,7 @@ osStatus_t svcRtxDelayUntil (uint32_t ticks_l, uint32_t ticks_h) { return osOK; } - osRtxThreadWaitEnter(osRtxThreadWaitingDelay, (uint32_t)ticks); + osRtxThreadWaitEnter(osRtxThreadWaitingDelay, ticks); return osOK; } @@ -78,11 +77,11 @@ osStatus_t osDelay (uint32_t ticks) { } /// Wait until specified time. -osStatus_t osDelayUntil (uint64_t ticks) { +osStatus_t osDelayUntil (uint32_t ticks) { EvrRtxThreadDelayUntil(ticks); if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { EvrRtxThreadError(NULL, osErrorISR); return osErrorISR; } - return __svcDelayUntil((uint32_t)ticks, (uint32_t)(ticks >> 32)); + return __svcDelayUntil(ticks); } diff --git a/rtos/TARGET_CORTEX/rtx5/rtx_evflags.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_evflags.c similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/rtx_evflags.c rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_evflags.c diff --git a/rtos/TARGET_CORTEX/rtx5/rtx_evr.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_evr.c similarity index 99% rename from rtos/TARGET_CORTEX/rtx5/rtx_evr.c rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_evr.c index f368df828a8..f81b927c83f 100644 --- a/rtos/TARGET_CORTEX/rtx5/rtx_evr.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_evr.c @@ -27,6 +27,8 @@ #include "cmsis_compiler.h" #include "rtx_evr.h" // RTX Event Recorder definitions +#include "RTE_Components.h" + #ifdef RTE_Compiler_EventRecorder #include "EventRecorder.h" // Keil::Compiler:Event Recorder @@ -501,9 +503,9 @@ __WEAK void EvrRtxKernelResumed (void) { #endif #if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_TICK_COUNT_DISABLE)) -__WEAK void EvrRtxKernelGetTickCount (uint64_t count) { +__WEAK void EvrRtxKernelGetTickCount (uint32_t count) { #if defined(RTE_Compiler_EventRecorder) - EventRecord2(EvtRtxKernelGetTickCount, (uint32_t)count, (uint32_t)(count>>32)); + EventRecord2(EvtRtxKernelGetTickCount, count, 0U); #else (void)count; #endif @@ -958,9 +960,9 @@ __WEAK void EvrRtxThreadDelay (uint32_t ticks) { #endif #if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DELAY_UNTIL_DISABLE)) -__WEAK void EvrRtxThreadDelayUntil (uint64_t ticks) { +__WEAK void EvrRtxThreadDelayUntil (uint32_t ticks) { #if defined(RTE_Compiler_EventRecorder) - EventRecord2(EvtRtxThreadDelayUntil, (uint32_t)ticks, (uint32_t)(ticks >> 32)); + EventRecord2(EvtRtxThreadDelayUntil, ticks, 0U); #else (void)ticks; #endif diff --git a/rtos/TARGET_CORTEX/rtx5/rtx_kernel.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_kernel.c similarity index 92% rename from rtos/TARGET_CORTEX/rtx5/rtx_kernel.c rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_kernel.c index 1f9a91f7d14..fad31603bf3 100644 --- a/rtos/TARGET_CORTEX/rtx5/rtx_kernel.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_kernel.c @@ -24,7 +24,6 @@ */ #include "rtx_lib.h" -#include "rt_OsEventObserver.h" // OS Runtime Information @@ -37,18 +36,14 @@ osRtxInfo_t osRtxInfo __attribute__((section(".data.os"))) = /// Block Kernel (disable: thread switching, time tick, post ISR processing). static void KernelBlock (void) { - if (osRtxInfo.tick_irqn >= 0) { - ExtTick_DisableIRQ(osRtxInfo.tick_irqn); - } - osRtxSysTimerDisable(); + OS_Tick_Disable(); + osRtxInfo.kernel.blocked = 1U; __DSB(); - if (osRtxInfo.tick_irqn < 0) { - osRtxInfo.kernel.pendISR = GetPendSV_ST(); - ClrPendSV_ST(); - } else { - osRtxInfo.kernel.pendISR = GetPendSV(); + + if (GetPendSV() != 0U) { ClrPendSV(); + osRtxInfo.kernel.pendSV = 1U; } } @@ -57,17 +52,13 @@ static void KernelUnblock (void) { osRtxInfo.kernel.blocked = 0U; __DSB(); + if (osRtxInfo.kernel.pendSV != 0U) { osRtxInfo.kernel.pendSV = 0U; SetPendSV(); } - if (osRtxInfo.kernel.pendISR != 0U) { - SetPendFlags(osRtxInfo.kernel.pendISR); - } - if (osRtxInfo.tick_irqn >= 0) { - ExtTick_EnableIRQ(osRtxInfo.tick_irqn); - } - osRtxSysTimerEnable(); + + OS_Tick_Enable(); } @@ -83,7 +74,7 @@ SVC0_1 (KernelRestoreLock, int32_t, int32_t) SVC0_0 (KernelSuspend, uint32_t) SVC0_1N(KernelResume, void, uint32_t) SVC0_0 (KernelGetState, osKernelState_t) -SVC0_0D(KernelGetTickCount, uint64_t) +SVC0_0 (KernelGetTickCount, uint32_t) SVC0_0 (KernelGetTickFreq, uint32_t) SVC0_0 (KernelGetSysTimerCount, uint32_t) SVC0_0 (KernelGetSysTimerFreq, uint32_t) @@ -254,7 +245,7 @@ osStatus_t svcRtxKernelStart (void) { // Create Idle Thread if (osRtxInfo.thread.idle == NULL) { - osRtxInfo.thread.idle = svcRtxThreadNew(osRtxIdleThread, NULL, osRtxConfig.idle_thread_attr, NULL); + osRtxInfo.thread.idle = svcRtxThreadNew(osRtxIdleThread, NULL, osRtxConfig.idle_thread_attr); if (osRtxInfo.thread.idle == NULL) { EvrRtxKernelError(osError); return osError; @@ -264,7 +255,7 @@ osStatus_t svcRtxKernelStart (void) { // Create Timer Thread if (osRtxConfig.timer_mq_mcnt != 0U) { if (osRtxInfo.timer.thread == NULL) { - osRtxInfo.timer.thread = svcRtxThreadNew(osRtxTimerThread, NULL, osRtxConfig.timer_thread_attr, NULL); + osRtxInfo.timer.thread = svcRtxThreadNew(osRtxTimerThread, NULL, osRtxConfig.timer_thread_attr); if (osRtxInfo.timer.thread == NULL) { EvrRtxKernelError(osError); return osError; @@ -272,6 +263,17 @@ osStatus_t svcRtxKernelStart (void) { } } + // Setup RTOS Tick + if (OS_Tick_Setup(osRtxConfig.tick_freq, OS_TICK_HANDLER) != 0U) { + return osError; + } + osRtxInfo.tick_irqn = OS_Tick_GetIRQn(); + + // Enable RTOS Tick + if (OS_Tick_Enable() != 0U) { + return osError; + } + // Switch to Ready Thread with highest Priority thread = osRtxThreadListGet(&osRtxInfo.thread.ready); if (thread == NULL) { @@ -288,16 +290,6 @@ osStatus_t svcRtxKernelStart (void) { __set_CONTROL(0x03U); } - osRtxInfo.kernel.sys_freq = SystemCoreClock; - - // Setup and Enable System Timer - osRtxInfo.tick_irqn = osRtxSysTimerSetup(); - if (osRtxInfo.tick_irqn >= 0) { - ExtTick_SetupIRQ (osRtxInfo.tick_irqn); - ExtTick_EnableIRQ(osRtxInfo.tick_irqn); - } - osRtxSysTimerEnable(); - osRtxInfo.kernel.state = osRtxKernelRunning; EvrRtxKernelStarted(); @@ -467,7 +459,7 @@ void svcRtxKernelResume (uint32_t sleep_ticks) { /// Get the RTOS kernel tick count. /// \note API identical to osKernelGetTickCount -uint64_t svcRtxKernelGetTickCount (void) { +uint32_t svcRtxKernelGetTickCount (void) { EvrRtxKernelGetTickCount(osRtxInfo.kernel.tick); return osRtxInfo.kernel.tick; } @@ -482,7 +474,16 @@ uint32_t svcRtxKernelGetTickFreq (void) { /// Get the RTOS kernel system timer count. /// \note API identical to osKernelGetSysTimerCount uint32_t svcRtxKernelGetSysTimerCount (void) { - uint32_t count = osRtxSysTimerGetCount(); + uint32_t tick; + uint32_t count; + + tick = (uint32_t)osRtxInfo.kernel.tick; + count = OS_Tick_GetCount(); + if (OS_Tick_GetOverflow()) { + count = OS_Tick_GetCount(); + tick++; + } + count += tick * OS_Tick_GetInterval(); EvrRtxKernelGetSysTimerCount(count); return count; } @@ -490,7 +491,7 @@ uint32_t svcRtxKernelGetSysTimerCount (void) { /// Get the RTOS kernel system timer frequency. /// \note API identical to osKernelGetSysTimerFreq uint32_t svcRtxKernelGetSysTimerFreq (void) { - uint32_t freq = osRtxSysTimerGetFreq(); + uint32_t freq = OS_Tick_GetClock(); EvrRtxKernelGetSysTimerFreq(freq); return freq; } @@ -542,15 +543,6 @@ osStatus_t osKernelStart (void) { EvrRtxKernelError(osErrorISR); return osErrorISR; } - - /* Call the pre-start event (from unprivileged mode) if the handler exists - * and the kernel is not running. */ - /* FIXME osEventObs needs to be readable but not writable from unprivileged - * code. */ - if (osKernelGetState() != osKernelRunning && osEventObs && osEventObs->pre_start) { - osEventObs->pre_start(); - } - return __svcKernelStart(); } @@ -605,7 +597,7 @@ void osKernelResume (uint32_t sleep_ticks) { } /// Get the RTOS kernel tick count. -uint64_t osKernelGetTickCount (void) { +uint32_t osKernelGetTickCount (void) { if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { return svcRtxKernelGetTickCount(); } else { diff --git a/rtos/TARGET_CORTEX/rtx5/rtx_lib.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_lib.c similarity index 97% rename from rtos/TARGET_CORTEX/rtx5/rtx_lib.c rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_lib.c index 70b18e917a8..1020f7adabc 100644 --- a/rtos/TARGET_CORTEX/rtx5/rtx_lib.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_lib.c @@ -595,11 +595,9 @@ void *__user_perthread_libspace (void) { typedef void *mutex; // Initialize mutex -#if !defined(__ARMCC_VERSION) || __ARMCC_VERSION < 6010050 __USED -#endif int _mutex_initialize(mutex *m); -__WEAK int _mutex_initialize(mutex *m) { +int _mutex_initialize(mutex *m) { *m = osMutexNew(NULL); if (*m == NULL) { osRtxErrorNotify(osRtxErrorClibMutex, m); @@ -609,33 +607,27 @@ __WEAK int _mutex_initialize(mutex *m) { } // Acquire mutex -#if !defined(__ARMCC_VERSION) || __ARMCC_VERSION < 6010050 __USED -#endif void _mutex_acquire(mutex *m); -__WEAK void _mutex_acquire(mutex *m) { +void _mutex_acquire(mutex *m) { if (os_kernel_is_active()) { osMutexAcquire(*m, osWaitForever); } } // Release mutex -#if !defined(__ARMCC_VERSION) || __ARMCC_VERSION < 6010050 __USED -#endif void _mutex_release(mutex *m); -__WEAK void _mutex_release(mutex *m) { +void _mutex_release(mutex *m) { if (os_kernel_is_active()) { osMutexRelease(*m); } } // Free mutex -#if !defined(__ARMCC_VERSION) || __ARMCC_VERSION < 6010050 __USED -#endif void _mutex_free(mutex *m); -__WEAK void _mutex_free(mutex *m) { +void _mutex_free(mutex *m) { osMutexDelete(*m); } diff --git a/rtos/TARGET_CORTEX/rtx5/rtx_lib.h b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_lib.h similarity index 97% rename from rtos/TARGET_CORTEX/rtx5/rtx_lib.h rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_lib.h index fb7423db1d7..17bfc006410 100644 --- a/rtos/TARGET_CORTEX/rtx5/rtx_lib.h +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_lib.h @@ -1,5 +1,3 @@ -/** \addtogroup rtos */ -/** @{*/ /* * Copyright (c) 2013-2017 ARM Limited. All rights reserved. * @@ -30,8 +28,11 @@ #include #include -#include "core_cm.h" // Cortex-M definitions +#include "rtx_core_c.h" // Cortex core definitions +#if ((__ARM_ARCH_8M_BASE__ != 0) || (__ARM_ARCH_8M_MAIN__ != 0)) #include "tz_context.h" // TrustZone Context API +#endif +#include "os_tick.h" #include "cmsis_os2.h" // CMSIS RTOS API #include "rtx_os.h" // RTX OS definitions #include "rtx_evr.h" // RTX Event Recorder definitions @@ -124,13 +125,13 @@ extern int32_t svcRtxKernelUnlock (void); extern int32_t svcRtxKernelRestoreLock (int32_t lock); extern uint32_t svcRtxKernelSuspend (void); extern void svcRtxKernelResume (uint32_t sleep_ticks); -extern uint64_t svcRtxKernelGetTickCount (void); +extern uint32_t svcRtxKernelGetTickCount (void); extern uint32_t svcRtxKernelGetTickFreq (void); extern uint32_t svcRtxKernelGetSysTimerCount (void); extern uint32_t svcRtxKernelGetSysTimerFreq (void); // Thread Service Calls -extern osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr, void *context); +extern osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); extern const char * svcRtxThreadGetName (osThreadId_t thread_id); extern osThreadId_t svcRtxThreadGetId (void); extern osThreadState_t svcRtxThreadGetState (osThreadId_t thread_id); @@ -154,7 +155,7 @@ extern uint32_t svcRtxThreadFlagsWait (uint32_t flags, uint32_t optio // Delay Service Calls extern osStatus_t svcRtxDelay (uint32_t ticks); -extern osStatus_t svcRtxDelayUntil (uint32_t ticks_l, uint32_t ticks_h); +extern osStatus_t svcRtxDelayUntil (uint32_t ticks); // Timer Service Calls extern osTimerId_t svcRtxTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr); @@ -212,5 +213,5 @@ extern uint32_t svcRtxMessageQueueGetSpace (osMessageQueueId_t mq_i extern osStatus_t svcRtxMessageQueueReset (osMessageQueueId_t mq_id); extern osStatus_t svcRtxMessageQueueDelete (osMessageQueueId_t mq_id); + #endif // RTX_LIB_H_ -/** @}*/ diff --git a/rtos/TARGET_CORTEX/rtx5/rtx_memory.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_memory.c similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/rtx_memory.c rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_memory.c diff --git a/rtos/TARGET_CORTEX/rtx5/rtx_mempool.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_mempool.c similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/rtx_mempool.c rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_mempool.c diff --git a/rtos/TARGET_CORTEX/rtx5/rtx_msgqueue.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_msgqueue.c similarity index 99% rename from rtos/TARGET_CORTEX/rtx5/rtx_msgqueue.c rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_msgqueue.c index d147e81c2f2..ae33f641f88 100644 --- a/rtos/TARGET_CORTEX/rtx5/rtx_msgqueue.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_msgqueue.c @@ -252,8 +252,7 @@ osMessageQueueId_t svcRtxMessageQueueNew (uint32_t msg_count, uint32_t msg_size, EvrRtxMessageQueueError(NULL, osErrorParameter); return NULL; } - msg_size = (msg_size + 3U) & ~3UL; - block_size = msg_size + sizeof(os_message_t); + block_size = ((msg_size + 3U) & ~3UL) + sizeof(os_message_t); if ((__CLZ(msg_count) + __CLZ(block_size)) < 32) { EvrRtxMessageQueueError(NULL, osErrorParameter); return NULL; diff --git a/rtos/TARGET_CORTEX/rtx5/rtx_mutex.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_mutex.c similarity index 93% rename from rtos/TARGET_CORTEX/rtx5/rtx_mutex.c rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_mutex.c index 4a274f8616b..2151c0251d0 100644 --- a/rtos/TARGET_CORTEX/rtx5/rtx_mutex.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_mutex.c @@ -161,10 +161,10 @@ const char *svcRtxMutexGetName (osMutexId_t mutex_id) { /// \note API identical to osMutexAcquire osStatus_t svcRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) { os_mutex_t *mutex = (os_mutex_t *)mutex_id; - os_thread_t *running_thread; + os_thread_t *runnig_thread; - running_thread = osRtxThreadGetRunning(); - if (running_thread == NULL) { + runnig_thread = osRtxThreadGetRunning(); + if (runnig_thread == NULL) { EvrRtxMutexError(mutex, osRtxErrorKernelNotRunning); return osError; } @@ -184,20 +184,20 @@ osStatus_t svcRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) { // Check if Mutex is not locked if (mutex->lock == 0U) { // Acquire Mutex - mutex->owner_thread = running_thread; - mutex->owner_next = running_thread->mutex_list; + mutex->owner_thread = runnig_thread; + mutex->owner_next = runnig_thread->mutex_list; mutex->owner_prev = NULL; - if (running_thread->mutex_list != NULL) { - running_thread->mutex_list->owner_prev = mutex; + if (runnig_thread->mutex_list != NULL) { + runnig_thread->mutex_list->owner_prev = mutex; } - running_thread->mutex_list = mutex; + runnig_thread->mutex_list = mutex; mutex->lock = 1U; EvrRtxMutexAcquired(mutex, mutex->lock); return osOK; } // Check if Mutex is recursive and running Thread is the owner - if ((mutex->attr & osMutexRecursive) && (mutex->owner_thread == running_thread)) { + if ((mutex->attr & osMutexRecursive) && (mutex->owner_thread == runnig_thread)) { // Increment lock counter if (mutex->lock == osRtxMutexLockLimit) { EvrRtxMutexError(mutex, osRtxErrorMutexLockLimit); @@ -213,14 +213,14 @@ osStatus_t svcRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) { // Check if Priority inheritance protocol is enabled if (mutex->attr & osMutexPrioInherit) { // Raise priority of owner Thread if lower than priority of running Thread - if (mutex->owner_thread->priority < running_thread->priority) { - mutex->owner_thread->priority = running_thread->priority; + if (mutex->owner_thread->priority < runnig_thread->priority) { + mutex->owner_thread->priority = runnig_thread->priority; osRtxThreadListSort(mutex->owner_thread); } } EvrRtxMutexAcquirePending(mutex, timeout); // Suspend current Thread - osRtxThreadListPut((os_object_t*)mutex, running_thread); + osRtxThreadListPut((os_object_t*)mutex, runnig_thread); osRtxThreadWaitEnter(osRtxThreadWaitingMutex, timeout); return osErrorTimeout; } @@ -237,11 +237,11 @@ osStatus_t svcRtxMutexRelease (osMutexId_t mutex_id) { os_mutex_t *mutex = (os_mutex_t *)mutex_id; os_mutex_t *mutex0; os_thread_t *thread; - os_thread_t *running_thread; + os_thread_t *runnig_thread; int8_t priority; - running_thread = osRtxThreadGetRunning(); - if (running_thread == NULL) { + runnig_thread = osRtxThreadGetRunning(); + if (runnig_thread == NULL) { EvrRtxMutexError(mutex, osRtxErrorKernelNotRunning); return osError; } @@ -259,7 +259,7 @@ osStatus_t svcRtxMutexRelease (osMutexId_t mutex_id) { } // Check if running Thread is not the owner - if (mutex->owner_thread != running_thread) { + if (mutex->owner_thread != runnig_thread) { EvrRtxMutexError(mutex, osRtxErrorMutexNotOwned); return osErrorResource; } @@ -286,13 +286,13 @@ osStatus_t svcRtxMutexRelease (osMutexId_t mutex_id) { if (mutex->owner_prev != NULL) { mutex->owner_prev->owner_next = mutex->owner_next; } else { - running_thread->mutex_list = mutex->owner_next; + runnig_thread->mutex_list = mutex->owner_next; } // Restore running Thread priority if (mutex->attr & osMutexPrioInherit) { - priority = running_thread->priority_base; - mutex0 = running_thread->mutex_list; + priority = runnig_thread->priority_base; + mutex0 = runnig_thread->mutex_list; while (mutex0) { // Mutexes owned by running Thread if ((mutex0->thread_list != NULL) && (mutex0->thread_list->priority > priority)) { @@ -301,7 +301,7 @@ osStatus_t svcRtxMutexRelease (osMutexId_t mutex_id) { } mutex0 = mutex0->owner_next; } - running_thread->priority = priority; + runnig_thread->priority = priority; } // Check if Thread is waiting for a Mutex diff --git a/rtos/TARGET_CORTEX/rtx5/rtx_semaphore.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_semaphore.c similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/rtx_semaphore.c rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_semaphore.c diff --git a/rtos/TARGET_CORTEX/rtx5/rtx_system.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_system.c similarity index 84% rename from rtos/TARGET_CORTEX/rtx5/rtx_system.c rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_system.c index c8715cd54d5..fc64c931c5b 100644 --- a/rtos/TARGET_CORTEX/rtx5/rtx_system.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_system.c @@ -120,7 +120,7 @@ static void *isr_queue_get (void) { void osRtxTick_Handler (void) { os_thread_t *thread; - osRtxSysTimerAckIRQ(); + OS_Tick_AcknowledgeIRQ(); osRtxInfo.kernel.tick++; // Process Timers @@ -207,51 +207,3 @@ void osRtxPostProcess (os_object_t *object) { osRtxErrorNotify(osRtxErrorISRQueueOverflow, object); } } - - -// ==== Public API ==== - -/// Setup System Timer. -__WEAK int32_t osRtxSysTimerSetup (void) { - - // Setup SysTick Timer - SysTick_Setup(osRtxInfo.kernel.sys_freq / osRtxConfig.tick_freq); - - return SysTick_IRQn; // Return IRQ number of SysTick -} - -/// Enable System Timer. -__WEAK void osRtxSysTimerEnable (void) { - SysTick_Enable(); -} - -/// Disable System Timer. -__WEAK void osRtxSysTimerDisable (void) { - SysTick_Disable(); -} - -/// Acknowledge System Timer IRQ. -__WEAK void osRtxSysTimerAckIRQ (void) { - SysTick_GetOvf(); -} - -/// Get System Timer count. -__WEAK uint32_t osRtxSysTimerGetCount (void) { - uint32_t tick; - uint32_t val; - - tick = (uint32_t)osRtxInfo.kernel.tick; - val = SysTick_GetVal(); - if (SysTick_GetOvf()) { - val = SysTick_GetVal(); - tick++; - } - val += tick * SysTick_GetPeriod(); - - return val; -} - -/// Get System Timer frequency. -__WEAK uint32_t osRtxSysTimerGetFreq (void) { - return osRtxInfo.kernel.sys_freq; -} diff --git a/rtos/TARGET_CORTEX/rtx5/rtx_thread.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c similarity index 96% rename from rtos/TARGET_CORTEX/rtx5/rtx_thread.c rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c index aae22a07ed4..26e4c38c166 100644 --- a/rtos/TARGET_CORTEX/rtx5/rtx_thread.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c @@ -24,7 +24,6 @@ */ #include "rtx_lib.h" -#include "rt_OsEventObserver.h" // ==== Helper functions ==== @@ -378,19 +377,7 @@ void osRtxThreadDelayTick (void) { /// \param[in] thread thread object. /// \return pointer to registers R0-R3. uint32_t *osRtxThreadRegPtr (os_thread_t *thread) { - -#if (__FPU_USED == 1U) - if (IS_EXTENDED_STACK_FRAME(thread->stack_frame)) { - // Extended Stack Frame: S16-S31, R4-R11, R0-R3, R12, LR, PC, xPSR, S0-S15, FPSCR - return ((uint32_t *)(thread->sp + (16U+8U)*4U)); - } else { - // Basic Stack Frame: R4-R11, R0-R3, R12, LR, PC, xPSR - return ((uint32_t *)(thread->sp + 8U *4U)); - } -#else - // Stack Frame: R4-R11, R0-R3, R12, LR, PC, xPSR - return ((uint32_t *)(thread->sp + 8U*4U)); -#endif + return ((uint32_t *)(thread->sp + STACK_OFFSET_R0(thread->stack_frame))); } /// Block running Thread execution and register it as Ready to Run. @@ -428,13 +415,6 @@ void osRtxThreadSwitch (os_thread_t *thread) { EvrRtxThreadSwitch(thread); } -/// Notify the OS event observer of an imminent thread switch. -void thread_switch_helper(void) { - if (osEventObs && osEventObs->thread_switch) { - osEventObs->thread_switch(osRtxInfo.thread.run.next->context); - } -} - /// Dispatch specified Thread or Ready Thread with Highest Priority. /// \param[in] thread thread object or NULL. void osRtxThreadDispatch (os_thread_t *thread) { @@ -443,6 +423,12 @@ void osRtxThreadDispatch (os_thread_t *thread) { kernel_state = osRtxKernelGetState(); thread_running = osRtxThreadGetRunning(); +#if (__ARM_ARCH_7A__ != 0U) + // On Cortex-A PendSV_Handler is executed before final context switch. + if ((thread_running != NULL) && (thread_running->state != osRtxThreadRunning)) { + thread_running = osRtxInfo.thread.run.next; + } +#endif if (thread == NULL) { thread = osRtxInfo.thread.ready.thread_list; @@ -556,7 +542,7 @@ void osRtxThreadPostProcess (os_thread_t *thread) { // ==== Service Calls ==== // Service Calls definitions -SVC0_4M(ThreadNew, osThreadId_t, osThreadFunc_t, void *, const osThreadAttr_t *, void *) +SVC0_3M(ThreadNew, osThreadId_t, osThreadFunc_t, void *, const osThreadAttr_t *) SVC0_1 (ThreadGetName, const char *, osThreadId_t) SVC0_0 (ThreadGetId, osThreadId_t) SVC0_1 (ThreadGetState, osThreadState_t, osThreadId_t) @@ -579,8 +565,8 @@ SVC0_0 (ThreadFlagsGet, uint32_t) SVC0_3 (ThreadFlagsWait, uint32_t, uint32_t, uint32_t, uint32_t) /// Create a thread and add it to Active Threads. -/// \note API identical to osThreadContextNew -osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr, void *context) { +/// \note API identical to osThreadNew +osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) { os_thread_t *thread; uint32_t attr_bits; void *stack_mem; @@ -769,7 +755,10 @@ osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThrea } *ptr++ = (uint32_t)osThreadExit; // LR *ptr++ = (uint32_t)func; // PC - *ptr++ = XPSR_INITIAL_VALUE; // xPSR + *ptr++ = xPSR_INIT( + (osRtxConfig.flags & osRtxConfigPrivilegedMode), + ((uint32_t)func & 1U) + ); // xPSR *(ptr-8) = (uint32_t)argument; // R0 // Register post ISR processing function @@ -777,13 +766,6 @@ osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThrea EvrRtxThreadCreated(thread); - /* Notify the OS event observer of a new thread. */ - if (osEventObs && osEventObs->thread_create) { - thread->context = osEventObs->thread_create((int)thread, context); - } else { - thread->context = context; - } - osRtxThreadDispatch(thread); return thread; @@ -1230,10 +1212,6 @@ osStatus_t svcRtxThreadTerminate (osThreadId_t thread_id) { return osErrorResource; } - if (osEventObs && osEventObs->thread_destroy) { - osEventObs->thread_destroy(thread->context); - } - // Release owned Mutexes osRtxMutexOwnerRelease(thread->mutex_list); @@ -1520,16 +1498,12 @@ uint32_t isrRtxThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) { /// Create a thread and add it to Active Threads. osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) { - return osThreadContextNew(func, argument, attr, NULL); -} - -osThreadId_t osThreadContextNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr, void *context) { EvrRtxThreadNew(func, argument, attr); if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { EvrRtxThreadError(NULL, osErrorISR); return NULL; } - return __svcThreadNew(func, argument, attr, context); + return __svcThreadNew(func, argument, attr); } /// Get name of a thread. diff --git a/rtos/TARGET_CORTEX/rtx5/rtx_timer.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_timer.c similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/rtx_timer.c rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_timer.c diff --git a/rtos/TARGET_CORTEX/rtx5/Source/os_systick.c b/rtos/TARGET_CORTEX/rtx5/Source/os_systick.c new file mode 100644 index 00000000000..3c18e31ee65 --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/Source/os_systick.c @@ -0,0 +1,134 @@ +/**************************************************************************//** + * @file os_systick.c + * @brief CMSIS OS Tick SysTick implementation + * @version V1.0.0 + * @date 05. June 2017 + ******************************************************************************/ +/* + * Copyright (c) 2017-2017 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 + * + * 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 "os_tick.h" + +#include "RTE_Components.h" +#include CMSIS_device_header + +#ifdef SysTick + +#ifndef SYSTICK_IRQ_PRIORITY +#define SYSTICK_IRQ_PRIORITY 0xFFU +#endif + +static uint8_t PendST; + +// Setup OS Tick. +__WEAK int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler) { + uint32_t load; + (void)handler; + + if (freq == 0U) { + return (-1); + } + + load = (SystemCoreClock / freq) - 1U; + if (load > 0x00FFFFFFU) { + return (-1); + } + + // Set SysTick Interrupt Priority +#if ((defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1U)) || \ + (defined(__CORTEX_M) && (__CORTEX_M == 7U))) + SCB->SHPR[11] = SYSTICK_IRQ_PRIORITY; +#elif (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ == 1U)) + SCB->SHPR[1] |= (SYSTICK_IRQ_PRIORITY << 24); +#elif ((defined(__ARM_ARCH_7M__) && (__ARM_ARCH_7M__ == 1U)) || \ + (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1U))) + SCB->SHP[11] = SYSTICK_IRQ_PRIORITY; +#elif (defined(__ARM_ARCH_6M__) && (__ARM_ARCH_6M__ == 1U)) + SCB->SHP[1] |= (SYSTICK_IRQ_PRIORITY << 24); +#else +#error "Unknown ARM Core!" +#endif + + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk; + SysTick->LOAD = load; + SysTick->VAL = 0U; + + PendST = 0U; + + return (0); +} + +/// Enable OS Tick. +__WEAK int32_t OS_Tick_Enable (void) { + + if (PendST != 0U) { + PendST = 0U; + SCB->ICSR = SCB_ICSR_PENDSTSET_Msk; + } + + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; + + return (0); +} + +/// Disable OS Tick. +__WEAK int32_t OS_Tick_Disable (void) { + + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + + if ((SCB->ICSR & SCB_ICSR_PENDSTSET_Msk) != 0U) { + SCB->ICSR = SCB_ICSR_PENDSTCLR_Msk; + PendST = 1U; + } + + return (0); +} + +// Acknowledge OS Tick IRQ. +__WEAK int32_t OS_Tick_AcknowledgeIRQ (void) { + (void)SysTick->CTRL; + return (0); +} + +// Get OS Tick IRQ number. +__WEAK int32_t OS_Tick_GetIRQn (void) { + return (SysTick_IRQn); +} + +// Get OS Tick clock. +__WEAK uint32_t OS_Tick_GetClock (void) { + return (SystemCoreClock); +} + +// Get OS Tick interval. +__WEAK uint32_t OS_Tick_GetInterval (void) { + return (SysTick->LOAD + 1U); +} + +// Get OS Tick count value. +__WEAK uint32_t OS_Tick_GetCount (void) { + uint32_t load = SysTick->LOAD; + return (load - SysTick->VAL); +} + +// Get OS Tick overflow status. +__WEAK uint32_t OS_Tick_GetOverflow (void) { + return ((SysTick->CTRL >> 16) & 1U); +} + +#endif // SysTick diff --git a/rtos/TARGET_CORTEX/rtx5/Source/os_tick_gtim.c b/rtos/TARGET_CORTEX/rtx5/Source/os_tick_gtim.c new file mode 100644 index 00000000000..a3b41ac4de6 --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/Source/os_tick_gtim.c @@ -0,0 +1,192 @@ +/**************************************************************************//** + * @file os_tick_gtim.c + * @brief CMSIS OS Tick implementation for Private Timer + * @version V1.0.0 + * @date 21. July 2017 + ******************************************************************************/ +/* + * Copyright (c) 2017 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 + * + * 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 "os_tick.h" +#include "irq_ctrl.h" + +#include "RTE_Components.h" +#include CMSIS_device_header + +#ifndef GTIM_IRQ_PRIORITY +#define GTIM_IRQ_PRIORITY 0xFFU +#endif + +#ifndef GTIM_IRQ_NUM +#define GTIM_IRQ_NUM SecurePhyTimer_IRQn +#endif + +// Timer interrupt pending flag +static uint8_t GTIM_PendIRQ; + +// Timer tick frequency +static uint32_t GTIM_Clock; + +// Timer load value +static uint32_t GTIM_Load; + +// Setup OS Tick. +int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler) { + uint32_t prio, bits; + + if (freq == 0U) { + return (-1); + } + + GTIM_PendIRQ = 0U; + + // Get timer clock +#ifdef SCTR_BASE + GTIM_Clock = *(uint32_t*)(SCTR_BASE+0x20); +#else + // FVP REFCLK CNTControl 100MHz + GTIM_Clock = 100000000UL; +#endif + + PL1_SetCounterFrequency(GTIM_Clock); + + // Calculate load value + GTIM_Load = (GTIM_Clock / freq) - 1U; + + // Disable Generic Timer and set load value + PL1_SetControl(0U); + PL1_SetLoadValue(GTIM_Load); + + // Disable corresponding IRQ + IRQ_Disable(GTIM_IRQ_NUM); + IRQ_ClearPending(GTIM_IRQ_NUM); + + // Determine number of implemented priority bits + IRQ_SetPriority(GTIM_IRQ_NUM, 0xFFU); + + prio = IRQ_GetPriority(GTIM_IRQ_NUM); + + // At least bits [7:4] must be implemented + if ((prio & 0xF0U) == 0U) { + return (-1); + } + + for (bits = 0; bits < 4; bits++) { + if ((prio & 0x01) != 0) { + break; + } + prio >>= 1; + } + + // Adjust configured priority to the number of implemented priority bits + prio = (GTIM_IRQ_PRIORITY << bits) & 0xFFUL; + + // Set Private Timer interrupt priority + IRQ_SetPriority(GTIM_IRQ_NUM, prio-1U); + + // Set edge-triggered IRQ + IRQ_SetMode(GTIM_IRQ_NUM, IRQ_MODE_TRIG_EDGE); + + // Register tick interrupt handler function + IRQ_SetHandler(GTIM_IRQ_NUM, handler); + + // Enable corresponding interrupt + IRQ_Enable(GTIM_IRQ_NUM); + + // Enable system counter and timer control +#ifdef SCTR_BASE + *(uint32_t*)SCTR_BASE |= 3U; +#endif + + // Enable timer control + PL1_SetControl(1U); + + return (0); +} + +/// Enable OS Tick. +int32_t OS_Tick_Enable (void) { + uint32_t ctrl; + + // Set pending interrupt if flag set + if (GTIM_PendIRQ != 0U) { + GTIM_PendIRQ = 0U; + IRQ_SetPending (GTIM_IRQ_NUM); + } + + // Start the Private Timer + ctrl = PL1_GetControl(); + // Set bit: Timer enable + ctrl |= 1U; + PL1_SetControl(ctrl); + + return (0); +} + +/// Disable OS Tick. +int32_t OS_Tick_Disable (void) { + uint32_t ctrl; + + // Stop the Private Timer + ctrl = PL1_GetControl(); + // Clear bit: Timer enable + ctrl &= ~1U; + PL1_SetControl(ctrl); + + // Remember pending interrupt flag + if (IRQ_GetPending(GTIM_IRQ_NUM) != 0) { + IRQ_ClearPending(GTIM_IRQ_NUM); + GTIM_PendIRQ = 1U; + } + + return (0); +} + +// Acknowledge OS Tick IRQ. +int32_t OS_Tick_AcknowledgeIRQ (void) { + IRQ_ClearPending (GTIM_IRQ_NUM); + PL1_SetLoadValue(GTIM_Load); + return (0); +} + +// Get OS Tick IRQ number. +int32_t OS_Tick_GetIRQn (void) { + return (GTIM_IRQ_NUM); +} + +// Get OS Tick clock. +uint32_t OS_Tick_GetClock (void) { + return (GTIM_Clock); +} + +// Get OS Tick interval. +uint32_t OS_Tick_GetInterval (void) { + return (GTIM_Load + 1U); +} + +// Get OS Tick count value. +uint32_t OS_Tick_GetCount (void) { + return (GTIM_Load - PL1_GetCurrentValue()); +} + +// Get OS Tick overflow status. +uint32_t OS_Tick_GetOverflow (void) { + CNTP_CTL_Type cntp_ctl; + cntp_ctl.w = PL1_GetControl(); + return (cntp_ctl.b.ISTATUS); +} diff --git a/rtos/TARGET_CORTEX/rtx5/Source/os_tick_ptim.c b/rtos/TARGET_CORTEX/rtx5/Source/os_tick_ptim.c new file mode 100644 index 00000000000..620c6a9437e --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/Source/os_tick_ptim.c @@ -0,0 +1,170 @@ +/**************************************************************************//** + * @file os_tick_ptim.c + * @brief CMSIS OS Tick implementation for Private Timer + * @version V1.0.0 + * @date 29. June 2017 + ******************************************************************************/ +/* + * Copyright (c) 2017 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 + * + * 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 "os_tick.h" +#include "irq_ctrl.h" + +#include "RTE_Components.h" +#include CMSIS_device_header + +#if defined(PTIM) + +#ifndef PTIM_IRQ_PRIORITY +#define PTIM_IRQ_PRIORITY 0xFFU +#endif + +static uint8_t PTIM_PendIRQ; // Timer interrupt pending flag + +// Setup OS Tick. +int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler) { + uint32_t load; + uint32_t prio; + uint32_t bits; + + if (freq == 0U) { + return (-1); + } + + PTIM_PendIRQ = 0U; + + // Private Timer runs with the system frequency + load = (SystemCoreClock / freq) - 1U; + + // Disable Private Timer and set load value + PTIM_SetControl (0U); + PTIM_SetLoadValue (load); + + // Disable corresponding IRQ + IRQ_Disable (PrivTimer_IRQn); + IRQ_ClearPending(PrivTimer_IRQn); + + // Determine number of implemented priority bits + IRQ_SetPriority (PrivTimer_IRQn, 0xFFU); + + prio = IRQ_GetPriority (PrivTimer_IRQn); + + // At least bits [7:4] must be implemented + if ((prio & 0xF0U) == 0U) { + return (-1); + } + + for (bits = 0; bits < 4; bits++) { + if ((prio & 0x01) != 0) { + break; + } + prio >>= 1; + } + + // Adjust configured priority to the number of implemented priority bits + prio = (PTIM_IRQ_PRIORITY << bits) & 0xFFUL; + + // Set Private Timer interrupt priority + IRQ_SetPriority(PrivTimer_IRQn, prio-1U); + + // Set edge-triggered IRQ + IRQ_SetMode(PrivTimer_IRQn, IRQ_MODE_TRIG_EDGE); + + // Register tick interrupt handler function + IRQ_SetHandler(PrivTimer_IRQn, handler); + + // Enable corresponding interrupt + IRQ_Enable (PrivTimer_IRQn); + + // Set bits: IRQ enable and Auto reload + PTIM_SetControl (0x06U); + + return (0); +} + +/// Enable OS Tick. +int32_t OS_Tick_Enable (void) { + uint32_t ctrl; + + // Set pending interrupt if flag set + if (PTIM_PendIRQ != 0U) { + PTIM_PendIRQ = 0U; + IRQ_SetPending (PrivTimer_IRQn); + } + + // Start the Private Timer + ctrl = PTIM_GetControl(); + // Set bit: Timer enable + ctrl |= 1U; + PTIM_SetControl (ctrl); + + return (0); +} + +/// Disable OS Tick. +int32_t OS_Tick_Disable (void) { + uint32_t ctrl; + + // Stop the Private Timer + ctrl = PTIM_GetControl(); + // Clear bit: Timer enable + ctrl &= ~1U; + PTIM_SetControl (ctrl); + + // Remember pending interrupt flag + if (IRQ_GetPending(PrivTimer_IRQn) != 0) { + IRQ_ClearPending (PrivTimer_IRQn); + PTIM_PendIRQ = 1U; + } + + return (0); +} + +// Acknowledge OS Tick IRQ. +int32_t OS_Tick_AcknowledgeIRQ (void) { + PTIM_ClearEventFlag(); + return (0); +} + +// Get OS Tick IRQ number. +int32_t OS_Tick_GetIRQn (void) { + return (PrivTimer_IRQn); +} + +// Get OS Tick clock. +uint32_t OS_Tick_GetClock (void) { + return (SystemCoreClock); +} + +// Get OS Tick interval. +uint32_t OS_Tick_GetInterval (void) { + return (PTIM_GetLoadValue() + 1U); +} + +// Get OS Tick count value. +uint32_t OS_Tick_GetCount (void) { + uint32_t load = PTIM_GetLoadValue(); + return (load - PTIM_GetCurrentValue()); +} + +// Get OS Tick overflow status. +uint32_t OS_Tick_GetOverflow (void) { + return (PTIM->ISR & 1); +} + +#endif // PTIM diff --git a/rtos/TARGET_CORTEX/rtx5/rt_OsEventObserver.c b/rtos/TARGET_CORTEX/rtx5/rt_OsEventObserver.c deleted file mode 100644 index 5fee0aab390..00000000000 --- a/rtos/TARGET_CORTEX/rtx5/rt_OsEventObserver.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2013-2016 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. - * - * ----------------------------------------------------------------------------- - * - * Project: CMSIS-RTOS RTX - * Title: OS Event Observer - * - * ----------------------------------------------------------------------------- - */ -#include "rt_OsEventObserver.h" - -/* - * _____ _____ ____ __ _____ - * | ___|_ _\ \/ / \/ | ____| - * | |_ | | \ /| |\/| | _| - * | _| | | / \| | | | |___ - * |_| |___/_/\_\_| |_|_____| - * - * FIXME: - * The osEventObs variable must be in protected memory. If not every box - * and box 0 can modify osEventObs to point to any handler to run code - * privileged. This issue is tracked at - * . - */ -const OsEventObserver *osEventObs; - -void osRegisterForOsEvents(const OsEventObserver *observer) -{ - static uint8_t has_been_called = 0; - if (has_been_called) { - return; - } - has_been_called = 1; - - osEventObs = observer; -} diff --git a/rtos/TARGET_CORTEX/rtx5/rt_OsEventObserver.h b/rtos/TARGET_CORTEX/rtx5/rt_OsEventObserver.h deleted file mode 100644 index 899f319029f..00000000000 --- a/rtos/TARGET_CORTEX/rtx5/rt_OsEventObserver.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2013-2016 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. - * - * ----------------------------------------------------------------------------- - * - * Project: CMSIS-RTOS RTX - * Title: OS Event Observer - * - * ----------------------------------------------------------------------------- - */ -#ifndef _RT_OS_EVENT_OBSERVER_H -#define _RT_OS_EVENT_OBSERVER_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - uint32_t version; - void (*pre_start)(void); - void *(*thread_create)(int thread_id, void *context); - void (*thread_destroy)(void *context); - void (*thread_switch)(void *context); -} OsEventObserver; -extern const OsEventObserver *osEventObs; - -void osRegisterForOsEvents(const OsEventObserver *observer); - -#ifdef __cplusplus -}; -#endif - -#endif - -/** @}*/ From d5933f198c4cec7f1bc36c9d1e257e36906dc498 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Tue, 4 Jul 2017 14:14:17 +0100 Subject: [PATCH 02/26] CMSIS/RTX: Patch RTX4 to preserve osThreadDef compatibility mbed OS used older RTX4 version and with osThreadDef accepting only 3 parameters, to preserve compatibility we hardcode the 'instances' parameter to 1. --- rtos/TARGET_CORTEX/rtx4/cmsis_os.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/rtos/TARGET_CORTEX/rtx4/cmsis_os.h b/rtos/TARGET_CORTEX/rtx4/cmsis_os.h index a5601622f09..af78fd3bf98 100644 --- a/rtos/TARGET_CORTEX/rtx4/cmsis_os.h +++ b/rtos/TARGET_CORTEX/rtx4/cmsis_os.h @@ -435,26 +435,25 @@ uint32_t osKernelSysTick (void); /// Create a Thread Definition with function, priority, and stack requirements. /// \param name name of the thread function. /// \param priority initial priority of the thread function. -/// \param instances number of possible thread instances. /// \param stacksz stack size (in bytes) requirements for the thread function. #if defined (osObjectsExternal) // object is external -#define osThreadDef(name, priority, instances, stacksz) \ +#define osThreadDef(name, priority, stacksz) \ extern const osThreadDef_t os_thread_def_##name #else // define the object #if (osCMSIS < 0x20000U) -#define osThreadDef(name, priority, instances, stacksz) \ +#define osThreadDef(name, priority, stacksz) \ const osThreadDef_t os_thread_def_##name = \ -{ (name), (priority), (instances), (stacksz) } +{ (name), (priority), 1, (stacksz) } #else -#define osThreadDef(name, priority, instances, stacksz) \ -static uint64_t os_thread_stack##name[(stacksz)?(((stacksz+7)/8)):1] __attribute__((section(".bss.os.thread.stack"))); \ +#define osThreadDef(name, priority, stacksz) \ +uint64_t os_thread_stack##name[(stacksz)?(((stacksz+7)/8)):1] __attribute__((section(".bss.os.thread.stack"))); \ static osRtxThread_t os_thread_cb_##name __attribute__((section(".bss.os.thread.cb"))); \ const osThreadDef_t os_thread_def_##name = \ { (name), \ { NULL, osThreadDetached, \ - (instances == 1) ? (&os_thread_cb_##name) : NULL,\ - (instances == 1) ? osRtxThreadCbSize : 0U, \ - ((stacksz) && (instances == 1)) ? (&os_thread_stack##name) : NULL, \ + &os_thread_cb_##name,\ + osRtxThreadCbSize, \ + (stacksz) ? (&os_thread_stack##name) : NULL, \ 8*((stacksz+7)/8), \ (priority), 0U, 0U } } #endif From 5d6abd65721dd68aef9c567e5047fc66a3863402 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Tue, 4 Jul 2017 15:01:10 +0100 Subject: [PATCH 03/26] CMSIS/RTX: Patch RTX includes to match mbed OS scheme --- cmsis/TARGET_CORTEX_A/irq_ctrl_gic.c | 3 +-- rtos/TARGET_CORTEX/rtx5/RTX/Config/RTX_Config.h | 4 +++- .../rtx5/RTX/Config/TARGET_CORTEX_A/handlers.c | 3 +-- rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_c.h | 3 +-- rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_ca.h | 3 +-- rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_cm.h | 3 +-- rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_evr.c | 2 -- rtos/TARGET_CORTEX/rtx5/Source/os_systick.c | 3 +-- rtos/TARGET_CORTEX/rtx5/Source/os_tick_ptim.c | 7 +++---- 9 files changed, 12 insertions(+), 19 deletions(-) diff --git a/cmsis/TARGET_CORTEX_A/irq_ctrl_gic.c b/cmsis/TARGET_CORTEX_A/irq_ctrl_gic.c index 1db4d8b4f89..39be23e04fa 100644 --- a/cmsis/TARGET_CORTEX_A/irq_ctrl_gic.c +++ b/cmsis/TARGET_CORTEX_A/irq_ctrl_gic.c @@ -24,8 +24,7 @@ #include -#include "RTE_Components.h" -#include CMSIS_device_header +#include #include "irq_ctrl.h" diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Config/RTX_Config.h b/rtos/TARGET_CORTEX/rtx5/RTX/Config/RTX_Config.h index 6cacee82488..4cd0f84a0e8 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Config/RTX_Config.h +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Config/RTX_Config.h @@ -27,7 +27,9 @@ #ifndef RTX_CONFIG_H_ #define RTX_CONFIG_H_ - + +#include "mbed_rtx_conf.h" + //-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- // System Configuration diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Config/TARGET_CORTEX_A/handlers.c b/rtos/TARGET_CORTEX/rtx5/RTX/Config/TARGET_CORTEX_A/handlers.c index 6afdccc8d26..861ab0513f0 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Config/TARGET_CORTEX_A/handlers.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Config/TARGET_CORTEX_A/handlers.c @@ -22,9 +22,8 @@ * * ----------------------------------------------------------------------------- */ -#include "RTE_Components.h" -#include CMSIS_device_header +#include //Fault Status Register (IFSR/DFSR) definitions #define FSR_ALIGNMENT_FAULT 0x01 //DFSR only. Fault on first lookup diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_c.h b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_c.h index 3e0ddd35294..8b95bc3c2fe 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_c.h +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_c.h @@ -26,8 +26,7 @@ #ifndef RTX_CORE_C_H_ #define RTX_CORE_C_H_ -#include "RTE_Components.h" -#include CMSIS_device_header +#include #ifndef __ARM_ARCH_6M__ #define __ARM_ARCH_6M__ 0U diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_ca.h b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_ca.h index f3a7a2addcc..c3ee341889b 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_ca.h +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_ca.h @@ -26,8 +26,7 @@ #ifndef RTX_CORE_CA_H_ #define RTX_CORE_CA_H_ -#include "RTE_Components.h" -#include CMSIS_device_header +#include #define __DOMAIN_NS 0U #define __EXCLUSIVE_ACCESS 1U diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_cm.h b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_cm.h index 3f2e8d1a4ba..a8b5cb9edb7 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_cm.h +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_cm.h @@ -26,8 +26,7 @@ #ifndef RTX_CORE_CM_H_ #define RTX_CORE_CM_H_ -#include "RTE_Components.h" -#include CMSIS_device_header +#include #ifdef RTE_CMSIS_RTOS2_RTX5_ARMV8M_NS #define __DOMAIN_NS 1U diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_evr.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_evr.c index f81b927c83f..2507d303806 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_evr.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_evr.c @@ -27,8 +27,6 @@ #include "cmsis_compiler.h" #include "rtx_evr.h" // RTX Event Recorder definitions -#include "RTE_Components.h" - #ifdef RTE_Compiler_EventRecorder #include "EventRecorder.h" // Keil::Compiler:Event Recorder diff --git a/rtos/TARGET_CORTEX/rtx5/Source/os_systick.c b/rtos/TARGET_CORTEX/rtx5/Source/os_systick.c index 3c18e31ee65..16bf53c0a41 100644 --- a/rtos/TARGET_CORTEX/rtx5/Source/os_systick.c +++ b/rtos/TARGET_CORTEX/rtx5/Source/os_systick.c @@ -24,8 +24,7 @@ #include "os_tick.h" -#include "RTE_Components.h" -#include CMSIS_device_header +#include #ifdef SysTick diff --git a/rtos/TARGET_CORTEX/rtx5/Source/os_tick_ptim.c b/rtos/TARGET_CORTEX/rtx5/Source/os_tick_ptim.c index 620c6a9437e..b909e7e3302 100644 --- a/rtos/TARGET_CORTEX/rtx5/Source/os_tick_ptim.c +++ b/rtos/TARGET_CORTEX/rtx5/Source/os_tick_ptim.c @@ -22,13 +22,12 @@ * limitations under the License. */ +#if defined(PTIM) + #include "os_tick.h" #include "irq_ctrl.h" -#include "RTE_Components.h" -#include CMSIS_device_header - -#if defined(PTIM) +#include #ifndef PTIM_IRQ_PRIORITY #define PTIM_IRQ_PRIORITY 0xFFU From 1b131edd69ef3c0c016346c2f44f64780ab6186c Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Tue, 4 Jul 2017 15:22:20 +0100 Subject: [PATCH 04/26] CMSIS/RTX: Patch RTX so irq_cm4f.s files work with no FPU targets --- .../RTX/Source/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/irq_cm4f.s | 6 ++++++ .../RTX/Source/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/irq_cm4f.S | 6 ++++++ .../RTX/Source/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/irq_cm4f.s | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/irq_cm4f.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/irq_cm4f.s index f0df8aaa040..44d0c7cb4a9 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/irq_cm4f.s +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/irq_cm4f.s @@ -66,16 +66,20 @@ SVC_Context CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted TST LR,#0x10 ; Check if extended stack frame BNE SVC_ContextSwitch +#ifdef __FPU_PRESENT LDR R1,=0xE000EF34 ; FPCCR Address LDR R0,[R1] ; Load FPCCR BIC R0,#1 ; Clear LSPACT (Lazy state) STR R0,[R1] ; Store FPCCR B SVC_ContextSwitch +#endif SVC_ContextSave STMDB R12!,{R4-R11} ; Save R4..R11 +#ifdef __FPU_PRESENT TST LR,#0x10 ; Check if extended stack frame VSTMDBEQ R12!,{S16-S31} ; Save VFP S16.S31 +#endif STR R12,[R1,#TCB_SP_OFS] ; Store SP STRB LR, [R1,#TCB_SF_OFS] ; Store stack frame information @@ -88,8 +92,10 @@ SVC_ContextRestore LDR R0,[R2,#TCB_SP_OFS] ; Load SP ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN +#ifdef __FPU_PRESENT TST LR,#0x10 ; Check if extended stack frame VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 +#endif LDMIA R0!,{R4-R11} ; Restore R4..R11 MSR PSP,R0 ; Set PSP diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/irq_cm4f.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/irq_cm4f.S index 8d10213d119..77345a348e9 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/irq_cm4f.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/irq_cm4f.S @@ -70,17 +70,21 @@ SVC_Context: CBNZ R1,SVC_ContextSave // Branch if running thread is not deleted TST LR,#0x10 // Check if extended stack frame BNE SVC_ContextSwitch +#ifdef __FPU_PRESENT LDR R1,=0xE000EF34 // FPCCR Address LDR R0,[R1] // Load FPCCR BIC R0,#1 // Clear LSPACT (Lazy state) STR R0,[R1] // Store FPCCR B SVC_ContextSwitch +#endif SVC_ContextSave: STMDB R12!,{R4-R11} // Save R4..R11 +#ifdef __FPU_PRESENT TST LR,#0x10 // Check if extended stack frame IT EQ VSTMDBEQ R12!,{S16-S31} // Save VFP S16.S31 +#endif STR R12,[R1,#TCB_SP_OFS] // Store SP STRB LR, [R1,#TCB_SF_OFS] // Store stack frame information @@ -93,9 +97,11 @@ SVC_ContextRestore: LDR R0,[R2,#TCB_SP_OFS] // Load SP ORR LR,R1,#0xFFFFFF00 // Set EXC_RETURN +#ifdef __FPU_PRESENT TST LR,#0x10 // Check if extended stack frame IT EQ VLDMIAEQ R0!,{S16-S31} // Restore VFP S16..S31 +#endif LDMIA R0!,{R4-R11} // Restore R4..R11 MSR PSP,R0 // Set PSP diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/irq_cm4f.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/irq_cm4f.s index 0d84409b392..d44f4017c4d 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/irq_cm4f.s +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/irq_cm4f.s @@ -69,17 +69,21 @@ SVC_Context CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted TST LR,#0x10 ; Check if extended stack frame BNE SVC_ContextSwitch +#ifdef __FPU_PRESENT LDR R1,=0xE000EF34 ; FPCCR Address LDR R0,[R1] ; Load FPCCR BIC R0,R0,#1 ; Clear LSPACT (Lazy state) STR R0,[R1] ; Store FPCCR B SVC_ContextSwitch +#endif SVC_ContextSave STMDB R12!,{R4-R11} ; Save R4..R11 +#ifdef __FPU_PRESENT TST LR,#0x10 ; Check if extended stack frame IT EQ VSTMDBEQ R12!,{S16-S31} ; Save VFP S16.S31 +#endif STR R12,[R1,#TCB_SP_OFS] ; Store SP STRB LR, [R1,#TCB_SF_OFS] ; Store stack frame information @@ -92,9 +96,11 @@ SVC_ContextRestore LDR R0,[R2,#TCB_SP_OFS] ; Load SP ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN +#ifdef __FPU_PRESENT TST LR,#0x10 ; Check if extended stack frame IT EQ VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 +#endif LDMIA R0!,{R4-R11} ; Restore R4..R11 MSR PSP,R0 ; Set PSP From 3f97e573645f17fd7fa42214e6c203306de55d52 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Thu, 12 Oct 2017 13:25:59 -0500 Subject: [PATCH 05/26] CMSIS/RTX: Remove os_tick_gtim.c This implementation of timer conflicts with the default ptim, we will keep the default and let the timer override the implmenetation if needed. --- rtos/TARGET_CORTEX/rtx5/Source/os_tick_gtim.c | 192 ------------------ 1 file changed, 192 deletions(-) delete mode 100644 rtos/TARGET_CORTEX/rtx5/Source/os_tick_gtim.c diff --git a/rtos/TARGET_CORTEX/rtx5/Source/os_tick_gtim.c b/rtos/TARGET_CORTEX/rtx5/Source/os_tick_gtim.c deleted file mode 100644 index a3b41ac4de6..00000000000 --- a/rtos/TARGET_CORTEX/rtx5/Source/os_tick_gtim.c +++ /dev/null @@ -1,192 +0,0 @@ -/**************************************************************************//** - * @file os_tick_gtim.c - * @brief CMSIS OS Tick implementation for Private Timer - * @version V1.0.0 - * @date 21. July 2017 - ******************************************************************************/ -/* - * Copyright (c) 2017 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 - * - * 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 "os_tick.h" -#include "irq_ctrl.h" - -#include "RTE_Components.h" -#include CMSIS_device_header - -#ifndef GTIM_IRQ_PRIORITY -#define GTIM_IRQ_PRIORITY 0xFFU -#endif - -#ifndef GTIM_IRQ_NUM -#define GTIM_IRQ_NUM SecurePhyTimer_IRQn -#endif - -// Timer interrupt pending flag -static uint8_t GTIM_PendIRQ; - -// Timer tick frequency -static uint32_t GTIM_Clock; - -// Timer load value -static uint32_t GTIM_Load; - -// Setup OS Tick. -int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler) { - uint32_t prio, bits; - - if (freq == 0U) { - return (-1); - } - - GTIM_PendIRQ = 0U; - - // Get timer clock -#ifdef SCTR_BASE - GTIM_Clock = *(uint32_t*)(SCTR_BASE+0x20); -#else - // FVP REFCLK CNTControl 100MHz - GTIM_Clock = 100000000UL; -#endif - - PL1_SetCounterFrequency(GTIM_Clock); - - // Calculate load value - GTIM_Load = (GTIM_Clock / freq) - 1U; - - // Disable Generic Timer and set load value - PL1_SetControl(0U); - PL1_SetLoadValue(GTIM_Load); - - // Disable corresponding IRQ - IRQ_Disable(GTIM_IRQ_NUM); - IRQ_ClearPending(GTIM_IRQ_NUM); - - // Determine number of implemented priority bits - IRQ_SetPriority(GTIM_IRQ_NUM, 0xFFU); - - prio = IRQ_GetPriority(GTIM_IRQ_NUM); - - // At least bits [7:4] must be implemented - if ((prio & 0xF0U) == 0U) { - return (-1); - } - - for (bits = 0; bits < 4; bits++) { - if ((prio & 0x01) != 0) { - break; - } - prio >>= 1; - } - - // Adjust configured priority to the number of implemented priority bits - prio = (GTIM_IRQ_PRIORITY << bits) & 0xFFUL; - - // Set Private Timer interrupt priority - IRQ_SetPriority(GTIM_IRQ_NUM, prio-1U); - - // Set edge-triggered IRQ - IRQ_SetMode(GTIM_IRQ_NUM, IRQ_MODE_TRIG_EDGE); - - // Register tick interrupt handler function - IRQ_SetHandler(GTIM_IRQ_NUM, handler); - - // Enable corresponding interrupt - IRQ_Enable(GTIM_IRQ_NUM); - - // Enable system counter and timer control -#ifdef SCTR_BASE - *(uint32_t*)SCTR_BASE |= 3U; -#endif - - // Enable timer control - PL1_SetControl(1U); - - return (0); -} - -/// Enable OS Tick. -int32_t OS_Tick_Enable (void) { - uint32_t ctrl; - - // Set pending interrupt if flag set - if (GTIM_PendIRQ != 0U) { - GTIM_PendIRQ = 0U; - IRQ_SetPending (GTIM_IRQ_NUM); - } - - // Start the Private Timer - ctrl = PL1_GetControl(); - // Set bit: Timer enable - ctrl |= 1U; - PL1_SetControl(ctrl); - - return (0); -} - -/// Disable OS Tick. -int32_t OS_Tick_Disable (void) { - uint32_t ctrl; - - // Stop the Private Timer - ctrl = PL1_GetControl(); - // Clear bit: Timer enable - ctrl &= ~1U; - PL1_SetControl(ctrl); - - // Remember pending interrupt flag - if (IRQ_GetPending(GTIM_IRQ_NUM) != 0) { - IRQ_ClearPending(GTIM_IRQ_NUM); - GTIM_PendIRQ = 1U; - } - - return (0); -} - -// Acknowledge OS Tick IRQ. -int32_t OS_Tick_AcknowledgeIRQ (void) { - IRQ_ClearPending (GTIM_IRQ_NUM); - PL1_SetLoadValue(GTIM_Load); - return (0); -} - -// Get OS Tick IRQ number. -int32_t OS_Tick_GetIRQn (void) { - return (GTIM_IRQ_NUM); -} - -// Get OS Tick clock. -uint32_t OS_Tick_GetClock (void) { - return (GTIM_Clock); -} - -// Get OS Tick interval. -uint32_t OS_Tick_GetInterval (void) { - return (GTIM_Load + 1U); -} - -// Get OS Tick count value. -uint32_t OS_Tick_GetCount (void) { - return (GTIM_Load - PL1_GetCurrentValue()); -} - -// Get OS Tick overflow status. -uint32_t OS_Tick_GetOverflow (void) { - CNTP_CTL_Type cntp_ctl; - cntp_ctl.w = PL1_GetControl(); - return (cntp_ctl.b.ISTATUS); -} From 02d01f42a603fb7ce98cf887e45a03701a5d6603 Mon Sep 17 00:00:00 2001 From: Martin Kojtal <0xc0170@gmail.com> Date: Wed, 21 Jun 2017 15:29:55 +0100 Subject: [PATCH 06/26] CSMIS/RTX: cmain IAR: add mbed main This fixes #4602 issue, mbed_main should be invoked right before the real main --- cmsis/TARGET_CORTEX_M/TOOLCHAIN_IAR/cmain.S | 101 ++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 cmsis/TARGET_CORTEX_M/TOOLCHAIN_IAR/cmain.S diff --git a/cmsis/TARGET_CORTEX_M/TOOLCHAIN_IAR/cmain.S b/cmsis/TARGET_CORTEX_M/TOOLCHAIN_IAR/cmain.S new file mode 100644 index 00000000000..0da55009b38 --- /dev/null +++ b/cmsis/TARGET_CORTEX_M/TOOLCHAIN_IAR/cmain.S @@ -0,0 +1,101 @@ +/************************************************** + * + * Part two of the system initialization code, contains C-level + * initialization, thumb-2 only variant. + * + * $Revision: 59783 $ + * + **************************************************/ +/* Copyright 2008-2017, IAR Systems AB. + This source code is the property of IAR Systems. The source code may only + be used together with the IAR Embedded Workbench. Redistribution and use + in source and binary forms, with or without modification, is permitted + provided that the following conditions are met: + - Redistributions of source code, in whole or in part, must retain the + above copyright notice, this list of conditions and the disclaimer below. + - IAR Systems name may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +; -------------------------------------------------- +; Module ?cmain, C-level initialization. +; + + + SECTION SHT$$PREINIT_ARRAY:CONST:NOROOT(2) + SECTION SHT$$INIT_ARRAY:CONST:NOROOT(2) + + SECTION .text:CODE:NOROOT(2) + + PUBLIC __cmain + ;; Keep ?main for legacy reasons, it is accessed in countless instances of cstartup.s around the world... + PUBLIC ?main + EXTWEAK __iar_data_init3 + EXTWEAK __iar_argc_argv + EXTERN __low_level_init + EXTERN __call_ctors + EXTERN main + EXTERN exit + EXTERN __iar_dynamic_initialization + EXTERN mbed_sdk_init + EXTERN mbed_main + EXTERN SystemInit + + THUMB +__cmain: +?main: + +; Initialize segments. +; __segment_init and __low_level_init are assumed to use the same +; instruction set and to be reachable by BL from the ICODE segment +; (it is safest to link them in segment ICODE). + + FUNCALL __cmain, __low_level_init + bl __low_level_init + cmp r0,#0 + beq ?l1 + FUNCALL __cmain, __iar_data_init3 + bl __iar_data_init3 + MOVS r0,#0 ; No parameters + FUNCALL __cmain, mbed_sdk_init + BL mbed_sdk_init + MOVS r0,#0 ; No parameters + FUNCALL __cmain, __iar_dynamic_initialization + BL __iar_dynamic_initialization ; C++ dynamic initialization + +?l1: + REQUIRE ?l3 + + SECTION .text:CODE:NOROOT(2) + + PUBLIC _main + PUBLIC _call_main + THUMB + +__iar_init$$done: ; Copy initialization is done + +?l3: +_call_main: + MOVS r0,#0 ; No parameters + FUNCALL __cmain, __iar_argc_argv + BL __iar_argc_argv ; Maybe setup command line + + MOVS r0,#0 ; No parameters + FUNCALL __cmain, mbed_main + BL mbed_main + + FUNCALL __cmain, main + BL main +_main: + FUNCALL __cmain, exit + BL exit + + END From 20357bc1fa09162d4cb853ab6d783404ff8d7ec3 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Thu, 12 Oct 2017 14:35:48 -0500 Subject: [PATCH 07/26] CMSIS/RTX: Reintroduce core_cmSecureAccess.h lost during CMSIS update --- cmsis/TARGET_CORTEX_M/core_cmSecureAccess.h | 201 ++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 cmsis/TARGET_CORTEX_M/core_cmSecureAccess.h diff --git a/cmsis/TARGET_CORTEX_M/core_cmSecureAccess.h b/cmsis/TARGET_CORTEX_M/core_cmSecureAccess.h new file mode 100644 index 00000000000..4903efdff68 --- /dev/null +++ b/cmsis/TARGET_CORTEX_M/core_cmSecureAccess.h @@ -0,0 +1,201 @@ +/**************************************************************************//** + * @file core_cmSecureAccess.h + * @brief CMSIS Cortex-M Core Secure Access Header File + * @version XXX + * @date 10. June 2016 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2016 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#ifndef __CORE_CM_SECURE_ACCESS_H +#define __CORE_CM_SECURE_ACCESS_H + + +/* ########################### Core Secure Access ########################### */ + +#ifdef FEATURE_UVISOR +#include "uvisor-lib/uvisor-lib.h" + +/* Secure uVisor implementation. */ + +/** Set the value at the target address. + * + * Equivalent to: `*address = value`. + * @param address[in] Target address + * @param value[in] Value to write at the address location. + */ +#define SECURE_WRITE(address, value) \ + uvisor_write(public_box, UVISOR_RGW_SHARED, address, value, UVISOR_RGW_OP_WRITE, 0xFFFFFFFFUL) + +/** Get the value at the target address. + * + * @param address[in] Target address + * @returns The value `*address`. + */ +#define SECURE_READ(address) \ + uvisor_read(public_box, UVISOR_RGW_SHARED, address, UVISOR_RGW_OP_READ, 0xFFFFFFFFUL) + +/** Get the selected bits at the target address. + * + * @param address[in] Target address + * @param mask[in] Bits to select out of the target address + * @returns The value `*address & mask`. + */ +#define SECURE_BITS_GET(address, mask) \ + UVISOR_BITS_GET(public_box, UVISOR_RGW_SHARED, address, mask) + +/** Check the selected bits at the target address. + * + * @param address[in] Address at which to check the bits + * @param mask[in] Bits to select out of the target address + * @returns The value `((*address & mask) == mask)`. + */ +#define SECURE_BITS_CHECK(address, mask) \ + UVISOR_BITS_CHECK(public_box, UVISOR_RGW_SHARED, address, mask) + +/** Set the selected bits to 1 at the target address. + * + * Equivalent to: `*address |= mask`. + * @param address[in] Target address + * @param mask[in] Bits to select out of the target address + */ +#define SECURE_BITS_SET(address, mask) \ + UVISOR_BITS_SET(public_box, UVISOR_RGW_SHARED, address, mask) + +/** Clear the selected bits at the target address. + * + * Equivalent to: `*address &= ~mask`. + * @param address[in] Target address + * @param mask[in] Bits to select out of the target address + */ +#define SECURE_BITS_CLEAR(address, mask) \ + UVISOR_BITS_CLEAR(public_box, UVISOR_RGW_SHARED, address, mask) + +/** Set the selected bits at the target address to the given value. + * + * Equivalent to: `*address = (*address & ~mask) | (value & mask)`. + * @param address[in] Target address + * @param mask[in] Bits to select out of the target address + * @param value[in] Value to write at the address location. Note: The value + * must be already shifted to the correct bit position + */ +#define SECURE_BITS_SET_VALUE(address, mask, value) \ + UVISOR_BITS_SET_VALUE(public_box, UVISOR_RGW_SHARED, address, mask, value) + +/** Toggle the selected bits at the target address. + * + * Equivalent to: `*address ^= mask`. + * @param address[in] Target address + * @param mask[in] Bits to select out of the target address + */ +#define SECURE_BITS_TOGGLE(address, mask) \ + UVISOR_BITS_TOGGLE(public_box, UVISOR_RGW_SHARED, address, mask) + +#else + +/* Insecure fallback implementation. */ + +/** Set the value at the target address. + * + * Equivalent to: `*address = value`. + * @param address[in] Target address + * @param value[in] Value to write at the address location. + */ +#define SECURE_WRITE(address, value) \ + *(address) = (value) + +/** Get the value at the target address. + * + * @param address[in] Target address + * @returns The value `*address`. + */ +#define SECURE_READ(address) \ + (*(address)) + +/** Get the selected bits at the target address. + * + * @param address[in] Target address + * @param mask[in] Bits to select out of the target address + * @returns The value `*address & mask`. + */ +#define SECURE_BITS_GET(address, mask) \ + (*(address) & (mask)) + +/** Check the selected bits at the target address. + * + * @param address[in] Address at which to check the bits + * @param mask[in] Bits to select out of the target address + * @returns The value `((*address & mask) == mask)`. + */ +#define SECURE_BITS_CHECK(address, mask) \ + ((*(address) & (mask)) == (mask)) + +/** Set the selected bits to 1 at the target address. + * + * Equivalent to: `*address |= mask`. + * @param address[in] Target address + * @param mask[in] Bits to select out of the target address + */ +#define SECURE_BITS_SET(address, mask) \ + *(address) |= (mask) + +/** Clear the selected bits at the target address. + * + * Equivalent to: `*address &= ~mask`. + * @param address[in] Target address + * @param mask[in] Bits to select out of the target address + */ +#define SECURE_BITS_CLEAR(address, mask) \ + *(address) &= ~(mask) + +/** Set the selected bits at the target address to the given value. + * + * Equivalent to: `*address = (*address & ~mask) | (value & mask)`. + * @param address[in] Target address + * @param mask[in] Bits to select out of the target address + * @param value[in] Value to write at the address location. Note: The value + * must be already shifted to the correct bit position + */ +#define SECURE_BITS_SET_VALUE(address, mask, value) \ + *(address) = (*(address) & ~(mask)) | ((value) & (mask)) + +/** Toggle the selected bits at the target address. + * + * Equivalent to: `*address ^= mask`. + * @param address[in] Target address + * @param mask[in] Bits to select out of the target address + */ +#define SECURE_BITS_TOGGLE(address, mask) \ + *(address) ^= (mask) + +#endif + +#endif /* __CORE_CM_SECURE_ACCESS_H */ From 4523b5d266b233018add6e30eab017e0008dc77e Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Wed, 18 Oct 2017 11:29:48 -0500 Subject: [PATCH 08/26] CMSIS/RTX: Allow overwriting _mutex_initialize symbol for ARMC --- rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_lib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_lib.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_lib.c index 1020f7adabc..26325c507b9 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_lib.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_lib.c @@ -595,9 +595,11 @@ void *__user_perthread_libspace (void) { typedef void *mutex; // Initialize mutex +#if !defined(__ARMCC_VERSION) || __ARMCC_VERSION < 6010050 __USED +#endif int _mutex_initialize(mutex *m); -int _mutex_initialize(mutex *m) { +__WEAK int _mutex_initialize(mutex *m) { *m = osMutexNew(NULL); if (*m == NULL) { osRtxErrorNotify(osRtxErrorClibMutex, m); From b8aa068def5ae622b5a500cce0e19b771c501025 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Wed, 25 Oct 2017 11:13:51 -0500 Subject: [PATCH 09/26] CMSIS/RTX: Rename asm files to upper case .S --- .../Source/TOOLCHAIN_ARM/TARGET_CORTEX_A/{irq_ca.s => irq_ca.S} | 0 .../RTX/Source/TOOLCHAIN_ARM/TARGET_M0/{irq_cm0.s => irq_cm0.S} | 0 .../RTX/Source/TOOLCHAIN_ARM/TARGET_M0P/{irq_cm0.s => irq_cm0.S} | 0 .../TOOLCHAIN_ARM/TARGET_M23/{irq_armv8mbl.s => irq_armv8mbl.S} | 0 .../TARGET_M23/{irq_armv8mbl_ns.s => irq_armv8mbl_ns.S} | 0 .../RTX/Source/TOOLCHAIN_ARM/TARGET_M3/{irq_cm3.s => irq_cm3.S} | 0 .../TOOLCHAIN_ARM/TARGET_M33/{irq_armv8mml.s => irq_armv8mml.S} | 0 .../TARGET_M33/{irq_armv8mml_ns.s => irq_armv8mml_ns.S} | 0 .../TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/{irq_cm4f.s => irq_cm4f.S} | 0 .../Source/TOOLCHAIN_IAR/TARGET_CORTEX_A/{irq_ca.s => irq_ca.S} | 0 .../RTX/Source/TOOLCHAIN_IAR/TARGET_M0/{irq_cm0.s => irq_cm0.S} | 0 .../RTX/Source/TOOLCHAIN_IAR/TARGET_M0P/{irq_cm0.s => irq_cm0.S} | 0 .../TOOLCHAIN_IAR/TARGET_M23/{irq_armv8mbl.s => irq_armv8mbl.S} | 0 .../TARGET_M23/{irq_armv8mbl_common.s => irq_armv8mbl_common.S} | 0 .../TARGET_M23/{irq_armv8mbl_ns.s => irq_armv8mbl_ns.S} | 0 .../RTX/Source/TOOLCHAIN_IAR/TARGET_M3/{irq_cm3.s => irq_cm3.S} | 0 .../TOOLCHAIN_IAR/TARGET_M33/{irq_armv8mml.s => irq_armv8mml.S} | 0 .../TARGET_M33/{irq_armv8mml_common.s => irq_armv8mml_common.S} | 0 .../TARGET_M33/{irq_armv8mml_ns.s => irq_armv8mml_ns.S} | 0 .../TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/{irq_cm4f.s => irq_cm4f.S} | 0 20 files changed, 0 insertions(+), 0 deletions(-) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_CORTEX_A/{irq_ca.s => irq_ca.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M0/{irq_cm0.s => irq_cm0.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M0P/{irq_cm0.s => irq_cm0.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/{irq_armv8mbl.s => irq_armv8mbl.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/{irq_armv8mbl_ns.s => irq_armv8mbl_ns.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M3/{irq_cm3.s => irq_cm3.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/{irq_armv8mml.s => irq_armv8mml.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/{irq_armv8mml_ns.s => irq_armv8mml_ns.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/{irq_cm4f.s => irq_cm4f.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_CORTEX_A/{irq_ca.s => irq_ca.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M0/{irq_cm0.s => irq_cm0.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M0P/{irq_cm0.s => irq_cm0.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/{irq_armv8mbl.s => irq_armv8mbl.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/{irq_armv8mbl_common.s => irq_armv8mbl_common.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/{irq_armv8mbl_ns.s => irq_armv8mbl_ns.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M3/{irq_cm3.s => irq_cm3.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/{irq_armv8mml.s => irq_armv8mml.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/{irq_armv8mml_common.s => irq_armv8mml_common.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/{irq_armv8mml_ns.s => irq_armv8mml_ns.S} (100%) rename rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/{irq_cm4f.s => irq_cm4f.S} (100%) diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_CORTEX_A/irq_ca.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_CORTEX_A/irq_ca.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_CORTEX_A/irq_ca.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_CORTEX_A/irq_ca.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M0/irq_cm0.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M0/irq_cm0.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M0/irq_cm0.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M0/irq_cm0.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M0P/irq_cm0.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M0P/irq_cm0.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M0P/irq_cm0.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M0P/irq_cm0.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl_ns.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl_ns.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl_ns.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M23/irq_armv8mbl_ns.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M3/irq_cm3.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M3/irq_cm3.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M3/irq_cm3.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M3/irq_cm3.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml_ns.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml_ns.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml_ns.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_M33/irq_armv8mml_ns.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/irq_cm4f.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/irq_cm4f.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/irq_cm4f.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/irq_cm4f.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_CORTEX_A/irq_ca.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_CORTEX_A/irq_ca.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_CORTEX_A/irq_ca.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_CORTEX_A/irq_ca.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M0/irq_cm0.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M0/irq_cm0.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M0/irq_cm0.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M0/irq_cm0.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M0P/irq_cm0.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M0P/irq_cm0.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M0P/irq_cm0.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M0P/irq_cm0.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl_common.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl_common.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl_common.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl_common.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl_ns.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl_ns.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl_ns.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M23/irq_armv8mbl_ns.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M3/irq_cm3.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M3/irq_cm3.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M3/irq_cm3.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M3/irq_cm3.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml_common.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml_common.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml_common.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml_common.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml_ns.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml_ns.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml_ns.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_M33/irq_armv8mml_ns.S diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/irq_cm4f.s b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/irq_cm4f.S similarity index 100% rename from rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/irq_cm4f.s rename to rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/irq_cm4f.S From 372b7b8b471691ddcf65a7b28be67457efabfb93 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Mon, 30 Jan 2017 13:10:54 +0000 Subject: [PATCH 10/26] RTX5: uVisor: Defer to uVisor for SVCall priority Only set the SVCall priority if uVisor is not present. If uVisor is present, keep using whatever priorities it has already set up. --- rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_cm.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_cm.h b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_cm.h index a8b5cb9edb7..fafe0981ed8 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_cm.h +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_core_cm.h @@ -606,7 +606,11 @@ __STATIC_INLINE void SVC_Initialize (void) { if (p >= n) { n = p + 1U; } + + /* Only change the SVCall priority if uVisor is not present. */ + #if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)) SCB->SHP[7] = (uint8_t)(0xFEU << n); + #endif #elif (__ARM_ARCH_6M__ == 1U) uint32_t n; From f363ccbb5999df9aa4d70f8339e5ba9d1accf96a Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Thu, 19 Jan 2017 13:41:05 +0000 Subject: [PATCH 11/26] RTX5: uVisor: Add OsEventObserver Add the OsEventObserver mechanism. A client interested in receiving notifications on certain OS events can register to receive notifications with osRegisterForOsEvents. This is useful for clients like the secure memory allocator, which observes thread switching events in order to swap in and out different memory allocator objects. --- .../rtx5/RTX/Source/rt_OsEventObserver.c | 51 +++++++++++++++++++ .../rtx5/RTX/Source/rt_OsEventObserver.h | 51 +++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/rt_OsEventObserver.c create mode 100644 rtos/TARGET_CORTEX/rtx5/RTX/Source/rt_OsEventObserver.h diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rt_OsEventObserver.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rt_OsEventObserver.c new file mode 100644 index 00000000000..5fee0aab390 --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rt_OsEventObserver.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2016 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: OS Event Observer + * + * ----------------------------------------------------------------------------- + */ +#include "rt_OsEventObserver.h" + +/* + * _____ _____ ____ __ _____ + * | ___|_ _\ \/ / \/ | ____| + * | |_ | | \ /| |\/| | _| + * | _| | | / \| | | | |___ + * |_| |___/_/\_\_| |_|_____| + * + * FIXME: + * The osEventObs variable must be in protected memory. If not every box + * and box 0 can modify osEventObs to point to any handler to run code + * privileged. This issue is tracked at + * . + */ +const OsEventObserver *osEventObs; + +void osRegisterForOsEvents(const OsEventObserver *observer) +{ + static uint8_t has_been_called = 0; + if (has_been_called) { + return; + } + has_been_called = 1; + + osEventObs = observer; +} diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rt_OsEventObserver.h b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rt_OsEventObserver.h new file mode 100644 index 00000000000..899f319029f --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rt_OsEventObserver.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2016 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: OS Event Observer + * + * ----------------------------------------------------------------------------- + */ +#ifndef _RT_OS_EVENT_OBSERVER_H +#define _RT_OS_EVENT_OBSERVER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint32_t version; + void (*pre_start)(void); + void *(*thread_create)(int thread_id, void *context); + void (*thread_destroy)(void *context); + void (*thread_switch)(void *context); +} OsEventObserver; +extern const OsEventObserver *osEventObs; + +void osRegisterForOsEvents(const OsEventObserver *observer); + +#ifdef __cplusplus +}; +#endif + +#endif + +/** @}*/ From 12a47f0031efb635713426485dc916f5800b6920 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Wed, 25 Jan 2017 17:19:27 +0000 Subject: [PATCH 12/26] RTX5: uVisor: Extend thread control block with context OsEventObserver objects expect a context to be maintained per thread on their behalf. Add this context to the thread control block and extend the thread creation functions with the ability to supply a context. --- rtos/TARGET_CORTEX/rtx5/Include/cmsis_os2.h | 1 + rtos/TARGET_CORTEX/rtx5/RTX/Include/rtx_os.h | 1 + rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_kernel.c | 4 ++-- rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_lib.h | 2 +- rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c | 12 ++++++++---- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/rtos/TARGET_CORTEX/rtx5/Include/cmsis_os2.h b/rtos/TARGET_CORTEX/rtx5/Include/cmsis_os2.h index 73fee84d3c4..2cbb2930417 100644 --- a/rtos/TARGET_CORTEX/rtx5/Include/cmsis_os2.h +++ b/rtos/TARGET_CORTEX/rtx5/Include/cmsis_os2.h @@ -363,6 +363,7 @@ uint32_t osKernelGetSysTimerFreq (void); /// \param[in] attr thread attributes; NULL: default values. /// \return thread ID for reference by other functions or NULL in case of error. osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); +osThreadId_t osThreadContextNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr, void *context); /// Get name of a thread. /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Include/rtx_os.h b/rtos/TARGET_CORTEX/rtx5/RTX/Include/rtx_os.h index cbb3f6a3dd8..0c2df7e6a3d 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Include/rtx_os.h +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Include/rtx_os.h @@ -127,6 +127,7 @@ typedef struct osRtxThread_s { uint32_t sp; ///< Current Stack Pointer uint32_t thread_addr; ///< Thread entry address uint32_t tz_memory; ///< TrustZone Memory Identifier + void *context; ///< Context for OsEventObserver objects } osRtxThread_t; diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_kernel.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_kernel.c index fad31603bf3..d9edfd14263 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_kernel.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_kernel.c @@ -245,7 +245,7 @@ osStatus_t svcRtxKernelStart (void) { // Create Idle Thread if (osRtxInfo.thread.idle == NULL) { - osRtxInfo.thread.idle = svcRtxThreadNew(osRtxIdleThread, NULL, osRtxConfig.idle_thread_attr); + osRtxInfo.thread.idle = svcRtxThreadNew(osRtxIdleThread, NULL, osRtxConfig.idle_thread_attr, NULL); if (osRtxInfo.thread.idle == NULL) { EvrRtxKernelError(osError); return osError; @@ -255,7 +255,7 @@ osStatus_t svcRtxKernelStart (void) { // Create Timer Thread if (osRtxConfig.timer_mq_mcnt != 0U) { if (osRtxInfo.timer.thread == NULL) { - osRtxInfo.timer.thread = svcRtxThreadNew(osRtxTimerThread, NULL, osRtxConfig.timer_thread_attr); + osRtxInfo.timer.thread = svcRtxThreadNew(osRtxTimerThread, NULL, osRtxConfig.timer_thread_attr, NULL); if (osRtxInfo.timer.thread == NULL) { EvrRtxKernelError(osError); return osError; diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_lib.h b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_lib.h index 17bfc006410..e5863f1b224 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_lib.h +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_lib.h @@ -131,7 +131,7 @@ extern uint32_t svcRtxKernelGetSysTimerCount (void); extern uint32_t svcRtxKernelGetSysTimerFreq (void); // Thread Service Calls -extern osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); +extern osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr, void *context); extern const char * svcRtxThreadGetName (osThreadId_t thread_id); extern osThreadId_t svcRtxThreadGetId (void); extern osThreadState_t svcRtxThreadGetState (osThreadId_t thread_id); diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c index 26e4c38c166..bec6712794c 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c @@ -542,7 +542,7 @@ void osRtxThreadPostProcess (os_thread_t *thread) { // ==== Service Calls ==== // Service Calls definitions -SVC0_3M(ThreadNew, osThreadId_t, osThreadFunc_t, void *, const osThreadAttr_t *) +SVC0_4M(ThreadNew, osThreadId_t, osThreadFunc_t, void *, const osThreadAttr_t *, void *) SVC0_1 (ThreadGetName, const char *, osThreadId_t) SVC0_0 (ThreadGetId, osThreadId_t) SVC0_1 (ThreadGetState, osThreadState_t, osThreadId_t) @@ -565,8 +565,8 @@ SVC0_0 (ThreadFlagsGet, uint32_t) SVC0_3 (ThreadFlagsWait, uint32_t, uint32_t, uint32_t, uint32_t) /// Create a thread and add it to Active Threads. -/// \note API identical to osThreadNew -osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) { +/// \note API identical to osThreadContextNew +osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr, void *context) { os_thread_t *thread; uint32_t attr_bits; void *stack_mem; @@ -1498,12 +1498,16 @@ uint32_t isrRtxThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) { /// Create a thread and add it to Active Threads. osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) { + return osThreadContextNew(func, argument, attr, NULL); +} + +osThreadId_t osThreadContextNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr, void *context) { EvrRtxThreadNew(func, argument, attr); if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { EvrRtxThreadError(NULL, osErrorISR); return NULL; } - return __svcThreadNew(func, argument, attr); + return __svcThreadNew(func, argument, attr, context); } /// Get name of a thread. From 474f6c63bac17fa792d63dad8bf3d147f1f946f2 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Thu, 19 Jan 2017 13:34:56 +0000 Subject: [PATCH 13/26] RTX5: uVisor: Use OsEventObserver --- rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_kernel.c | 10 ++++++++++ rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c | 17 ++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_kernel.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_kernel.c index d9edfd14263..8284034f2f1 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_kernel.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_kernel.c @@ -24,6 +24,7 @@ */ #include "rtx_lib.h" +#include "rt_OsEventObserver.h" // OS Runtime Information @@ -543,6 +544,15 @@ osStatus_t osKernelStart (void) { EvrRtxKernelError(osErrorISR); return osErrorISR; } + + /* Call the pre-start event (from unprivileged mode) if the handler exists + * and the kernel is not running. */ + /* FIXME osEventObs needs to be readable but not writable from unprivileged + * code. */ + if (osKernelGetState() != osKernelRunning && osEventObs && osEventObs->pre_start) { + osEventObs->pre_start(); + } + return __svcKernelStart(); } diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c index bec6712794c..4f4067e42a4 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c @@ -24,7 +24,7 @@ */ #include "rtx_lib.h" - +#include "rt_OsEventObserver.h" // ==== Helper functions ==== @@ -413,6 +413,10 @@ void osRtxThreadSwitch (os_thread_t *thread) { osRtxInfo.thread.run.next = thread; osRtxThreadStackCheck(); EvrRtxThreadSwitch(thread); + + if (osEventObs && osEventObs->thread_switch) { + osEventObs->thread_switch(thread->context); + } } /// Dispatch specified Thread or Ready Thread with Highest Priority. @@ -766,6 +770,13 @@ osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThrea EvrRtxThreadCreated(thread); + /* Notify the OS event observer of a new thread. */ + if (osEventObs && osEventObs->thread_create) { + thread->context = osEventObs->thread_create((int)thread, context); + } else { + thread->context = context; + } + osRtxThreadDispatch(thread); return thread; @@ -1212,6 +1223,10 @@ osStatus_t svcRtxThreadTerminate (osThreadId_t thread_id) { return osErrorResource; } + if (osEventObs && osEventObs->thread_destroy) { + osEventObs->thread_destroy(thread->context); + } + // Release owned Mutexes osRtxMutexOwnerRelease(thread->mutex_list); From 75ad20b65f1a585cca5029ab610acd4f0f7ddcb4 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Thu, 25 May 2017 09:48:04 +0100 Subject: [PATCH 14/26] RTX5: uVisor: Switch threads very carefully uVisor doesn't set the PSP of the target thread. The RTOS sets the PSP of the target thread from the target thread's TCB. However, when interrupts of higher priority than PendSV happen between the call to uVisor to switch boxes, and the RTOS setting PSP, the uVisor vIRQ interrupt handler will attempt to use an invalid PSP (the PSP from before the box and thread switch). This leads to a crash. Make box and thread switching atomic by disabling interrupts immediately before the box switching until immediately after the new PSP is set. --- .../RTX/Source/TOOLCHAIN_GCC/TARGET_M3/irq_cm3.S | 15 +++++++++++++++ .../TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/irq_cm4f.S | 15 +++++++++++++++ rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c | 5 ++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M3/irq_cm3.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M3/irq_cm3.S index 0bdf091d319..875b03bc6fc 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M3/irq_cm3.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_M3/irq_cm3.S @@ -73,12 +73,27 @@ SVC_ContextSave: STR R12,[R1,#TCB_SP_OFS] // Store SP SVC_ContextSwitch: +#ifdef FEATURE_UVISOR + CPSID I // The call to the thread switch helper and PSP loading must be atomic. +#endif + /* The call to thread_switch_helper can clobber R2 and R3, but we don't + * want to clobber R2 or R3. We can't save R2 and R3 to the stack (as + * the stack we save them onto is likely to be inaccessible after the + * call to thread_switch_helper). So, we just re-obtain the values from + * osRtxInfo again. */ + BL thread_switch_helper + LDR R3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run + LDM R3,{R1,R2} // Load osRtxInfo.thread.run: curr & next + STR R2,[R3] // osRtxInfo.thread.run: curr = next SVC_ContextRestore: LDR R0,[R2,#TCB_SP_OFS] // Load SP LDMIA R0!,{R4-R11} // Restore R4..R11 MSR PSP,R0 // Set PSP +#ifdef FEATURE_UVISOR + CPSIE I // The PSP has been set. Re-enable interrupts. +#endif MVN LR,#~0xFFFFFFFD // Set EXC_RETURN value SVC_Exit: diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/irq_cm4f.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/irq_cm4f.S index 77345a348e9..b38f9d5de76 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/irq_cm4f.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/irq_cm4f.S @@ -90,6 +90,18 @@ SVC_ContextSave: STRB LR, [R1,#TCB_SF_OFS] // Store stack frame information SVC_ContextSwitch: +#ifdef FEATURE_UVISOR + CPSID I // The call to the thread switch helper and PSP loading must be atomic. +#endif + /* The call to thread_switch_helper can clobber R2 and R3, but we don't + * want to clobber R2 or R3. We can't save R2 and R3 to the stack (as + * the stack we save them onto is likely to be inaccessible after the + * call to thread_switch_helper). So, we just re-obtain the values from + * osRtxInfo again. */ + BL thread_switch_helper + LDR R3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run + LDM R3,{R1,R2} // Load osRtxInfo.thread.run: curr & next + STR R2,[R3] // osRtxInfo.thread.run: curr = next SVC_ContextRestore: @@ -104,6 +116,9 @@ SVC_ContextRestore: #endif LDMIA R0!,{R4-R11} // Restore R4..R11 MSR PSP,R0 // Set PSP +#ifdef FEATURE_UVISOR + CPSIE I // The PSP has been set. Re-enable interrupts. +#endif SVC_Exit: BX LR // Exit from handler diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c index 4f4067e42a4..6e15a4c4fa6 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/rtx_thread.c @@ -413,9 +413,12 @@ void osRtxThreadSwitch (os_thread_t *thread) { osRtxInfo.thread.run.next = thread; osRtxThreadStackCheck(); EvrRtxThreadSwitch(thread); +} +/// Notify the OS event observer of an imminent thread switch. +void thread_switch_helper(void) { if (osEventObs && osEventObs->thread_switch) { - osEventObs->thread_switch(thread->context); + osEventObs->thread_switch(osRtxInfo.thread.run.next->context); } } From c10dd0a725620c7070efad43fc53dc1990ac875d Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Tue, 4 Jul 2017 16:47:55 +0100 Subject: [PATCH 15/26] RZ_A1H: Fix cmsis header name --- targets/TARGET_RENESAS/TARGET_RZ_A1H/device/MBRZA1H.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1H/device/MBRZA1H.h b/targets/TARGET_RENESAS/TARGET_RZ_A1H/device/MBRZA1H.h index d3a8174ef98..27dc426d44b 100644 --- a/targets/TARGET_RENESAS/TARGET_RZ_A1H/device/MBRZA1H.h +++ b/targets/TARGET_RENESAS/TARGET_RZ_A1H/device/MBRZA1H.h @@ -626,7 +626,7 @@ typedef enum IRQn #define __NVIC_PRIO_BITS 5 /*!< Number of Bits used for Priority Levels */ #define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ -#include +#include #include "system_MBRZA1H.h" From 855844f5a142ba34464057b34754640897ceff7e Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Tue, 25 Jul 2017 09:50:39 +0100 Subject: [PATCH 16/26] Update CThunk to support new CMSIS Cortex A ops --- platform/CThunk.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/CThunk.h b/platform/CThunk.h index 90e150b6a9c..a3e94e5e887 100644 --- a/platform/CThunk.h +++ b/platform/CThunk.h @@ -220,15 +220,15 @@ class CThunk uint32_t start_addr = (uint32_t)&m_thunk & 0xFFFFFFE0; uint32_t end_addr = (uint32_t)&m_thunk + sizeof(m_thunk); uint32_t addr; - + /* Data cache clean and invalid */ for (addr = start_addr; addr < end_addr; addr += 0x20) { - __v7_clean_inv_dcache_mva((void *)addr); + L1C_CleanInvalidateDCacheMVA((void *)addr); } /* Instruction cache invalid */ - __v7_inv_icache_all(); - __ca9u_inv_tlb_all(); - __v7_inv_btac(); + L1C_InvalidateICacheAll(); + MMU_InvalidateTLB(); + L1C_InvalidateBTAC(); } #endif #if defined(__CORTEX_M7) From 717087c772c30183161c145828ed2a1a50545ad8 Mon Sep 17 00:00:00 2001 From: Bartosz Szatkowski Date: Tue, 25 Jul 2017 10:25:04 +0100 Subject: [PATCH 17/26] Renesas: Add empty mbed_rtx.h --- targets/TARGET_RENESAS/mbed_rtx.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 targets/TARGET_RENESAS/mbed_rtx.h diff --git a/targets/TARGET_RENESAS/mbed_rtx.h b/targets/TARGET_RENESAS/mbed_rtx.h new file mode 100644 index 00000000000..75193d4863c --- /dev/null +++ b/targets/TARGET_RENESAS/mbed_rtx.h @@ -0,0 +1,19 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 ARM Limited + * + * 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 MBED_MBED_RTX_H +#define MBED_MBED_RTX_H + +#endif // MBED_MBED_RTX_H \ No newline at end of file From 048a8967414ce178c44dbd02e165229edf67f23c Mon Sep 17 00:00:00 2001 From: Bartosz Szatkowski Date: Tue, 25 Jul 2017 15:45:11 +0100 Subject: [PATCH 18/26] Update definitions of CPSR modes --- platform/mbed_critical.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/mbed_critical.c b/platform/mbed_critical.c index 6afb48e5a99..db6c05bb2a0 100644 --- a/platform/mbed_critical.c +++ b/platform/mbed_critical.c @@ -39,10 +39,10 @@ bool core_util_is_isr_active(void) { #if defined(__CORTEX_A9) switch(__get_CPSR() & 0x1FU) { - case MODE_USR: - case MODE_SYS: + case CPSR_M_USR: + case CPSR_M_SYS: return false; - case MODE_SVC: + case CPSR_M_SVC: default: return true; } From 8eebcff166366a87e3c2f93e1e3f17283d62a624 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Tue, 5 Sep 2017 14:30:41 +0100 Subject: [PATCH 19/26] Disable heap and stack tests for Cortex A These tests are not compatible with Cortex A due to __get_MSP usage. --- TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp b/TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp index 7e273504d14..a9766f429a5 100644 --- a/TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp @@ -14,6 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#if defined(TARGET_CORTEX_A) +  #error [NOT_SUPPORTED] This function not supported for this target +#endif + #include #include #include From 4b354f80cfbd819a951b9ac93ea7c781f3d5a77b Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Thu, 12 Oct 2017 14:39:15 -0500 Subject: [PATCH 20/26] Update include paths to match updated CMSIS --- rtos/TARGET_CORTEX/mbed_rtx_idle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtos/TARGET_CORTEX/mbed_rtx_idle.cpp b/rtos/TARGET_CORTEX/mbed_rtx_idle.cpp index 1ea59c5b793..8c924fae2cc 100644 --- a/rtos/TARGET_CORTEX/mbed_rtx_idle.cpp +++ b/rtos/TARGET_CORTEX/mbed_rtx_idle.cpp @@ -24,7 +24,7 @@ #include "platform/mbed_sleep.h" #include "TimerEvent.h" #include "lp_ticker_api.h" -#include "core_cm.h" +#include "rtx_core_cm.h" #include "mbed_critical.h" #include "mbed_assert.h" #include From 2ea01ac8a95293d18ca433d3274ead497a05a5c7 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Wed, 18 Oct 2017 13:53:11 -0500 Subject: [PATCH 21/26] Enabled restrict keyword for IAR --- tools/profiles/debug.json | 2 +- tools/profiles/develop.json | 2 +- tools/profiles/release.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/profiles/debug.json b/tools/profiles/debug.json index ad4fab345a7..ff8d9ed0561 100644 --- a/tools/profiles/debug.json +++ b/tools/profiles/debug.json @@ -51,7 +51,7 @@ "common": [ "--no_wrap_diagnostics", "-e", "--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-On", "-r", "-DMBED_DEBUG", - "-DMBED_TRAP_ERRORS_ENABLED=1"], + "-DMBED_TRAP_ERRORS_ENABLED=1", "--enable_restrict"], "asm": [], "c": ["--vla"], "cxx": ["--guard_calls", "--no_static_destruction"], diff --git a/tools/profiles/develop.json b/tools/profiles/develop.json index 6142485a5fa..465a1853f80 100644 --- a/tools/profiles/develop.json +++ b/tools/profiles/develop.json @@ -46,7 +46,7 @@ "IAR": { "common": [ "--no_wrap_diagnostics", "-e", - "--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-Oh"], + "--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-Oh", "--enable_restrict"], "asm": [], "c": ["--vla"], "cxx": ["--guard_calls", "--no_static_destruction"], diff --git a/tools/profiles/release.json b/tools/profiles/release.json index eedbce067f6..11207322d66 100644 --- a/tools/profiles/release.json +++ b/tools/profiles/release.json @@ -46,7 +46,7 @@ "IAR": { "common": [ "--no_wrap_diagnostics", "-e", - "--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-Ohz", "-DNDEBUG"], + "--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-Ohz", "-DNDEBUG", "--enable_restrict"], "asm": [], "c": ["--vla"], "cxx": ["--guard_calls", "--no_static_destruction"], From 7bee352dd77e841cc42b79f4b2dc9f2958f00db3 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Wed, 18 Oct 2017 13:53:55 -0500 Subject: [PATCH 22/26] Update SysTick API usage for tickless mode --- rtos/TARGET_CORTEX/mbed_rtx_idle.cpp | 38 ++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/rtos/TARGET_CORTEX/mbed_rtx_idle.cpp b/rtos/TARGET_CORTEX/mbed_rtx_idle.cpp index 8c924fae2cc..32d5ead975e 100644 --- a/rtos/TARGET_CORTEX/mbed_rtx_idle.cpp +++ b/rtos/TARGET_CORTEX/mbed_rtx_idle.cpp @@ -58,7 +58,7 @@ class RtosTimer : private TimerEvent { // Ensure SysTick has the correct priority as it is still used // to trigger software interrupts on each tick. The period does // not matter since it will never start counting. - SysTick_Setup(16); + OS_Tick_Setup(osRtxConfig.tick_freq, OS_TICK_HANDLER); #endif }; @@ -138,41 +138,57 @@ class RtosTimer : private TimerEvent { static RtosTimer *os_timer; static uint64_t os_timer_data[sizeof(RtosTimer) / 8]; -/// Setup System Timer. -int32_t osRtxSysTimerSetup (void) +/// Enable System Timer. +int32_t OS_Tick_Enable (void) { // Do not use SingletonPtr since this relies on the RTOS if (NULL == os_timer) { os_timer = new (os_timer_data) RtosTimer(); } - return -1; -} -/// Enable System Timer. -void osRtxSysTimerEnable (void) -{ // set to fire interrupt on next tick os_timer->schedule_tick(); + + return 0; } /// Disable System Timer. -void osRtxSysTimerDisable (void) +int32_t OS_Tick_Disable (void) { os_timer->cancel_tick(); + + return 0; } /// Acknowledge System Timer IRQ. -void osRtxSysTimerAckIRQ (void) +int32_t OS_Tick_AcknowledgeIRQ (void) { os_timer->schedule_tick(); + + return 0; } /// Get System Timer count. -uint32_t osRtxSysTimerGetCount (void) +uint32_t OS_Tick_GetCount (void) { return os_timer->get_time() & 0xFFFFFFFF; } +// Get OS Tick IRQ number. +int32_t OS_Tick_GetIRQn (void) { + return -1; +} + +// Get OS Tick overflow status. +uint32_t OS_Tick_GetOverflow (void) { + return 0; +} + +// Get OS Tick interval. +uint32_t OS_Tick_GetInterval (void) { + return 1000; +} + static void default_idle_hook(void) { uint32_t elapsed_ticks = 0; From 106f34e2edd89dc385bd501d8d180d2f53d51e87 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Thu, 19 Oct 2017 13:42:25 -0500 Subject: [PATCH 23/26] Add arm_math.h --- cmsis/TARGET_CORTEX_M/arm_math.h | 7257 ++++++++++++++++++++++++++++++ 1 file changed, 7257 insertions(+) create mode 100644 cmsis/TARGET_CORTEX_M/arm_math.h diff --git a/cmsis/TARGET_CORTEX_M/arm_math.h b/cmsis/TARGET_CORTEX_M/arm_math.h new file mode 100644 index 00000000000..6d754018966 --- /dev/null +++ b/cmsis/TARGET_CORTEX_M/arm_math.h @@ -0,0 +1,7257 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_math.h + * Description: Public header file for CMSIS DSP Library + * + * $Date: 27. January 2017 + * $Revision: V.1.5.1 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2017 ARM Limited or its affiliates. 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 + * + * 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. + */ + +/** + \mainpage CMSIS DSP Software Library + * + * Introduction + * ------------ + * + * This user manual describes the CMSIS DSP software library, + * a suite of common signal processing functions for use on Cortex-M processor based devices. + * + * The library is divided into a number of functions each covering a specific category: + * - Basic math functions + * - Fast math functions + * - Complex math functions + * - Filters + * - Matrix functions + * - Transforms + * - Motor control functions + * - Statistical functions + * - Support functions + * - Interpolation functions + * + * The library has separate functions for operating on 8-bit integers, 16-bit integers, + * 32-bit integer and 32-bit floating-point values. + * + * Using the Library + * ------------ + * + * The library installer contains prebuilt versions of the libraries in the Lib folder. + * - arm_cortexM7lfdp_math.lib (Cortex-M7, Little endian, Double Precision Floating Point Unit) + * - arm_cortexM7bfdp_math.lib (Cortex-M7, Big endian, Double Precision Floating Point Unit) + * - arm_cortexM7lfsp_math.lib (Cortex-M7, Little endian, Single Precision Floating Point Unit) + * - arm_cortexM7bfsp_math.lib (Cortex-M7, Big endian and Single Precision Floating Point Unit on) + * - arm_cortexM7l_math.lib (Cortex-M7, Little endian) + * - arm_cortexM7b_math.lib (Cortex-M7, Big endian) + * - arm_cortexM4lf_math.lib (Cortex-M4, Little endian, Floating Point Unit) + * - arm_cortexM4bf_math.lib (Cortex-M4, Big endian, Floating Point Unit) + * - arm_cortexM4l_math.lib (Cortex-M4, Little endian) + * - arm_cortexM4b_math.lib (Cortex-M4, Big endian) + * - arm_cortexM3l_math.lib (Cortex-M3, Little endian) + * - arm_cortexM3b_math.lib (Cortex-M3, Big endian) + * - arm_cortexM0l_math.lib (Cortex-M0 / Cortex-M0+, Little endian) + * - arm_cortexM0b_math.lib (Cortex-M0 / Cortex-M0+, Big endian) + * - arm_ARMv8MBLl_math.lib (ARMv8M Baseline, Little endian) + * - arm_ARMv8MMLl_math.lib (ARMv8M Mainline, Little endian) + * - arm_ARMv8MMLlfsp_math.lib (ARMv8M Mainline, Little endian, Single Precision Floating Point Unit) + * - arm_ARMv8MMLld_math.lib (ARMv8M Mainline, Little endian, DSP instructions) + * - arm_ARMv8MMLldfsp_math.lib (ARMv8M Mainline, Little endian, DSP instructions, Single Precision Floating Point Unit) + * + * The library functions are declared in the public file arm_math.h which is placed in the Include folder. + * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single + * public header file arm_math.h for Cortex-M cores with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. + * Define the appropriate pre processor MACRO ARM_MATH_CM7 or ARM_MATH_CM4 or ARM_MATH_CM3 or + * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application. + * For ARMv8M cores define pre processor MACRO ARM_MATH_ARMV8MBL or ARM_MATH_ARMV8MML. + * Set Pre processor MACRO __DSP_PRESENT if ARMv8M Mainline core supports DSP instructions. + * + * + * Examples + * -------- + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * Toolchain Support + * ------------ + * + * The library has been developed and tested with MDK-ARM version 5.14.0.0 + * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. + * + * Building the Library + * ------------ + * + * The library installer contains a project file to re build libraries on MDK-ARM Tool chain in the CMSIS\\DSP_Lib\\Source\\ARM folder. + * - arm_cortexM_math.uvprojx + * + * + * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional pre processor MACROs detailed above. + * + * Pre-processor Macros + * ------------ + * + * Each library project have differant pre-processor macros. + * + * - UNALIGNED_SUPPORT_DISABLE: + * + * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access + * + * - ARM_MATH_BIG_ENDIAN: + * + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. + * + * - ARM_MATH_MATRIX_CHECK: + * + * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices + * + * - ARM_MATH_ROUNDING: + * + * Define macro ARM_MATH_ROUNDING for rounding on support functions + * + * - ARM_MATH_CMx: + * + * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target + * and ARM_MATH_CM0 for building library on Cortex-M0 target, ARM_MATH_CM0PLUS for building library on Cortex-M0+ target, and + * ARM_MATH_CM7 for building the library on cortex-M7. + * + * - ARM_MATH_ARMV8MxL: + * + * Define macro ARM_MATH_ARMV8MBL for building the library on ARMv8M Baseline target, ARM_MATH_ARMV8MBL for building library + * on ARMv8M Mainline target. + * + * - __FPU_PRESENT: + * + * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for floating point libraries. + * + * - __DSP_PRESENT: + * + * Initialize macro __DSP_PRESENT = 1 when ARMv8M Mainline core supports DSP instructions. + * + *
+ * CMSIS-DSP in ARM::CMSIS Pack + * ----------------------------- + * + * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: + * |File/Folder |Content | + * |------------------------------|------------------------------------------------------------------------| + * |\b CMSIS\\Documentation\\DSP | This documentation | + * |\b CMSIS\\DSP_Lib | Software license agreement (license.txt) | + * |\b CMSIS\\DSP_Lib\\Examples | Example projects demonstrating the usage of the library functions | + * |\b CMSIS\\DSP_Lib\\Source | Source files for rebuilding the library | + * + *
+ * Revision History of CMSIS-DSP + * ------------ + * Please refer to \ref ChangeLog_pg. + * + * Copyright Notice + * ------------ + * + * Copyright (C) 2010-2015 ARM Limited. All rights reserved. + */ + + +/** + * @defgroup groupMath Basic Math Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CMSIS math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + *
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * 
+ * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size numRows X numCols + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + *
+ *     pData[i*numCols + j]
+ * 
+ * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to the function arm_mat_init_f32(), arm_mat_init_q31() + * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ * 
+ * where nRows specifies the number of rows, nColumns + * specifies the number of columns, and pData points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + *
+ *     ARM_MATH_SIZE_MISMATCH
+ * 
+ * Otherwise the functions return + *
+ *     ARM_MATH_SUCCESS
+ * 
+ * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + *
+ *     ARM_MATH_MATRIX_CHECK
+ * 
+ * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return ARM_MATH_SUCCESS. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + +/** + * @defgroup groupExamples Examples + */ +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +/* Compiler specific diagnostic adjustment */ +#if defined ( __CC_ARM ) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + +#elif defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#elif defined ( __ICCARM__ ) + +#elif defined ( __TI_ARM__ ) + +#elif defined ( __CSMC__ ) + +#elif defined ( __TASKING__ ) + +#else + #error Unknown compiler +#endif + + +#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ + +#if defined(ARM_MATH_CM7) + #include "core_cm7.h" + #define ARM_MATH_DSP +#elif defined (ARM_MATH_CM4) + #include "core_cm4.h" + #define ARM_MATH_DSP +#elif defined (ARM_MATH_CM3) + #include "core_cm3.h" +#elif defined (ARM_MATH_CM0) + #include "core_cm0.h" + #define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_CM0PLUS) + #include "core_cm0plus.h" + #define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_ARMV8MBL) + #include "core_armv8mbl.h" + #define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_ARMV8MML) + #include "core_armv8mml.h" + #if (defined (__DSP_PRESENT) && (__DSP_PRESENT == 1)) + #define ARM_MATH_DSP + #endif +#else + #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS, ARM_MATH_CM0, ARM_MATH_ARMV8MBL, ARM_MATH_ARMV8MML" +#endif + +#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ +#include "string.h" +#include "math.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 (0x100) +#define DELTA_Q15 0x5 +#define INDEX_MASK 0x0000003F +#ifndef PI + #define PI 3.14159265358979f +#endif + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define FAST_MATH_TABLE_SIZE 512 +#define FAST_MATH_Q31_SHIFT (32 - 10) +#define FAST_MATH_Q15_SHIFT (16 - 10) +#define CONTROLLER_Q31_SHIFT (32 - 9) +#define TABLE_SPACING_Q31 0x400000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + /** + * @brief Macro for Unaligned Support + */ +#ifndef UNALIGNED_SUPPORT_DISABLE + #define ALIGN4 +#else + #if defined (__GNUC__) + #define ALIGN4 __attribute__((aligned(4))) + #else + #define ALIGN4 __align(4) + #endif +#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + ARM_MATH_SUCCESS = 0, /**< No error */ + ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ + ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ + ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } arm_status; + + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + /** + * @brief definition to read/write two 16 bit values. + */ +#if defined ( __CC_ARM ) + #define __SIMD32_TYPE int32_t __packed + #define CMSIS_UNUSED __attribute__((unused)) + #define CMSIS_INLINE __attribute__((always_inline)) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + #define CMSIS_INLINE __attribute__((always_inline)) + +#elif defined ( __GNUC__ ) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + #define CMSIS_INLINE __attribute__((always_inline)) + +#elif defined ( __ICCARM__ ) + #define __SIMD32_TYPE int32_t __packed + #define CMSIS_UNUSED + #define CMSIS_INLINE + +#elif defined ( __TI_ARM__ ) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + #define CMSIS_INLINE + +#elif defined ( __CSMC__ ) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED + #define CMSIS_INLINE + +#elif defined ( __TASKING__ ) + #define __SIMD32_TYPE __unaligned int32_t + #define CMSIS_UNUSED + #define CMSIS_INLINE + +#else + #error Unknown compiler +#endif + +#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) +#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr)) +#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr)) +#define __SIMD64(addr) (*(int64_t **) & (addr)) + +/* #if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ +#if !defined (ARM_MATH_DSP) + /** + * @brief definition to pack two 16 bit values. + */ +#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) +#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) + +/* #endif // defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ +#endif /* !defined (ARM_MATH_DSP) */ + + /** + * @brief definition to pack four 8 bit values. + */ +#ifndef ARM_MATH_BIG_ENDIAN + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) +#else + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) + +#endif + + + /** + * @brief Clips Q63 to Q31 values. + */ + CMSIS_INLINE __STATIC_INLINE q31_t clip_q63_to_q31( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; + } + + /** + * @brief Clips Q63 to Q15 values. + */ + CMSIS_INLINE __STATIC_INLINE q15_t clip_q63_to_q15( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); + } + + /** + * @brief Clips Q31 to Q7 values. + */ + CMSIS_INLINE __STATIC_INLINE q7_t clip_q31_to_q7( + q31_t x) + { + return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? + ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; + } + + /** + * @brief Clips Q31 to Q15 values. + */ + CMSIS_INLINE __STATIC_INLINE q15_t clip_q31_to_q15( + q31_t x) + { + return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? + ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; + } + + /** + * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. + */ + + CMSIS_INLINE __STATIC_INLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y))); + } + +/* + #if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM ) + #define __CLZ __clz + #endif + */ +/* note: function can be removed when all toolchain support __CLZ for Cortex-M0 */ +#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) ) + CMSIS_INLINE __STATIC_INLINE uint32_t __CLZ( + q31_t data); + + CMSIS_INLINE __STATIC_INLINE uint32_t __CLZ( + q31_t data) + { + uint32_t count = 0; + uint32_t mask = 0x80000000; + + while ((data & mask) == 0) + { + count += 1u; + mask = mask >> 1u; + } + + return (count); + } +#endif + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. + */ + + CMSIS_INLINE __STATIC_INLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + q31_t * pRecipTable) + { + q31_t out; + uint32_t tempVal; + uint32_t index, i; + uint32_t signBits; + + if (in > 0) + { + signBits = ((uint32_t) (__CLZ( in) - 1)); + } + else + { + signBits = ((uint32_t) (__CLZ(-in) - 1)); + } + + /* Convert input sample to 1.31 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 24); + index = (index & INDEX_MASK); + + /* 1.31 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0u; i < 2u; i++) + { + tempVal = (uint32_t) (((q63_t) in * out) >> 31); + tempVal = 0x7FFFFFFFu - tempVal; + /* 1.31 with exp 1 */ + /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */ + out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1u); + } + + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. + */ + CMSIS_INLINE __STATIC_INLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + q15_t * pRecipTable) + { + q15_t out = 0; + uint32_t tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if (in > 0) + { + signBits = ((uint32_t)(__CLZ( in) - 17)); + } + else + { + signBits = ((uint32_t)(__CLZ(-in) - 17)); + } + + /* Convert input sample to 1.15 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 8); + index = (index & INDEX_MASK); + + /* 1.15 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0u; i < 2u; i++) + { + tempVal = (uint32_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFFu - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((q31_t) out * tempVal) >> 14); + /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */ + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1); + } + + + /* + * @brief C custom defined intrinisic function for only M0 processors + */ +#if defined(ARM_MATH_CM0_FAMILY) + CMSIS_INLINE __STATIC_INLINE q31_t __SSAT( + q31_t x, + uint32_t y) + { + int32_t posMax, negMin; + uint32_t i; + + posMax = 1; + for (i = 0; i < (y - 1); i++) + { + posMax = posMax * 2; + } + + if (x > 0) + { + posMax = (posMax - 1); + + if (x > posMax) + { + x = posMax; + } + } + else + { + negMin = -posMax; + + if (x < negMin) + { + x = negMin; + } + } + return (x); + } +#endif /* end of ARM_MATH_CM0_FAMILY */ + + + /* + * @brief C custom defined intrinsic function for M3 and M0 processors + */ +/* #if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ +#if !defined (ARM_MATH_DSP) + + /* + * @brief C custom defined QADD8 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QADD8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QSUB8 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QSUB8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QADD16( + uint32_t x, + uint32_t y) + { +/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */ + q31_t r = 0, s = 0; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHADD16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SHADD16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSUB16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSUB16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SHSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QASX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHASX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SHASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSAX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSAX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SHSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SMUSDX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMUSDX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + /* + * @brief C custom defined SMUADX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMUADX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + + /* + * @brief C custom defined QADD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE int32_t __QADD( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y))); + } + + + /* + * @brief C custom defined QSUB for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE int32_t __QSUB( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y))); + } + + + /* + * @brief C custom defined SMLAD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMLAD( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLADX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMLADX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLSDX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMLSDX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint64_t __SMLALD( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALDX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint64_t __SMLALDX( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMUAD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMUAD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SMUSD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMUSD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SXTB16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SXTB16( + uint32_t x) + { + return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) | + ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) )); + } + + /* + * @brief C custom defined SMMLA for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE int32_t __SMMLA( + int32_t x, + int32_t y, + int32_t sum) + { + return (sum + (int32_t) (((int64_t) x * y) >> 32)); + } + +#if 0 + /* + * @brief C custom defined PKHBT for unavailable DSP extension + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __PKHBT( + uint32_t x, + uint32_t y, + uint32_t leftshift) + { + return ( ((x ) & 0x0000FFFFUL) | + ((y << leftshift) & 0xFFFF0000UL) ); + } + + /* + * @brief C custom defined PKHTB for unavailable DSP extension + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __PKHTB( + uint32_t x, + uint32_t y, + uint32_t rightshift) + { + return ( ((x ) & 0xFFFF0000UL) | + ((y >> rightshift) & 0x0000FFFFUL) ); + } +#endif + +/* #endif // defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ +#endif /* !defined (ARM_MATH_DSP) */ + + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_f32; + + + /** + * @brief Processing function for the Q7 FIR filter. + * @param[in] S points to an instance of the Q7 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q7( + const arm_fir_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 FIR filter. + * @param[in,out] S points to an instance of the Q7 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed. + */ + void arm_fir_init_q7( + arm_fir_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR filter. + * @param[in] S points to an instance of the Q15 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR filter. + * @param[in,out] S points to an instance of the Q15 FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if + * numTaps is not a supported value. + */ + arm_status arm_fir_init_q15( + arm_fir_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR filter. + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR filter. + * @param[in,out] S points to an instance of the Q31 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_q31( + arm_fir_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR filter. + * @param[in] S points to an instance of the floating-point FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_f32( + const arm_fir_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR filter. + * @param[in,out] S points to an instance of the floating-point FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_f32( + arm_fir_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q15; + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_casd_df1_inst_f32; + + + /** + * @brief Processing function for the Q15 Biquad cascade filter. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q15( + arm_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + + /** + * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 Biquad cascade filter + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q31( + arm_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + + /** + * @brief Processing function for the floating-point Biquad cascade filter. + * @param[in] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_f32( + const arm_biquad_casd_df1_inst_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point Biquad cascade filter. + * @param[in,out] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df1_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f32; + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float64_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f64; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q31; + + + /** + * @brief Floating-point matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pScratch); + + + /** + * @brief Q31, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + + /** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_fast_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + + /** + * @brief Q31 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix scaling. + * @param[in] pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] pDst points to the output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_q31( + arm_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + + + /** + * @brief Q15 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_q15( + arm_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + + + /** + * @brief Floating-point matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_f32( + arm_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + + + /** + * @brief Instance structure for the Q15 PID Control. + */ + typedef struct + { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ +#if !defined (ARM_MATH_DSP) + q15_t A1; + q15_t A2; +#else + q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ +#endif + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q15; + + /** + * @brief Instance structure for the Q31 PID Control. + */ + typedef struct + { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q31; + + /** + * @brief Instance structure for the floating-point PID Control. + */ + typedef struct + { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ + } arm_pid_instance_f32; + + + + /** + * @brief Initialization function for the floating-point PID Control. + * @param[in,out] S points to an instance of the PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_f32( + arm_pid_instance_f32 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + */ + void arm_pid_reset_f32( + arm_pid_instance_f32 * S); + + + /** + * @brief Initialization function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q31( + arm_pid_instance_q31 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + */ + + void arm_pid_reset_q31( + arm_pid_instance_q31 * S); + + + /** + * @brief Initialization function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q15( + arm_pid_instance_q15 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q15 PID Control. + * @param[in,out] S points to an instance of the q15 PID Control structure + */ + void arm_pid_reset_q15( + arm_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } arm_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q7; + + + /** + * @brief Q7 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q15( + arm_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q15( + const arm_cfft_radix2_instance_q15 * S, + q15_t * pSrc); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q31; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q31( + arm_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q31( + const arm_cfft_radix2_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q31; + +/* Deprecated */ + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix2_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_f32( + arm_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_f32( + const arm_cfft_radix2_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix4_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q15; + +void arm_cfft_q15( + const arm_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q31; + +void arm_cfft_q31( + const arm_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_f32; + + void arm_cfft_f32( + const arm_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q15; + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q31; + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_f32; + + arm_status arm_rfft_init_f32( + arm_rfft_instance_f32 * S, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ +typedef struct + { + arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f32 ; + +arm_status arm_rfft_fast_init_f32 ( + arm_rfft_fast_instance_f32 * S, + uint16_t fftLen); + +void arm_rfft_fast_f32( + arm_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + float32_t *pTwiddle; /**< points to the twiddle factor table. */ + float32_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_f32; + + + /** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. + */ + arm_status arm_dct4_init_f32( + arm_dct4_instance_f32 * S, + arm_rfft_instance_f32 * S_RFFT, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + + /** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_f32( + const arm_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + q31_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q31; + + + /** + * @brief Initialization function for the Q31 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure + * @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q31( + arm_dct4_instance_q31 * S, + arm_rfft_instance_q31 * S_RFFT, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + + /** + * @brief Processing function for the Q31 DCT4/IDCT4. + * @param[in] S points to an instance of the Q31 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q31( + const arm_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + q15_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q15; + + + /** + * @brief Initialization function for the Q15 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q15( + arm_dct4_instance_q15 * S, + arm_rfft_instance_q15 * S_RFFT, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + + /** + * @brief Processing function for the Q15 DCT4/IDCT4. + * @param[in] S points to an instance of the Q15 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q15( + const arm_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + + /** + * @brief Floating-point vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a floating-point vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scale scale factor to be applied + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_f32( + float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q7 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q7( + q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q15 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q15( + q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q31 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q31( + q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Dot product of floating-point vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + + /** + * @brief Dot product of Q7 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q7( + q7_t * pSrcA, + q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + + /** + * @brief Dot product of Q15 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Dot product of Q31 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Shifts the elements of a Q7 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q7( + q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q15 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q15( + q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q31 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q31( + q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_f32( + float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q7( + q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q15( + q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q31( + q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a floating-point vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q7 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a floating-point vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q7 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q15 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q31 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Partial convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q7 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_f32; + + + /** + * @brief Processing function for the floating-point FIR decimator. + * @param[in] S points to an instance of the floating-point FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_f32( + const arm_fir_decimate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR decimator. + * @param[in,out] S points to an instance of the floating-point FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_f32( + arm_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR decimator. + * @param[in,out] S points to an instance of the Q15 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q15( + arm_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR decimator. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q31( + const arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q31( + arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR decimator. + * @param[in,out] S points to an instance of the Q31 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q31( + arm_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + } arm_fir_interpolate_instance_f32; + + + /** + * @brief Processing function for the Q15 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q15( + const arm_fir_interpolate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR interpolator. + * @param[in,out] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q15( + arm_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q31( + const arm_fir_interpolate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR interpolator. + * @param[in,out] S points to an instance of the Q31 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q31( + arm_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR interpolator. + * @param[in] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_f32( + const arm_fir_interpolate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR interpolator. + * @param[in,out] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_f32( + arm_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ + } arm_biquad_cas_df1_32x64_ins_q31; + + + /** + * @param[in] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cas_df1_32x64_q31( + const arm_biquad_cas_df1_32x64_ins_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @param[in,out] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cas_df1_32x64_init_q31( + arm_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_stereo_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f64; + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_stereo_df2T_f32( + const arm_biquad_cascade_stereo_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f64( + const arm_biquad_cascade_df2T_instance_f64 * S, + float64_t * pSrc, + float64_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_stereo_df2T_init_f32( + arm_biquad_cascade_stereo_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f64( + arm_biquad_cascade_df2T_instance_f64 * S, + uint8_t numStages, + float64_t * pCoeffs, + float64_t * pState); + + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_f32; + + + /** + * @brief Initialization function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q15( + arm_fir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pCoeffs, + q15_t * pState); + + + /** + * @brief Processing function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q15( + const arm_fir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q31( + arm_fir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pCoeffs, + q31_t * pState); + + + /** + * @brief Processing function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q31( + const arm_fir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_f32( + arm_fir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Processing function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_f32( + const arm_fir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_f32; + + + /** + * @brief Processing function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_f32( + const arm_iir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize-1. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_f32( + arm_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q31( + const arm_iir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_q31( + arm_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the Q15 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q15( + const arm_iir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the fixed-point Q15 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process per call. + */ + void arm_iir_lattice_init_q15( + arm_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ + } arm_lms_instance_f32; + + + /** + * @brief Processing function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_f32( + const arm_lms_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_init_f32( + arm_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q15; + + + /** + * @brief Initialization function for the Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q15( + arm_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Processing function for Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q15( + const arm_lms_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q31; + + + /** + * @brief Processing function for Q31 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q31( + const arm_lms_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 LMS filter. + * @param[in] S points to an instance of the Q31 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q31( + arm_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_f32; + + + /** + * @brief Processing function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_f32( + arm_lms_norm_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_init_f32( + arm_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q31; + + + /** + * @brief Processing function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q31( + arm_lms_norm_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q31( + arm_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q15; + + + /** + * @brief Processing function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q15( + arm_lms_norm_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q15( + arm_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Correlation of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Correlation of Q15 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ + void arm_correlate_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + + void arm_correlate_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + + void arm_correlate_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ + void arm_correlate_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_correlate_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q7; + + + /** + * @brief Processing function for the floating-point sparse FIR filter. + * @param[in] S points to an instance of the floating-point sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_f32( + arm_fir_sparse_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point sparse FIR filter. + * @param[in,out] S points to an instance of the floating-point sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_f32( + arm_fir_sparse_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 sparse FIR filter. + * @param[in] S points to an instance of the Q31 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q31( + arm_fir_sparse_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 sparse FIR filter. + * @param[in,out] S points to an instance of the Q31 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q31( + arm_fir_sparse_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 sparse FIR filter. + * @param[in] S points to an instance of the Q15 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q15( + arm_fir_sparse_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 sparse FIR filter. + * @param[in,out] S points to an instance of the Q15 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q15( + arm_fir_sparse_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q7 sparse FIR filter. + * @param[in] S points to an instance of the Q7 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q7( + arm_fir_sparse_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 sparse FIR filter. + * @param[in,out] S points to an instance of the Q7 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q7( + arm_fir_sparse_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Floating-point sin_cos function. + * @param[in] theta input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cos output. + */ + void arm_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCosVal); + + + /** + * @brief Q31 sin_cos function. + * @param[in] theta scaled input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cosine output. + */ + void arm_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + + /** + * @brief Floating-point complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * S points to an instance of the PID control data structure. in + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + *
+   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+   *    A0 = Kp + Ki + Kd
+   *    A1 = (-Kp ) - (2 * Kd )
+   *    A2 = Kd  
+ * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup PID + * @{ + */ + + /** + * @brief Process function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + */ + CMSIS_INLINE __STATIC_INLINE float32_t arm_pid_f32( + arm_pid_instance_f32 * S, + float32_t in) + { + float32_t out; + + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @brief Process function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 64-bit accumulator. + * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + * Thus, if the accumulator result overflows it wraps around rather than clip. + * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ + CMSIS_INLINE __STATIC_INLINE q31_t arm_pid_q31( + arm_pid_instance_q31 * S, + q31_t in) + { + q63_t acc; + q31_t out; + + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31u); + + /* out += y[n-1] */ + out += S->state[2]; + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + + /** + * @brief Process function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using a 64-bit internal accumulator. + * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + * Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ + CMSIS_INLINE __STATIC_INLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + +#if defined (ARM_MATH_DSP) + __SIMD32_TYPE *vstate; + + /* Implementation of PID controller */ + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in); + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + vstate = __SIMD32_CONST(S->state); + acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)*vstate, (uint64_t)acc); +#else + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; +#endif + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT((acc >> 15), 16)); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + /** + * @} end of PID group + */ + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * src, + arm_matrix_instance_f32 * dst); + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f64( + const arm_matrix_instance_f64 * src, + arm_matrix_instance_f64 * dst); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents + * in the two-phase orthogonal stator axis Ialpha and Ibeta. + * When Ialpha is superposed with Ia as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta + * can be calculated using only Ia and Ib. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where Ia and Ib are the instantaneous stator phases and + * pIalpha and pIbeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup clarke + * @{ + */ + + /** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + */ + CMSIS_INLINE __STATIC_INLINE void arm_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) + { + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); + } + + + /** + * @brief Clarke transform for Q31 version + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + CMSIS_INLINE __STATIC_INLINE void arm_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); + } + + /** + * @} end of clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q31( + q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where pIa and pIb are the instantaneous stator phases and + * Ialpha and Ibeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_clarke + * @{ + */ + + /** + * @brief Floating-point Inverse Clarke transform + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + */ + CMSIS_INLINE __STATIC_INLINE void arm_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) + { + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta; + } + + + /** + * @brief Inverse Clarke transform for Q31 version + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the subtraction, hence there is no risk of overflow. + */ + CMSIS_INLINE __STATIC_INLINE void arm_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); + } + + /** + * @} end of inv_clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q15( + q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where Ialpha and Ibeta are the stator vector components, + * pId and pIq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup park + * @{ + */ + + /** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * The function implements the forward Park transform. + * + */ + CMSIS_INLINE __STATIC_INLINE void arm_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; + } + + + /** + * @brief Park transform for Q31 version + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ + CMSIS_INLINE __STATIC_INLINE void arm_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); + + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); + } + + /** + * @} end of park group + */ + + /** + * @brief Converts the elements of the Q7 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q7_to_float( + q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where pIalpha and pIbeta are the stator vector components, + * Id and Iq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_park + * @{ + */ + + /** + * @brief Floating-point Inverse Park transform + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + */ + CMSIS_INLINE __STATIC_INLINE void arm_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; + } + + + /** + * @brief Inverse Park transform for Q31 version + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + CMSIS_INLINE __STATIC_INLINE void arm_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); + + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); + } + + /** + * @} end of Inverse park group + */ + + + /** + * @brief Converts the elements of the Q31 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_float( + q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + *
+   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+   *       where x0, x1 are nearest values of input x
+   *             y0, y1 are nearest values to output y
+   * 
+ * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * S points to an instance of the Linear Interpolate function data structure. + * x is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ + + /** + * @addtogroup LinearInterpolate + * @{ + */ + + /** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ + CMSIS_INLINE __STATIC_INLINE float32_t arm_linear_interp_f32( + arm_linear_interp_instance_f32 * S, + float32_t x) + { + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + + /* Calculation of index */ + i = (int32_t) ((x - S->x1) / xSpacing); + + if (i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if ((uint32_t)i >= S->nValues) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + + } + + /* returns output value */ + return (y); + } + + + /** + * + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + CMSIS_INLINE __STATIC_INLINE q31_t arm_linear_interp_q31( + q31_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (q31_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if (index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); + + /* Convert y to 1.31 format */ + return (y << 1u); + } + } + + + /** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + CMSIS_INLINE __STATIC_INLINE q15_t arm_linear_interp_q15( + q15_t * pYData, + q31_t x, + uint32_t nValues) + { + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (int32_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if (index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); + + /* convert y to 1.15 format */ + return (q15_t) (y >> 20); + } + } + + + /** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ + CMSIS_INLINE __STATIC_INLINE q7_t arm_linear_interp_q7( + q7_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + uint32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + if (x < 0) + { + return (pYData[0]); + } + index = (x >> 20) & 0xfff; + + if (index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + + /* convert y to 1.7(q7) format */ + return (q7_t) (y >> 20); + } + } + + /** + * @} end of LinearInterpolate group + */ + + /** + * @brief Fast approximation to the trigonometric sine function for floating-point data. + * @param[in] x input value in radians. + * @return sin(x). + */ + float32_t arm_sin_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q31_t arm_sin_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q15_t arm_sin_q15( + q15_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for floating-point data. + * @param[in] x input value in radians. + * @return cos(x). + */ + float32_t arm_cos_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q31_t arm_cos_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q15_t arm_cos_q15( + q15_t x); + + + /** + * @ingroup groupFastMath + */ + + + /** + * @defgroup SQRT Square Root + * + * Computes the square root of a number. + * There are separate functions for Q15, Q31, and floating-point data types. + * The square root function is computed using the Newton-Raphson algorithm. + * This is an iterative algorithm of the form: + *
+   *      x1 = x0 - f(x0)/f'(x0)
+   * 
+ * where x1 is the current estimate, + * x0 is the previous estimate, and + * f'(x0) is the derivative of f() evaluated at x0. + * For the square root function, the algorithm reduces to: + *
+   *     x0 = in/2                         [initial guess]
+   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+   * 
+ */ + + + /** + * @addtogroup SQRT + * @{ + */ + + /** + * @brief Floating-point square root function. + * @param[in] in input value. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + CMSIS_INLINE __STATIC_INLINE arm_status arm_sqrt_f32( + float32_t in, + float32_t * pOut) + { + if (in >= 0.0f) + { + +#if (__FPU_USED == 1) && defined ( __CC_ARM ) + *pOut = __sqrtf(in); +#elif (__FPU_USED == 1) && (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) + *pOut = __builtin_sqrtf(in); +#elif (__FPU_USED == 1) && defined(__GNUC__) + *pOut = __builtin_sqrtf(in); +#elif (__FPU_USED == 1) && defined ( __ICCARM__ ) && (__VER__ >= 6040000) + __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in)); +#else + *pOut = sqrtf(in); +#endif + + return (ARM_MATH_SUCCESS); + } + else + { + *pOut = 0.0f; + return (ARM_MATH_ARGUMENT_ERROR); + } + } + + + /** + * @brief Q31 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q31( + q31_t in, + q31_t * pOut); + + + /** + * @brief Q15 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q15( + q15_t in, + q15_t * pOut); + + /** + * @} end of SQRT group + */ + + + /** + * @brief floating-point Circular write function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularWrite_f32( + int32_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const int32_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularRead_f32( + int32_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + int32_t * dst, + int32_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == (int32_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q15 Circular write function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularWrite_q15( + q15_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q15_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q15 Circular Read function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularRead_q15( + q15_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q15_t * dst, + q15_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == (q15_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update wOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q7 Circular write function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularWrite_q7( + q7_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q7_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q7 Circular Read function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularRead_q7( + q7_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q7_t * dst, + q7_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == (q7_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Sum of the squares of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q15( + q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q7( + q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + + /** + * @brief Mean value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Mean value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Variance of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Standard deviation of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Floating-point complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + + /** + * @brief Q31 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + + /** + * @brief Floating-point complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + + /** + * @brief Q15 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q15( + q15_t * pSrcCmplx, + q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q31( + q31_t * pSrcCmplx, + q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_f32( + float32_t * pSrcCmplx, + float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Minimum value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] result is output pointer + * @param[in] index is the array index of the minimum value in the input buffer. + */ + void arm_min_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + + /** + * @brief Minimum value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[in] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q7 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q15 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a floating-point vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Q15 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Converts the elements of the floating-point vector to Q31 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q31 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q31( + float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q15 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q15( + float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q7 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q7 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q7( + float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q15 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q15( + q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q7( + q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_float( + q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q31 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q31( + q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q7( + q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function f(x, y) is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * Algorithm + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + *
+   *   typedef struct
+   *   {
+   *     uint16_t numRows;
+   *     uint16_t numCols;
+   *     float32_t *pData;
+   * } arm_bilinear_interp_instance_f32;
+   * 
+ * + * \par + * where numRows specifies the number of rows in the table; + * numCols specifies the number of columns in the table; + * and pData points to an array of size numRows*numCols values. + * The data table pTable is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. + * + * \par + * Let (x, y) specify the desired interpolation point. Then define: + *
+   *     XF = floor(x)
+   *     YF = floor(y)
+   * 
+ * \par + * The interpolated output point is computed as: + *
+   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+   * 
+ * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ + + /** + * @addtogroup BilinearInterpolate + * @{ + */ + + + /** + * + * @brief Floating-point bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate. + * @param[in] Y interpolation coordinate. + * @return out interpolated value. + */ + CMSIS_INLINE __STATIC_INLINE float32_t arm_bilinear_interp_f32( + const arm_bilinear_interp_instance_f32 * S, + float32_t X, + float32_t Y) + { + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1)) + { + return (0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex - 1) + (yIndex - 1) * S->numCols; + + + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex - 1) + (yIndex) * S->numCols; + + + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + + /* return to application */ + return (out); + } + + + /** + * + * @brief Q31 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + CMSIS_INLINE __STATIC_INLINE q31_t arm_bilinear_interp_q31( + arm_bilinear_interp_instance_q31 * S, + q31_t X, + q31_t Y) + { + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + (int32_t)nCols * (cI) ]; + x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1]; + + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ]; + y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* Convert acc to 1.31(q31) format */ + return ((q31_t)(acc << 2)); + } + + + /** + * @brief Q15 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + CMSIS_INLINE __STATIC_INLINE q15_t arm_bilinear_interp_q15( + arm_bilinear_interp_instance_q15 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ + out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u); + acc = ((q63_t) out * (0xFFFFF - yfract)); + + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u); + acc += ((q63_t) out * (xfract)); + + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return ((q15_t)(acc >> 36)); + } + + + /** + * @brief Q7 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + CMSIS_INLINE __STATIC_INLINE q7_t arm_bilinear_interp_q7( + arm_bilinear_interp_instance_q7 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); + acc = (((q63_t) out * (0xFFFFF - yfract))); + + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); + + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return ((q7_t)(acc >> 40)); + } + + /** + * @} end of BilinearInterpolate group + */ + + +/* SMMLAR */ +#define multAcc_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMLSR */ +#define multSub_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMULR */ +#define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) + +/* SMMLA */ +#define multAcc_32x32_keep32(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + +/* SMMLS */ +#define multSub_32x32_keep32(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +/* SMMUL */ +#define mult_32x32_keep32(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) + + +#if defined ( __CC_ARM ) + /* Enter low optimization region - place directly above function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("push") \ + _Pragma ("O1") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) + #define LOW_OPTIMIZATION_EXIT \ + _Pragma ("pop") + #else + #define LOW_OPTIMIZATION_EXIT + #endif + + /* Enter low optimization region - place directly above function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined (__ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __GNUC__ ) + #define LOW_OPTIMIZATION_ENTER \ + __attribute__(( optimize("-O1") )) + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __ICCARM__ ) + /* Enter low optimization region - place directly above function definition */ + #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define LOW_OPTIMIZATION_EXIT + + /* Enter low optimization region - place directly above function definition */ + #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __TI_ARM__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __CSMC__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __TASKING__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#endif + + +#ifdef __cplusplus +} +#endif + +/* Compiler specific diagnostic adjustment */ +#if defined ( __CC_ARM ) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + +#elif defined ( __GNUC__ ) +#pragma GCC diagnostic pop + +#elif defined ( __ICCARM__ ) + +#elif defined ( __TI_ARM__ ) + +#elif defined ( __CSMC__ ) + +#elif defined ( __TASKING__ ) + +#else + #error Unknown compiler +#endif + +#endif /* _ARM_MATH_H */ + +/** + * + * End of file. + */ From c5a54382563b5b985833d2591ead8996cf427509 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Thu, 19 Oct 2017 13:56:24 -0500 Subject: [PATCH 24/26] Update params in calls to LD/STREXW to be uint32_t --- targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_lock.h | 2 +- targets/TARGET_Maxim/TARGET_MAX32630/mxc/mxc_lock.h | 4 ++-- .../TARGET_STM/TARGET_STM32F2/device/stm32f2xx_hal_def.h | 8 ++++---- .../TARGET_STM/TARGET_STM32F3/device/stm32f3xx_hal_def.h | 8 ++++---- .../TARGET_STM/TARGET_STM32F4/device/stm32f4xx_hal_def.h | 8 ++++---- .../TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_def.h | 8 ++++---- .../TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_def.h | 8 ++++---- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_lock.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_lock.h index 28bb062f6ec..475024adbaa 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_lock.h +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/mxc_lock.h @@ -69,7 +69,7 @@ __STATIC_INLINE int mxc_get_lock(uint32_t *lock, uint32_t value) do { // Return if the lock is taken by a different thread - if(__LDREXW((volatile unsigned long *)lock) != 0) { + if(__LDREXW((volatile uint32_t *)lock) != 0) { return E_BUSY; } diff --git a/targets/TARGET_Maxim/TARGET_MAX32630/mxc/mxc_lock.h b/targets/TARGET_Maxim/TARGET_MAX32630/mxc/mxc_lock.h index 3c17a9298e7..bd2988eb658 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32630/mxc/mxc_lock.h +++ b/targets/TARGET_Maxim/TARGET_MAX32630/mxc/mxc_lock.h @@ -80,12 +80,12 @@ __STATIC_INLINE int mxc_get_lock(uint32_t *lock, uint32_t value) do { // Return if the lock is taken by a different thread - if(__LDREXW((volatile unsigned long *)lock) != 0) { + if(__LDREXW((volatile uint32_t *)lock) != 0) { return E_BUSY; } // Attempt to take the lock - } while(__STREXW(value, (volatile unsigned long *)lock) != 0); + } while(__STREXW(value, (volatile uint32_t *)lock) != 0); // Do not start any other memory access until memory barrier is complete __DMB(); diff --git a/targets/TARGET_STM/TARGET_STM32F2/device/stm32f2xx_hal_def.h b/targets/TARGET_STM/TARGET_STM32F2/device/stm32f2xx_hal_def.h index 546122d81ec..ea2397fe571 100644 --- a/targets/TARGET_STM/TARGET_STM32F2/device/stm32f2xx_hal_def.h +++ b/targets/TARGET_STM/TARGET_STM32F2/device/stm32f2xx_hal_def.h @@ -130,9 +130,9 @@ static inline void atomic_set_u32(volatile uint32_t *ptr, uint32_t mask) { uint32_t newValue; do { - newValue = (uint32_t)__LDREXW((volatile unsigned long *)ptr) | mask; + newValue = (uint32_t)__LDREXW(ptr) | mask; - } while (__STREXW(newValue,(volatile unsigned long*) ptr)); + } while (__STREXW(newValue, ptr)); } @@ -140,9 +140,9 @@ static inline void atomic_clr_u32(volatile uint32_t *ptr, uint32_t mask) { uint32_t newValue; do { - newValue = (uint32_t)__LDREXW((volatile unsigned long *)ptr) &~mask; + newValue = (uint32_t)__LDREXW(ptr) &~mask; - } while (__STREXW(newValue,(volatile unsigned long*) ptr)); + } while (__STREXW(newValue, ptr)); } #if defined ( __GNUC__ ) && !defined ( __CC_ARM ) diff --git a/targets/TARGET_STM/TARGET_STM32F3/device/stm32f3xx_hal_def.h b/targets/TARGET_STM/TARGET_STM32F3/device/stm32f3xx_hal_def.h index 757a6e8458d..87328a7192c 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/device/stm32f3xx_hal_def.h +++ b/targets/TARGET_STM/TARGET_STM32F3/device/stm32f3xx_hal_def.h @@ -129,9 +129,9 @@ static inline void atomic_set_u32(volatile uint32_t *ptr, uint32_t mask) { uint32_t newValue; do { - newValue = (uint32_t)__LDREXW((volatile unsigned long *)ptr) | mask; + newValue = (uint32_t)__LDREXW(ptr) | mask; - } while (__STREXW(newValue,(volatile unsigned long*) ptr)); + } while (__STREXW(newValue, ptr)); } @@ -139,9 +139,9 @@ static inline void atomic_clr_u32(volatile uint32_t *ptr, uint32_t mask) { uint32_t newValue; do { - newValue = (uint32_t)__LDREXW((volatile unsigned long *)ptr) &~mask; + newValue = (uint32_t)__LDREXW(ptr) &~mask; - } while (__STREXW(newValue,(volatile unsigned long*) ptr)); + } while (__STREXW(newValue, ptr)); } #if defined ( __GNUC__ ) && !defined ( __CC_ARM ) diff --git a/targets/TARGET_STM/TARGET_STM32F4/device/stm32f4xx_hal_def.h b/targets/TARGET_STM/TARGET_STM32F4/device/stm32f4xx_hal_def.h index 8462aa4fe02..efa60dee6ee 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/device/stm32f4xx_hal_def.h +++ b/targets/TARGET_STM/TARGET_STM32F4/device/stm32f4xx_hal_def.h @@ -129,9 +129,9 @@ static inline void atomic_set_u32(volatile uint32_t *ptr, uint32_t mask) { uint32_t newValue; do { - newValue = (uint32_t)__LDREXW((volatile unsigned long *)ptr) | mask; + newValue = (uint32_t)__LDREXW(ptr) | mask; - } while (__STREXW(newValue,(volatile unsigned long*) ptr)); + } while (__STREXW(newValue, ptr)); } @@ -139,9 +139,9 @@ static inline void atomic_clr_u32(volatile uint32_t *ptr, uint32_t mask) { uint32_t newValue; do { - newValue = (uint32_t)__LDREXW((volatile unsigned long *)ptr) &~mask; + newValue = (uint32_t)__LDREXW(ptr) &~mask; - } while (__STREXW(newValue,(volatile unsigned long*) ptr)); + } while (__STREXW(newValue, ptr)); } #endif /* USE_RTOS */ diff --git a/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_def.h b/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_def.h index 825d7fd0a15..fbdf3875009 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_def.h +++ b/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_def.h @@ -130,9 +130,9 @@ static inline void atomic_set_u32(volatile uint32_t *ptr, uint32_t mask) { uint32_t newValue; do { - newValue = (uint32_t)__LDREXW((volatile unsigned long *)ptr) | mask; + newValue = (uint32_t)__LDREXW(ptr) | mask; - } while (__STREXW(newValue,(volatile unsigned long*) ptr)); + } while (__STREXW(newValue, ptr)); } @@ -140,9 +140,9 @@ static inline void atomic_clr_u32(volatile uint32_t *ptr, uint32_t mask) { uint32_t newValue; do { - newValue = (uint32_t)__LDREXW((volatile unsigned long *)ptr) &~mask; + newValue = (uint32_t)__LDREXW(ptr) &~mask; - } while (__STREXW(newValue,(volatile unsigned long*) ptr)); + } while (__STREXW(newValue, ptr)); } #if defined ( __GNUC__ ) && !defined ( __CC_ARM ) diff --git a/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_def.h b/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_def.h index ad596e5534f..9dde4bccd2e 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_def.h +++ b/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_def.h @@ -132,9 +132,9 @@ static inline void atomic_set_u32(volatile uint32_t *ptr, uint32_t mask) { uint32_t newValue; do { - newValue = (uint32_t)__LDREXW((volatile unsigned long *)ptr) | mask; + newValue = (uint32_t)__LDREXW(ptr) | mask; - } while (__STREXW(newValue,(volatile unsigned long*) ptr)); + } while (__STREXW(newValue, ptr)); } @@ -142,9 +142,9 @@ static inline void atomic_clr_u32(volatile uint32_t *ptr, uint32_t mask) { uint32_t newValue; do { - newValue = (uint32_t)__LDREXW((volatile unsigned long *)ptr) &~mask; + newValue = (uint32_t)__LDREXW(ptr) &~mask; - } while (__STREXW(newValue,(volatile unsigned long*) ptr)); + } while (__STREXW(newValue, ptr)); } #if defined ( __GNUC__ ) && !defined ( __CC_ARM ) From 6e11dc2c4ab282a69fa0a067696863549f8afeca Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Fri, 20 Oct 2017 13:51:20 -0500 Subject: [PATCH 25/26] Modification to arm_math.h Remove redefinition of __CLZ and __SSAT. --- cmsis/TARGET_CORTEX_M/arm_math.h | 67 ------------------- features/unsupported/dsp/cmsis_dsp/arm_math.h | 41 ------------ 2 files changed, 108 deletions(-) diff --git a/cmsis/TARGET_CORTEX_M/arm_math.h b/cmsis/TARGET_CORTEX_M/arm_math.h index 6d754018966..f867d494309 100644 --- a/cmsis/TARGET_CORTEX_M/arm_math.h +++ b/cmsis/TARGET_CORTEX_M/arm_math.h @@ -572,32 +572,6 @@ extern "C" (((q63_t) (x >> 32) * y))); } -/* - #if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM ) - #define __CLZ __clz - #endif - */ -/* note: function can be removed when all toolchain support __CLZ for Cortex-M0 */ -#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) ) - CMSIS_INLINE __STATIC_INLINE uint32_t __CLZ( - q31_t data); - - CMSIS_INLINE __STATIC_INLINE uint32_t __CLZ( - q31_t data) - { - uint32_t count = 0; - uint32_t mask = 0x80000000; - - while ((data & mask) == 0) - { - count += 1u; - mask = mask >> 1u; - } - - return (count); - } -#endif - /** * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. */ @@ -700,47 +674,6 @@ extern "C" return (signBits + 1); } - - /* - * @brief C custom defined intrinisic function for only M0 processors - */ -#if defined(ARM_MATH_CM0_FAMILY) - CMSIS_INLINE __STATIC_INLINE q31_t __SSAT( - q31_t x, - uint32_t y) - { - int32_t posMax, negMin; - uint32_t i; - - posMax = 1; - for (i = 0; i < (y - 1); i++) - { - posMax = posMax * 2; - } - - if (x > 0) - { - posMax = (posMax - 1); - - if (x > posMax) - { - x = posMax; - } - } - else - { - negMin = -posMax; - - if (x < negMin) - { - x = negMin; - } - } - return (x); - } -#endif /* end of ARM_MATH_CM0_FAMILY */ - - /* * @brief C custom defined intrinsic function for M3 and M0 processors */ diff --git a/features/unsupported/dsp/cmsis_dsp/arm_math.h b/features/unsupported/dsp/cmsis_dsp/arm_math.h index b1393de1a07..370c6fddd07 100644 --- a/features/unsupported/dsp/cmsis_dsp/arm_math.h +++ b/features/unsupported/dsp/cmsis_dsp/arm_math.h @@ -659,47 +659,6 @@ extern "C" return (signBits + 1); } - - /* - * @brief C custom defined intrinisic function for only M0 processors - */ -#if defined(ARM_MATH_CM0_FAMILY) - static __INLINE q31_t __SSAT( - q31_t x, - uint32_t y) - { - int32_t posMax, negMin; - uint32_t i; - - posMax = 1; - for (i = 0; i < (y - 1); i++) - { - posMax = posMax * 2; - } - - if(x > 0) - { - posMax = (posMax - 1); - - if(x > posMax) - { - x = posMax; - } - } - else - { - negMin = -posMax; - - if(x < negMin) - { - x = negMin; - } - } - return (x); - } -#endif /* end of ARM_MATH_CM0_FAMILY */ - - /* * @brief C custom defined intrinsic function for M3 and M0 processors */ From a451498141669141e7c48f812f3ad3981ded22aa Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Tue, 24 Oct 2017 23:32:53 +0800 Subject: [PATCH 26/26] rtl8195am - remove redundant header file inclusion Signed-off-by: Tony Wu --- .../TARGET_RTL8195A/device/rtl8195a_init.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/rtl8195a_init.c b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/rtl8195a_init.c index 1882a7c7472..68d7f44edfa 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/rtl8195a_init.c +++ b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/rtl8195a_init.c @@ -15,17 +15,6 @@ */ #include "rtl8195a.h" -#if defined(__CC_ARM) -#include "cmsis_armcc.h" -#elif (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 6010050) -#include "cmsis_armclang.h" -#elif defined(__GNUC__) -#include "cmsis_gcc.h" -#else -#include -#endif - - #if defined(__CC_ARM) || \ (defined (__ARMCC_VERSION) && __ARMCC_VERSION >= 6010050)