1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2020 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_llwu.h"
10
11 /* Component ID definition, used by tools. */
12 #ifndef FSL_COMPONENT_ID
13 #define FSL_COMPONENT_ID "platform.drivers.llwu"
14 #endif
15
16 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN)
17 /*!
18 * brief Sets the external input pin source mode.
19 *
20 * This function sets the external input pin source mode that is used
21 * as a wake up source.
22 *
23 * param base LLWU peripheral base address.
24 * param pinIndex A pin index to be enabled as an external wakeup source starting from 1.
25 * param pinMode A pin configuration mode defined in the llwu_external_pin_modes_t.
26 */
LLWU_SetExternalWakeupPinMode(LLWU_Type * base,uint32_t pinIndex,llwu_external_pin_mode_t pinMode)27 void LLWU_SetExternalWakeupPinMode(LLWU_Type *base, uint32_t pinIndex, llwu_external_pin_mode_t pinMode)
28 {
29 #if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
30 volatile uint32_t *regBase;
31 uint32_t regOffset;
32 uint32_t reg;
33
34 switch (pinIndex >> 4U)
35 {
36 case 0U:
37 regBase = &base->PE1;
38 break;
39 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
40 case 1U:
41 regBase = &base->PE2;
42 break;
43 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
44 default:
45 regBase = NULL;
46 break;
47 }
48
49 if (NULL != regBase)
50 {
51 reg = *regBase;
52 regOffset = ((pinIndex & 0x0FU) << 1U);
53 reg &= LLWU_REG_VAL(~(3UL << regOffset));
54 reg |= ((uint32_t)pinMode << regOffset);
55 *regBase = reg;
56 }
57 #else
58 volatile uint8_t *regBase;
59 uint8_t regOffset;
60 uint8_t reg;
61 switch (pinIndex >> 2U)
62 {
63 case 0U:
64 regBase = &base->PE1;
65 break;
66 case 1U:
67 regBase = &base->PE2;
68 break;
69 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8))
70 case 2U:
71 regBase = &base->PE3;
72 break;
73 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
74 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 12))
75 case 3U:
76 regBase = &base->PE4;
77 break;
78 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
79 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
80 case 4U:
81 regBase = &base->PE5;
82 break;
83 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
84 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 20))
85 case 5U:
86 regBase = &base->PE6;
87 break;
88 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
89 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24))
90 case 6U:
91 regBase = &base->PE7;
92 break;
93 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
94 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 28))
95 case 7U:
96 regBase = &base->PE8;
97 break;
98 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
99 default:
100 regBase = NULL;
101 break;
102 }
103
104 if (NULL != regBase)
105 {
106 reg = *regBase;
107 regOffset = (uint8_t)((pinIndex & 0x03U) << 1U);
108 reg &= LLWU_REG_VAL(~(3UL << regOffset));
109 reg |= (uint8_t)((uint32_t)pinMode << regOffset);
110 *regBase = reg;
111 }
112 #endif /* FSL_FEATURE_LLWU_REG_BITWIDTH == 32 */
113 }
114
115 /*!
116 * brief Gets the external wakeup source flag.
117 *
118 * This function checks the external pin flag to detect whether the MCU is
119 * woken up by the specific pin.
120 *
121 * param base LLWU peripheral base address.
122 * param pinIndex A pin index, which starts from 1.
123 * return True if the specific pin is a wakeup source.
124 */
LLWU_GetExternalWakeupPinFlag(LLWU_Type * base,uint32_t pinIndex)125 bool LLWU_GetExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex)
126 {
127 #if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
128 return (0U != (base->PF & (1UL << pinIndex)));
129 #else
130 bool ret;
131 volatile uint8_t *regBase;
132
133 switch (pinIndex >> 3U)
134 {
135 #if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF)
136 case 0U:
137 regBase = &base->PF1;
138 break;
139 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8))
140 case 1U:
141 regBase = &base->PF2;
142 break;
143 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
144 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
145 case 2U:
146 regBase = &base->PF3;
147 break;
148 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
149 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24))
150 case 3U:
151 regBase = &base->PF4;
152 break;
153 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
154 #else
155 case 0U:
156 regBase = &base->F1;
157 break;
158 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8))
159 case 1U:
160 regBase = &base->F2;
161 break;
162 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
163 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
164 case 2U:
165 regBase = &base->F3;
166 break;
167 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
168 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24))
169 case 3U:
170 regBase = &base->F4;
171 break;
172 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
173 #endif /* FSL_FEATURE_LLWU_HAS_PF */
174 default:
175 regBase = NULL;
176 break;
177 }
178
179 if (NULL != regBase)
180 {
181 if (0U != (*regBase & (1U << pinIndex % 8U)))
182 {
183 ret = true;
184 }
185 else
186 {
187 ret = false;
188 }
189 }
190 else
191 {
192 ret = false;
193 }
194
195 return ret;
196 #endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
197 }
198
199 /*!
200 * brief Clears the external wakeup source flag.
201 *
202 * This function clears the external wakeup source flag for a specific pin.
203 *
204 * param base LLWU peripheral base address.
205 * param pinIndex A pin index, which starts from 1.
206 */
LLWU_ClearExternalWakeupPinFlag(LLWU_Type * base,uint32_t pinIndex)207 void LLWU_ClearExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex)
208 {
209 #if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
210 base->PF = (1UL << pinIndex);
211 #else
212 volatile uint8_t *regBase;
213 switch (pinIndex >> 3U)
214 {
215 #if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF)
216 case 0U:
217 regBase = &base->PF1;
218 break;
219 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8))
220 case 1U:
221 regBase = &base->PF2;
222 break;
223 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
224 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
225 case 2U:
226 regBase = &base->PF3;
227 break;
228 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
229 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24))
230 case 3U:
231 regBase = &base->PF4;
232 break;
233 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
234 #else
235 case 0U:
236 regBase = &base->F1;
237 break;
238 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8))
239 case 1U:
240 regBase = &base->F2;
241 break;
242 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
243 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
244 case 2U:
245 regBase = &base->F3;
246 break;
247 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
248 #if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24))
249 case 3U:
250 regBase = &base->F4;
251 break;
252 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
253 #endif /* FSL_FEATURE_LLWU_HAS_PF */
254 default:
255 regBase = NULL;
256 break;
257 }
258 if (NULL != regBase)
259 {
260 *regBase = (1U << pinIndex % 8U);
261 }
262 #endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
263 }
264 #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
265
266 #if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && FSL_FEATURE_LLWU_HAS_PIN_FILTER)
267 /*!
268 * brief Sets the pin filter configuration.
269 *
270 * This function sets the pin filter configuration.
271 *
272 * param base LLWU peripheral base address.
273 * param filterIndex A pin filter index used to enable/disable the digital filter, starting from 1.
274 * param filterMode A filter mode configuration
275 */
LLWU_SetPinFilterMode(LLWU_Type * base,uint32_t filterIndex,llwu_external_pin_filter_mode_t filterMode)276 void LLWU_SetPinFilterMode(LLWU_Type *base, uint32_t filterIndex, llwu_external_pin_filter_mode_t filterMode)
277 {
278 #if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
279 uint32_t filt;
280 uint32_t shiftInReg;
281
282 if ((filterIndex > 0U) && (filterIndex <= (uint32_t)FSL_FEATURE_LLWU_HAS_PIN_FILTER))
283 {
284 shiftInReg = (filterIndex - 1U) * 8U;
285
286 filt = base->FILT;
287 /* Clean the W1C bits, in case the flags are cleared by mistake. */
288 filt &= ~(((uint32_t)LLWU_FILT_FILTF1_MASK << 0U) | ((uint32_t)LLWU_FILT_FILTF1_MASK << 8U) |
289 ((uint32_t)LLWU_FILT_FILTF1_MASK << 16U) | ((uint32_t)LLWU_FILT_FILTF1_MASK << 24U));
290
291 filt &= ~(((uint32_t)LLWU_FILT_FILTSEL1_MASK | (uint32_t)LLWU_FILT_FILTE1_MASK) << shiftInReg);
292
293 filt |=
294 ((LLWU_FILT_FILTSEL1(filterMode.pinIndex) | LLWU_FILT_FILTE1(filterMode.filterMode) | LLWU_FILT_FILTF1_MASK)
295 << shiftInReg);
296
297 base->FILT = filt;
298 }
299 #else
300 volatile uint8_t *regBase;
301
302 switch (filterIndex)
303 {
304 case 1U:
305 regBase = &base->FILT1;
306 break;
307 #if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1))
308 case 2U:
309 regBase = &base->FILT2;
310 break;
311 #endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
312 #if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2))
313 case 3U:
314 regBase = &base->FILT3;
315 break;
316 #endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
317 #if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3))
318 case 4U:
319 regBase = &base->FILT4;
320 break;
321 #endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
322 default:
323 regBase = NULL;
324 break;
325 }
326
327 if (NULL != regBase)
328 {
329 *regBase = (uint8_t)((*regBase & ~(LLWU_FILT1_FILTSEL_MASK | LLWU_FILT1_FILTE_MASK)) |
330 LLWU_FILT1_FILTSEL(filterMode.pinIndex) | LLWU_FILT1_FILTE(filterMode.filterMode) |
331 LLWU_FILT1_FILTF_MASK) /* W1C to clear the FILTF flag bit. */
332 ;
333 }
334 #endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
335 }
336
337 /*!
338 * brief Gets the pin filter configuration.
339 *
340 * This function gets the pin filter flag.
341 *
342 * param base LLWU peripheral base address.
343 * param filterIndex A pin filter index, which starts from 1.
344 * return True if the flag is a source of the existing low-leakage power mode.
345 */
LLWU_GetPinFilterFlag(LLWU_Type * base,uint32_t filterIndex)346 bool LLWU_GetPinFilterFlag(LLWU_Type *base, uint32_t filterIndex)
347 {
348 #if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
349 return (0U != (base->FILT & (1UL << (filterIndex * 8U - 1U))));
350 #else
351 bool status = false;
352
353 switch (filterIndex)
354 {
355 case 1:
356 status = ((base->FILT1 & LLWU_FILT1_FILTF_MASK) != 0U);
357 break;
358 #if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1))
359 case 2:
360 status = ((base->FILT2 & LLWU_FILT2_FILTF_MASK) != 0U);
361 break;
362 #endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
363 #if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2))
364 case 3:
365 status = ((base->FILT3 & LLWU_FILT3_FILTF_MASK) != 0U);
366 break;
367 #endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
368 #if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3))
369 case 4:
370 status = ((base->FILT4 & LLWU_FILT4_FILTF_MASK) != 0U);
371 break;
372 #endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
373 default:
374 status = false;
375 break;
376 }
377
378 return status;
379 #endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
380 }
381
382 /*!
383 * brief Clears the pin filter configuration.
384 *
385 * This function clears the pin filter flag.
386 *
387 * param base LLWU peripheral base address.
388 * param filterIndex A pin filter index to clear the flag, starting from 1.
389 */
LLWU_ClearPinFilterFlag(LLWU_Type * base,uint32_t filterIndex)390 void LLWU_ClearPinFilterFlag(LLWU_Type *base, uint32_t filterIndex)
391 {
392 #if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
393
394 #if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 0))
395 uint32_t reg;
396
397 if ((filterIndex > 0U) && (filterIndex <= (uint32_t)FSL_FEATURE_LLWU_HAS_PIN_FILTER))
398 {
399 reg = base->FILT;
400
401 /* Clean the W1C bits, in case the flags are cleared by mistake. */
402 reg &= ~(((uint32_t)LLWU_FILT_FILTF1_MASK << 0U) | ((uint32_t)LLWU_FILT_FILTF1_MASK << 8U) |
403 ((uint32_t)LLWU_FILT_FILTF1_MASK << 16U) | ((uint32_t)LLWU_FILT_FILTF1_MASK << 24U));
404
405 reg |= ((uint32_t)LLWU_FILT_FILTF1_MASK << ((filterIndex - 1U) * 8U));
406
407 base->FILT = reg;
408 }
409
410 #endif
411
412 return;
413 #else
414 volatile uint8_t *regBase;
415 uint8_t reg;
416
417 switch (filterIndex)
418 {
419 case 1:
420 regBase = &base->FILT1;
421 break;
422 #if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1))
423 case 2:
424 regBase = &base->FILT2;
425 break;
426 #endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
427 #if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2))
428 case 3:
429 regBase = &base->FILT3;
430 break;
431 #endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
432 #if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3))
433 case 4:
434 regBase = &base->FILT4;
435 break;
436 #endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
437 default:
438 regBase = NULL;
439 break;
440 }
441
442 if (NULL != regBase)
443 {
444 reg = *regBase;
445 reg |= LLWU_FILT1_FILTF_MASK;
446 *regBase = reg;
447 }
448 #endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
449 }
450 #endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
451
452 #if (defined(FSL_FEATURE_LLWU_HAS_RESET_ENABLE) && FSL_FEATURE_LLWU_HAS_RESET_ENABLE)
453 /*!
454 * brief Sets the reset pin mode.
455 *
456 * This function determines how the reset pin is used as a low leakage mode exit source.
457 *
458 * param pinEnable Enable reset the pin filter
459 * param pinFilterEnable Specify whether the pin filter is enabled in Low-Leakage power mode.
460 */
LLWU_SetResetPinMode(LLWU_Type * base,bool pinEnable,bool pinFilterEnable)461 void LLWU_SetResetPinMode(LLWU_Type *base, bool pinEnable, bool pinFilterEnable)
462 {
463 uint8_t reg;
464
465 reg = base->RST;
466
467 reg &= (uint8_t)(~(LLWU_RST_LLRSTE_MASK | LLWU_RST_RSTFILT_MASK));
468
469 if (pinEnable)
470 {
471 reg |= LLWU_RST_LLRSTE_MASK;
472 }
473
474 if (pinFilterEnable)
475 {
476 reg |= LLWU_RST_RSTFILT_MASK;
477 }
478
479 base->RST = reg;
480 }
481 #endif /* FSL_FEATURE_LLWU_HAS_RESET_ENABLE */
482