1 /******************************************************************************
2 *  Filename:       pwr_ctrl.c
3 *  Revised:        2015-05-19 11:38:08 +0200 (Tue, 19 May 2015)
4 *  Revision:       43528
5 *
6 *  Description:    Power Control driver.
7 *
8 *  Copyright (c) 2015, Texas Instruments Incorporated
9 *  All rights reserved.
10 *
11 *  Redistribution and use in source and binary forms, with or without
12 *  modification, are permitted provided that the following conditions are met:
13 *
14 *  1) Redistributions of source code must retain the above copyright notice,
15 *     this list of conditions and the following disclaimer.
16 *
17 *  2) Redistributions in binary form must reproduce the above copyright notice,
18 *     this list of conditions and the following disclaimer in the documentation
19 *     and/or other materials provided with the distribution.
20 *
21 *  3) Neither the name of the ORGANIZATION nor the names of its contributors may
22 *     be used to endorse or promote products derived from this software without
23 *     specific prior written permission.
24 *
25 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 *  POSSIBILITY OF SUCH DAMAGE.
36 *
37 ******************************************************************************/
38 
39 #include <driverlib/pwr_ctrl.h>
40 
41 //*****************************************************************************
42 //
43 // Handle support for DriverLib in ROM:
44 // This section will undo prototype renaming made in the header file
45 //
46 //*****************************************************************************
47 #if !defined(DOXYGEN)
48     #undef  PowerCtrlStateSet
49     #define PowerCtrlStateSet               NOROM_PowerCtrlStateSet
50     #undef  PowerCtrlSourceSet
51     #define PowerCtrlSourceSet              NOROM_PowerCtrlSourceSet
52 #endif
53 
54 //*****************************************************************************
55 //
56 // Force the system in to low power modes.
57 //
58 //*****************************************************************************
59 void
PowerCtrlStateSet(uint32_t ui32Powerstate)60 PowerCtrlStateSet(uint32_t ui32Powerstate)
61 {
62     //
63     // Check the arguments.
64     //
65     ASSERT((ui32Powerstate == PWRCTRL_STANDBY) ||
66            (ui32Powerstate == PWRCTRL_POWER_DOWN) ||
67            (ui32Powerstate == PWRCTRL_SHUTDOWN));
68 
69     //
70     // Configure the desired power state.
71     //
72     if(ui32Powerstate == PWRCTRL_STANDBY)
73     {
74         //
75         //
76         // Turn of all power domains in the MCU voltage domain. This is
77         // necessary to conserve power before switching to the uLDO.
78         //
79         PRCMPowerDomainOff(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_SERIAL |
80                            PRCM_DOMAIN_PERIPH | PRCM_DOMAIN_CPU |
81                            PRCM_DOMAIN_VIMS);
82 
83         //
84         // Make sure to request power off of the JTAG domain.
85         //
86         AONWUCJtagPowerOff();
87 
88         //
89         // Configuration of clock source for MCU and AUX in standby mode.
90         //
91         AONWUCMcuPowerDownConfig(AONWUC_CLOCK_SRC_LF);
92         AONWUCAuxPowerDownConfig(AONWUC_CLOCK_SRC_LF);
93 
94         //
95         // Configure the recharge controller and request the uLDO as power
96         // source.
97         //
98         AONWUCRechargeCtrlConfigSet(true, 34, 2500, 5000);
99 
100         //
101         // Enable AUX power down
102         // This will tell the system that no HF source is needed and will
103         // allow the system to use the low-leakage/effect power supply.
104         // NB. This does not allow co-existence of an independent
105         // Sensor Controller.
106         //
107         AUXWUCPowerCtrl(AUX_WUC_POWER_DOWN);
108         while(AONWUCPowerStatusGet() & AONWUC_AUX_POWER_ON);
109 
110         //
111         // Request the uLDO for standby power consumption.
112         //
113         PowerCtrlSourceSet(PWRCTRL_PWRSRC_ULDO);
114 
115         //
116         // Sync the AON interface to ensure all writes have gone through
117         //
118         HWREG(AON_RTC_BASE + AON_RTC_O_SYNC);
119 
120         //
121         // Enable transition to standby.
122         //
123         PRCMDeepSleep();
124     }
125     else if(ui32Powerstate == PWRCTRL_POWER_DOWN)
126     {
127         //
128         // Latch the current IO configuration before going to sleep to ensure
129         // the IOs retain their value even after boot and reset of the
130         // configuration.
131         //
132         AONIOCFreezeEnable();
133 
134         //
135         // Make sure retention on MCU SRAM is on - on pr. default.
136         //
137         AONWUCMcuSRamConfig(MCU_RAM0_RETENTION | MCU_RAM1_RETENTION |
138                             MCU_RAM2_RETENTION | MCU_RAM3_RETENTION);
139 
140         //
141         // Allow power off on all domains in the MCU voltage domain.
142         // This is necessary to conserve power before switching to the uLDO.
143         //
144         PRCMPowerDomainOff(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_SERIAL |
145                            PRCM_DOMAIN_PERIPH | PRCM_DOMAIN_CPU |
146                            PRCM_DOMAIN_VIMS);
147 
148         //
149         // Turn off the MCU voltage domain. This will not take effect until System CPU
150         // is in deep sleep.
151         //
152         PRCMMcuPowerOff();
153 
154         //
155         // Set the wake up mode  - default value coming out of reset
156         //
157         AONWUCMcuWakeUpConfig(MCU_IMM_WAKE_UP);
158 
159         //
160         // VIRTUAL POWER OFF DISABLE is the default value coming out of reset
161         //
162         AONWUCMcuPowerOffConfig(MCU_VIRT_PWOFF_DISABLE);
163 
164         //
165         // Configure the recharge controller and request the uLDO as power
166         // source.
167         // Recommended maximum numbers for lowest power consumption
168         // AdaptRate = 96
169         // MaxPeriod = 21440
170         // InitPeriod = 14816
171         //
172         AONWUCRechargeCtrlConfigSet(true, 75, 5000, 7500);
173 
174         //
175         // Enable AUX power down with LF clock source
176         // Turn off JTAG domain and enable powerdown - values are default.
177         //
178         AONWUCAuxPowerDownConfig(AONWUC_CLOCK_SRC_LF);
179         AUXWUCPowerCtrl(AUX_WUC_POWER_DOWN);
180         AONWUCDomainPowerDownEnable();
181         while(AONWUCPowerStatusGet() & AONWUC_AUX_POWER_ON);
182 
183         //
184         // Sync the AON interface to ensure all writes have gone through
185         //
186         HWREG(AON_RTC_BASE + AON_RTC_O_SYNC);
187 
188         //
189         // Enable transition to power down.
190         //
191         PRCMDeepSleep();
192     }
193     else
194     {
195         //
196         // Latch the current IO configuration before going to sleep to ensure
197         // the IOs retain their value even after boot and reset of the
198         // configuration.
199         //
200         AONIOCFreezeEnable();
201 
202         //
203         // Turn of all power domains in the MCU voltage domain.
204         //
205         PRCMPowerDomainOff(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_SERIAL |
206                            PRCM_DOMAIN_PERIPH | PRCM_DOMAIN_CPU |
207                            PRCM_DOMAIN_VIMS);
208 
209         //
210         // Turn off the MCU voltage domain. This will not take effect until System CPU
211         // is in deep sleep.
212         //
213         PRCMMcuPowerOff();
214 
215         //
216         // Set the wake up mode of MCU to immediate
217         //
218         AONWUCMcuWakeUpConfig(MCU_IMM_WAKE_UP);
219         AONWUCMcuPowerOffConfig(MCU_VIRT_PWOFF_DISABLE);
220 
221         //
222         // Turn off the AUX domain and wait for power to be off.
223         //
224         // Is this required for shutdown mode? or will AUX automatically
225         // power off.
226         AUXWUCPowerCtrl(AUX_WUC_POWER_OFF);
227         while(AONWUCPowerStatusGet() & AONWUC_AUX_POWER_ON)
228         { }
229 
230         //
231         // Latch the IOs in the padring before going to sleep to retain their
232         // value even after boot and reset of the configuration.
233         //
234         PowerCtrlIOFreezeEnable();
235 
236         //
237         // Enable shutdown and make sure the AON interface is in sync on the
238         // 32kHz clock.
239         //
240         AONWUCShutDownEnable();
241 
242         //
243         // Sync the AON interface to ensure all writes have gone through
244         //
245         HWREG(AON_RTC_BASE + AON_RTC_O_SYNC);
246 
247         //
248         // Enable transition to shutdown.
249         //
250         PRCMDeepSleep();
251     }
252 }
253 
254 //*****************************************************************************
255 //
256 //! Set (Request) the main power source
257 //
258 //*****************************************************************************
259 void
PowerCtrlSourceSet(uint32_t ui32PowerConfig)260 PowerCtrlSourceSet(uint32_t ui32PowerConfig)
261 {
262     //
263     // Check the arguments.
264     //
265     ASSERT((ui32PowerConfig == PWRCTRL_PWRSRC_DCDC) ||
266            (ui32PowerConfig == PWRCTRL_PWRSRC_GLDO) ||
267            (ui32PowerConfig == PWRCTRL_PWRSRC_ULDO));
268 
269     //
270     // Configure the power.
271     //
272     if(ui32PowerConfig == PWRCTRL_PWRSRC_DCDC) {
273         HWREG(AON_SYSCTL_BASE + AON_SYSCTL_O_PWRCTL) |=
274             (AON_SYSCTL_PWRCTL_DCDC_EN | AON_SYSCTL_PWRCTL_DCDC_ACTIVE);
275     }
276     else if (ui32PowerConfig == PWRCTRL_PWRSRC_GLDO)
277     {
278         HWREG(AON_SYSCTL_BASE + AON_SYSCTL_O_PWRCTL) &=
279             ~(AON_SYSCTL_PWRCTL_DCDC_EN | AON_SYSCTL_PWRCTL_DCDC_ACTIVE);
280     }
281     else
282     {
283         PRCMMcuUldoConfigure(true);
284     }
285 }
286