1 /*
2  * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the License); you may
7  * not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * Change Logs:
19  * Date           Author        Notes
20  * 2020-01-14     wangyq        the first version
21  * 2021-04-20     liuhy         the second version
22  */
23 
24 #include <rthw.h>
25 #include <rtthread.h>
26 #include "board.h"
27 #include "drv_uart.h"
28 #include "drv_gpio.h"
29 #include <ald_gpio.h>
30 #include "ald_dma.h"
31 
32 /**
33  * @addtogroup es32f3
34  */
35 
36 /*@{*/
37 
38 /*******************************************************************************
39 * Function Name  : NVIC_Configuration
40 * Description    : Configures Vector Table base location.
41 * Input          : None
42 * Output         : None
43 * Return         : None
44 *******************************************************************************/
NVIC_Configuration(void)45 void NVIC_Configuration(void)
46 {
47 }
48 
49 /*******************************************************************************
50  * Function Name  : SystemClock_Configuration
51  * Description    : Configures the System Clock.
52  * Input          : None
53  * Output         : None
54  * Return         : None
55  *******************************************************************************/
SystemClock_Config(void)56 void  SystemClock_Config(void)
57 {
58 
59     SYSCFG_UNLOCK();
60 #if  ES_CMU_LRC_EN
61     SET_BIT(CMU->CLKENR, CMU_CLKENR_LRCEN_MSK);
62 #else
63     CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_LRCEN_MSK);
64 #endif  /*ES_CMU_LRC_EN*/
65 
66 #if ES_CMU_LOSC_EN
67     SET_BIT(CMU->CLKENR, CMU_CLKENR_LOSCEN_MSK);
68 #else
69     CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_LOSCEN_MSK);
70 #endif  /*ES_CMU_LOSC_EN*/
71 
72 #if ES_CMU_HRC_EN
73     SET_BIT(CMU->CLKENR, CMU_CLKENR_HRCEN_MSK);
74 #else
75     CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_HRCEN_MSK);
76 #endif  /*ES_CMU_HRC_EN*/
77 
78 #if ES_CMU_HOSC_EN
79     SET_BIT(CMU->CLKENR, CMU_CLKENR_HOSCEN_MSK);
80 #else
81     CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_HOSCEN_MSK);
82 #endif  /*ES_CMU_HOSC_EN*/
83 
84     SYSCFG_LOCK();
85 
86 #if  ES_CMU_PLL1_EN
87     /*PLL的源必须是4M*/
88     ald_cmu_pll1_config(ES_PLL1_REFER_CLK, ES_PLL1_OUT_CLK);
89 
90     #if ES_CMU_PLL1_SAFE_EN
91         ald_cmu_pll_safe_config(ENABLE);
92     #else
93         ald_cmu_pll_safe_config(DISABLE);
94     #endif
95 
96 #else
97     CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_PLL1EN_MSK);
98 #endif  /*ES_CMU_PLL1_EN*/
99 
100     ald_cmu_clock_config(ES_SYS_CLK_SOURSE, ES_SYS_CLK);
101 
102     ald_cmu_div_config(CMU_SYS,ES_CMU_SYS_DIV);
103     ald_cmu_div_config(CMU_HCLK_1,ES_CMU_HCLK_1_DIV);
104     ald_cmu_div_config(CMU_HCLK_2,ES_CMU_HCLK_2_DIV);
105     ald_cmu_div_config(CMU_PCLK_1,ES_CMU_PCLK_1_DIV);
106     ald_cmu_div_config(CMU_PCLK_2,ES_CMU_PCLK_2_DIV);
107 
108     ald_cmu_perh_clock_config(CMU_PERH_ALL, ENABLE);
109 
110 /*低功耗时钟使能*/
111 #ifdef RT_USING_PM
112         SYSCFG_UNLOCK();
113         SET_BIT(CMU->LPENR, CMU_LPENR_LRCEN_MSK);
114         SET_BIT(CMU->LPENR, CMU_LPENR_LOSCEN_MSK);
115         SET_BIT(CMU->LPENR, CMU_LPENR_HRCEN_MSK);
116         SET_BIT(CMU->LPENR, CMU_LPENR_HOSCEN_MSK);
117         SYSCFG_LOCK();
118 #endif
119 
120 }
121 
122 /*******************************************************************************
123  * Function Name  : SysTick_Configuration
124  * Description    : Configures the SysTick for OS tick.
125  * Input          : None
126  * Output         : None
127  * Return         : None
128  *******************************************************************************/
SysTick_Configuration(void)129 void  SysTick_Configuration(void)
130 {
131     /* ticks = sysclk / RT_TICK_PER_SECOND */
132     SysTick_Config(ald_cmu_get_sys_clock() / RT_TICK_PER_SECOND);
133 
134     __systick_interval = 1;
135 }
136 
137 /**
138  * This is the timer interrupt service routine.
139  *
140  */
SysTick_Handler(void)141 void SysTick_Handler(void)
142 {
143     /* enter interrupt */
144     rt_interrupt_enter();
145     ald_inc_tick();
146     rt_tick_increase();
147     /* leave interrupt */
148     rt_interrupt_leave();
149 }
150 
151 /**
152  * This is the cmu interrupt service.
153  *
154  */
CMU_Handler(void)155 void CMU_Handler(void)
156 {
157     ald_cmu_irq_handler();
158 }
159 /**
160  * This is the DMA interrupt service.
161  *
162  */
DMA_Handler(void)163 void DMA_Handler(void)
164 {
165     /* enter interrupt */
166     rt_interrupt_enter();
167     ald_dma_irq_handler();
168     /* leave interrupt */
169     rt_interrupt_leave();
170 }
171 /*@}*/
172 /**
173  * This function will initial ES32F3 board.
174  */
rt_hw_board_init(void)175 void rt_hw_board_init(void)
176 {
177     /* NVIC Configuration */
178     NVIC_Configuration();
179     /*System Clock Configuration */
180     SystemClock_Config();
181     /* Configure the SysTick */
182     SysTick_Configuration();
183 
184 #ifdef RT_USING_HEAP
185     rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
186 #endif
187 #ifdef RT_USING_COMPONENTS_INIT
188     rt_components_board_init();
189 #endif
190 #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
191     rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
192 #endif
193 #ifdef BSP_USING_DMA0
194     ald_cmu_perh_clock_config(CMU_PERH_DMA, ENABLE);
195     ald_dma_init(DMA0);
196 #endif
197 }
198 
199 /**
200  * This function will delay for some us.
201  *
202  * @param us the delay time of us
203  */
rt_hw_us_delay(rt_uint32_t us)204 void rt_hw_us_delay(rt_uint32_t us)
205 {
206     unsigned int start, now, delta, reload, us_tick;
207     start = SysTick->VAL;
208     reload = SysTick->LOAD;
209     us_tick = ald_cmu_get_sys_clock() / 1000000UL;
210     do
211     {
212         now = SysTick->VAL;
213         delta = start > now ? start - now : reload + start - now;
214     }
215     while (delta <  us_tick * us);
216 }
217