1 /**
2  * @file    lp.c
3  * @brief   Low power functions
4  */
5 
6 /* ****************************************************************************
7  * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a
10  * copy of this software and associated documentation files (the "Software"),
11  * to deal in the Software without restriction, including without limitation
12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  * and/or sell copies of the Software, and to permit persons to whom the
14  * Software is furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included
17  * in all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22  * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
23  * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25  * OTHER DEALINGS IN THE SOFTWARE.
26  *
27  * Except as contained in this notice, the name of Maxim Integrated
28  * Products, Inc. shall not be used except as stated in the Maxim Integrated
29  * Products, Inc. Branding Policy.
30  *
31  * The mere transfer of this software does not imply any licenses
32  * of trade secrets, proprietary technology, copyrights, patents,
33  * trademarks, maskwork rights, or any other form of intellectual
34  * property whatsoever. Maxim Integrated Products, Inc. retains all
35  * ownership rights.
36  *
37  * $Date: 2019-10-07 11:05:30 -0500 (Mon, 07 Oct 2019) $
38  * $Revision: 47429 $
39  *
40  *************************************************************************** */
41 
42 
43 /***** Includes *****/
44 #include "lp.h"
45 #include "pwrseq_regs.h"
46 #include "mxc_errors.h"
47 #include "gcr_regs.h"
48 #include "mxc_config.h"
49 #include "mxc_sys.h"
50 #include "flc.h"
51 #include "tmr_utils.h"
52 
53 /***** Functions *****/
LP_ClearWakeStatus(void)54 void LP_ClearWakeStatus(void)
55 {
56     MXC_PWRSEQ->lp_wakefl = 0xFFFFFFFF;
57 
58     /* These flags are slow to clear, so block until they do */
59     while(MXC_PWRSEQ->lp_wakefl & (MXC_PWRSEQ->lpwk_en));
60 }
61 
LP_EnableSRAM3(void)62 void LP_EnableSRAM3(void)
63 {
64     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_SRAM3_OFF;
65 }
66 
LP_DisableSRAM3(void)67 void LP_DisableSRAM3(void)
68 {
69     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_SRAM3_OFF;
70 }
71 
LP_EnableSRAM2(void)72 void LP_EnableSRAM2(void)
73 {
74     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_SRAM2_OFF;
75 }
76 
LP_DisableSRAM2(void)77 void LP_DisableSRAM2(void)
78 {
79     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_SRAM2_OFF;
80 }
81 
LP_EnableSRAM1(void)82 void LP_EnableSRAM1(void)
83 {
84     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_SRAM1_OFF;
85 }
86 
LP_DisableSRAM1(void)87 void LP_DisableSRAM1(void)
88 {
89     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_SRAM1_OFF;
90 }
91 
LP_EnableSRAM0(void)92 void LP_EnableSRAM0(void)
93 {
94     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_SRAM0_OFF;
95 }
96 
LP_DisableSRAM0(void)97 void LP_DisableSRAM0(void)
98 {
99     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_SRAM0_OFF;
100 }
101 
LP_EnableICacheLightSleep(void)102 void LP_EnableICacheLightSleep(void)
103 {
104     MXC_GCR->memckcn |= (MXC_F_GCR_MEMCKCN_ICACHELS);
105 }
106 
LP_DisableICacheLightSleep(void)107 void LP_DisableICacheLightSleep(void)
108 {
109     MXC_GCR->memckcn &= ~(MXC_F_GCR_MEMCKCN_ICACHELS);
110 }
111 
LP_EnableSysRAM3LightSleep(void)112 void LP_EnableSysRAM3LightSleep(void)
113 {
114     MXC_GCR->memckcn |= (MXC_F_GCR_MEMCKCN_SYSRAM3LS);
115 }
116 
LP_DisableSysRAM3LightSleep(void)117 void LP_DisableSysRAM3LightSleep(void)
118 {
119     MXC_GCR->memckcn &= ~(MXC_F_GCR_MEMCKCN_SYSRAM3LS);
120 }
121 
LP_EnableSysRAM2LightSleep(void)122 void LP_EnableSysRAM2LightSleep(void)
123 {
124     MXC_GCR->memckcn |= (MXC_F_GCR_MEMCKCN_SYSRAM2LS);
125 }
126 
LP_DisableSysRAM2LightSleep(void)127 void LP_DisableSysRAM2LightSleep(void)
128 {
129     MXC_GCR->memckcn &= ~(MXC_F_GCR_MEMCKCN_SYSRAM2LS);
130 }
131 
LP_EnableSysRAM1LightSleep(void)132 void LP_EnableSysRAM1LightSleep(void)
133 {
134     MXC_GCR->memckcn |= (MXC_F_GCR_MEMCKCN_SYSRAM1LS);
135 }
136 
LP_DisableSysRAM1LightSleep(void)137 void LP_DisableSysRAM1LightSleep(void)
138 {
139     MXC_GCR->memckcn &= ~(MXC_F_GCR_MEMCKCN_SYSRAM1LS);
140 }
141 
LP_EnableSysRAM0LightSleep(void)142 void LP_EnableSysRAM0LightSleep(void)
143 {
144     MXC_GCR->memckcn |= (MXC_F_GCR_MEMCKCN_SYSRAM0LS);
145 }
146 
LP_DisableSysRAM0LightSleep(void)147 void LP_DisableSysRAM0LightSleep(void)
148 {
149     MXC_GCR->memckcn &= ~(MXC_F_GCR_MEMCKCN_SYSRAM0LS);
150 }
151 
LP_EnableRTCAlarmWakeup(void)152 void LP_EnableRTCAlarmWakeup(void)
153 {
154     MXC_GCR->pm |= MXC_F_GCR_PM_RTCWKEN;
155 }
156 
LP_DisableRTCAlarmWakeup(void)157 void LP_DisableRTCAlarmWakeup(void)
158 {
159     MXC_GCR->pm &= ~MXC_F_GCR_PM_RTCWKEN;
160 }
161 
LP_EnableGPIOWakeup(const gpio_cfg_t * wu_pins)162 void LP_EnableGPIOWakeup(const gpio_cfg_t *wu_pins)
163 {
164     MXC_GCR->pm |= MXC_F_GCR_PM_GPIOWKEN;
165     switch(wu_pins->port)
166     {
167       case 0: MXC_PWRSEQ->lpwk_en |= wu_pins->mask; break;
168     }
169 }
170 
LP_DisableGPIOWakeup(const gpio_cfg_t * wu_pins)171 void LP_DisableGPIOWakeup(const gpio_cfg_t *wu_pins)
172 {
173     switch(wu_pins->port)
174     {
175       case 0: MXC_PWRSEQ->lpwk_en &= ~wu_pins->mask; break;
176     }
177 
178     if(MXC_PWRSEQ->lpwk_en == 0)
179     {
180         MXC_GCR->pm &= ~MXC_F_GCR_PM_GPIOWKEN;
181     }
182 }
183 
LP_EnterSleepMode(void)184 void LP_EnterSleepMode(void)
185 {
186     // Clear SLEEPDEEP bit
187     SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
188 
189     // Go into Sleep mode and wait for an interrupt to wake the processor
190     __WFI();
191 }
192 
LP_EnterDeepSleepMode(void)193 void LP_EnterDeepSleepMode(void)
194 {
195     // Set SLEEPDEEP bit
196     SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
197 
198     // Auto-powerdown 96 MHz oscillator when in deep sleep
199     MXC_GCR->pm |= MXC_F_GCR_PM_HIRCPD;
200     // Go into Deepsleep mode and wait for an interrupt to wake the processor
201     __WFI();
202 }
203 
LP_EnterBackupMode(void)204 void LP_EnterBackupMode(void)
205 {
206     MXC_GCR->pm &= ~MXC_F_GCR_PM_MODE;
207     MXC_GCR->pm |= MXC_S_GCR_PM_MODE_BACKUP;
208     while(1);
209 }
210 
LP_EnterShutdownMode(void)211 void LP_EnterShutdownMode(void)
212 {
213     MXC_GCR->pm &= ~MXC_F_GCR_PM_MODE;
214     MXC_GCR->pm |= MXC_S_GCR_PM_MODE_SHUTDOWN;
215     while(1);
216 }
LP_SetOperatingVoltage(lp_ovr_t ovr)217 void LP_SetOperatingVoltage(lp_ovr_t ovr)
218 {
219     uint32_t div;
220 
221     //Set flash wait state for any clock so its not to low after clock changes.
222     MXC_GCR->memckcn = (MXC_GCR->memckcn & ~(MXC_F_GCR_MEMCKCN_FWS)) | (0x5UL << MXC_F_GCR_MEMCKCN_FWS_POS);
223 
224     //set the OVR bits
225     MXC_PWRSEQ->lp_ctrl &= ~(MXC_F_PWRSEQ_LP_CTRL_OVR);
226     MXC_PWRSEQ->lp_ctrl |= ovr;
227 
228     //Set LVE bit
229     if(ovr == LP_OVR_0_9){
230         MXC_FLC->cn |= MXC_F_FLC_CN_LVE;
231     }
232     else{
233         MXC_FLC->cn &= ~(MXC_F_FLC_CN_LVE);
234     }
235 
236     // Update SystemCoreClock variable
237     SystemCoreClockUpdate();
238 
239     // Get the clock divider
240     div = (MXC_GCR->clkcn & MXC_F_GCR_CLKCN_PSC) >> MXC_F_GCR_CLKCN_PSC_POS;
241 
242     //Set Flash Wait States
243     if(ovr == LP_OVR_0_9){
244 
245         if(div == 0){
246             MXC_GCR->memckcn = (MXC_GCR->memckcn & ~(MXC_F_GCR_MEMCKCN_FWS)) | (0x2UL << MXC_F_GCR_MEMCKCN_FWS_POS);
247 
248         } else{
249             MXC_GCR->memckcn = (MXC_GCR->memckcn & ~(MXC_F_GCR_MEMCKCN_FWS)) | (0x1UL << MXC_F_GCR_MEMCKCN_FWS_POS);
250 
251         }
252 
253     } else if( ovr == LP_OVR_1_0){
254         if(div == 0){
255             MXC_GCR->memckcn = (MXC_GCR->memckcn & ~(MXC_F_GCR_MEMCKCN_FWS)) | (0x2UL << MXC_F_GCR_MEMCKCN_FWS_POS);
256 
257         } else{
258             MXC_GCR->memckcn = (MXC_GCR->memckcn & ~(MXC_F_GCR_MEMCKCN_FWS)) | (0x1UL << MXC_F_GCR_MEMCKCN_FWS_POS);
259 
260         }
261 
262     } else {
263 
264         if(div == 0){
265             MXC_GCR->memckcn = (MXC_GCR->memckcn & ~(MXC_F_GCR_MEMCKCN_FWS)) | (0x4UL << MXC_F_GCR_MEMCKCN_FWS_POS);
266         } else if(div == 1){
267             MXC_GCR->memckcn = (MXC_GCR->memckcn & ~(MXC_F_GCR_MEMCKCN_FWS)) | (0x2UL << MXC_F_GCR_MEMCKCN_FWS_POS);
268 
269         } else{
270             MXC_GCR->memckcn = (MXC_GCR->memckcn & ~(MXC_F_GCR_MEMCKCN_FWS)) | (0x1UL << MXC_F_GCR_MEMCKCN_FWS_POS);
271 
272         }
273     }
274 
275 }
276 
LP_EnableSRamRet0(void)277 void LP_EnableSRamRet0(void){
278     MXC_PWRSEQ->lp_ctrl |= MXC_F_PWRSEQ_LP_CTRL_RAMRET_SEL0;
279 }
280 
LP_DisableSRamRet0(void)281 void LP_DisableSRamRet0(void){
282     MXC_PWRSEQ->lp_ctrl &= ~MXC_F_PWRSEQ_LP_CTRL_RAMRET_SEL0;
283 }
284 
LP_EnableSRamRet1(void)285 void LP_EnableSRamRet1(void){
286     MXC_PWRSEQ->lp_ctrl |= MXC_F_PWRSEQ_LP_CTRL_RAMRET_SEL1;
287 }
288 
LP_DisableSRamRet1(void)289 void LP_DisableSRamRet1(void){
290     MXC_PWRSEQ->lp_ctrl &= ~MXC_F_PWRSEQ_LP_CTRL_RAMRET_SEL1;
291 }
292 
LP_EnableSRamRet2(void)293 void LP_EnableSRamRet2(void){
294     MXC_PWRSEQ->lp_ctrl |= MXC_F_PWRSEQ_LP_CTRL_RAMRET_SEL2;
295 }
296 
LP_DisableSRamRet2(void)297 void LP_DisableSRamRet2(void){
298     MXC_PWRSEQ->lp_ctrl &= ~MXC_F_PWRSEQ_LP_CTRL_RAMRET_SEL2;
299 }
300 
LP_EnableSRamRet3(void)301 void LP_EnableSRamRet3(void){
302     MXC_PWRSEQ->lp_ctrl |= MXC_F_PWRSEQ_LP_CTRL_RAMRET_SEL3;
303 }
304 
LP_DisableSRamRet3(void)305 void LP_DisableSRamRet3(void){
306     MXC_PWRSEQ->lp_ctrl &= ~MXC_F_PWRSEQ_LP_CTRL_RAMRET_SEL3;
307 }
308 
LP_EnableBlockDetect(void)309 void LP_EnableBlockDetect(void){
310     MXC_PWRSEQ->lp_ctrl &= ~MXC_F_PWRSEQ_LP_CTRL_VCORE_DET_BYPASS;
311 }
312 
LP_DisableBlockDetect(void)313 void LP_DisableBlockDetect(void){
314     MXC_PWRSEQ->lp_ctrl |= MXC_F_PWRSEQ_LP_CTRL_VCORE_DET_BYPASS;
315 }
316 
LP_EnableRamRetReg(void)317 void LP_EnableRamRetReg(void){
318     MXC_PWRSEQ->lp_ctrl |= MXC_F_PWRSEQ_LP_CTRL_RETREG_EN;
319 }
320 
LP_DisableRamRetReg(void)321 void LP_DisableRamRetReg(void){
322     MXC_PWRSEQ->lp_ctrl &= ~MXC_F_PWRSEQ_LP_CTRL_RETREG_EN;
323 }
324 
LP_EnableFastWk(void)325 void LP_EnableFastWk(void){
326     MXC_PWRSEQ->lp_ctrl |= MXC_F_PWRSEQ_LP_CTRL_FAST_WK_EN;
327 }
328 
LP_DisableFastWk(void)329 void LP_DisableFastWk(void){
330     MXC_PWRSEQ->lp_ctrl &= ~MXC_F_PWRSEQ_LP_CTRL_FAST_WK_EN;
331 }
332 
LP_EnableBandGap(void)333 void LP_EnableBandGap(void){
334     MXC_PWRSEQ->lp_ctrl &= ~MXC_F_PWRSEQ_LP_CTRL_BG_OFF;
335 }
336 
LP_DisableBandGap(void)337 void LP_DisableBandGap(void){
338     MXC_PWRSEQ->lp_ctrl |= MXC_F_PWRSEQ_LP_CTRL_BG_OFF;
339 }
340 
LP_EnableVCorePORSignal(void)341 void LP_EnableVCorePORSignal(void){
342     MXC_PWRSEQ->lp_ctrl &= ~MXC_F_PWRSEQ_LP_CTRL_VCORE_POR_DIS;
343 }
344 
LP_DisableVCorePORSignal(void)345 void LP_DisableVCorePORSignal(void){
346     MXC_PWRSEQ->lp_ctrl |= MXC_F_PWRSEQ_LP_CTRL_VCORE_POR_DIS;
347 }
348 
LP_EnableLDO(void)349 void LP_EnableLDO(void){
350     MXC_PWRSEQ->lp_ctrl &= ~MXC_F_PWRSEQ_LP_CTRL_LDO_DIS;
351 }
352 
LP_DisableLDO(void)353 void LP_DisableLDO(void){
354     MXC_PWRSEQ->lp_ctrl |= MXC_F_PWRSEQ_LP_CTRL_LDO_DIS;
355 }
356 
LP_EnableVCoreSVM(void)357 void LP_EnableVCoreSVM(void){
358     MXC_PWRSEQ->lp_ctrl &= ~MXC_F_PWRSEQ_LP_CTRL_VCORE_SVM_DIS;
359 }
360 
LP_DisableVCoreSVM(void)361 void LP_DisableVCoreSVM(void){
362     MXC_PWRSEQ->lp_ctrl |= MXC_F_PWRSEQ_LP_CTRL_VCORE_SVM_DIS;
363 }
364 
LP_EnableVDDIOPorMonitoF(void)365 void LP_EnableVDDIOPorMonitoF(void){
366     MXC_PWRSEQ->lp_ctrl &= ~MXC_F_PWRSEQ_LP_CTRL_VDDIO_POR_DIS;
367 }
368 
LP_DisableVDDIOPorMonitor(void)369 void LP_DisableVDDIOPorMonitor(void){
370     MXC_PWRSEQ->lp_ctrl |= MXC_F_PWRSEQ_LP_CTRL_VDDIO_POR_DIS;
371 }
372