1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 
7 /***********************************************************************************************************************
8  * Includes   <System Includes> , "Project Includes"
9  **********************************************************************************************************************/
10 #include <stdint.h>
11 #include "bsp_api.h"
12 
13 #if BSP_PRV_POWER_USE_DCDC
14 
15 /***********************************************************************************************************************
16  * Macro definitions
17  **********************************************************************************************************************/
18  #define BSP_PRV_LDO_STABILIZATION_TIME_US    (60U)
19 
20 /***********************************************************************************************************************
21  * Typedef definitions
22  **********************************************************************************************************************/
23 
24 /***********************************************************************************************************************
25  * Switch from DCDC to LDO. Requires LPM register protection and interrupts to be disabled.
26  *
27  * This function follows the procedure given in the RA2L1 User's Manual (R01UH0853EJ0100) Section 10.5.1 (4) "Switching
28  * from High-speed/Middle-speed mode (DCDC power mode) to High-speed/Middle-speed mode (LDO power mode)"
29  **********************************************************************************************************************/
bsp_power_dcdc_disable(bsp_power_mode_t mode)30 static inline void bsp_power_dcdc_disable (bsp_power_mode_t mode)
31 {
32     /* Save all module stop bits, then stop all peripherals. */
33     uint32_t mstpcrb = R_MSTP->MSTPCRB;
34     R_MSTP->MSTPCRB = UINT32_MAX;
35     uint32_t mstpcrc = R_MSTP->MSTPCRC;
36     R_MSTP->MSTPCRC = UINT32_MAX;
37     uint32_t mstpcrd = R_MSTP->MSTPCRD;
38     R_MSTP->MSTPCRD = UINT32_MAX;
39 
40     /* Switch to LDO. */
41     R_SYSTEM->DCDCCTL = (uint8_t) mode;
42 
43     /* Wait for LDO to stabilize. */
44     R_BSP_SoftwareDelay(BSP_PRV_LDO_STABILIZATION_TIME_US, BSP_DELAY_UNITS_MICROSECONDS);
45 
46     /* Restore all module stop bits. */
47     R_MSTP->MSTPCRB = mstpcrb;
48     R_MSTP->MSTPCRC = mstpcrc;
49     R_MSTP->MSTPCRD = mstpcrd;
50 }
51 
52 /***********************************************************************************************************************
53  * Switch from LDO to DCDC. Requires LPM register protection and interrupts to be disabled.
54  *
55  * This function follows the procedure given in the RA2L1 User's Manual (R01UH0853EJ0100) Section 10.5.1 (3) "Switching
56  * from the High-Speed/Middle-Speed mode (LDO power mode) to the High-speed/Middle speed mode (DCDC power mode)"
57  **********************************************************************************************************************/
bsp_power_dcdc_enable(void)58 static inline void bsp_power_dcdc_enable (void)
59 {
60     /* Enable DCDC IO buffer. */
61     uint8_t dcdcctl = R_SYSTEM->DCDCCTL | R_SYSTEM_DCDCCTL_STOPZA_Msk;
62     R_SYSTEM->DCDCCTL = dcdcctl;
63 
64     /* Turn on DCDC Vref. */
65     R_SYSTEM->DCDCCTL = dcdcctl & (uint8_t) (~R_SYSTEM_DCDCCTL_PD_Msk);
66 
67     /* Wait for Vref to stabilize. */
68     R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MICROSECONDS);
69 
70     /* Switch DCDC Vref to low-power mode. */
71     R_SYSTEM->DCDCCTL = 0x10;
72 
73     /* Wait for Vref to stabilize. */
74     R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MICROSECONDS);
75 
76     /* Turn off LDO and turn on DCDC. */
77     R_SYSTEM->DCDCCTL = 0x11;
78 
79     /* Wait for DCDC to stabilize. */
80     R_BSP_SoftwareDelay(2, BSP_DELAY_UNITS_MICROSECONDS);
81 
82     /* Enable DCDC overcurrent protection. */
83     R_SYSTEM->DCDCCTL = 0x13;
84 }
85 
86 /*******************************************************************************************************************//**
87  * @addtogroup BSP_MCU_RA2L1
88  * @{
89  **********************************************************************************************************************/
90 
91 /*******************************************************************************************************************//**
92  * Select either the LDO or DCDC regulator and/or update the MCU supply voltage range. Returns the previously selected
93  * mode.
94  *
95  * @note DCDC mode has the following limitations:
96  *         - Supply voltage must be 2.4V or greater
97  *         - Low- and Subosc-speed modes are not available
98  *         - Software Standby is not available
99  *       Ensure these limitations are respected before entering DCDC mode. If supply voltage may drop below 2.4V during
100  *       operation, configure a LVD channel to interrupt or reset the MCU near this threshold to switch back to the LDO.
101  *
102  * @note Switching to DCDC mode temporarily disables all interrupts and blocks for 22 microseconds; switching to LDO
103  *       from DCDC temporarily disables all peripherals and interrupts and blocks for 60 microseconds.
104  *
105  * @note If the supply voltage falls outside the range originally specified when starting the DCDC regulator, call this
106  *       function again with the updated supply voltage.
107  *
108  * @return  The previously selected power mode.
109  **********************************************************************************************************************/
R_BSP_PowerModeSet(bsp_power_mode_t mode)110 bsp_power_mode_t R_BSP_PowerModeSet (bsp_power_mode_t mode)
111 {
112     /* Get current mode to return to caller. */
113     bsp_power_mode_t previous_mode = R_SYSTEM->DCDCCTL & R_SYSTEM_DCDCCTL_DCDCON_Msk ?
114                                      (bsp_power_mode_t) R_SYSTEM->VCCSEL : BSP_POWER_MODE_LDO;
115 
116     /* Enable writing to Low Power Mode registers. */
117     R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_OM_LPC_BATT);
118 
119     /* Set VCCSEL if a DCDC mode is selected. */
120     bool dcdc_mode = mode < BSP_POWER_MODE_LDO;
121     if (dcdc_mode)
122     {
123         /* Set supply voltage range. */
124         R_SYSTEM->VCCSEL = (uint8_t) mode;
125     }
126 
127     /* Only change mode if the specified mode is not already set. */
128     if (dcdc_mode != (previous_mode < BSP_POWER_MODE_LDO))
129     {
130         /* Enter critical section to prevent any peripheral or power mode changes while transitioning. */
131         FSP_CRITICAL_SECTION_DEFINE;
132         FSP_CRITICAL_SECTION_ENTER;
133 
134         if (mode >= BSP_POWER_MODE_LDO)
135         {
136             bsp_power_dcdc_disable(mode);
137         }
138         else
139         {
140             bsp_power_dcdc_enable();
141         }
142 
143         FSP_CRITICAL_SECTION_EXIT;
144     }
145 
146     /* Disable writing to Low Power Mode registers. */
147     R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_OM_LPC_BATT);
148 
149     return previous_mode;
150 }
151 
152 /*******************************************************************************************************************//**
153  * @} (end addtogroup BSP_MCU_RA2L1)
154  **********************************************************************************************************************/
155 
156 #endif                                 /* BSP_PRV_POWER_USE_DCDC */
157