1 /*
2 * Copyright 2019-2024 NXP.
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_wuu.h"
9
10 /*******************************************************************************
11 * Definitions
12 ******************************************************************************/
13
14 /* Component ID definition, used by tools. */
15 #ifndef FSL_COMPONENT_ID
16 #define FSL_COMPONENT_ID "platform.drivers.wuu"
17 #endif
18
19 #define WUU_PE_REG_BIT_FIELD_MASK 0x03UL
20 #define WUU_PDC_REG_BIT_FIELD_MASK 0x03UL
21 #define WUU_PMC_REG_BIT_FIELD_MASK 0x01UL
22
23 #define WUU_ME_REG_WUME_FIELD_MASK 0x01UL
24 #define WUU_DE_REG_WUME_FIELD_MASK 0x01UL
25
26 #define WUU_FILT_REG_FILTE_FIELD_MASK 0x60U
27 #define WUU_FILT_REG_FILTSET_FIELD_MASK 0x1FU
28 #define WUU_FDC_REG_FILTC_FIELD_MASK 0x3U
29 #define WUU_FMC_REG_FILTM_FIELD_MASK 0x1U
30
31 #define WUU_FILT_REG_FILTSET_FIELD(x) (((uint32_t)(x) << 5UL) & WUU_FILT_REG_FILTE_FIELD_MASK)
32 #define WUU_CLEAR_BIT_FIELD_IN_REG(mask, offset) (~((uint32_t)(mask) << (offset)))
33 #define WUU_SET_BIT_FIELD_IN_REG(val, offset) ((uint32_t)(val) << (offset))
34 /*******************************************************************************
35 * Prototypes
36 ******************************************************************************/
37
38 /*******************************************************************************
39 * Variables
40 ******************************************************************************/
41
42 /*******************************************************************************
43 * Code
44 ******************************************************************************/
45
46 /*!
47 * brief Enables and Configs External WakeUp Pins.
48 *
49 * This function enables/disables the external pin as wakeup input. What's more this
50 * function configs pins options, including edge detection wakeup event and operate mode.
51 *
52 * param base MUU peripheral base address.
53 * param pinIndex The index of the external input pin. See Reference Manual for the details.
54 * param config Pointer to wuu_external_wakeup_pin_config_t structure.
55 */
WUU_SetExternalWakeUpPinsConfig(WUU_Type * base,uint8_t pinIndex,const wuu_external_wakeup_pin_config_t * config)56 void WUU_SetExternalWakeUpPinsConfig(WUU_Type *base, uint8_t pinIndex, const wuu_external_wakeup_pin_config_t *config)
57 {
58 assert(config != NULL);
59
60 volatile uint32_t *edgeRegBase = NULL;
61 volatile uint32_t *eventRegBase = NULL;
62 uint32_t edgeReg;
63 uint32_t eventReg;
64 uint32_t modeReg;
65 uint8_t offset;
66
67 /* Calculate offset. */
68 offset = 2U * (pinIndex & 0xFU);
69
70 if (config->edge != kWUU_ExternalPinDisable)
71 {
72 /* Based on pin index, get register base address. */
73 if ((pinIndex >> 4U) != 0U)
74 {
75 edgeRegBase = &base->PE2;
76 eventRegBase = &base->PDC2;
77 }
78 else
79 {
80 edgeRegBase = &base->PE1;
81 eventRegBase = &base->PDC1;
82 }
83
84 /* Enable and config the edge detection. */
85 edgeReg = *edgeRegBase;
86 edgeReg &= WUU_CLEAR_BIT_FIELD_IN_REG(WUU_PE_REG_BIT_FIELD_MASK, offset);
87 edgeReg |= WUU_SET_BIT_FIELD_IN_REG(config->edge, offset);
88 *edgeRegBase = edgeReg;
89
90 /* Config the wakeup event. */
91 eventReg = *eventRegBase;
92 eventReg &= WUU_CLEAR_BIT_FIELD_IN_REG(WUU_PDC_REG_BIT_FIELD_MASK, offset);
93 eventReg |= WUU_SET_BIT_FIELD_IN_REG(config->event, offset);
94 *eventRegBase = eventReg;
95
96 /* Config operate mode. */
97 modeReg = base->PMC;
98 modeReg &= WUU_CLEAR_BIT_FIELD_IN_REG(WUU_PMC_REG_BIT_FIELD_MASK, pinIndex);
99 modeReg |= WUU_SET_BIT_FIELD_IN_REG(config->mode, pinIndex);
100
101 base->PMC = modeReg;
102 }
103 else
104 {
105 /* Based on pin index, get register base address. */
106 if ((pinIndex >> 4U) != 0U)
107 {
108 edgeRegBase = &base->PE2;
109 }
110 else
111 {
112 edgeRegBase = &base->PE1;
113 }
114
115 edgeReg = *edgeRegBase;
116 edgeReg &= WUU_CLEAR_BIT_FIELD_IN_REG(WUU_PE_REG_BIT_FIELD_MASK, offset);
117 *edgeRegBase = edgeReg;
118 }
119 }
120
121 /*!
122 * brief Disable and clear external wakeup pin settings.
123 *
124 * param base MUU peripheral base address.
125 * param pinIndex The index of the external input pin.
126 */
WUU_ClearExternalWakeupPinsConfig(WUU_Type * base,uint8_t pinIndex)127 void WUU_ClearExternalWakeupPinsConfig(WUU_Type *base, uint8_t pinIndex)
128 {
129 if (pinIndex <= 15U)
130 {
131 base->PE1 &= ~(WUU_PE_REG_BIT_FIELD_MASK << (2UL * (uint32_t)pinIndex));
132 base->PDC1 &= ~(WUU_PDC_REG_BIT_FIELD_MASK << (2UL * (uint32_t)pinIndex));
133 }
134 else
135 {
136 base->PE1 &= ~(WUU_PE_REG_BIT_FIELD_MASK << (2UL * (uint32_t)((uint32_t)pinIndex % 16UL)));
137 base->PDC1 &= ~(WUU_PDC_REG_BIT_FIELD_MASK << (2UL * (uint32_t)((uint32_t)pinIndex % 16UL)));
138 }
139 }
140
141 /*!
142 * brief Config Internal modules' event as the wake up soures.
143 *
144 * This function configs the internal modules event as the wake up sources.
145 *
146 * param base WUU peripheral base address.
147 * param moduleIndex The selected internal module. See the Reference Manual for the details.
148 * param event Select interrupt or DMA/Trigger of the internal module as the wake up source.
149 */
WUU_SetInternalWakeUpModulesConfig(WUU_Type * base,uint8_t moduleIndex,wuu_internal_wakeup_module_event_t event)150 void WUU_SetInternalWakeUpModulesConfig(WUU_Type *base, uint8_t moduleIndex, wuu_internal_wakeup_module_event_t event)
151 {
152 switch (event)
153 {
154 case kWUU_InternalModuleInterrupt:
155 base->ME |= WUU_SET_BIT_FIELD_IN_REG(WUU_ME_REG_WUME_FIELD_MASK, moduleIndex);
156 break;
157 case kWUU_InternalModuleDMATrigger:
158 base->DE |= WUU_SET_BIT_FIELD_IN_REG(WUU_DE_REG_WUME_FIELD_MASK, moduleIndex);
159 break;
160 default:
161 assert(false);
162 break;
163 }
164 }
165
166 /*!
167 * brief Disable an on-chip internal modules' event as the wakeup sources.
168 *
169 * param base WUU peripheral base address.
170 * param moduleIndex The selected internal module. See the Reference Manual for the details.
171 * param event The event(interrupt or DMA/trigger) of the internal module to disable.
172 */
WUU_ClearInternalWakeUpModulesConfig(WUU_Type * base,uint8_t moduleIndex,wuu_internal_wakeup_module_event_t event)173 void WUU_ClearInternalWakeUpModulesConfig(WUU_Type *base, uint8_t moduleIndex, wuu_internal_wakeup_module_event_t event)
174 {
175 switch(event)
176 {
177 case kWUU_InternalModuleInterrupt:
178 base->ME &= ~WUU_SET_BIT_FIELD_IN_REG(WUU_ME_REG_WUME_FIELD_MASK, moduleIndex);
179 break;
180 case kWUU_InternalModuleDMATrigger:
181 base->DE &= ~WUU_SET_BIT_FIELD_IN_REG(WUU_DE_REG_WUME_FIELD_MASK, moduleIndex);
182 break;
183 default:
184 assert(false);
185 break;
186 }
187 }
188
189 /*!
190 * brief Configs and Enables Pin filters.
191 *
192 * This function configs Pin filter, including pin select, filer operate mode
193 * filer wakeup event and filter edge detection.
194 *
195 * param base WUU peripheral base address.
196 * param filterIndex The index of the pin filer.
197 * param config Pointer to wuu_pin_filter_config_t structure.
198 */
WUU_SetPinFilterConfig(WUU_Type * base,uint8_t filterIndex,const wuu_pin_filter_config_t * config)199 void WUU_SetPinFilterConfig(WUU_Type *base, uint8_t filterIndex, const wuu_pin_filter_config_t *config)
200 {
201 assert(config != NULL);
202
203 uint8_t shift;
204 uint32_t filterReg;
205 uint32_t eventReg;
206 uint32_t modeReg;
207
208 shift = (filterIndex - 1U) * 8U;
209 filterReg = base->FILT;
210 filterReg &= WUU_CLEAR_BIT_FIELD_IN_REG(WUU_FILT_REG_FILTE_FIELD_MASK, shift);
211 filterReg |= WUU_SET_BIT_FIELD_IN_REG(WUU_FILT_REG_FILTSET_FIELD(config->edge), shift);
212
213 if (config->edge != kWUU_FilterDisabled)
214 {
215 filterReg &= WUU_CLEAR_BIT_FIELD_IN_REG(WUU_FILT_REG_FILTSET_FIELD_MASK, shift);
216 filterReg |= WUU_SET_BIT_FIELD_IN_REG(config->pinIndex, shift);
217
218 /* Config wake up event. */
219 shift = (filterIndex - 1U) * 2U;
220 eventReg = base->FDC;
221 eventReg &= WUU_CLEAR_BIT_FIELD_IN_REG(WUU_FDC_REG_FILTC_FIELD_MASK, shift);
222 eventReg |= WUU_SET_BIT_FIELD_IN_REG(config->event, shift);
223 base->FDC = eventReg;
224
225 /* Config operate mode. */
226 shift = (filterIndex - 1U) * 1U;
227 modeReg = base->FMC;
228 modeReg &= WUU_CLEAR_BIT_FIELD_IN_REG(WUU_FMC_REG_FILTM_FIELD_MASK, shift);
229 modeReg |= WUU_SET_BIT_FIELD_IN_REG(config->mode, shift);
230 base->FMC = modeReg;
231 }
232
233 base->FILT = filterReg;
234 }
235
236 /*!
237 * brief Gets the pin filter configuration.
238 *
239 * This function gets the pin filter flag.
240 *
241 * param base WUU peripheral base address.
242 * param filterIndex A pin filter index, which starts from 1.
243 * return True if the flag is a source of the existing low-leakage power mode.
244 */
WUU_GetPinFilterFlag(WUU_Type * base,uint8_t filterIndex)245 bool WUU_GetPinFilterFlag(WUU_Type *base, uint8_t filterIndex)
246 {
247 bool ret = false;
248
249 switch (filterIndex)
250 {
251 case 1:
252 ret = ((base->FILT & WUU_FILT_FILTF1_MASK) != 0U);
253 break;
254 case 2:
255 ret = ((base->FILT & WUU_FILT_FILTF2_MASK) != 0U);
256 break;
257 default:
258 ret = false;
259 break;
260 }
261
262 return ret;
263 }
264
265 /*!
266 * brief Clears the pin filter configuration.
267 *
268 * This function clears the pin filter flag.
269 *
270 * param base WUU peripheral base address.
271 * param filterIndex A pin filter index to clear the flag, starting from 1.
272 */
WUU_ClearPinFilterFlag(WUU_Type * base,uint8_t filterIndex)273 void WUU_ClearPinFilterFlag(WUU_Type *base, uint8_t filterIndex)
274 {
275 uint32_t reg;
276
277 reg = base->FILT;
278 /* Clean the W1C bits, in case the flags are cleared by mistake. */
279 reg &= ~(WUU_FILT_FILTF1_MASK | WUU_FILT_FILTF2_MASK);
280
281 reg |= WUU_SET_BIT_FIELD_IN_REG(WUU_FILT_FILTF1_MASK, ((filterIndex - 1U) * 8U));
282
283 base->FILT = reg;
284 }
285
286 /*!
287 * brief Gets the external wakeup source flag.
288 *
289 * This function checks the external pin flag to detect whether the MCU is
290 * woken up by the specific pin.
291 *
292 * param base WUU peripheral base address.
293 * param pinIndex A pin index, which starts from 0.
294 * return True if the specific pin is a wakeup source.
295 */
WUU_GetExternalWakeupPinFlag(WUU_Type * base,uint32_t pinIndex)296 bool WUU_GetExternalWakeupPinFlag(WUU_Type *base, uint32_t pinIndex)
297 {
298 return (0U != (base->PF & (1UL << pinIndex)));
299 }
300
301 /*!
302 * brief Clears the external wakeup source flag.
303 *
304 * This function clears the external wakeup source flag for a specific pin.
305 *
306 * param base WUU peripheral base address.
307 * param pinIndex A pin index, which starts from 0.
308 */
WUU_ClearExternalWakeupPinFlag(WUU_Type * base,uint32_t pinIndex)309 void WUU_ClearExternalWakeupPinFlag(WUU_Type *base, uint32_t pinIndex)
310 {
311 base->PF = (1UL << pinIndex);
312 }
313