aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/ext/mcux-sdk/devices/LPC824/drivers/fsl_power.h
blob: 1807d5830a8b145727bbb4fdfcb1bbf71abcbf7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
/*
 * Copyright (c) 2016, Freescale Semiconductor, Inc.
 * Copyright 2016-2018, 2020 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#ifndef _FSL_POWER_H_
#define _FSL_POWER_H_

#include "fsl_common.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*!
 * @addtogroup power
 * @{
 */

/*! @name Driver version */
/*@{*/
/*! @brief power driver version 2.0.4. */
#define FSL_POWER_DRIVER_VERSION (MAKE_VERSION(2, 0, 4))
/*@}*/

/*! @brief PMU PCON reserved mask, used to clear reserved field which should not write 1*/
#define PMUC_PCON_RESERVED_MASK ((0xf << 4) | (0x6 << 8) | 0xfffff000u)

#define POWER_EnbaleLPO                    POWER_EnableLPO
#define POWER_EnbaleLPOInDeepPowerDownMode POWER_EnableLPOInDeepPowerDownMode

typedef enum pd_bits
{
    kPDRUNCFG_PD_IRC_OUT = SYSCON_PDRUNCFG_IRCOUT_PD_MASK,
    kPDRUNCFG_PD_IRC     = SYSCON_PDRUNCFG_IRC_PD_MASK,
    kPDRUNCFG_PD_FLASH   = SYSCON_PDRUNCFG_FLASH_PD_MASK,
    kPDRUNCFG_PD_BOD     = SYSCON_PDRUNCFG_BOD_PD_MASK,
    kPDRUNCFG_PD_ADC0    = SYSCON_PDRUNCFG_ADC_PD_MASK,
    kPDRUNCFG_PD_SYSOSC  = SYSCON_PDRUNCFG_SYSOSC_PD_MASK,
    kPDRUNCFG_PD_WDT_OSC = SYSCON_PDRUNCFG_WDTOSC_PD_MASK,
    kPDRUNCFG_PD_SYSPLL  = SYSCON_PDRUNCFG_SYSPLL_PD_MASK,
    kPDRUNCFG_PD_ACMP    = SYSCON_PDRUNCFG_ACMP_MASK,

    /*
    This enum member has no practical meaning,it is used to avoid MISRA issue,
    user should not trying to use it.
    */
    kPDRUNCFG_ForceUnsigned = (int)0x80000000U,
} pd_bit_t;

/*! @brief Deep sleep and power down mode wake up configurations */
enum _power_wakeup
{
    kPDAWAKECFG_Wakeup_IRC_OUT = SYSCON_PDAWAKECFG_IRCOUT_PD_MASK,
    kPDAWAKECFG_Wakeup_IRC     = SYSCON_PDAWAKECFG_IRC_PD_MASK,
    kPDAWAKECFG_Wakeup_FLASH   = SYSCON_PDAWAKECFG_FLASH_PD_MASK,
    kPDAWAKECFG_Wakeup_BOD     = SYSCON_PDAWAKECFG_BOD_PD_MASK,
    kPDAWAKECFG_Wakeup_ADC     = SYSCON_PDAWAKECFG_ADC_PD_MASK,
    kPDAWAKECFG_Wakeup_SYSOSC  = SYSCON_PDAWAKECFG_SYSOSC_PD_MASK,
    kPDAWAKECFG_Wakeup_WDT_OSC = SYSCON_PDAWAKECFG_WDTOSC_PD_MASK,
    kPDAWAKECFG_Wakeup_SYSPLL  = SYSCON_PDAWAKECFG_SYSPLL_PD_MASK,
    kPDAWAKECFG_Wakeup_ACMP    = SYSCON_PDAWAKECFG_ACMP_MASK,
};

/*! @brief Deep sleep/power down mode active part */
enum _power_deep_sleep_active
{
    kPDSLEEPCFG_DeepSleepBODActive    = SYSCON_PDSLEEPCFG_BOD_PD_MASK,
    kPDSLEEPCFG_DeepSleepWDTOscActive = SYSCON_PDSLEEPCFG_WDTOSC_PD_MASK,
};

/*! @brief pmu general purpose register index */
typedef enum _power_gen_reg
{
    kPmu_GenReg0 = 0U, /*!< general purpose register0 */
    kPmu_GenReg1 = 1U, /*!< general purpose register1 */
    kPmu_GenReg2 = 2U, /*!< general purpose register2 */
    kPmu_GenReg3 = 3U, /*!< general purpose register3 */
    kPmu_GenReg4 = 4U, /*!< DPDCTRL bit 31-4 */
} power_gen_reg_t;

