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