1 /*
2 * Copyright (c) 2021 Bestechnic (Shanghai) Co., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef MBED_CMSIS_H
16 #define MBED_CMSIS_H
17
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21
22 #include "plat_addr_map.h"
23 #include _TO_STRING(CONCAT_SUFFIX(CHIP_ID_LITERAL, h))
24
25 #define IRQ_PRIORITY_REALTIME 0
26 #define IRQ_PRIORITY_HIGHPLUSPLUS 1
27 #define IRQ_PRIORITY_HIGHPLUS 2
28 #define IRQ_PRIORITY_HIGH 3
29 #define IRQ_PRIORITY_ABOVENORMAL 4
30 #define IRQ_PRIORITY_NORMAL 5
31 #define IRQ_PRIORITY_BELOWNORMAL 6
32 #define IRQ_PRIORITY_LOW 7
33
34 #ifdef __ARM_ARCH_ISA_ARM
35 #define IRQ_LOCK_MASK (CPSR_I_Msk | CPSR_F_Msk)
36 #else
37 #define NVIC_USER_IRQ_OFFSET 16
38 #define NVIC_NUM_VECTORS (NVIC_USER_IRQ_OFFSET + USER_IRQn_QTY)
39 #endif
40
41 #ifndef __ASSEMBLER__
42
43 #ifdef __ARMCC_VERSION
44 // Stupid armclang
45 #undef __SSAT
46 #define __SSAT(ARG1,ARG2) \
47 __extension__ \
48 ({ \
49 int32_t __RES, __ARG1 = (ARG1); \
50 __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
51 __RES; \
52 })
53 #endif
54
55 struct irq_masked_address {uint32_t pc; uint32_t lr;};
56 extern struct irq_masked_address irq_masked_addr;
57
int_lock_global(void)58 __STATIC_FORCEINLINE uint32_t int_lock_global(void)
59 {
60 #ifdef __ARM_ARCH_ISA_ARM
61 uint32_t cpsr = __get_CPSR();
62 uint32_t st = cpsr & IRQ_LOCK_MASK;
63 if (st != IRQ_LOCK_MASK) {
64 cpsr |= IRQ_LOCK_MASK;
65 __set_CPSR(cpsr);
66 }
67 return st;
68 #else
69 uint32_t pri = __get_PRIMASK();
70 if ((pri & 0x1) == 0) {
71 __disable_irq();
72 }
73 return pri;
74 #endif
75 }
76
int_unlock_global(uint32_t pri)77 __STATIC_FORCEINLINE void int_unlock_global(uint32_t pri)
78 {
79 #ifdef __ARM_ARCH_ISA_ARM
80 if (pri != IRQ_LOCK_MASK) {
81 uint32_t cpsr = __get_CPSR();
82 cpsr = (cpsr & ~IRQ_LOCK_MASK) | pri;
83 __set_CPSR(cpsr);
84 }
85 #else
86 if ((pri & 0x1) == 0) {
87 __enable_irq();
88 }
89 #endif
90 }
91
92 #if defined(NUTTX_BUILD) || defined(KERNEL_LITEOS_A) ||\
93 (defined(__ARM_ARCH_ISA_ARM) && (defined(KERNEL_RHINO) || defined(KERNEL_RTT)))
94 extern uint32_t int_lock(void);
95 extern void int_unlock(uint32_t pri);
96 extern uint32_t int_lock_local(void);
97 extern void int_unlock_local(uint32_t pri);
98 #else
int_lock(void)99 __STATIC_FORCEINLINE uint32_t int_lock(void)
100 {
101 #ifdef INT_LOCK_EXCEPTION
102 #ifdef __ARM_ARCH_ISA_ARM
103 uint32_t mask = GIC_GetInterfacePriorityMask();
104 // Only allow IRQs with priority IRQ_PRIORITY_HIGHPLUSPLUS and IRQ_PRIORITY_REALTIME
105 GIC_SetInterfacePriorityMask(((IRQ_PRIORITY_HIGHPLUS << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL));
106 return mask;
107 #else
108 uint32_t pri = __get_BASEPRI();
109 uint32_t pc;
110 __ASM volatile ("mov %0, PC" : "=r"(pc));
111 irq_masked_addr.pc = pc;
112 irq_masked_addr.lr = (uint32_t)__builtin_return_address(0);
113 // Only allow IRQs with priority IRQ_PRIORITY_HIGHPLUSPLUS and IRQ_PRIORITY_REALTIME
114 __set_BASEPRI(((IRQ_PRIORITY_HIGHPLUS << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL));
115 return pri;
116 #endif
117 #else
118 return int_lock_global();
119 #endif
120 }
121
int_unlock(uint32_t pri)122 __STATIC_FORCEINLINE void int_unlock(uint32_t pri)
123 {
124 #ifdef INT_LOCK_EXCEPTION
125 #ifdef __ARM_ARCH_ISA_ARM
126 GIC_SetInterfacePriorityMask(pri);
127 #else
128 __set_BASEPRI(pri);
129 #endif
130 #else
131 int_unlock_global(pri);
132 #endif
133 }
134
int_lock_local(void)135 __STATIC_FORCEINLINE uint32_t int_lock_local(void)
136 {
137 return int_lock();
138 }
int_unlock_local(uint32_t pri)139 __STATIC_FORCEINLINE void int_unlock_local(uint32_t pri)
140 {
141 int_unlock(pri);
142 }
143
int_lock_smp_com(void)144 __STATIC_FORCEINLINE uint32_t int_lock_smp_com(void)
145 {
146 return int_lock();
147 }
int_unlock_smp_com(uint32_t pri)148 __STATIC_FORCEINLINE void int_unlock_smp_com(uint32_t pri)
149 {
150 int_unlock(pri);
151 }
152
153
154 #endif
in_isr(void)155 __STATIC_FORCEINLINE int in_isr(void)
156 {
157 #ifdef __ARM_ARCH_ISA_ARM
158 #ifdef KERNEL_RHINO
159 extern int rhino_in_isr(void);
160 return rhino_in_isr();
161 #else
162 uint32_t mode = __get_mode();
163 return mode != CPSR_M_USR && mode != CPSR_M_SYS;
164 #endif
165 #else
166 return __get_IPSR() != 0;
167 #endif
168 }
169
ftoi_nearest(float f)170 __STATIC_FORCEINLINE int32_t ftoi_nearest(float f)
171 {
172 return (f >= 0) ? (int32_t)(f + 0.5) : (int32_t)(f - 0.5);
173 }
174
unsigned_range_value_map(uint32_t from_val,uint32_t from_min,uint32_t from_max,uint32_t to_min,uint32_t to_max)175 __STATIC_FORCEINLINE uint32_t unsigned_range_value_map(uint32_t from_val, uint32_t from_min, uint32_t from_max, uint32_t to_min, uint32_t to_max)
176 {
177 if (from_val <= from_min) {
178 return to_min;
179 }
180 if (from_val >= from_max) {
181 return to_max;
182 }
183 return ((from_val - from_min) * (to_max - to_min) + (from_max - from_min) / 2) / (from_max - from_min) + to_min;
184 }
185
186 void GotBaseInit(void);
187
188 void boot_init_boot_sections(void);
189
190 void boot_init_sram_sections(void);
191
192 void boot_init_rom_in_flash(void);
193
194 int set_bool_flag(bool *flag);
195
196 void clear_bool_flag(bool *flag);
197
198 float db_to_float(float db);
199
200 uint32_t get_msb_pos(uint32_t val);
201
202 uint32_t get_lsb_pos(uint32_t val);
203
204 uint32_t integer_sqrt(uint32_t val);
205
206 uint32_t integer_sqrt_nearest(uint32_t val);
207
208 #endif
209
210 #ifdef __cplusplus
211 }
212 #endif
213
214 #endif
215