/* Power mode configuration API parameter */
typedef enum _power_mode_config
{
    kPmu_Sleep          = 0U,
    kPmu_Deep_Sleep     = 1U,
    kPmu_PowerDown      = 2U,
    kPmu_Deep_PowerDown = 3U,
} power_mode_cfg_t;

/*******************************************************************************
 * API
 ******************************************************************************/

#ifdef __cplusplus
extern "C" {
#endif

/*!
 * @name SYSCON Power Configuration
 * @{
 */

/*!
 * @brief API to enable PDRUNCFG bit in the Syscon. Note that enabling the bit powers down the peripheral
 *
 * @param en    peripheral for which to enable the PDRUNCFG bit
 * @return none
 */
static inline void POWER_EnablePD(pd_bit_t en)
{
    SYSCON->PDRUNCFG |= (uint32_t)en;
}

/*!
 * @brief API to disable PDRUNCFG bit in the Syscon. Note that disabling the bit powers up the peripheral
 *
 * @param en    peripheral for which to disable the PDRUNCFG bit
 * @return none
 */
static inline void POWER_DisablePD(pd_bit_t en)
{
    SYSCON->PDRUNCFG &= ~(uint32_t)en;
}

/*!
 * @brief API to config wakeup configurations for deep sleep mode and power down mode.
 *
 * @param mask: wake up configurations for deep sleep mode and power down mode, reference _power_wakeup.
 * @param powerDown: true is power down the mask part, false is powered part.
 */
static inline void POWER_WakeUpConfig(uint32_t mask, bool powerDown)
{
    if (powerDown)
    {
        SYSCON->PDAWAKECFG |= mask;
    }
    else
    {
        SYSCON->PDAWAKECFG &= ~mask;
    }
}

/*!
 * @brief API to config active part for deep sleep mode and power down mode.
 *
 * @param mask: active part configurations for deep sleep mode and power down mode, reference _power_deep_sleep_active.
 * @param powerDown: true is power down the mask part, false is powered part.
 */
static inline void POWER_DeepSleepConfig(uint32_t mask, bool powerDown)
{
    if (powerDown)
    {
        SYSCON->PDSLEEPCFG |= mask;
    }
    else
    {
        SYSCON->PDSLEEPCFG &= ~mask;
    }
}

/* @} */

/*!
 * @name ARM core Power Configuration
 * @{
 */

/*!
 * @brief API to enable deep sleep bit in the ARM Core.
 *
 * @return none
 */
static inline void POWER_EnableDeepSleep(void)
{
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
}

/*!
 * @brief API to disable deep sleep bit in the ARM Core.
 *
 * @return none
 */
static inline void POWER_DisableDeepSleep(void)
{
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
}

/* @} */

/*!
 * @name PMU functionality
 * @{
 */

/*!
 * @brief API to enter sleep power mode.
 *
 * @return none
 */
void POWER_EnterSleep(void);

/*!
 * @brief API to enter deep sleep power mode.
 *
 * @param activePart: should be a single or combine value of _power_deep_sleep_active .
 * @return none
 */
void POWER_EnterDeepSleep(uint32_t activePart);

/*!
 * @brief API to enter power down mode.
 *
 * @param activePart: should be a single or combine value of _power_deep_sleep_active .
 * @return none
 */
void POWER_EnterPowerDown(uint32_t activePart);

/*!
 * @brief API to enter deep power down mode.
 *
 * @return none
 */
void POWER_EnterDeepPowerDownMode(void);

/*!
 * @brief API to get sleep mode flag.
 *
 * @return sleep mode flag: 0 is active mode, 1 is sleep mode entered.
 */
static inline uint32_t POWER_GetSleepModeFlag(void)
{
    return (PMU->PCON & PMU_PCON_SLEEPFLAG_MASK) >> PMU_PCON_SLEEPFLAG_SHIFT;
}

/*!
 * @brief API to clear sleep mode flag.
 *
 */
static inline void POWER_ClrSleepModeFlag(void)
{
    PMU->PCON |= PMU_PCON_SLEEPFLAG_MASK;
}

/*!
 * @brief API to get deep power down mode flag.
 *
 * @return sleep mode flag: 0 not deep power down, 1 is deep power down mode entered.
 */
static inline uint32_t POWER_GetDeepPowerDownModeFlag(void)
{
    return (PMU->PCON & PMU_PCON_DPDFLAG_MASK) >> PMU_PCON_DPDFLAG_SHIFT;
}

/*!
 * @brief API to clear deep power down mode flag.
 *
 */
static inline void POWER_ClrDeepPowerDownModeFlag(void)
{
    PMU->PCON |= PMU_PCON_DPDFLAG_MASK;
}

/*!
 * @brief API to enable non deep power down mode.
 *
 * @param enable: true is enable non deep power down, otherwise disable.
 */
static inline void POWER_EnableNonDpd(bool enable)
{
    if (enable)
    {
        PMU->PCON |= PMU_PCON_NODPD_MASK;
    }
    else
    {
        PMU->PCON &= ~PMU_PCON_NODPD_MASK;
    }
}

/*!
 * @brief API to enable LPO.
 *
 * @param enable: true to enable LPO, false to disable LPO.
 */
static inline void POWER_EnableLPO(bool enable)
{
    if (enable)
    {
        PMU->DPDCTRL |= PMU_DPDCTRL_LPOSCEN_MASK;
    }
    else
    {
        PMU->DPDCTRL &= ~PMU_DPDCTRL_LPOSCEN_MASK;
    }
}

/*!
 * @brief API to enable LPO in deep power down mode.
 *
 * @param enable: true to enable LPO, false to disable LPO.
 */
static inline void POWER_EnableLPOInDeepPowerDownMode(bool enable)
{
    if (enable)
    {
        PMU->DPDCTRL |= PMU_DPDCTRL_LPOSCDPDEN_MASK;
    }
    else
    {
        PMU->DPDCTRL &= ~PMU_DPDCTRL_LPOSCDPDEN_MASK;
    }
}

/*!
 * @brief API to retore data to general purpose register which can be retain during deep power down mode.
 * Note the kPMU_GenReg4 can retore 3 byte data only, so the general purpose register can store 19bytes data.
 * @param index: general purpose data register index.
 * @param data: data to restore.
 */
static inline void POWER_SetRetainData(power_gen_reg_t index, uint32_t data)
{
    if (index <= kPmu_GenReg3)
    {
        PMU->GPREG[index] = data;
    }
    else
    {
        /* only 26 bits can store in GPDATA field */
        PMU->DPDCTRL = (PMU->DPDCTRL & (~PMU_DPDCTRL_GPDATA_MASK)) | PMU_DPDCTRL_GPDATA(data);
    }
}

/*!
 * @brief API to get data from general purpose register which retain during deep power down mode.
 * Note the kPMU_GenReg4 can retore 3 byte data only, so the general purpose register can store 19bytes data.
 * @param index: general purpose data register index.
 * @return data stored in the general purpose register.
 */
static inline uint32_t POWER_GetRetainData(power_gen_reg_t index)
{
    if (index == kPmu_GenReg4)
    {
        return (PMU->DPDCTRL & PMU_DPDCTRL_GPDATA_MASK) >> PMU_DPDCTRL_GPDATA_SHIFT;
    }

    return PMU->GPREG[index];
}

/*!
 * @brief API to enable external clock input for self wake up timer.
 *
 * @param enable: true is enable external clock input for self-wake-up timer, otherwise disable.
 * @param enHysteresis: true is enable Hysteresis for the pin, otherwise disable.
 */
static inline void POWER_EnableWktClkIn(bool enable, bool enHysteresis)
{
    PMU->DPDCTRL = (PMU->DPDCTRL & (~(PMU_DPDCTRL_WAKEUPCLKHYS_MASK | PMU_DPDCTRL_WAKECLKPAD_DISABLE_MASK))) |
                   PMU_DPDCTRL_WAKECLKPAD_DISABLE(enable) | PMU_DPDCTRL_WAKEUPCLKHYS(enHysteresis);
}

/*!
 * @brief API to enable wake up pin for deep power down mode.
 *
 * @param enable: true is enable, otherwise disable.
 * @param enHysteresis: true is enable Hysteresis for the pin, otherwise disable.
 */
static inline void POWER_EnableWakeupPinForDeepPowerDown(bool enable, bool enHysteresis)
{
    PMU->DPDCTRL = (PMU->DPDCTRL & (~(PMU_DPDCTRL_WAKEUPHYS_MASK | PMU_DPDCTRL_WAKEPAD_DISABLE_MASK))) |
                   PMU_DPDCTRL_WAKEPAD_DISABLE(!enable) | PMU_DPDCTRL_WAKEUPHYS(enHysteresis);
}

/* @} */

#ifdef __cplusplus
}
#endif

/*!
 * @}
 */

#endif /* _FSL_POWER_H_ */