1 /**
2   ******************************************************************************
3   * @file    stm32c0xx_hal_pwr_ex.c
4   * @author  MCD Application Team
5   * @brief   Extended PWR HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Power Controller (PWR) peripheral:
8   *           + Extended Initialization and de-initialization functions
9   *           + Extended Peripheral Control functions
10   *
11   ******************************************************************************
12   * @attention
13   *
14   * Copyright (c) 2022 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
22   */
23 
24 /* Includes ------------------------------------------------------------------*/
25 #include "stm32c0xx_hal.h"
26 
27 /** @addtogroup STM32C0xx_HAL_Driver
28   * @{
29   */
30 
31 /** @addtogroup PWREx
32   * @{
33   */
34 
35 #ifdef HAL_PWR_MODULE_ENABLED
36 
37 /* Private typedef -----------------------------------------------------------*/
38 /* Private define ------------------------------------------------------------*/
39 /** @defgroup PWR_Extended_Private_Defines PWR Extended Private Defines
40   * @{
41   */
42 
43 /** @defgroup PWREx_Gpio_Pin_Number  PWREx Gpio Pin Number
44   * @{
45   */
46 #define PWR_GPIO_PIN_NB                     16u  /*!< Number of gpio pin in bank */
47 /**
48   * @}
49   */
50 
51 /**
52   * @}
53   */
54 
55 /* Private macro -------------------------------------------------------------*/
56 /* Private variables ---------------------------------------------------------*/
57 /* Private function prototypes -----------------------------------------------*/
58 /* Exported functions --------------------------------------------------------*/
59 /** @addtogroup PWREx_Exported_Functions PWR Extended Exported Functions
60   * @{
61   */
62 
63 /** @addtogroup PWREx_Exported_Functions_Group1 Extended Peripheral Control functions
64   *  @brief   Extended Peripheral Control functions
65   *
66 @verbatim
67  ===============================================================================
68   ##### Extended Peripheral Initialization and de-initialization functions #####
69  ===============================================================================
70     [..]
71 
72 @endverbatim
73   * @{
74   */
75 
76 #if defined (PWR_PVM_SUPPORT)
77 /**
78   * @brief Enable the Power Voltage Monitoring for USB peripheral (power domain Vddio2)
79   * @retval None
80   */
HAL_PWREx_EnablePVMUSB(void)81 void HAL_PWREx_EnablePVMUSB(void)
82 {
83   SET_BIT(PWR->CR2, PWR_CR2_PVM_VDDIO2_0);
84 }
85 
86 /**
87   * @brief Disable the Power Voltage Monitoring for USB peripheral (power domain Vddio2)
88   * @retval None
89   */
HAL_PWREx_DisablePVMUSB(void)90 void HAL_PWREx_DisablePVMUSB(void)
91 {
92   CLEAR_BIT(PWR->CR2, PWR_CR2_PVM_VDDIO2_0);
93 }
94 
95 /**
96   * @brief Configure the Peripheral Voltage Monitoring (PVM).
97   * @param sConfigPVM: pointer to a PWR_PVMTypeDef structure that contains the
98   *        PVM configuration information.
99   * @note The API configures a single PVM according to the information contained
100   *       in the input structure. To configure several PVMs, the API must be singly
101   *       called for each PVM used.
102   * @note Refer to the electrical characteristics of your device datasheet for
103   *         more details about the voltage thresholds corresponding to each
104   *         detection level and to each monitored supply.
105   * @retval HAL status
106   */
HAL_PWREx_ConfigPVM(PWR_PVMTypeDef * sConfigPVM)107 HAL_StatusTypeDef HAL_PWREx_ConfigPVM(PWR_PVMTypeDef *sConfigPVM)
108 {
109   HAL_StatusTypeDef status = HAL_OK;
110 
111   /* Check the parameters */
112   assert_param(IS_PWR_PVM_TYPE(sConfigPVM->PVMType));
113   assert_param(IS_PWR_PVM_MODE(sConfigPVM->Mode));
114 
115   /* Configure EXTI 34 interrupts if so required:
116      scan through PVMType to detect which PVMx is set and
117      configure the corresponding EXTI line accordingly. */
118   switch (sConfigPVM->PVMType)
119   {
120     case PWR_PVM_USB:
121       /* Clear any previous config. Keep it clear if no event or IT mode is selected */
122       __HAL_PWR_PVM_EXTI_DISABLE_EVENT();
123       __HAL_PWR_PVM_EXTI_DISABLE_IT();
124       __HAL_PWR_PVM_EXTI_DISABLE_FALLING_EDGE();
125       __HAL_PWR_PVM_EXTI_DISABLE_RISING_EDGE();
126 
127       /* Configure interrupt mode */
128       if ((sConfigPVM->Mode & PVM_MODE_IT) == PVM_MODE_IT)
129       {
130         __HAL_PWR_PVM_EXTI_ENABLE_IT();
131       }
132 
133       /* Configure event mode */
134       if ((sConfigPVM->Mode & PVM_MODE_EVT) == PVM_MODE_EVT)
135       {
136         __HAL_PWR_PVM_EXTI_ENABLE_EVENT();
137       }
138 
139       /* Configure the edge */
140       if ((sConfigPVM->Mode & PVM_RISING_EDGE) == PVM_RISING_EDGE)
141       {
142         __HAL_PWR_PVM_EXTI_ENABLE_RISING_EDGE();
143       }
144 
145       if ((sConfigPVM->Mode & PVM_FALLING_EDGE) == PVM_FALLING_EDGE)
146       {
147         __HAL_PWR_PVM_EXTI_ENABLE_FALLING_EDGE();
148       }
149       break;
150 
151     default:
152       status = HAL_ERROR;
153       break;
154   }
155 
156   return status;
157 }
158 #endif /* PWR_PVM_SUPPORT */
159 /**
160   * @brief  Enable Internal Wake-up Line.
161   * @retval None
162   */
HAL_PWREx_EnableInternalWakeUpLine(void)163 void HAL_PWREx_EnableInternalWakeUpLine(void)
164 {
165   SET_BIT(PWR->CR3, PWR_CR3_EIWUL);
166 }
167 
168 
169 /**
170   * @brief  Disable Internal Wake-up Line.
171   * @retval None
172   */
HAL_PWREx_DisableInternalWakeUpLine(void)173 void HAL_PWREx_DisableInternalWakeUpLine(void)
174 {
175   CLEAR_BIT(PWR->CR3, PWR_CR3_EIWUL);
176 }
177 
178 
179 /**
180   * @brief  Enable GPIO pull-up state in Standby and Shutdown modes.
181   * @note   Set the relevant PUy bit of PWR_PUCRx register to configure the I/O in
182   *         pull-up state in Standby and Shutdown modes.
183   * @note   This state is effective in Standby and Shutdown modes only if APC bit
184   *         is set through HAL_PWREx_EnablePullUpPullDownConfig() API.
185   * @note   The configuration is lost when exiting the Shutdown mode due to the
186   *         power-on reset, maintained when exiting the Standby mode.
187   * @note   To avoid any conflict at Standby and Shutdown modes exits, the corresponding
188   *         PDy bit of PWR_PDCRx register is cleared unless it is reserved.
189   * @param  GPIO Specify the IO port. This parameter can be PWR_GPIO_A, ..., PWR_GPIO_F
190   *         to select the GPIO peripheral.
191   * @param  GPIONumber Specify the I/O pins numbers.
192   *         This parameter can be one of the following values:
193   *         PWR_GPIO_BIT_0, ..., PWR_GPIO_BIT_15 (except for ports where less
194   *         I/O pins are available) or the logical OR of several of them to set
195   *         several bits for a given port in a single API call.
196   * @retval HAL Status
197   */
HAL_PWREx_EnableGPIOPullUp(uint32_t GPIO,uint32_t GPIONumber)198 HAL_StatusTypeDef HAL_PWREx_EnableGPIOPullUp(uint32_t GPIO, uint32_t GPIONumber)
199 {
200   HAL_StatusTypeDef status = HAL_OK;
201 
202   assert_param(IS_PWR_GPIO(GPIO));
203   assert_param(IS_PWR_GPIO_BIT_NUMBER(GPIONumber));
204 
205   switch (GPIO)
206   {
207     case PWR_GPIO_A:
208       SET_BIT(PWR->PUCRA, GPIONumber);
209       CLEAR_BIT(PWR->PDCRA, GPIONumber);
210       break;
211 
212     case PWR_GPIO_B:
213       SET_BIT(PWR->PUCRB, GPIONumber);
214       CLEAR_BIT(PWR->PDCRB, GPIONumber);
215       break;
216 
217     case PWR_GPIO_C:
218       SET_BIT(PWR->PUCRC, GPIONumber);
219       CLEAR_BIT(PWR->PDCRC, GPIONumber);
220       break;
221 #if defined (GPIOD)
222     case PWR_GPIO_D:
223       SET_BIT(PWR->PUCRD, GPIONumber);
224       CLEAR_BIT(PWR->PDCRD, GPIONumber);
225       break;
226 #endif /* GPIOD */
227     case PWR_GPIO_F:
228       SET_BIT(PWR->PUCRF, GPIONumber);
229       CLEAR_BIT(PWR->PDCRF, GPIONumber);
230       break;
231 
232     default:
233       status = HAL_ERROR;
234       break;
235   }
236 
237   return status;
238 }
239 
240 
241 /**
242   * @brief  Disable GPIO pull-up state in Standby mode and Shutdown modes.
243   * @note   Reset the relevant PUy bit of PWR_PUCRx register used to configure the I/O
244   *         in pull-up state in Standby and Shutdown modes.
245   * @param  GPIO Specifies the IO port. This parameter can be PWR_GPIO_A, ..., PWR_GPIO_F
246   *         to select the GPIO peripheral.
247   * @param  GPIONumber Specify the I/O pins numbers.
248   *         This parameter can be one of the following values:
249   *         PWR_GPIO_BIT_0, ..., PWR_GPIO_BIT_15 (except for ports where less
250   *         I/O pins are available) or the logical OR of several of them to reset
251   *         several bits for a given port in a single API call.
252   * @retval HAL Status
253   */
HAL_PWREx_DisableGPIOPullUp(uint32_t GPIO,uint32_t GPIONumber)254 HAL_StatusTypeDef HAL_PWREx_DisableGPIOPullUp(uint32_t GPIO, uint32_t GPIONumber)
255 {
256   HAL_StatusTypeDef status = HAL_OK;
257 
258   assert_param(IS_PWR_GPIO(GPIO));
259   assert_param(IS_PWR_GPIO_BIT_NUMBER(GPIONumber));
260 
261   switch (GPIO)
262   {
263     case PWR_GPIO_A:
264       CLEAR_BIT(PWR->PUCRA, GPIONumber);
265       break;
266 
267     case PWR_GPIO_B:
268       CLEAR_BIT(PWR->PUCRB, GPIONumber);
269       break;
270 
271     case PWR_GPIO_C:
272       CLEAR_BIT(PWR->PUCRC, GPIONumber);
273       break;
274 #if defined (GPIOD)
275     case PWR_GPIO_D:
276       CLEAR_BIT(PWR->PUCRD, GPIONumber);
277       break;
278 #endif /* GPIOD */
279     case PWR_GPIO_F:
280       CLEAR_BIT(PWR->PUCRF, GPIONumber);
281       break;
282 
283     default:
284       status = HAL_ERROR;
285       break;
286   }
287 
288   return status;
289 }
290 
291 
292 /**
293   * @brief  Enable GPIO pull-down state in Standby and Shutdown modes.
294   * @note   Set the relevant PDy bit of PWR_PDCRx register to configure the I/O in
295   *         pull-down state in Standby and Shutdown modes.
296   * @note   This state is effective in Standby and Shutdown modes only if APC bit
297   *         is set through HAL_PWREx_EnablePullUpPullDownConfig() API.
298   * @note   The configuration is lost when exiting the Shutdown mode due to the
299   *         power-on reset, maintained when exiting the Standby mode.
300   * @note   To avoid any conflict at Standby and Shutdown modes exits, the corresponding
301   *         PUy bit of PWR_PUCRx register is cleared unless it is reserved.
302   * @param  GPIO Specify the IO port. This parameter can be PWR_GPIO_A..PWR_GPIO_F
303   *         to select the GPIO peripheral.
304   * @param  GPIONumber Specify the I/O pins numbers.
305   *         This parameter can be one of the following values:
306   *         PWR_GPIO_BIT_0, ..., PWR_GPIO_BIT_15 (except for ports where less
307   *         I/O pins are available) or the logical OR of several of them to set
308   *         several bits for a given port in a single API call.
309   * @retval HAL Status
310   */
HAL_PWREx_EnableGPIOPullDown(uint32_t GPIO,uint32_t GPIONumber)311 HAL_StatusTypeDef HAL_PWREx_EnableGPIOPullDown(uint32_t GPIO, uint32_t GPIONumber)
312 {
313   HAL_StatusTypeDef status = HAL_OK;
314 
315   assert_param(IS_PWR_GPIO(GPIO));
316   assert_param(IS_PWR_GPIO_BIT_NUMBER(GPIONumber));
317 
318   switch (GPIO)
319   {
320     case PWR_GPIO_A:
321       SET_BIT(PWR->PDCRA, GPIONumber);
322       CLEAR_BIT(PWR->PUCRA, GPIONumber);
323       break;
324 
325     case PWR_GPIO_B:
326       SET_BIT(PWR->PDCRB, GPIONumber);
327       CLEAR_BIT(PWR->PUCRB, GPIONumber);
328       break;
329 
330     case PWR_GPIO_C:
331       SET_BIT(PWR->PDCRC, GPIONumber);
332       CLEAR_BIT(PWR->PUCRC, GPIONumber);
333       break;
334 #if defined (GPIOD)
335     case PWR_GPIO_D:
336       SET_BIT(PWR->PDCRD, GPIONumber);
337       CLEAR_BIT(PWR->PUCRD, GPIONumber);
338       break;
339 #endif /* GPIOD */
340     case PWR_GPIO_F:
341       SET_BIT(PWR->PDCRF, GPIONumber);
342       CLEAR_BIT(PWR->PUCRF, GPIONumber);
343       break;
344 
345     default:
346       status = HAL_ERROR;
347       break;
348   }
349 
350   return status;
351 }
352 
353 
354 /**
355   * @brief  Disable GPIO pull-down state in Standby and Shutdown modes.
356   * @note   Reset the relevant PDy bit of PWR_PDCRx register used to configure the I/O
357   *         in pull-down state in Standby and Shutdown modes.
358   * @param  GPIO Specifies the IO port. This parameter can be PWR_GPIO_A..PWR_GPIO_F
359   *         to select the GPIO peripheral.
360   * @param  GPIONumber Specify the I/O pins numbers.
361   *         This parameter can be one of the following values:
362   *         PWR_GPIO_BIT_0, ..., PWR_GPIO_BIT_15 (except for ports where less
363   *         I/O pins are available) or the logical OR of several of them to reset
364   *         several bits for a given port in a single API call.
365   * @retval HAL Status
366   */
HAL_PWREx_DisableGPIOPullDown(uint32_t GPIO,uint32_t GPIONumber)367 HAL_StatusTypeDef HAL_PWREx_DisableGPIOPullDown(uint32_t GPIO, uint32_t GPIONumber)
368 {
369   HAL_StatusTypeDef status = HAL_OK;
370 
371   assert_param(IS_PWR_GPIO(GPIO));
372   assert_param(IS_PWR_GPIO_BIT_NUMBER(GPIONumber));
373 
374   switch (GPIO)
375   {
376     case PWR_GPIO_A:
377       CLEAR_BIT(PWR->PDCRA, GPIONumber);
378       break;
379 
380     case PWR_GPIO_B:
381       CLEAR_BIT(PWR->PDCRB, GPIONumber);
382       break;
383 
384     case PWR_GPIO_C:
385       CLEAR_BIT(PWR->PDCRC, GPIONumber);
386       break;
387 #if defined (GPIOD)
388     case PWR_GPIO_D:
389       CLEAR_BIT(PWR->PDCRD, GPIONumber);
390       break;
391 #endif /* GPIOD */
392     case PWR_GPIO_F:
393       CLEAR_BIT(PWR->PDCRF, GPIONumber);
394       break;
395 
396     default:
397       status = HAL_ERROR;
398       break;
399   }
400 
401   return status;
402 }
403 
404 
405 /**
406   * @brief  Enable pull-up and pull-down configuration.
407   * @note   When APC bit is set, the I/O pull-up and pull-down configurations defined in
408   *         PWR_PUCRx and PWR_PDCRx registers are applied in Standby and Shutdown modes.
409   * @note   Pull-up set by PUy bit of PWR_PUCRx register is not activated if the corresponding
410   *         PDy bit of PWR_PDCRx register is also set (pull-down configuration priority is higher).
411   *         HAL_PWREx_EnableGPIOPullUp() and HAL_PWREx_EnableGPIOPullDown() APIs ensure there
412   *         is no conflict when setting PUy or PDy bit.
413   * @retval None
414   */
HAL_PWREx_EnablePullUpPullDownConfig(void)415 void HAL_PWREx_EnablePullUpPullDownConfig(void)
416 {
417   SET_BIT(PWR->CR3, PWR_CR3_APC);
418 }
419 
420 /**
421   * @brief  Disable pull-up and pull-down configuration.
422   * @note   When APC bit is cleared, the I/O pull-up and pull-down configurations defined in
423   *         PWR_PUCRx and PWR_PDCRx registers are not applied in Standby and Shutdown modes.
424   * @retval None
425   */
HAL_PWREx_DisablePullUpPullDownConfig(void)426 void HAL_PWREx_DisablePullUpPullDownConfig(void)
427 {
428   CLEAR_BIT(PWR->CR3, PWR_CR3_APC);
429 }
430 
431 
432 /**
433   * @brief  Enable Flash Power Down.
434   * @note   This API allows to enable flash power down capabilities in sleep and stop modes.
435   * @param  PowerMode this can be a combination of following values:
436   *           @arg @ref PWR_FLASHPD_SLEEP
437   *           @arg @ref PWR_FLASHPD_STOP
438   * @retval None
439   */
HAL_PWREx_EnableFlashPowerDown(uint32_t PowerMode)440 void HAL_PWREx_EnableFlashPowerDown(uint32_t PowerMode)
441 {
442   assert_param(IS_PWR_FLASH_POWERDOWN(PowerMode));
443 
444   PWR->CR1 |= PowerMode;
445 }
446 
447 
448 /**
449   * @brief  Disable Flash Power Down.
450   * @note   This API allows to disable flash power down capabilities in sleep and stop modes.
451   * @param  PowerMode this can be a combination of following values:
452   *           @arg @ref PWR_FLASHPD_SLEEP
453   *           @arg @ref PWR_FLASHPD_STOP
454   * @retval None
455   */
HAL_PWREx_DisableFlashPowerDown(uint32_t PowerMode)456 void HAL_PWREx_DisableFlashPowerDown(uint32_t PowerMode)
457 {
458   assert_param(IS_PWR_FLASH_POWERDOWN(PowerMode));
459 
460   PWR->CR1 &= ~PowerMode;
461 }
462 
463 
464 /**
465   * @brief  Enter Shutdown mode.
466   * @note   In Shutdown mode, the PLL, the HSI, the LSI and the HSE oscillators are switched
467   *         off. The voltage regulator is disabled and Vcore domain is powered off.
468   *         SRAM and registers contents are lost except for registers in the Backup domain.
469   *         The BOR is not available.
470   * @note   The I/Os can be configured either with a pull-up or pull-down or can
471   *         be kept in analog state.
472   *         HAL_PWREx_EnableGPIOPullUp() and HAL_PWREx_EnableGPIOPullDown()
473   *         respectively enable Pull Up and PullDown state.
474   *         HAL_PWREx_DisableGPIOPullUp() & HAL_PWREx_DisableGPIOPullDown()
475   *         disable the same. These states are effective in Standby mode only if
476   *         APC bit is set through HAL_PWREx_EnablePullUpPullDownConfig() API.
477   * @retval None
478 
479   * @retval None
480   */
HAL_PWREx_EnterSHUTDOWNMode(void)481 void HAL_PWREx_EnterSHUTDOWNMode(void)
482 {
483   /* Set Shutdown mode */
484   MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_LOWPOWERMODE_SHUTDOWN);
485 
486   /* Set SLEEPDEEP bit of Cortex System Control Register */
487   SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
488 
489   /* This option is used to ensure that store operations are completed */
490 #if defined ( __CC_ARM)
491   __force_stores();
492 #endif /* __CC_ARM */
493 
494   /* Request Wait For Interrupt */
495   __WFI();
496 }
497 
498 /**
499   * @}
500   */
501 
502 /** @addtogroup PWREx_Exported_Functions_Group2 Extended PWR Backup register functions
503   * @brief      Extended PWR Backup register functions
504   *
505 @verbatim
506   ===============================================================================
507              ##### Extended PWR Backup register functions #####
508   ===============================================================================
509   [..]
510    This subsection provides functions allowing to
511    (+) Write a data in a specified PWR Backup data register
512    (+) Read a data in a specified PWR Backup data register
513 @endverbatim
514   * @{
515   */
516 
517 
518 /**
519   * @brief  Write a data in a specified PWR Backup data register.
520   * @param  BackupRegister PWR Backup data Register number.
521   *          This parameter can be PWR_BKP_DRx where x can be from 0 to PWR_BACKUP_NB
522   * @param  Data Data to be written in the specified Backup data register.
523   * @retval None
524   */
HAL_PWREx_BKUPWrite(uint32_t BackupRegister,uint16_t Data)525 void HAL_PWREx_BKUPWrite(uint32_t BackupRegister, uint16_t Data)
526 {
527   uint32_t tmp;
528 
529   /* Check the parameters */
530   assert_param(IS_PWR_BKP(BackupRegister));
531 
532   tmp = (uint32_t) &(PWR->BKP0R);
533   tmp += (BackupRegister * 4U);
534 
535   /* Write the specified register */
536   *(__IO uint32_t *)tmp = (uint16_t)Data;
537 }
538 
539 
540 /**
541   * @brief  Reads data from the specified PWR Backup data Register.
542   * @param  BackupRegister PWR Backup data Register number.
543   *          This parameter can be PWR_BKP_DRx where x can be from 0 to PWR_BACKUP_NB
544   * @retval Read value
545   */
HAL_PWREx_BKUPRead(uint32_t BackupRegister)546 uint32_t HAL_PWREx_BKUPRead(uint32_t BackupRegister)
547 {
548   uint32_t tmp;
549 
550   /* Check the parameters */
551   assert_param(IS_PWR_BKP(BackupRegister));
552 
553   tmp = (uint32_t) &(PWR->BKP0R);
554   tmp += (BackupRegister * 4U);
555 
556   /* Read the specified register */
557   return (*(__IO uint32_t *)tmp);
558 }
559 
560 /**
561   * @}
562   */
563 
564 /**
565   * @}
566   */
567 
568 #endif /* HAL_PWR_MODULE_ENABLED */
569 /**
570   * @}
571   */
572 
573 /**
574   * @}
575   */
576