1 /**
2   ******************************************************************************
3   * @file    stm32wb0x_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) 2024 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 "stm32wb0x_hal.h"
26 
27 /** @addtogroup STM32WB0x_HAL_Driver
28   * @{
29   */
30 /** @defgroup PWREx PWREx
31   * @brief PWR Extended HAL module driver
32   * @{
33   */
34 
35 #ifdef HAL_PWR_MODULE_ENABLED
36 
37 /* Private typedef -----------------------------------------------------------*/
38 /* Private define ------------------------------------------------------------*/
39 /* Private macro -------------------------------------------------------------*/
40 /* Private variables ---------------------------------------------------------*/
41 /* Private function prototypes -----------------------------------------------*/
42 /* Exported functions --------------------------------------------------------*/
43 /** @defgroup PWREx_Exported_Functions PWREx Extended Exported Functions
44   * @{
45   */
46 
47 /**
48   * @brief Enable Internal Wake-up Line (RTC).
49   * @retval None
50   */
HAL_PWREx_EnableInternalWakeUpLine(void)51 void HAL_PWREx_EnableInternalWakeUpLine(void)
52 {
53   SET_BIT(PWR->CR3, PWR_WAKEUP_PIN_RTC);
54 }
55 
56 /**
57   * @brief Disable Internal Wake-up Line (RTC).
58   * @retval None
59   */
HAL_PWREx_DisableInternalWakeUpLine(void)60 void HAL_PWREx_DisableInternalWakeUpLine(void)
61 {
62   CLEAR_BIT(PWR->CR3, PWR_WAKEUP_PIN_RTC);
63 }
64 
65 #if defined (PWR_CR3_EIWL2)
66 /**
67   * @brief Enable Internal Wake-up Line2 (LPUART).
68   * @retval None
69   */
HAL_PWREx_EnableInternalWakeUpLineLpuart(void)70 void HAL_PWREx_EnableInternalWakeUpLineLpuart(void)
71 {
72   SET_BIT(PWR->CR3, PWR_WAKEUP_PIN_LPUART);
73 }
74 
75 /**
76   * @brief Disable Internal Wake-up Line2 (LPUART).
77   * @retval None
78   */
HAL_PWREx_DisableInternalWakeUpLineLpuart(void)79 void HAL_PWREx_DisableInternalWakeUpLineLpuart(void)
80 {
81   CLEAR_BIT(PWR->CR3, PWR_WAKEUP_PIN_LPUART);
82 }
83 #endif /* PWR_CR3_EIWL2 */
84 
85 /**
86   * @brief Enable wakeup on Bluetooth LE Host CPU.
87   * @retval None
88   */
HAL_PWREx_EnableBleHostCpuWakeUp(void)89 void HAL_PWREx_EnableBleHostCpuWakeUp(void)
90 {
91   SET_BIT(PWR->CR3, PWR_CR3_EWBLEHCPU);
92 }
93 
94 /**
95   * @brief Disable wakeup on Bluetooth LE Host CPU.
96   * @retval None
97   */
HAL_PWREx_DisableBleHostCpuWakeUp(void)98 void HAL_PWREx_DisableBleHostCpuWakeUp(void)
99 {
100   CLEAR_BIT(PWR->CR3, PWR_CR3_EWBLEHCPU);
101 }
102 
103 /**
104   * @brief Enable wakeup on Bluetooth LE.
105   * @retval None
106   */
HAL_PWREx_EnableBleWakeUp(void)107 void HAL_PWREx_EnableBleWakeUp(void)
108 {
109   SET_BIT(PWR->CR3, PWR_CR3_EWBLE);
110 }
111 
112 /**
113   * @brief Disable wakeup on Bluetooth LE.
114   * @retval None
115   */
HAL_PWREx_DisableBleWakeUp(void)116 void HAL_PWREx_DisableBleWakeUp(void)
117 {
118   CLEAR_BIT(PWR->CR3, PWR_CR3_EWBLE);
119 }
120 
121 /**
122   * @brief Enable GPIO pull-up state in DeepStop and Shutdown modes.
123   * @note  Set the relevant PUy bits of PWR_PUCRx register to configure the I/O in
124   *        pull-up state in DeepStop and Shutdown modes.
125   * @note  This state is effective in DeepStop and Shutdown modes only if APC bit
126   *        is set through HAL_PWREx_EnablePullUpPullDownConfig() API.
127   * @note  The configuration is lost when exiting the Shutdown mode due to the
128   *        power-on reset, maintained when exiting the  mode.
129   * @note  To avoid any conflict at DeepStop and Shutdown modes exits, the corresponding
130   *        PDy bit of PWR_PDCRx register is cleared unless it is reserved.
131   * @note  Even if a PUy bit to set is reserved, the other PUy bits entered as input
132   *        parameter at the same time are set.
133   * @param GPIO Specify the IO port. This parameter can be PWR_GPIO_A, PWR_GPIO_B
134   *         to select the GPIO peripheral.
135   * @param GPIONumber Specify the I/O pins numbers.
136   *         This parameter can be one of the following values:
137   *         PWR_GPIO_BIT_0, ..., PWR_GPIO_BIT_15 or the logical OR
138   *         of several of them to setseveral bits for a given port in a single API call.
139   * @retval HAL Status
140   */
HAL_PWREx_EnableGPIOPullUp(uint32_t GPIO,uint32_t GPIONumber)141 HAL_StatusTypeDef HAL_PWREx_EnableGPIOPullUp(uint32_t GPIO, uint32_t GPIONumber)
142 {
143   HAL_StatusTypeDef status = HAL_OK;
144 
145   assert_param(IS_PWR_GPIO(GPIO));
146   assert_param(IS_PWR_GPIO_BIT_NUMBER(GPIONumber));
147 
148   switch (GPIO)
149   {
150     case PWR_GPIO_A:
151       SET_BIT(PWR->PUCRA, GPIONumber);
152       CLEAR_BIT(PWR->PDCRA, GPIONumber);
153       break;
154     case PWR_GPIO_B:
155       SET_BIT(PWR->PUCRB, GPIONumber);
156       CLEAR_BIT(PWR->PDCRB, GPIONumber);
157       break;
158     default:
159       status = HAL_ERROR;
160       break;
161   }
162 
163   return status;
164 }
165 
166 /**
167   * @brief Disable GPIO pull-up state in DeepStop mode and Shutdown modes.
168   * @note  Reset the relevant PUy bits of PWR_PUCRx register used to configure the I/O
169   *        in pull-up state in DeepStop and Shutdown modes.
170   * @note  Even if a PUy bit to reset is reserved, the other PUy bits entered as input
171   *        parameter at the same time are reset.
172   * @param GPIO Specifies the IO port. This parameter can be PWR_GPIO_A, PWR_GPIO_B
173   *         to select the GPIO peripheral.
174   * @param GPIONumber Specify the I/O pins numbers.
175   *         This parameter can be one of the following values:
176   *         PWR_GPIO_BIT_0, ..., PWR_GPIO_BIT_15
177   *         or the logical OR of several of them to reset
178   *         several bits for a given port in a single API call.
179   * @retval HAL Status
180   */
HAL_PWREx_DisableGPIOPullUp(uint32_t GPIO,uint32_t GPIONumber)181 HAL_StatusTypeDef HAL_PWREx_DisableGPIOPullUp(uint32_t GPIO, uint32_t GPIONumber)
182 {
183   HAL_StatusTypeDef status = HAL_OK;
184 
185   assert_param(IS_PWR_GPIO(GPIO));
186   assert_param(IS_PWR_GPIO_BIT_NUMBER(GPIONumber));
187 
188   switch (GPIO)
189   {
190     case PWR_GPIO_A:
191       CLEAR_BIT(PWR->PUCRA, GPIONumber);
192       break;
193     case PWR_GPIO_B:
194       CLEAR_BIT(PWR->PUCRB, GPIONumber);
195       break;
196     default:
197       status = HAL_ERROR;
198       break;
199   }
200 
201   return status;
202 }
203 
204 /**
205   * @brief Enable GPIO pull-down state in DeepStop and Shutdown modes.
206   * @note  Set the relevant PDy bits of PWR_PDCRx register to configure the I/O in
207   *        pull-down state in DeepStop and Shutdown modes.
208   * @note  This state is effective in DeepStop and Shutdown modes only if APC bit
209   *        is set through HAL_PWREx_EnablePullUpPullDownConfig() API.
210   * @note  The configuration is lost when exiting the Shutdown mode due to the
211   *        power-on reset, maintained when exiting the DeepStop mode.
212   * @note  To avoid any conflict at DeepStop and Shutdown modes exits, the corresponding
213   *        PUy bit of PWR_PUCRx register is cleared unless it is reserved.
214   * @note  Even if a PDy bit to set is reserved, the other PDy bits entered as input
215   *        parameter at the same time are set.
216   * @param GPIO Specify the IO port. This parameter can be PWR_GPIO_A, PWR_GPIO_B
217   *         to select the GPIO peripheral.
218   * @param GPIONumber Specify the I/O pins numbers.
219   *         This parameter can be one of the following values:
220   *         PWR_GPIO_BIT_0, ..., PWR_GPIO_BIT_15
221   *         or the logical OR of several of them to set
222   *         several bits for a given port in a single API call.
223   * @retval HAL Status
224   */
HAL_PWREx_EnableGPIOPullDown(uint32_t GPIO,uint32_t GPIONumber)225 HAL_StatusTypeDef HAL_PWREx_EnableGPIOPullDown(uint32_t GPIO, uint32_t GPIONumber)
226 {
227   HAL_StatusTypeDef status = HAL_OK;
228 
229   assert_param(IS_PWR_GPIO(GPIO));
230   assert_param(IS_PWR_GPIO_BIT_NUMBER(GPIONumber));
231 
232   switch (GPIO)
233   {
234     case PWR_GPIO_A:
235       SET_BIT(PWR->PDCRA, GPIONumber);
236       CLEAR_BIT(PWR->PUCRA, GPIONumber);
237       break;
238     case PWR_GPIO_B:
239       SET_BIT(PWR->PDCRB, GPIONumber);
240       CLEAR_BIT(PWR->PUCRB, GPIONumber);
241       break;
242     default:
243       status = HAL_ERROR;
244       break;
245   }
246 
247   return status;
248 }
249 
250 /**
251   * @brief Disable GPIO pull-down state in DeepStop and Shutdown modes.
252   * @note  Reset the relevant PDy bits of PWR_PDCRx register used to configure the I/O
253   *        in pull-down state in DeepStop and Shutdown modes.
254   * @note  Even if a PDy bit to reset is reserved, the other PDy bits entered as input
255   *        parameter at the same time are reset.
256   * @param GPIO Specifies the IO port. This parameter can be PWR_GPIO_A, PWR_GPIO_B
257   *         to select the GPIO peripheral.
258   * @param GPIONumber Specify the I/O pins numbers.
259   *         This parameter can be one of the following values:
260   *         PWR_GPIO_BIT_0, ..., PWR_GPIO_BIT_15
261   *         or the logical OR of several of them to reset
262   *         several bits for a given port in a single API call.
263   * @retval HAL Status
264   */
HAL_PWREx_DisableGPIOPullDown(uint32_t GPIO,uint32_t GPIONumber)265 HAL_StatusTypeDef HAL_PWREx_DisableGPIOPullDown(uint32_t GPIO, uint32_t GPIONumber)
266 {
267   HAL_StatusTypeDef status = HAL_OK;
268 
269   assert_param(IS_PWR_GPIO(GPIO));
270   assert_param(IS_PWR_GPIO_BIT_NUMBER(GPIONumber));
271 
272   switch (GPIO)
273   {
274     case PWR_GPIO_A:
275       CLEAR_BIT(PWR->PDCRA, GPIONumber);
276       break;
277     case PWR_GPIO_B:
278       CLEAR_BIT(PWR->PDCRB, GPIONumber);
279       break;
280     default:
281       status = HAL_ERROR;
282       break;
283   }
284 
285   return status;
286 }
287 
288 /**
289   * @brief Enable pull-up and pull-down configuration.
290   * @note  When APC bit is set, the I/O pull-up and pull-down configurations defined in
291   *        PWR_PUCRx and PWR_PDCRx registers are applied in DeepStop and Shutdown modes.
292   * @note  Pull-up set by PUy bit of PWR_PUCRx register is not activated if the corresponding
293   *        PDy bit of PWR_PDCRx register is also set (pull-down configuration priority is higher).
294   *        HAL_PWREx_EnableGPIOPullUp() and HAL_PWREx_EnableGPIOPullDown() API's ensure there
295   *        is no conflict when setting PUy or PDy bit.
296   * @retval None
297   */
HAL_PWREx_EnablePullUpPullDownConfig(void)298 void HAL_PWREx_EnablePullUpPullDownConfig(void)
299 {
300   SET_BIT(PWR->CR1, PWR_CR1_APC);
301 }
302 
303 /**
304   * @brief Disable pull-up and pull-down configuration.
305   * @note  When APC bit is cleared, the I/O pull-up and pull-down configurations defined in
306   *        PWR_PUCRx and PWR_PDCRx registers are not applied in DeepStop and Shutdown modes.
307   * @retval None
308   */
HAL_PWREx_DisablePullUpPullDownConfig(void)309 void HAL_PWREx_DisablePullUpPullDownConfig(void)
310 {
311   CLEAR_BIT(PWR->CR1, PWR_CR1_APC);
312 }
313 
314 /**
315   * @brief Enable RAMx content retention in DEEPSTOP mode.
316   * @rmtoll CR2         RAMRET1    HAL_PWREx_EnableSRAMRetention
317   *         CR2         RAMRET2    HAL_PWREx_EnableSRAMRetention
318   *         CR2         RAMRET3    HAL_PWREx_EnableSRAMRetention
319   * @param  banks RAM bank selection. This parameter can be a combination of the following values:
320   *         @arg @ref PWR_RAMRET_1
321   *         @arg @ref PWR_RAMRET_2 (*)
322   *         @arg @ref PWR_RAMRET_3 (*)
323   *         (*) Not available on devices STM32WB05
324   * @retval None
325   */
HAL_PWREx_EnableSRAMRetention(uint32_t banks)326 void HAL_PWREx_EnableSRAMRetention(uint32_t banks)
327 {
328   LL_PWR_EnableRAMBankRet(banks);
329 }
330 
331 /**
332   * @brief Disable RAMx content retention in DEEPSTOP mode.
333   * @rmtoll CR2         RAMRET1    HAL_PWREx_DisableSRAMRetention
334   *         CR2         RAMRET2    HAL_PWREx_DisableSRAMRetention
335   *         CR2         RAMRET3    HAL_PWREx_DisableSRAMRetention
336   * @param  banks RAM bank selection. This parameter can be a combination of the following values:
337   *         @arg @ref PWR_RAMRET_1
338   *         @arg @ref PWR_RAMRET_2 (*)
339   *         @arg @ref PWR_RAMRET_3 (*)
340   *         (*) Not available on devices STM32WB05
341   * @retval None
342   */
HAL_PWREx_DisableSRAMRetention(uint32_t banks)343 void HAL_PWREx_DisableSRAMRetention(uint32_t banks)
344 {
345   LL_PWR_DisableRAMBankRet(banks);
346 }
347 
348 #if defined (PWR_CR2_GPIORET)
349 /**
350   * @brief  Enable the GPIORET feature, GPIO retain their status during DEEPSTOP
351   *         and exiting from DEEPSTOP.
352   * @rmtoll CR2         GPIORET      HAL_PWREx_EnableGPIORetention
353   * @retval None
354   */
HAL_PWREx_EnableGPIORetention(void)355 void HAL_PWREx_EnableGPIORetention(void)
356 {
357   LL_PWR_EnableGPIORET();
358 }
359 
360 /**
361   * @brief  Disable the GPIORET feature, don't retain their status during DEEPSTOP and exiting from DEEPSTOP.
362   * @rmtoll CR2         GPIORET      HAL_PWREx_DisableGPIORetention
363   * @retval None
364   */
HAL_PWREx_DisableGPIORetention(void)365 void HAL_PWREx_DisableGPIORetention(void)
366 {
367   LL_PWR_DisableGPIORET();
368 }
369 #endif /* PWR_CR2_GPIORET */
370 
371 #if defined (PWR_CR2_DBGRET)
372 /**
373   * @brief  Enable the DBGRET feature, PA2 and PA3 retain their status during DEEPSTOP
374   *         and exiting from DEEPSTOP.
375   * @rmtoll CR2         DBGRET      HAL_PWREx_EnableDBGRetention
376   * @retval None
377   */
HAL_PWREx_EnableDBGRetention(void)378 void HAL_PWREx_EnableDBGRetention(void)
379 {
380   LL_PWR_EnableDBGRET();
381 }
382 
383 /**
384   * @brief  Disable the DBGRET feature, don't retain their status during DEEPSTOP and exiting from DEEPSTOP.
385   * @rmtoll CR2         DBGRET      HAL_PWREx_DisableDBGRetention
386   * @retval None
387   */
HAL_PWREx_DisableDBGRetention(void)388 void HAL_PWREx_DisableDBGRetention(void)
389 {
390   LL_PWR_DisableDBGRET();
391 }
392 #endif /* PWR_CR2_DBGRET */
393 
394 /**
395   * @brief Configure the SMPS step down converter.
396   * @param OutputVoltage SMPS output voltage configuration.
397   *        This parameter can be one of the following values:
398   *         @arg @ref PWR_SMPS_OUTPUT_VOLTAGE_1V20
399   *         @arg @ref PWR_SMPS_OUTPUT_VOLTAGE_1V25
400   *         @arg @ref PWR_SMPS_OUTPUT_VOLTAGE_1V30
401   *         @arg @ref PWR_SMPS_OUTPUT_VOLTAGE_1V35
402   *         @arg @ref PWR_SMPS_OUTPUT_VOLTAGE_1V40
403   *         @arg @ref PWR_SMPS_OUTPUT_VOLTAGE_1V45
404   *         @arg @ref PWR_SMPS_OUTPUT_VOLTAGE_1V50
405   *         @arg @ref PWR_SMPS_OUTPUT_VOLTAGE_1V55
406   *         @arg @ref PWR_SMPS_OUTPUT_VOLTAGE_1V60
407   *         @arg @ref PWR_SMPS_OUTPUT_VOLTAGE_1V65
408   *         @arg @ref PWR_SMPS_OUTPUT_VOLTAGE_1V70
409   *         @arg @ref PWR_SMPS_OUTPUT_VOLTAGE_1V75
410   *         @arg @ref PWR_SMPS_OUTPUT_VOLTAGE_1V80
411   *         @arg @ref PWR_SMPS_OUTPUT_VOLTAGE_1V85
412   *         @arg @ref PWR_SMPS_OUTPUT_VOLTAGE_1V90
413   *         @arg @ref PWR_SMPS_OUTPUT_VOLTAGE_1V95
414   * @param BOM SMPS BOM configuration.
415   * @note  To set and enable SMPS operating mode, refer to function
416   *        "HAL_PWREx_SMPS_SetMode()".
417   * @retval HAL status
418   */
HAL_PWREx_ConfigSMPS(uint32_t OutputVoltage,uint32_t BOM)419 HAL_StatusTypeDef HAL_PWREx_ConfigSMPS(uint32_t OutputVoltage, uint32_t BOM)
420 {
421   /* Check the parameter */
422   assert_param(IS_PWR_SMPS_OUTPUT_VOLTAGE(OutputVoltage));
423   assert_param(IS_PWR_SMPS_BOM(BOM));
424 
425   MODIFY_REG(PWR->CR5, PWR_CR5_SMPSLVL, OutputVoltage);
426   MODIFY_REG(PWR->CR5, PWR_CR5_SMPSBOMSEL, BOM);
427 
428   return HAL_OK;
429 }
430 
431 /**
432   * @brief Set SMPS operating mode.
433   * @param  OperatingMode This parameter can be one of the following values:
434   *         @arg @ref PWR_SMPS_ON
435   *         @arg @ref PWR_SMPS_OFF
436   *         @arg @ref PWR_SMPS_BYPASS
437   *
438   * @retval None
439   */
HAL_PWREx_SMPS_SetMode(uint32_t OperatingMode)440 void HAL_PWREx_SMPS_SetMode(uint32_t OperatingMode)
441 {
442   /* Check the parameter */
443   assert_param(IS_PWR_SMPS_MODE(OperatingMode));
444 
445   if (OperatingMode == PWR_SMPS_ON)
446   {
447     MODIFY_REG(PWR->CR5, PWR_CR5_NOSMPS, PWR_SMPS_ON);
448     while (!LL_PWR_IsSMPSinRUNMode());
449     MODIFY_REG(PWR->CR5, PWR_CR5_SMPSFBYP, PWR_NO_SMPS_PRECHARGE);
450   }
451 
452   /* SMPS Precharge Configuration */
453   if (OperatingMode == PWR_SMPS_BYPASS)
454   {
455     MODIFY_REG(PWR->CR5, PWR_CR5_NOSMPS, PWR_SMPS_ON);
456     while (!LL_PWR_IsSMPSinRUNMode());
457     MODIFY_REG(PWR->CR5, PWR_CR5_SMPSFBYP, PWR_SMPS_PRECHARGE);
458   }
459 
460   /* SMPS OFF Configuration */
461   if (OperatingMode == PWR_SMPS_OFF)
462   {
463     MODIFY_REG(PWR->CR5, PWR_CR5_NOSMPS, PWR_SMPS_OFF);
464     while (LL_PWR_IsSMPSinRUNMode());
465     MODIFY_REG(PWR->CR5, PWR_CR5_SMPSFBYP, PWR_NO_SMPS_PRECHARGE);
466   }
467 }
468 
469 /**
470   * @brief  Get SMPS operating mode
471   * @retval Returned value can be one of the following values:
472   *         @arg @ref PWR_SMPS_ON
473   *         @arg @ref PWR_SMPS_OFF
474   *         @arg @ref PWR_SMPS_PRECHARGE
475   */
HAL_PWREx_SMPS_GetMode(void)476 uint32_t HAL_PWREx_SMPS_GetMode(void)
477 {
478   return (uint32_t)(READ_BIT(PWR->SR2, (PWR_SR2_SMPSENR | PWR_SR2_SMPSBYPR)));
479 }
480 
481 /**
482   * @brief  Enter Shutdown mode.
483   * @note   In Shutdown mode, all clocks are off as RC64MPLL, LSI and LSE are switched
484   *         off. The system is powered down as both regulators are OFF is powered off.
485   * @note   The I/Os can be configured either with a pull-up or pull-down or can
486   *         be kept in analog state.
487   *         HAL_PWREx_EnableGPIOPullUp() and HAL_PWREx_EnableGPIOPullDown()
488   *         respectively enable Pull Up and Pull Down state.
489   *         HAL_PWREx_DisableGPIOPullUp() & HAL_PWREx_DisableGPIOPullDown()
490   *         disable the same. These states are effective in Standby mode only if
491   *         APC bit is set through HAL_PWREx_EnablePullUpPullDownConfig() API.
492   * @retval None
493   */
HAL_PWREx_EnterSHUTDOWNMode(void)494 void HAL_PWREx_EnterSHUTDOWNMode(void)
495 {
496   /* Clear all the wake-up pin flags */
497   LL_PWR_ClearWakeupSource(LL_PWR_WAKEUP_ALL);
498 
499   /* Set Shutdown mode */
500   SET_BIT(PWR->CR1, PWR_LOWPOWERMODE_SHUTDOWN);
501 
502   /* Set SLEEPDEEP bit of Cortex System Control Register */
503   SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
504 
505   /* This option is used to ensure that store operations are completed */
506 #if defined ( __CC_ARM)
507   __force_stores();
508 #endif /* __CC_ARM */
509 
510   /* Request Wait For Interrupt */
511   __WFI();
512 }
513 
514 
515 /**
516   * @}
517   */
518 
519 #endif /* HAL_PWR_MODULE_ENABLED */
520 /**
521   * @}
522   */
523 
524 /**
525   * @}
526   */
527