1 /**
2   *********************************************************************************
3   *
4   * @file    ald_pmu.c
5   * @brief   PMU module driver.
6   *
7   * @version V1.0
8   * @date    04 Dec 2019
9   * @author  AE Team
10   * @note
11   *          Change Logs:
12   *          Date            Author          Notes
13   *          04 Dec 2019     AE Team         The first version
14   *
15   * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
16   *
17   * SPDX-License-Identifier: Apache-2.0
18   *
19   * Licensed under the Apache License, Version 2.0 (the License); you may
20   * not use this file except in compliance with the License.
21   * You may obtain a copy of the License at
22   *
23   * www.apache.org/licenses/LICENSE-2.0
24   *
25   * Unless required by applicable law or agreed to in writing, software
26   * distributed under the License is distributed on an AS IS BASIS, WITHOUT
27   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28   * See the License for the specific language governing permissions and
29   * limitations under the License.
30   **********************************************************************************
31   */
32 
33 #include "ald_conf.h"
34 
35 
36 /** @addtogroup ES32FXXX_ALD
37   * @{
38   */
39 
40 /** @defgroup PMU PMU
41   * @brief PMU module driver
42   * @{
43   */
44 #ifdef ALD_PMU
45 
46 
47 /** @defgroup PMU_Private_Functions PMU Private Functions
48   * @{
49   */
50 
51 /**
52   * @brief  PMU module interrupt handler
53   * @retval None
54   */
ald_lvd_irq_handler(void)55 void ald_lvd_irq_handler(void)
56 {
57 	SYSCFG_UNLOCK();
58 	SET_BIT(PMU->LVDCR, PMU_LVDCR_LVDCIF_MSK);
59 	SYSCFG_LOCK();
60 
61 	return;
62 }
63 /**
64   * @}
65   */
66 
67 /** @defgroup PMU_Public_Functions PMU Public Functions
68   * @{
69   */
70 
71 /** @addtogroup PMU_Public_Functions_Group1 Low Power Mode
72   * @brief Low power mode select functions
73   *
74   * @verbatim
75   ==============================================================================
76               ##### Low power mode select functions #####
77   ==============================================================================
78     [..]  This section provides functions allowing to:
79       (+) Enter stop1 mode.
80       (+) Enter stop2 mode.
81       (+) Enter standby mode.
82       (+) Get wakeup status.
83       (+) Clear wakeup status.
84 
85     @endverbatim
86   * @{
87   */
88 
89 /**
90   * @brief  Enter stop1 mode
91   * @retval None
92   */
ald_pmu_stop1_enter(void)93 void ald_pmu_stop1_enter(void)
94 {
95 	int cnt = 4000;
96 
97 	SYSCFG_UNLOCK();
98 
99 	CLEAR_BIT(PMU->CR0, PMU_CR0_MTSTOP_MSK);
100 #ifdef ES32F336x  /* MCU Series: ES32F336x */
101 	SET_BIT(PMU->CR0, PMU_CR0_LPSTOP_MSK);
102 #endif
103 	MODIFY_REG(PMU->CR1, PMU_CR1_LDO18MOD_MSK, PMU_LDO_18_HOLD << PMU_CR1_LDO18MOD_POSS);
104 	MODIFY_REG(PMU->CR0, PMU_CR0_LPM_MSK, PMU_LP_STOP1 << PMU_CR0_LPM_POSS);
105 	SYSCFG_LOCK();
106 
107 	while ((!(PMU->CR1 & PMU_CR1_LDO18RDY_MSK)) && (cnt--));
108 
109 	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
110 	SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
111 	__WFI();
112 	SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
113 
114 	return;
115 }
116 
117 /**
118   * @brief  Enter stop2 mode
119   * @retval None
120   */
ald_pmu_stop2_enter(void)121 void ald_pmu_stop2_enter(void)
122 {
123 	int cnt = 4000;
124 
125 	SYSCFG_UNLOCK();
126 
127 	SET_BIT(PMU->CR0, PMU_CR0_MTSTOP_MSK);
128 #ifdef ES32F336x  /* MCU Series: ES32F336x */
129 	SET_BIT(PMU->CR0, PMU_CR0_LPSTOP_MSK);
130 #endif
131 	MODIFY_REG(PMU->CR1, PMU_CR1_LDO18MOD_MSK, PMU_LDO_18_HOLD << PMU_CR1_LDO18MOD_POSS);
132 	MODIFY_REG(PMU->CR0, PMU_CR0_LPM_MSK, PMU_LP_STOP2 << PMU_CR0_LPM_POSS);
133 	SYSCFG_LOCK();
134 
135 	while ((!(PMU->CR1 & PMU_CR1_LDO18RDY_MSK)) && (cnt--));
136 
137 	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
138 	SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
139 	__WFI();
140 	SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
141 
142 	return;
143 }
144 
145 /**
146   * @brief  Enter standby mode
147   * @param  port: The port whick wake up the standby mode.
148   * @param  level: Wakeup level.
149   * @retval None
150   */
ald_pmu_standby_enter(bkpc_wakeup_port_t port,bkpc_wakeup_level_t level)151 void ald_pmu_standby_enter(bkpc_wakeup_port_t port, bkpc_wakeup_level_t level)
152 {
153 	ald_bkpc_standby_wakeup_config(port, level);
154 
155 	SYSCFG_UNLOCK();
156 	MODIFY_REG(PMU->CR0, PMU_CR0_LPM_MSK, PMU_LP_STANDBY << PMU_CR0_LPM_POSS);
157 	SYSCFG_LOCK();
158 
159 	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
160 	SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
161 	__WFI();
162 	SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
163 
164 	return;
165 }
166 
167 /**
168   * @brief  Enable/Disable LDO(1.2V) hold mode. It must be disabled in STOP1.
169   * @param  state: Enable/Disable
170   * @retval None
171   */
ald_pmu_ldo_12_config(type_func_t state)172 void ald_pmu_ldo_12_config(type_func_t state)
173 {
174 	assert_param(IS_FUNC_STATE(state));
175 	SYSCFG_UNLOCK();
176 
177 	if (state)
178 		SET_BIT(PMU->CR0, PMU_CR0_MTSTOP_MSK);
179 	else
180 		CLEAR_BIT(PMU->CR0, PMU_CR0_MTSTOP_MSK);
181 
182 	SYSCFG_LOCK();
183 	return;
184 }
185 
186 /**
187   * @brief  Configure LDO(1.8V) mode
188   * @param  mode: Mode of the LDO(1.8V)
189   * @retval None
190   */
ald_pmu_ldo_18_config(pmu_ldo_18_mode_t mode)191 void ald_pmu_ldo_18_config(pmu_ldo_18_mode_t mode)
192 {
193 	uint32_t cnt = 4000;
194 
195 	assert_param(IS_PMU_LDO18_MODE(mode));
196 
197 	SYSCFG_UNLOCK();
198 	MODIFY_REG(PMU->CR1, PMU_CR1_LDO18MOD_MSK, mode << PMU_CR1_LDO18MOD_POSS);
199 	SYSCFG_LOCK();
200 
201 	while ((!(PMU->CR1 & PMU_CR1_LDO18RDY_MSK)) && (cnt--));
202 	return;
203 }
204 
205 #ifdef ES32F336x  /* MCU Series: ES32F336x */
206 
207 /**
208   * @brief  Configures low power mode. The system clock must
209   *         be less than 2MHz. Such as: LOSC or LRC.
210   * @param  vol: LDO output voltage select in low power mode.
211   * @param  state: New state, ENABLE/DISABLE;
212   * @retval None
213   */
ald_pmu_lprun_config(pmu_ldo_lpmode_output_t vol,type_func_t state)214 void ald_pmu_lprun_config(pmu_ldo_lpmode_output_t vol, type_func_t state)
215 {
216 	assert_param(IS_FUNC_STATE(state));
217 	SYSCFG_UNLOCK();
218 
219 	if (state) {
220 		assert_param(IS_PMU_LDO_LPMODE_OUTPUT(vol));
221 
222 		MODIFY_REG(PMU->CR0, PMU_CR0_LPVS_MSK, vol << PMU_CR0_LPVS_POSS);
223 		SET_BIT(PMU->CR0, PMU_CR0_LPRUN_MSK);
224 	}
225 	else {
226 		CLEAR_BIT(PMU->CR0, PMU_CR0_LPRUN_MSK);
227 	}
228 
229 	SYSCFG_LOCK();
230 	return;
231 }
232 #endif
233 
234 /**
235   * @brief  Get wakup status.
236   * @param  sr: Status bit.
237   * @retval Status.
238   */
ald_pmu_get_status(pmu_status_t sr)239 flag_status_t ald_pmu_get_status(pmu_status_t sr)
240 {
241 	assert_param(IS_PMU_STATUS(sr));
242 
243 	if (READ_BIT(PMU->SR, sr))
244 		return SET;
245 
246 	return RESET;
247 }
248 
249 /**
250   * @brief  Clear wakup status.
251   * @param  sr: Status bit.
252   * @retval None
253   */
ald_pmu_clear_status(pmu_status_t sr)254 void ald_pmu_clear_status(pmu_status_t sr)
255 {
256 	assert_param(IS_PMU_STATUS(sr));
257 	SYSCFG_UNLOCK();
258 
259 	if (sr == PMU_SR_WUF)
260 		SET_BIT(PMU->CR0, PMU_CR0_CWUF_MSK);
261 	else if (sr == PMU_SR_STANDBYF)
262 		SET_BIT(PMU->CR0, PMU_CR0_CSTANDBYF_MSK);
263 	else
264 		;/* do nothing */
265 
266 	SYSCFG_LOCK();
267 	return;
268 }
269 
270 /**
271   * @brief  Configure peripheral power
272   * @param  perh: The peripheral
273   * @param  state: ENABLE/DISABLE
274   * @retval None
275   */
ald_pmu_perh_power_config(pmu_perh_power_t perh,type_func_t state)276 void ald_pmu_perh_power_config(pmu_perh_power_t perh, type_func_t state)
277 {
278 	assert_param(IS_PMU_PERH_POWER(perh));
279 	assert_param(IS_FUNC_STATE(state));
280 
281 	SYSCFG_UNLOCK();
282 
283 	if (state)
284 		SET_BIT(PMU->PWRCR, perh);
285 	else
286 		CLEAR_BIT(PMU->PWRCR, perh);
287 
288 	SYSCFG_LOCK();
289 	return;
290 }
291 /**
292   * @}
293   */
294 
295 /** @addtogroup PMU_Public_Functions_Group2 LVD Configure
296   * @brief LVD configure functions
297   *
298   * @verbatim
299   ==============================================================================
300               ##### LVD configure functions #####
301   ==============================================================================
302     [..]  This section provides functions allowing to:
303       (+) Configure lvd parameters.
304 
305     @endverbatim
306   * @{
307   */
308 
309 /**
310   * @brief  Configure lvd using specified parameters.
311   * @param  sel: LVD threshold voltage.
312   * @param  mode: LVD trigger mode.
313   * @param  state: New state, ENABLE/DISABLE;
314   * @retval None
315   */
ald_pmu_lvd_config(pmu_lvd_voltage_sel_t sel,pmu_lvd_trigger_mode_t mode,type_func_t state)316 void ald_pmu_lvd_config(pmu_lvd_voltage_sel_t sel, pmu_lvd_trigger_mode_t mode, type_func_t state)
317 {
318 	assert_param(IS_FUNC_STATE(state));
319 	SYSCFG_UNLOCK();
320 
321 	if (state) {
322 		assert_param(IS_PMU_LVD_VOL_SEL(sel));
323 		assert_param(IS_PMU_LVD_TRIGGER_MODE(mode));
324 
325 		MODIFY_REG(PMU->LVDCR, PMU_LVDCR_LVDS_MSK, sel << PMU_LVDCR_LVDS_POSS);
326 		MODIFY_REG(PMU->LVDCR, PMU_LVDCR_LVIFS_MSK, mode << PMU_LVDCR_LVIFS_POSS);
327 		SET_BIT(PMU->LVDCR, PMU_LVDCR_LVDFLT_MSK);
328 		SET_BIT(PMU->LVDCR, PMU_LVDCR_LVDCIF_MSK);
329 		SET_BIT(PMU->LVDCR, PMU_LVDCR_LVDIE_MSK);
330 		SET_BIT(PMU->LVDCR, PMU_LVDCR_LVDEN_MSK);
331 	}
332 	else {
333 		SET_BIT(PMU->LVDCR, PMU_LVDCR_LVDCIF_MSK);
334 		CLEAR_BIT(PMU->LVDCR, PMU_LVDCR_LVDIE_MSK);
335 		CLEAR_BIT(PMU->LVDCR, PMU_LVDCR_LVDEN_MSK);
336 	}
337 
338 	SYSCFG_LOCK();
339 	return;
340 }
341 /**
342   * @}
343   */
344 
345 
346 /**
347   * @}
348   */
349 #endif /* ALD_PMU */
350 /**
351   * @}
352   */
353 
354 /**
355   * @}
356   */
357