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