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