1 /*********************************************************************************************************//**
2 * @file ht32_cm0plus_misc.c
3 * @version $Rev:: 7888 $
4 * @date $Date:: 2024-07-22 #$
5 * @brief This file provides all the miscellaneous firmware functions.
6 *************************************************************************************************************
7 * @attention
8 *
9 * Firmware Disclaimer Information
10 *
11 * 1. The customer hereby acknowledges and agrees that the program technical documentation, including the
12 * code, which is supplied by Holtek Semiconductor Inc., (hereinafter referred to as "HOLTEK") is the
13 * proprietary and confidential intellectual property of HOLTEK, and is protected by copyright law and
14 * other intellectual property laws.
15 *
16 * 2. The customer hereby acknowledges and agrees that the program technical documentation, including the
17 * code, is confidential information belonging to HOLTEK, and must not be disclosed to any third parties
18 * other than HOLTEK and the customer.
19 *
20 * 3. The program technical documentation, including the code, is provided "as is" and for customer reference
21 * only. After delivery by HOLTEK, the customer shall use the program technical documentation, including
22 * the code, at their own risk. HOLTEK disclaims any expressed, implied or statutory warranties, including
23 * the warranties of merchantability, satisfactory quality and fitness for a particular purpose.
24 *
25 * <h2><center>Copyright (C) Holtek Semiconductor Inc. All rights reserved</center></h2>
26 ************************************************************************************************************/
27
28 /* Includes ------------------------------------------------------------------------------------------------*/
29 #include "ht32_cm0plus_misc.h"
30 #include "ht32_div.c"
31 #include "ht32_rand.c"
32 #ifdef HTCFG_TIME_IPSEL
33 #include "ht32_time.c"
34 #endif
35
36 /** @addtogroup HT32_Peripheral_Driver HT32 Peripheral Driver
37 * @{
38 */
39
40 /** @defgroup MISC MISC
41 * @brief MISC driver modules
42 * @{
43 */
44
45
46 /* Private definitions -------------------------------------------------------------------------------------*/
47 /** @defgroup MISC_Private_Define MISC private definitions
48 * @{
49 */
50 #define AIRCR_VECTKEY_MASK ((u32)0x05FA0000)
51 #define CTRL_TICKINT_SET ((u32)0x00000002)
52 #define CTRL_TICKINT_RESET ((u32)0xFFFFFFFD)
53 /**
54 * @}
55 */
56
57 /* Global functions ----------------------------------------------------------------------------------------*/
58 /** @defgroup MISC_Exported_Functions MISC exported functions
59 * @{
60 */
61 /*********************************************************************************************************//**
62 * @brief Set the vector table location and Offset.
63 * @param NVIC_VectTable: Specify if the vector table is in FLASH or RAM.
64 * This parameter can be one of the following values:
65 * @arg NVIC_VECTTABLE_RAM
66 * @arg NVIC_VECTTABLE_FLASH
67 * @param NVIC_Offset: Vector Table base offset field.
68 * This value must be a multiple of 0x100.
69 * @retval None
70 ***********************************************************************************************************/
NVIC_SetVectorTable(u32 NVIC_VectTable,u32 NVIC_Offset)71 void NVIC_SetVectorTable(u32 NVIC_VectTable, u32 NVIC_Offset)
72 {
73 /* Check the parameters */
74 Assert_Param(IS_NVIC_VECTTABLE(NVIC_VectTable));
75 Assert_Param(IS_NVIC_OFFSET(NVIC_Offset));
76
77 SCB->VTOR = NVIC_VectTable | (NVIC_Offset & (u32)0x1FFFFF80);
78 }
79
80 /*********************************************************************************************************//**
81 * @brief Select which low power mode to execute to the system.
82 * @param NVIC_LowPowerMode: Specify the new low power mode to execute to the system.
83 * This parameter can be one of the following values:
84 * @arg NVIC_LOWPOWER_SEVONPEND
85 * @arg NVIC_LOWPOWER_SLEEPDEEP
86 * @arg NVIC_LOWPOWER_SLEEPONEXIT
87 * @param NewState: new state of low power condition.
88 * This parameter can be: ENABLE or DISABLE.
89 * @retval None
90 ***********************************************************************************************************/
NVIC_LowPowerConfig(u8 NVIC_LowPowerMode,ControlStatus NewState)91 void NVIC_LowPowerConfig(u8 NVIC_LowPowerMode, ControlStatus NewState)
92 {
93 /* Check the parameters */
94 Assert_Param(IS_NVIC_LOWPOWER(NVIC_LowPowerMode));
95 Assert_Param(IS_CONTROL_STATUS(NewState));
96
97 if (NewState != DISABLE)
98 {
99 SCB->SCR |= NVIC_LowPowerMode;
100 }
101 else
102 {
103 SCB->SCR &= (u32)(~(u32)NVIC_LowPowerMode);
104 }
105 }
106
107 /*********************************************************************************************************//**
108 * @brief Set the pending bit for a system handler.
109 * @param SystemHandler: Specify the system handler pending bit to be set.
110 * This parameter can be one of the following values:
111 * @arg SYSTEMHANDLER_NMI
112 * @arg SYSTEMHANDLER_PSV
113 * @arg SYSTEMHANDLER_SYSTICK
114 * @retval None
115 ***********************************************************************************************************/
NVIC_SetPendingSystemHandler(u32 SystemHandler)116 void NVIC_SetPendingSystemHandler(u32 SystemHandler)
117 {
118 /* Check the parameters */
119 Assert_Param(IS_NVIC_SYSTEMHANDLER(SystemHandler));
120
121 /* Set the corresponding System Handler pending bit */
122 SCB->ICSR |= SystemHandler;
123 }
124
125 /*********************************************************************************************************//**
126 * @brief Configure the SysTick clock source.
127 * @param SysTick_ClockSource: Specify the SysTick clock source.
128 * This parameter can be one of the following values:
129 * @arg SYSTICK_SRC_STCLK : External reference clock is selected as SysTick clock source.
130 * @arg SYSTICK_SRC_FCLK : AHB clock is selected as SysTick clock source.
131 * @retval None
132 ***********************************************************************************************************/
SYSTICK_ClockSourceConfig(u32 SysTick_ClockSource)133 void SYSTICK_ClockSourceConfig(u32 SysTick_ClockSource)
134 {
135 /* Check the parameters */
136 Assert_Param(IS_SYSTICK_CLOCK_SOURCE(SysTick_ClockSource));
137
138 if (SysTick_ClockSource == SYSTICK_SRC_FCLK)
139 {
140 SysTick->CTRL |= SYSTICK_SRC_FCLK;
141 }
142 else
143 {
144 SysTick->CTRL &= SYSTICK_SRC_STCLK;
145 }
146 }
147
148 /*********************************************************************************************************//**
149 * @brief Enable or Disable the SysTick counter.
150 * @param SysTick_Counter: new state of the SysTick counter.
151 * This parameter can be one of the following values:
152 * @arg SYSTICK_COUNTER_DISABLE : Disable counter
153 * @arg SYSTICK_COUNTER_ENABLE : Enable counter
154 * @arg SYSTICK_COUNTER_CLEAR : Clear counter value to 0
155 * @retval None
156 ***********************************************************************************************************/
SYSTICK_CounterCmd(u32 SysTick_Counter)157 void SYSTICK_CounterCmd(u32 SysTick_Counter)
158 {
159 /* Check the parameters */
160 Assert_Param(IS_SYSTICK_COUNTER(SysTick_Counter));
161
162 if (SysTick_Counter == SYSTICK_COUNTER_CLEAR)
163 {
164 SysTick->VAL = SYSTICK_COUNTER_CLEAR;
165 }
166 else
167 {
168 if (SysTick_Counter == SYSTICK_COUNTER_ENABLE)
169 {
170 SysTick->CTRL |= SYSTICK_COUNTER_ENABLE;
171 }
172 else
173 {
174 SysTick->CTRL &= SYSTICK_COUNTER_DISABLE;
175 }
176 }
177 }
178
179 /*********************************************************************************************************//**
180 * @brief Enable or Disable the SysTick Interrupt.
181 * @param NewState: new state of the SysTick Interrupt.
182 * This parameter can be: ENABLE or DISABLE.
183 * @retval None
184 ***********************************************************************************************************/
SYSTICK_IntConfig(ControlStatus NewState)185 void SYSTICK_IntConfig(ControlStatus NewState)
186 {
187 /* Check the parameters */
188 Assert_Param(IS_CONTROL_STATUS(NewState));
189
190 if (NewState != DISABLE)
191 {
192 SysTick->CTRL |= CTRL_TICKINT_SET;
193 }
194 else
195 {
196 SysTick->CTRL &= CTRL_TICKINT_RESET;
197 }
198 }
199
200 /*********************************************************************************************************//**
201 * @brief Set SysTick counter reload value.
202 * @param SysTick_Reload: SysTick reload new value.
203 * This parameter must be a number between 1 and 0xFFFFFF.
204 * @retval None
205 ***********************************************************************************************************/
SYSTICK_SetReloadValue(u32 SysTick_Reload)206 void SYSTICK_SetReloadValue(u32 SysTick_Reload)
207 {
208 /* Check the parameters */
209 Assert_Param(IS_SYSTICK_RELOAD(SysTick_Reload));
210
211 SysTick->LOAD = SysTick_Reload;
212 }
213
214 /*********************************************************************************************************//**
215 * @brief Reverse bits.
216 * @param in: Input data
217 * @retval uRBIT
218 ***********************************************************************************************************/
RBIT(u32 in)219 u32 RBIT(u32 in)
220 {
221 u32 uRBIT = 0;
222 s32 i;
223
224 for (i = 31; i >=0; i--)
225 {
226 uRBIT |= ((in & 0x1) << i);
227 in = in >> 1;
228 }
229
230 return uRBIT;
231 }
232
233 #if 0
234 // Copy the code below to the begin of the main().
235 // START
236
237 #if (HTCFG_STACK_USAGE_ANALYSIS == 1)
238 /* !!! NOTICE !!!
239 Please update the Keil HT32 PACK and HT32 Firmware Library to the latest version to make sure the
240 Stack Usage Analysis function works properly.
241 */
242 /*
243 Set HTCFG_STACK_USAGE_ANALYSIS as 1 in the "ht32xxxxxx_conf.h" to enable Stack Usage Analysis feature.
244 This feature is only applicable to the Keil MDK-ARM. Please call the "StackUsageAnalysisInit()" function
245 in the begin of the "main()".
246 The "StackUsageAnalysisInit()" parameter shall be the start address of the vector table.
247 Under Keil Debug mode, tick "View > Watch Window > HT32 Stack Usage Analysis" to show the stack usage
248 information. Those information is only valid after calling "StackUsageAnalysisInit()" function.
249 */
250 StackUsageAnalysisInit(0x00000000);
251 #endif
252
253 // END
254 #endif
255
256 #if (HTCFG_STACK_USAGE_ANALYSIS == 1)
257 #if defined (__CC_ARM)
258 #define STACKLIMITADDR 0x20000010
259 #define STACKSTART 0x20000014
260 u32 _StackLimit __attribute__((at(STACKLIMITADDR)))= HT_SRAM_BASE + LIBCFG_RAM_SIZE;
261 u32 _StackStart __attribute__((at(STACKSTART)))= HT_SRAM_BASE;
262 /*********************************************************************************************************//**
263 * @brief Stack Usage Analysis Init
264 * @retval None
265 ***********************************************************************************************************/
StackUsageAnalysisInit(u32 addr)266 __ASM void StackUsageAnalysisInit(u32 addr)
267 {
268 extern _StackLimit;
269 extern __HT_check_sp;
270 extern _StackStart;
271 LDR R0, [r0]
272 LDR R1, =_StackLimit
273 STR R0, [r1]
274
275 LDR R0, =__HT_check_sp
276 LDR R1, =_StackStart
277 STR R0, [r1]
278 MOV R1, SP
279 LDR R2, =0xCDCDCDCD
280 LDR R3, =0xABABABAB
281 STR R3, [ R0 ]
282 B Loop_Check
283 Loop
284 STR R2, [ R0 ]
285 Loop_Check
286 ADDS R0, R0, #0x04
287 CMP R0, R1
288 BLT Loop
289 BX LR
290 ALIGN
291 }
292 #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
293 #define STACKLIMITADDR "0x20000010"
294 #define STACKSTART "0x20000014"
295 u32 _StackLimit __attribute__((section(".ARM.__at_"STACKLIMITADDR))) = HT_SRAM_BASE + LIBCFG_RAM_SIZE;
296 u32 _StackStart __attribute__((section(".ARM.__at_"STACKSTART))) = HT_SRAM_BASE;
297 /*********************************************************************************************************//**
298 * @brief Stack Usage Analysis Init
299 * @retval None
300 ***********************************************************************************************************/
StackUsageAnalysisInit(u32 addr)301 __attribute__((noinline)) void StackUsageAnalysisInit(u32 addr)
302 {
303 __ASM volatile (" LDR R0, [r0]");
304 __ASM volatile (" LDR R1, =_StackLimit");
305 __ASM volatile (" STR R0, [r1]");
306
307 __ASM volatile (" LDR R0, =__HT_check_sp");
308 __ASM volatile (" LDR R1, =_StackStart");
309 __ASM volatile (" STR R0, [r1]");
310 __ASM volatile (" MOV R1, SP");
311 __ASM volatile (" LDR R2, =0xCDCDCDCD");
312 __ASM volatile (" LDR R3, =0xABABABAB");
313 __ASM volatile (" STR R3, [ R0 ]");
314 __ASM volatile (" B Loop_Check");
315 __ASM volatile ("Loop:");
316 __ASM volatile (" STR R2, [ R0 ]");
317 __ASM volatile ("Loop_Check:");
318 __ASM volatile (" ADDS R0, R0, #0x04");
319 __ASM volatile (" CMP R0, R1");
320 __ASM volatile (" BLT Loop");
321 __ASM volatile (" BX LR");
322 }
323 #endif
324 #endif
325 /**
326 * @}
327 */
328
329
330 /**
331 * @}
332 */
333
334 /**
335 * @}
336 */
337