1 /**************************************************************************//**
3 * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file
5 * @date 13. November 2022
6 ******************************************************************************/
8 * Copyright (c) 2009-2021 Arm Limited. All rights reserved.
10 * SPDX-License-Identifier: Apache-2.0
12 * Licensed under the Apache License, Version 2.0 (the License); you may
13 * not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
16 * www.apache.org/licenses/LICENSE-2.0
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
20 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
25 #ifndef __CMSIS_ARMCC_H
26 #define __CMSIS_ARMCC_H
29 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
30 #error "Please use Arm Compiler Toolchain V4.0.677 or later!"
33 /* CMSIS compiler control architecture macros */
34 #if (defined (__TARGET_ARCH_7_A ) && (__TARGET_ARCH_7_A == 1))
35 #define __ARM_ARCH_7A__ 1
38 /* CMSIS compiler specific defines */
43 #define __INLINE __inline
46 #define __FORCEINLINE __forceinline
48 #ifndef __STATIC_INLINE
49 #define __STATIC_INLINE static __inline
51 #ifndef __STATIC_FORCEINLINE
52 #define __STATIC_FORCEINLINE static __forceinline
55 #define __NO_RETURN __declspec(noreturn)
57 #ifndef CMSIS_DEPRECATED
58 #define CMSIS_DEPRECATED __attribute__((deprecated))
61 #define __USED __attribute__((used))
64 #define __WEAK __attribute__((weak))
67 #define __PACKED __attribute__((packed))
69 #ifndef __PACKED_STRUCT
70 #define __PACKED_STRUCT __packed struct
72 #ifndef __PACKED_UNION
73 #define __PACKED_UNION __packed union
75 #ifndef __UNALIGNED_UINT32 /* deprecated */
76 #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
78 #ifndef __UNALIGNED_UINT16_WRITE
79 #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val))
81 #ifndef __UNALIGNED_UINT16_READ
82 #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr)))
84 #ifndef __UNALIGNED_UINT32_WRITE
85 #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
87 #ifndef __UNALIGNED_UINT32_READ
88 #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
91 #define __ALIGNED(x) __attribute__((aligned(x)))
94 #define __RESTRICT __restrict
96 #ifndef __COMPILER_BARRIER
97 #define __COMPILER_BARRIER() __memory_changed()
100 /* ########################## Core Instruction Access ######################### */
103 \details No Operation does nothing. This instruction can be used for code alignment purposes.
109 \brief Wait For Interrupt
110 \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
116 \brief Wait For Event
117 \details Wait For Event is a hint instruction that permits the processor to enter
118 a low-power state until one of a number of events occurs.
125 \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
131 \brief Instruction Synchronization Barrier
132 \details Instruction Synchronization Barrier flushes the pipeline in the processor,
133 so that all instructions following the ISB are fetched from cache or memory,
134 after the instruction has been completed.
136 #define __ISB() __isb(0xF)
139 \brief Data Synchronization Barrier
140 \details Acts as a special kind of Data Memory Barrier.
141 It completes when all explicit memory accesses before this instruction complete.
143 #define __DSB() __dsb(0xF)
146 \brief Data Memory Barrier
147 \details Ensures the apparent order of the explicit memory operations before
148 and after the instruction, without ensuring their completion.
150 #define __DMB() __dmb(0xF)
154 \brief Reverse byte order (32 bit)
155 \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
156 \param [in] value Value to reverse
157 \return Reversed value
163 \brief Reverse byte order (16 bit)
164 \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
165 \param [in] value Value to reverse
166 \return Reversed value
168 #ifndef __NO_EMBEDDED_ASM
169 __attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
178 \brief Reverse byte order (16 bit)
179 \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
180 \param [in] value Value to reverse
181 \return Reversed value
183 #ifndef __NO_EMBEDDED_ASM
184 __attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value)
193 \brief Rotate Right in unsigned value (32 bit)
194 \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
195 \param [in] op1 Value to rotate
196 \param [in] op2 Number of Bits to rotate
197 \return Rotated value
204 \details Causes the processor to enter Debug state.
205 Debug tools can use this to investigate system state when the instruction at a particular address is reached.
206 \param [in] value is ignored by the processor.
207 If required, a debugger can use it to store additional information about the breakpoint.
209 #define __BKPT(value) __breakpoint(value)
213 \brief Reverse bit order of value
214 \details Reverses the bit order of the given value.
215 \param [in] value Value to reverse
216 \return Reversed value
218 #define __RBIT __rbit
221 \brief Count leading zeros
222 \details Counts the number of leading zeros of a data value.
223 \param [in] value Value to count the leading zeros
224 \return number of leading zeros in value
229 \brief LDR Exclusive (8 bit)
230 \details Executes a exclusive LDR instruction for 8 bit value.
231 \param [in] ptr Pointer to data
232 \return value of type uint8_t at (*ptr)
234 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
235 #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
237 #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
242 \brief LDR Exclusive (16 bit)
243 \details Executes a exclusive LDR instruction for 16 bit values.
244 \param [in] ptr Pointer to data
245 \return value of type uint16_t at (*ptr)
247 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
248 #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
250 #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
255 \brief LDR Exclusive (32 bit)
256 \details Executes a exclusive LDR instruction for 32 bit values.
257 \param [in] ptr Pointer to data
258 \return value of type uint32_t at (*ptr)
260 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
261 #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
263 #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
268 \brief STR Exclusive (8 bit)
269 \details Executes a exclusive STR instruction for 8 bit values.
270 \param [in] value Value to store
271 \param [in] ptr Pointer to location
272 \return 0 Function succeeded
273 \return 1 Function failed
275 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
276 #define __STREXB(value, ptr) __strex(value, ptr)
278 #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
283 \brief STR Exclusive (16 bit)
284 \details Executes a exclusive STR instruction for 16 bit values.
285 \param [in] value Value to store
286 \param [in] ptr Pointer to location
287 \return 0 Function succeeded
288 \return 1 Function failed
290 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
291 #define __STREXH(value, ptr) __strex(value, ptr)
293 #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
298 \brief STR Exclusive (32 bit)
299 \details Executes a exclusive STR instruction for 32 bit values.
300 \param [in] value Value to store
301 \param [in] ptr Pointer to location
302 \return 0 Function succeeded
303 \return 1 Function failed
305 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
306 #define __STREXW(value, ptr) __strex(value, ptr)
308 #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
313 \brief Remove the exclusive lock
314 \details Removes the exclusive lock which is created by LDREX.
316 #define __CLREX __clrex
320 \brief Signed Saturate
321 \details Saturates a signed value.
322 \param [in] value Value to be saturated
323 \param [in] sat Bit position to saturate to (1..32)
324 \return Saturated value
326 #define __SSAT __ssat
330 \brief Unsigned Saturate
331 \details Saturates an unsigned value.
332 \param [in] value Value to be saturated
333 \param [in] sat Bit position to saturate to (0..31)
334 \return Saturated value
336 #define __USAT __usat
338 /* ########################### Core Function Access ########################### */
341 \brief Enable IRQ Interrupts
342 \details Enables IRQ interrupts by clearing special-purpose register PRIMASK.
343 Can only be executed in Privileged modes.
345 /* intrinsic void __enable_irq(); */
349 \brief Disable IRQ Interrupts
350 \details Disables IRQ interrupts by setting special-purpose register PRIMASK.
351 Can only be executed in Privileged modes.
353 /* intrinsic void __disable_irq(void); */
357 \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
358 Can only be executed in Privileged modes.
360 #define __enable_fault_irq __enable_fiq
364 \details Disables FIQ interrupts by setting the F-bit in the CPSR.
365 Can only be executed in Privileged modes.
367 #define __disable_fault_irq __disable_fiq
370 \brief Get FPSCR (Floating Point Status/Control)
371 \return Floating Point Status/Control register value
373 __STATIC_INLINE uint32_t __get_FPSCR(void)
375 #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
376 (defined (__FPU_USED ) && (__FPU_USED == 1U)) )
377 register uint32_t __regfpscr __ASM("fpscr");
385 \brief Set FPSCR (Floating Point Status/Control)
386 \param [in] fpscr Floating Point Status/Control value to set
388 __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
390 #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
391 (defined (__FPU_USED ) && (__FPU_USED == 1U)) )
392 register uint32_t __regfpscr __ASM("fpscr");
393 __regfpscr = (fpscr);
399 /** \brief Get CPSR (Current Program Status Register)
400 \return CPSR Register value
402 __STATIC_INLINE uint32_t __get_CPSR(void)
404 register uint32_t __regCPSR __ASM("cpsr");
409 /** \brief Set CPSR (Current Program Status Register)
410 \param [in] cpsr CPSR value to set
412 __STATIC_INLINE void __set_CPSR(uint32_t cpsr)
414 register uint32_t __regCPSR __ASM("cpsr");
419 \return Processor Mode
421 __STATIC_INLINE uint32_t __get_mode(void)
423 return (__get_CPSR() & 0x1FU);
427 \param [in] mode Mode value to set
429 __STATIC_INLINE __ASM void __set_mode(uint32_t mode)
436 /** \brief Get Stack Pointer
437 \return Stack Pointer
439 __STATIC_INLINE __ASM uint32_t __get_SP(void)
445 /** \brief Set Stack Pointer
446 \param [in] stack Stack Pointer value to set
448 __STATIC_INLINE __ASM void __set_SP(uint32_t stack)
455 /** \brief Get USR/SYS Stack Pointer
456 \return USR/SYSStack Pointer
458 __STATIC_INLINE __ASM uint32_t __get_SP_usr(void)
464 CPS #0x1F ;no effect in USR mode
466 MSR CPSR_c, R1 ;no effect in USR mode
471 /** \brief Set USR/SYS Stack Pointer
472 \param [in] topOfProcStack USR/SYS Stack Pointer value to set
474 __STATIC_INLINE __ASM void __set_SP_usr(uint32_t topOfProcStack)
480 CPS #0x1F ;no effect in USR mode
482 MSR CPSR_c, R1 ;no effect in USR mode
487 /** \brief Get FPEXC (Floating Point Exception Control Register)
488 \return Floating Point Exception Control Register value
490 __STATIC_INLINE uint32_t __get_FPEXC(void)
492 #if (__FPU_PRESENT == 1)
493 register uint32_t __regfpexc __ASM("fpexc");
500 /** \brief Set FPEXC (Floating Point Exception Control Register)
501 \param [in] fpexc Floating Point Exception Control value to set
503 __STATIC_INLINE void __set_FPEXC(uint32_t fpexc)
505 #if (__FPU_PRESENT == 1)
506 register uint32_t __regfpexc __ASM("fpexc");
507 __regfpexc = (fpexc);
512 * Include common core functions to access Coprocessor 15 registers
515 #define __get_CP(cp, op1, Rt, CRn, CRm, op2) do { register volatile uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); (Rt) = tmp; } while(0)
516 #define __set_CP(cp, op1, Rt, CRn, CRm, op2) do { register volatile uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); tmp = (Rt); } while(0)
517 #define __get_CP64(cp, op1, Rt, CRm) \
519 uint32_t ltmp, htmp; \
520 __ASM volatile("MRRC p" # cp ", " # op1 ", ltmp, htmp, c" # CRm); \
521 (Rt) = ((((uint64_t)htmp) << 32U) | ((uint64_t)ltmp)); \
524 #define __set_CP64(cp, op1, Rt, CRm) \
526 const uint64_t tmp = (Rt); \
527 const uint32_t ltmp = (uint32_t)(tmp); \
528 const uint32_t htmp = (uint32_t)(tmp >> 32U); \
529 __ASM volatile("MCRR p" # cp ", " # op1 ", ltmp, htmp, c" # CRm); \
532 #include "cmsis_cp15.h"
534 /** \brief Enable Floating Point Unit
536 Critical section, called from undef handler, so systick is disabled
538 __STATIC_INLINE __ASM void __FPU_Enable(void)
542 //Permit access to VFP/NEON, registers by modifying CPACR
544 ORR R1,R1,#0x00F00000
547 //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
552 ORR R1,R1,#0x40000000
555 //Initialise VFP/NEON registers to 0
558 //Initialise D16 registers to 0
576 IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32
577 //Initialise D32 registers to 0
596 //Initialise FPSCR to a known state
598 LDR R2,=0x00086060 //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
605 #endif /* __CMSIS_ARMCC_H */