1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2018-11-7      SummerGift   first version
9  */
10 
11 #include "drv_common.h"
12 #include <board.h>
13 
14 #ifdef RT_USING_PIN
15 #include <drv_gpio.h>
16 #endif
17 
18 #ifdef RT_USING_SERIAL
19 #ifdef RT_USING_SERIAL_V2
20 #include <drv_usart_v2.h>
21 #else
22 #include <drv_usart.h>
23 #endif /* RT_USING_SERIAL */
24 #endif /* RT_USING_SERIAL_V2 */
25 
26 #define DBG_TAG "drv_common"
27 #define DBG_LVL DBG_INFO
28 #include <rtdbg.h>
29 
30 #ifdef RT_USING_FINSH
31 #include <finsh.h>
reboot(uint8_t argc,char ** argv)32 static void reboot(uint8_t argc, char **argv)
33 {
34     rt_hw_cpu_reset();
35 }
36 MSH_CMD_EXPORT(reboot, Reboot System);
37 #endif /* RT_USING_FINSH */
38 
39 extern __IO uint32_t uwTick;
40 static uint32_t _systick_ms = 1;
41 
42 /* SysTick configuration */
rt_hw_systick_init(void)43 void rt_hw_systick_init(void)
44 {
45     // Updates the variable SystemCoreClock
46     SystemCoreClockUpdate();
47 
48     HAL_SYSTICK_Config(SystemCoreClock / RT_TICK_PER_SECOND);
49 
50     NVIC_SetPriority(SysTick_IRQn, 0xFF);
51 
52     _systick_ms = 1000u / RT_TICK_PER_SECOND;
53     if (_systick_ms == 0)
54         _systick_ms = 1;
55 }
56 
57 /**
58  * This is the timer interrupt service routine.
59  *
60  */
SysTick_Handler(void)61 void SysTick_Handler(void)
62 {
63     /* enter interrupt */
64     rt_interrupt_enter();
65 
66     if (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)
67         HAL_IncTick();
68 
69     rt_tick_increase();
70 
71     /* leave interrupt */
72     rt_interrupt_leave();
73 }
74 
HAL_GetTick(void)75 uint32_t HAL_GetTick(void)
76 {
77     if (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)
78         HAL_IncTick();
79 
80     return uwTick;
81 }
82 
HAL_IncTick(void)83 void HAL_IncTick(void)
84 {
85     uwTick += _systick_ms;
86 }
87 
HAL_SuspendTick(void)88 void HAL_SuspendTick(void)
89 {
90 }
91 
HAL_ResumeTick(void)92 void HAL_ResumeTick(void)
93 {
94 }
95 
HAL_Delay(__IO uint32_t Delay)96 void HAL_Delay(__IO uint32_t Delay)
97 {
98     if (rt_thread_self())
99     {
100         rt_thread_mdelay(Delay);
101     }
102     else
103     {
104         for (rt_uint32_t count = 0; count < Delay; count++)
105         {
106             rt_hw_us_delay(1000);
107         }
108     }
109 }
110 
111 /* re-implement tick interface for STM32 HAL */
HAL_InitTick(uint32_t TickPriority)112 HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
113 {
114     #ifndef SOC_SERIES_STM32MP1
115         rt_hw_systick_init();
116     #endif
117 
118     /* Return function status */
119     return HAL_OK;
120 }
121 
122 /**
123  * @brief  This function is executed in case of error occurrence.
124  * @param  None
125  * @retval None
126  */
_Error_Handler(char * s,int num)127 void _Error_Handler(char *s, int num)
128 {
129     /* USER CODE BEGIN Error_Handler */
130     /* User can add his own implementation to report the HAL error return state */
131     LOG_E("Error_Handler at file:%s num:%d", s, num);
132     while (1)
133     {
134     }
135     /* USER CODE END Error_Handler */
136 }
137 
138 /**
139  * This function will delay for some us.
140  *
141  * @param us the delay time of us
142  */
rt_hw_us_delay(rt_uint32_t us)143 void rt_hw_us_delay(rt_uint32_t us)
144 {
145     rt_uint64_t ticks;
146     rt_uint32_t told, tnow, tcnt = 0;
147     rt_uint32_t reload = SysTick->LOAD;
148 
149     ticks = us * (reload / (1000000 / RT_TICK_PER_SECOND));
150     told = SysTick->VAL;
151     while (1)
152     {
153         tnow = SysTick->VAL;
154         if (tnow != told)
155         {
156             if (tnow < told)
157             {
158                 tcnt += told - tnow;
159             }
160             else
161             {
162                 tcnt += reload - tnow + told;
163             }
164             told = tnow;
165             if (tcnt >= ticks)
166             {
167                 break;
168             }
169         }
170     }
171 }
172 
173 /**
174  * This function will initial STM32 board.
175  */
rt_hw_board_init(void)176 rt_weak void rt_hw_board_init(void)
177 {
178 #ifdef BSP_SCB_ENABLE_I_CACHE
179     /* Enable I-Cache---------------------------------------------------------*/
180     SCB_EnableICache();
181 #endif
182 
183 #ifdef BSP_SCB_ENABLE_D_CACHE
184     /* Enable D-Cache---------------------------------------------------------*/
185     SCB_EnableDCache();
186 #endif
187 
188     /* HAL_Init() function is called at the beginning of the program */
189     HAL_Init();
190 
191     /* System clock initialization */
192     SystemClock_Config();
193 
194 #if defined(RT_USING_HEAP)
195     /* Heap initialization */
196     rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
197 #endif
198 
199 #ifdef RT_USING_PIN
200     rt_hw_pin_init();
201 #endif
202 
203 #ifdef RT_USING_SERIAL
204     rt_hw_usart_init();
205 #endif
206 
207 #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
208     /* Set the shell console output device */
209     rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
210 #endif
211 
212 #if defined(RT_USING_CONSOLE) && defined(RT_USING_NANO)
213     extern void rt_hw_console_init(void);
214     rt_hw_console_init();
215 #endif
216 
217 #ifdef RT_USING_COMPONENTS_INIT
218     /* Board underlying hardware initialization */
219     rt_components_board_init();
220 #endif
221 }
222