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 * 2019-01-23 wangyq the first version
21 * 2019-11-01 wangyq update libraries
22 * 2021-04-20 liuhy the second version
23 */
24
25 #include <rthw.h>
26 #include <rtthread.h>
27 #include "board.h"
28 #include "drv_uart.h"
29 #include "drv_gpio.h"
30 #include <ald_gpio.h>
31
32 /**
33 * @addtogroup es32f0
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 SYSCFG_UNLOCK();
59 #if ES_CMU_LRC_EN
60 SET_BIT(CMU->CLKENR, CMU_CLKENR_LRCEN_MSK);
61 #else
62 CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_LRCEN_MSK);
63 #endif /*ES_CMU_LRC_EN*/
64
65 #if ES_CMU_LOSC_EN
66 SET_BIT(CMU->CLKENR, CMU_CLKENR_LOSCEN_MSK);
67 #else
68 CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_LOSCEN_MSK);
69 #endif /*ES_CMU_LOSC_EN*/
70
71 #if ES_CMU_HRC_EN
72 SET_BIT(CMU->CLKENR, CMU_CLKENR_HRCEN_MSK);
73 #else
74 CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_HRCEN_MSK);
75 #endif /*ES_CMU_HRC_EN*/
76
77 #if ES_CMU_HOSC_EN
78 SET_BIT(CMU->CLKENR, CMU_CLKENR_HOSCEN_MSK);
79 #else
80 CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_HOSCEN_MSK);
81 #endif /*ES_CMU_HOSC_EN*/
82
83 SYSCFG_LOCK();
84
85 #if ES_CMU_PLL1_EN
86 /*PLL的源必须是4M*/
87 ald_cmu_pll1_config(ES_PLL1_REFER_CLK, ES_PLL1_OUT_CLK);
88
89 #if ES_CMU_PLL1_SAFE_EN
90 ald_cmu_pll_safe_config(ENABLE);
91 #else
92 ald_cmu_pll_safe_config(DISABLE);
93 #endif
94
95 #else
96 CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_PLL1EN_MSK);
97 #endif /*ES_CMU_PLL1_EN*/
98
99 ald_cmu_clock_config(ES_SYS_CLK_SOURSE, ES_SYS_CLK);
100
101 ald_cmu_div_config(CMU_SYS,ES_CMU_SYS_DIV);
102 ald_cmu_div_config(CMU_HCLK_1,ES_CMU_HCLK_1_DIV);
103 ald_cmu_div_config(CMU_PCLK_1,ES_CMU_PCLK_1_DIV);
104 ald_cmu_div_config(CMU_PCLK_2,ES_CMU_PCLK_2_DIV);
105
106 ald_cmu_perh_clock_config(CMU_PERH_ALL, ENABLE);
107
108 /*低功耗时钟使能*/
109 #ifdef RT_USING_PM
110 SYSCFG_UNLOCK();
111 SET_BIT(CMU->LPENR, CMU_LPENR_LRCEN_MSK);
112 SET_BIT(CMU->LPENR, CMU_LPENR_LOSCEN_MSK);
113 SET_BIT(CMU->LPENR, CMU_LPENR_HRCEN_MSK);
114 SET_BIT(CMU->LPENR, CMU_LPENR_HOSCEN_MSK);
115 SYSCFG_LOCK();
116 #endif
117 }
118
119 /*******************************************************************************
120 * Function Name : SysTick_Configuration
121 * Description : Configures the SysTick for OS tick.
122 * Input : None
123 * Output : None
124 * Return : None
125 *******************************************************************************/
SysTick_Configuration(void)126 void SysTick_Configuration(void)
127 {
128 /* ticks = sysclk / RT_TICK_PER_SECOND */
129 SysTick_Config(ald_cmu_get_sys_clock() / RT_TICK_PER_SECOND);
130
131 __systick_interval = 1;
132 }
133
134 /**
135 * This is the timer interrupt service routine.
136 *
137 */
SysTick_Handler(void)138 void SysTick_Handler(void)
139 {
140 /* enter interrupt */
141 rt_interrupt_enter();
142 ald_inc_tick();
143 rt_tick_increase();
144
145 /* leave interrupt */
146 rt_interrupt_leave();
147 }
148
149 /**
150 * This is the cmu interrupt service.
151 *
152 */
CMU_Handler(void)153 void CMU_Handler(void)
154 {
155 ald_cmu_irq_handler();
156 }
157
158 /*@}*/
159 /**
160 * This function will initial ES32F0 board.
161 */
rt_hw_board_init(void)162 void rt_hw_board_init(void)
163 {
164 /* NVIC Configuration */
165 NVIC_Configuration();
166
167 /*System Clock Configuration */
168 SystemClock_Config();
169
170 /* Configure the SysTick */
171 SysTick_Configuration();
172
173 #ifdef RT_USING_HEAP
174 rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
175 #endif
176 #ifdef RT_USING_COMPONENTS_INIT
177 rt_components_board_init();
178 #endif
179 #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
180 rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
181 #endif
182 }
183
184 /**
185 * This function will delay for some us.
186 *
187 * @param us the delay time of us
188 */
rt_hw_us_delay(rt_uint32_t us)189 void rt_hw_us_delay(rt_uint32_t us)
190 {
191 unsigned int start, now, delta, reload, us_tick;
192 start = SysTick->VAL;
193 reload = SysTick->LOAD;
194 us_tick = ald_cmu_get_sys_clock() / 1000000UL;
195 do
196 {
197 now = SysTick->VAL;
198 delta = start > now ? start - now : reload + start - now;
199 }
200 while (delta < us_tick * us);
201 }
202