1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2023 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef _FSL_GPIO_H_
10 #define _FSL_GPIO_H_
11 
12 #include "fsl_common.h"
13 
14 /*!
15  * @addtogroup gpio
16  * @{
17  */
18 
19 /*******************************************************************************
20  * Definitions
21  ******************************************************************************/
22 
23 /*! @name Driver version */
24 /*@{*/
25 /*! @brief GPIO driver version. */
26 #define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 7, 2))
27 /*@}*/
28 
29 #if defined(FSL_FEATURE_GPIO_REGISTERS_WIDTH) && (FSL_FEATURE_GPIO_REGISTERS_WIDTH == 8U)
30 #define GPIO_FIT_REG(value) \
31     ((uint8_t)(value)) /*!< For some platforms with 8-bit register width, cast the type to uint8_t */
32 #else
33 #define GPIO_FIT_REG(value) ((uint32_t)(value))
34 #endif /*FSL_FEATURE_GPIO_REGISTERS_WIDTH*/
35 
36 /*! @brief GPIO direction definition */
37 typedef enum _gpio_pin_direction
38 {
39     kGPIO_DigitalInput  = 0U, /*!< Set current pin as digital input*/
40     kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/
41 } gpio_pin_direction_t;
42 
43 #if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER
44 /*! @brief GPIO checker attribute */
45 typedef enum _gpio_checker_attribute
46 {
47     kGPIO_UsernonsecureRWUsersecureRWPrivilegedsecureRW =
48         0x00U, /*!< User nonsecure:Read+Write; User Secure:Read+Write; Privileged Secure:Read+Write */
49     kGPIO_UsernonsecureRUsersecureRWPrivilegedsecureRW =
50         0x01U, /*!< User nonsecure:Read;       User Secure:Read+Write; Privileged Secure:Read+Write */
51     kGPIO_UsernonsecureNUsersecureRWPrivilegedsecureRW =
52         0x02U, /*!< User nonsecure:None;       User Secure:Read+Write; Privileged Secure:Read+Write */
53     kGPIO_UsernonsecureRUsersecureRPrivilegedsecureRW =
54         0x03U, /*!< User nonsecure:Read;       User Secure:Read;       Privileged Secure:Read+Write */
55     kGPIO_UsernonsecureNUsersecureRPrivilegedsecureRW =
56         0x04U, /*!< User nonsecure:None;       User Secure:Read;       Privileged Secure:Read+Write */
57     kGPIO_UsernonsecureNUsersecureNPrivilegedsecureRW =
58         0x05U, /*!< User nonsecure:None;       User Secure:None;       Privileged Secure:Read+Write */
59     kGPIO_UsernonsecureNUsersecureNPrivilegedsecureR =
60         0x06U, /*!< User nonsecure:None;       User Secure:None;       Privileged Secure:Read */
61     kGPIO_UsernonsecureNUsersecureNPrivilegedsecureN =
62         0x07U, /*!< User nonsecure:None;       User Secure:None;       Privileged Secure:None */
63     kGPIO_IgnoreAttributeCheck = 0x80U, /*!< Ignores the attribute check */
64 } gpio_checker_attribute_t;
65 #endif
66 
67 /*!
68  * @brief The GPIO pin configuration structure.
69  *
70  * Each pin can only be configured as either an output pin or an input pin at a time.
71  * If configured as an input pin, leave the outputConfig unused.
72  * Note that in some use cases, the corresponding port property should be configured in advance
73  *        with the PORT_SetPinConfig().
74  */
75 typedef struct _gpio_pin_config
76 {
77     gpio_pin_direction_t pinDirection; /*!< GPIO direction, input or output */
78     /* Output configurations; ignore if configured as an input pin */
79     uint8_t outputLogic; /*!< Set a default output logic, which has no use in input */
80 } gpio_pin_config_t;
81 
82 #if (defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) || \
83      !(defined(FSL_FEATURE_SOC_PORT_COUNT))
84 /*! @brief Configures the interrupt generation condition. */
85 typedef enum _gpio_interrupt_config
86 {
87     kGPIO_InterruptStatusFlagDisabled   = 0x0U,  /*!< Interrupt status flag is disabled. */
88     kGPIO_DMARisingEdge                 = 0x1U,  /*!< ISF flag and DMA request on rising edge. */
89     kGPIO_DMAFallingEdge                = 0x2U,  /*!< ISF flag and DMA request on falling edge. */
90     kGPIO_DMAEitherEdge                 = 0x3U,  /*!< ISF flag and DMA request on either edge. */
91     kGPIO_FlagRisingEdge                = 0x05U, /*!< Flag sets on rising edge. */
92     kGPIO_FlagFallingEdge               = 0x06U, /*!< Flag sets on falling edge. */
93     kGPIO_FlagEitherEdge                = 0x07U, /*!< Flag sets on either edge. */
94     kGPIO_InterruptLogicZero            = 0x8U,  /*!< Interrupt when logic zero. */
95     kGPIO_InterruptRisingEdge           = 0x9U,  /*!< Interrupt on rising edge. */
96     kGPIO_InterruptFallingEdge          = 0xAU,  /*!< Interrupt on falling edge. */
97     kGPIO_InterruptEitherEdge           = 0xBU,  /*!< Interrupt on either edge. */
98     kGPIO_InterruptLogicOne             = 0xCU,  /*!< Interrupt when logic one. */
99     kGPIO_ActiveHighTriggerOutputEnable = 0xDU,  /*!< Enable active high-trigger output. */
100     kGPIO_ActiveLowTriggerOutputEnable  = 0xEU,  /*!< Enable active low-trigger output. */
101 } gpio_interrupt_config_t;
102 #endif
103 
104 #if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) && FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT)
105 /*! @brief Configures the selection of interrupt/DMA request/trigger output. */
106 typedef enum _gpio_interrupt_selection
107 {
108     kGPIO_InterruptOutput0 = 0x0U, /*!< Interrupt/DMA request/trigger output 0. */
109     kGPIO_InterruptOutput1 = 0x1U, /*!< Interrupt/DMA request/trigger output 1. */
110 } gpio_interrupt_selection_t;
111 #endif /* FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT */
112 
113 #if defined(FSL_FEATURE_GPIO_HAS_VERSION_INFO_REGISTER) && FSL_FEATURE_GPIO_HAS_VERSION_INFO_REGISTER
114 /*! @brief GPIO version information. */
115 typedef struct _gpio_version_info
116 {
117     uint16_t feature; /*!< Feature Specification Number. */
118     uint8_t minor;    /*!< Minor Version Number. */
119     uint8_t major;    /*!< Major Version Number. */
120 } gpio_version_info_t;
121 #endif /* FSL_FEATURE_GPIO_HAS_VERSION_INFO_REGISTER */
122 
123 #if defined(FSL_FEATURE_GPIO_HAS_SECURE_PRIVILEGE_CONTROL) && FSL_FEATURE_GPIO_HAS_SECURE_PRIVILEGE_CONTROL
124 /*! @brief GPIO pin and interrupt control. */
125 typedef enum
126 {
127     kGPIO_PinControlNonSecure          = 0x01U, /*!< Pin Control Non-Secure. */
128     kGPIO_InterruptControlNonSecure    = 0x02U, /*!< Interrupt Control Non-Secure. */
129     kGPIO_PinControlNonPrivilege       = 0x04U, /*!< Pin Control Non-Privilege. */
130     kGPIO_InterruptControlNonPrivilege = 0x08U, /*!< Interrupt Control Non-Privilege. */
131 } gpio_pin_interrupt_control_t;
132 #endif /* FSL_FEATURE_GPIO_HAS_SECURE_PRIVILEGE_CONTROL */
133 
134 /*! @} */
135 
136 /*******************************************************************************
137  * API
138  ******************************************************************************/
139 
140 #if defined(__cplusplus)
141 extern "C" {
142 #endif
143 
144 /*!
145  * @addtogroup gpio_driver
146  * @{
147  */
148 
149 /*! @name GPIO Configuration */
150 /*@{*/
151 
152 /*!
153  * @brief Initializes a GPIO pin used by the board.
154  *
155  * To initialize the GPIO, define a pin configuration, as either input or output, in the user file.
156  * Then, call the GPIO_PinInit() function.
157  *
158  * This is an example to define an input pin or an output pin configuration.
159  * @code
160  * Define a digital input pin configuration,
161  * gpio_pin_config_t config =
162  * {
163  *   kGPIO_DigitalInput,
164  *   0,
165  * }
166  * Define a digital output pin configuration,
167  * gpio_pin_config_t config =
168  * {
169  *   kGPIO_DigitalOutput,
170  *   0,
171  * }
172  * @endcode
173  *
174  * @param base   GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
175  * @param pin    GPIO port pin number
176  * @param config GPIO pin configuration pointer
177  */
178 void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config);
179 
180 #if defined(FSL_FEATURE_GPIO_HAS_VERSION_INFO_REGISTER) && FSL_FEATURE_GPIO_HAS_VERSION_INFO_REGISTER
181 /*!
182  * @brief Get GPIO version information.
183  *
184  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
185  * @param info GPIO version information
186  */
187 void GPIO_GetVersionInfo(GPIO_Type *base, gpio_version_info_t *info);
188 #endif /* FSL_FEATURE_GPIO_HAS_VERSION_INFO_REGISTER */
189 
190 #if defined(FSL_FEATURE_GPIO_HAS_SECURE_PRIVILEGE_CONTROL) && FSL_FEATURE_GPIO_HAS_SECURE_PRIVILEGE_CONTROL
191 /*!
192  * @brief lock or unlock secure privilege.
193  *
194  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
195  * @param mask pin or interrupt macro
196  */
GPIO_SecurePrivilegeLock(GPIO_Type * base,gpio_pin_interrupt_control_t mask)197 static inline void GPIO_SecurePrivilegeLock(GPIO_Type *base, gpio_pin_interrupt_control_t mask)
198 {
199     base->LOCK |= GPIO_FIT_REG(mask);
200 }
201 
202 /*!
203  * @brief Enable Pin Control Non-Secure.
204  *
205  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
206  * @param mask GPIO pin number macro
207  */
GPIO_EnablePinControlNonSecure(GPIO_Type * base,uint32_t mask)208 static inline void GPIO_EnablePinControlNonSecure(GPIO_Type *base, uint32_t mask)
209 {
210     base->PCNS |= GPIO_FIT_REG(mask);
211 }
212 
213 /*!
214  * @brief Disable Pin Control Non-Secure.
215  *
216  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
217  * @param mask GPIO pin number macro
218  */
GPIO_DisablePinControlNonSecure(GPIO_Type * base,uint32_t mask)219 static inline void GPIO_DisablePinControlNonSecure(GPIO_Type *base, uint32_t mask)
220 {
221     base->PCNS &= GPIO_FIT_REG(~mask);
222 }
223 
224 /*!
225  * @brief Enable Pin Control Non-Privilege.
226  *
227  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
228  * @param mask GPIO pin number macro
229  */
GPIO_EnablePinControlNonPrivilege(GPIO_Type * base,uint32_t mask)230 static inline void GPIO_EnablePinControlNonPrivilege(GPIO_Type *base, uint32_t mask)
231 {
232     base->PCNP |= GPIO_FIT_REG(mask);
233 }
234 
235 /*!
236  * @brief Disable Pin Control Non-Privilege.
237  *
238  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
239  * @param mask GPIO pin number macro
240  */
GPIO_DisablePinControlNonPrivilege(GPIO_Type * base,uint32_t mask)241 static inline void GPIO_DisablePinControlNonPrivilege(GPIO_Type *base, uint32_t mask)
242 {
243     base->PCNP &= GPIO_FIT_REG(~mask);
244 }
245 
246 /*!
247  * @brief Enable Interrupt Control Non-Secure.
248  *
249  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
250  * @param mask GPIO pin number macro
251  */
GPIO_EnableInterruptControlNonSecure(GPIO_Type * base,uint32_t mask)252 static inline void GPIO_EnableInterruptControlNonSecure(GPIO_Type *base, uint32_t mask)
253 {
254     base->ICNS |= GPIO_FIT_REG(mask);
255 }
256 
257 /*!
258  * @brief Disable Interrupt Control Non-Secure.
259  *
260  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
261  * @param mask GPIO pin number macro
262  */
GPIO_DisableInterruptControlNonSecure(GPIO_Type * base,uint32_t mask)263 static inline void GPIO_DisableInterruptControlNonSecure(GPIO_Type *base, uint32_t mask)
264 {
265     base->ICNS &= GPIO_FIT_REG(~mask);
266 }
267 
268 /*!
269  * @brief Enable Interrupt Control Non-Privilege.
270  *
271  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
272  * @param mask GPIO pin number macro
273  */
GPIO_EnableInterruptControlNonPrivilege(GPIO_Type * base,uint32_t mask)274 static inline void GPIO_EnableInterruptControlNonPrivilege(GPIO_Type *base, uint32_t mask)
275 {
276     base->ICNP |= GPIO_FIT_REG(mask);
277 }
278 
279 /*!
280  * @brief Disable Interrupt Control Non-Privilege.
281  *
282  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
283  * @param mask GPIO pin number macro
284  */
GPIO_DisableInterruptControlNonPrivilege(GPIO_Type * base,uint32_t mask)285 static inline void GPIO_DisableInterruptControlNonPrivilege(GPIO_Type *base, uint32_t mask)
286 {
287     base->ICNP &= GPIO_FIT_REG(~mask);
288 }
289 #endif /* FSL_FEATURE_GPIO_HAS_SECURE_PRIVILEGE_CONTROL */
290 
291 #if defined(FSL_FEATURE_GPIO_HAS_PORT_INPUT_CONTROL) && FSL_FEATURE_GPIO_HAS_PORT_INPUT_CONTROL
292 /*!
293  * @brief Enable port input.
294  *
295  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
296  * @param mask GPIO pin number macro
297  */
GPIO_PortInputEnable(GPIO_Type * base,uint32_t mask)298 static inline void GPIO_PortInputEnable(GPIO_Type *base, uint32_t mask)
299 {
300     base->PIDR &= GPIO_FIT_REG(~mask);
301 }
302 
303 /*!
304  * @brief Disable port input.
305  *
306  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
307  * @param mask GPIO pin number macro
308  */
GPIO_PortInputDisable(GPIO_Type * base,uint32_t mask)309 static inline void GPIO_PortInputDisable(GPIO_Type *base, uint32_t mask)
310 {
311     base->PIDR |= GPIO_FIT_REG(mask);
312 }
313 #endif /* FSL_FEATURE_GPIO_HAS_PORT_INPUT_CONTROL */
314 
315 /*@}*/
316 
317 /*! @name GPIO Output Operations */
318 /*@{*/
319 
320 /*!
321  * @brief Sets the output level of the multiple GPIO pins to the logic 1 or 0.
322  *
323  * @param base    GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
324  * @param pin     GPIO pin number
325  * @param output  GPIO pin output logic level.
326  *        - 0: corresponding pin output low-logic level.
327  *        - 1: corresponding pin output high-logic level.
328  */
GPIO_PinWrite(GPIO_Type * base,uint32_t pin,uint8_t output)329 static inline void GPIO_PinWrite(GPIO_Type *base, uint32_t pin, uint8_t output)
330 {
331 #if !(defined(FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL) && FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL)
332     if (output == 0U)
333     {
334         base->PCOR = GPIO_FIT_REG(1UL << pin);
335     }
336     else
337     {
338         base->PSOR = GPIO_FIT_REG(1UL << pin);
339     }
340 #else
341     if (output == 0U)
342     {
343         base->PDOR |= GPIO_FIT_REG(1UL << pin);
344     }
345     else
346     {
347         base->PDOR &= ~GPIO_FIT_REG(1UL << pin);
348     }
349 #endif
350 }
351 
352 /*!
353  * @brief Sets the output level of the multiple GPIO pins to the logic 1.
354  *
355  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
356  * @param mask GPIO pin number macro
357  */
GPIO_PortSet(GPIO_Type * base,uint32_t mask)358 static inline void GPIO_PortSet(GPIO_Type *base, uint32_t mask)
359 {
360 #if !(defined(FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL) && FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL)
361     base->PSOR = GPIO_FIT_REG(mask);
362 #else
363     base->PDOR |= GPIO_FIT_REG(mask);
364 #endif
365 }
366 
367 /*!
368  * @brief Sets the output level of the multiple GPIO pins to the logic 0.
369  *
370  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
371  * @param mask GPIO pin number macro
372  */
GPIO_PortClear(GPIO_Type * base,uint32_t mask)373 static inline void GPIO_PortClear(GPIO_Type *base, uint32_t mask)
374 {
375 #if !(defined(FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL) && FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL)
376     base->PCOR = GPIO_FIT_REG(mask);
377 #else
378     base->PDOR &= ~GPIO_FIT_REG(mask);
379 #endif
380 }
381 
382 /*!
383  * @brief Reverses the current output logic of the multiple GPIO pins.
384  *
385  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
386  * @param mask GPIO pin number macro
387  */
GPIO_PortToggle(GPIO_Type * base,uint32_t mask)388 static inline void GPIO_PortToggle(GPIO_Type *base, uint32_t mask)
389 {
390 #if !(defined(FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL) && FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL)
391     base->PTOR = GPIO_FIT_REG(mask);
392 #else
393     base->PDOR ^= GPIO_FIT_REG(mask);
394 #endif
395 }
396 
397 /*@}*/
398 
399 /*! @name GPIO Input Operations */
400 /*@{*/
401 
402 /*!
403  * @brief Reads the current input value of the GPIO port.
404  *
405  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
406  * @param pin     GPIO pin number
407  * @retval GPIO port input value
408  *        - 0: corresponding pin input low-logic level.
409  *        - 1: corresponding pin input high-logic level.
410  */
GPIO_PinRead(GPIO_Type * base,uint32_t pin)411 static inline uint32_t GPIO_PinRead(GPIO_Type *base, uint32_t pin)
412 {
413     return (((uint32_t)(base->PDIR) >> pin) & 0x01UL);
414 }
415 
416 /*@}*/
417 
418 /*! @name GPIO Interrupt */
419 /*@{*/
420 #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && \
421     defined(FSL_FEATURE_SOC_PORT_COUNT)
422 /*!
423  * @brief Reads the GPIO port interrupt status flag.
424  *
425  * If a pin is configured to generate the DMA request, the corresponding flag
426  * is cleared automatically at the completion of the requested DMA transfer.
427  * Otherwise, the flag remains set until a logic one is written to that flag.
428  * If configured for a level sensitive interrupt that remains asserted, the flag
429  * is set again immediately.
430  *
431  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
432  * @retval The current GPIO port interrupt status flag, for example, 0x00010001 means the
433  *         pin 0 and 17 have the interrupt.
434  */
435 uint32_t GPIO_PortGetInterruptFlags(GPIO_Type *base);
436 
437 /*!
438  * @brief Clears multiple GPIO pin interrupt status flags.
439  *
440  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
441  * @param mask GPIO pin number macro
442  */
443 void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t mask);
444 #else
445 /*!
446  * @brief Configures the gpio pin interrupt/DMA request.
447  *
448  * @param base    GPIO peripheral base pointer.
449  * @param pin     GPIO pin number.
450  * @param config  GPIO pin interrupt configuration.
451  *        - #kGPIO_InterruptStatusFlagDisabled: Interrupt/DMA request disabled.
452  *        - #kGPIO_DMARisingEdge : DMA request on rising edge(if the DMA requests exit).
453  *        - #kGPIO_DMAFallingEdge: DMA request on falling edge(if the DMA requests exit).
454  *        - #kGPIO_DMAEitherEdge : DMA request on either edge(if the DMA requests exit).
455  *        - #kGPIO_FlagRisingEdge : Flag sets on rising edge(if the Flag states exit).
456  *        - #kGPIO_FlagFallingEdge : Flag sets on falling edge(if the Flag states exit).
457  *        - #kGPIO_FlagEitherEdge : Flag sets on either edge(if the Flag states exit).
458  *        - #kGPIO_InterruptLogicZero  : Interrupt when logic zero.
459  *        - #kGPIO_InterruptRisingEdge : Interrupt on rising edge.
460  *        - #kGPIO_InterruptFallingEdge: Interrupt on falling edge.
461  *        - #kGPIO_InterruptEitherEdge : Interrupt on either edge.
462  *        - #kGPIO_InterruptLogicOne   : Interrupt when logic one.
463  *        - #kGPIO_ActiveHighTriggerOutputEnable : Enable active high-trigger output (if the trigger states exit).
464  *        - #kGPIO_ActiveLowTriggerOutputEnable  : Enable active low-trigger output (if the trigger states exit).
465  */
GPIO_SetPinInterruptConfig(GPIO_Type * base,uint32_t pin,gpio_interrupt_config_t config)466 static inline void GPIO_SetPinInterruptConfig(GPIO_Type *base, uint32_t pin, gpio_interrupt_config_t config)
467 {
468     assert(base);
469 
470     base->ICR[pin] = GPIO_FIT_REG((base->ICR[pin] & ~GPIO_ICR_IRQC_MASK) | GPIO_ICR_IRQC(config));
471 }
472 
473 #if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) && FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT)
474 /*!
475  * @brief Configures the gpio pin interrupt/DMA request/trigger output channel selection.
476  *
477  * @param base    GPIO peripheral base pointer.
478  * @param pin     GPIO pin number.
479  * @param selection  GPIO pin interrupt output selection.
480  *        - #kGPIO_InterruptOutput0: Interrupt/DMA request/trigger output 0.
481  *        - #kGPIO_InterruptOutput1 : Interrupt/DMA request/trigger output 1.
482  */
GPIO_SetPinInterruptChannel(GPIO_Type * base,uint32_t pin,gpio_interrupt_selection_t selection)483 static inline void GPIO_SetPinInterruptChannel(GPIO_Type *base, uint32_t pin, gpio_interrupt_selection_t selection)
484 {
485     assert(base);
486 
487     base->ICR[pin] = GPIO_FIT_REG((base->ICR[pin] & ~GPIO_ICR_IRQS_MASK) | GPIO_ICR_IRQS(selection));
488 }
489 #endif
490 /*!
491  * @brief Read the GPIO interrupt status flags.
492  *
493  * @param base GPIO peripheral base pointer. (GPIOA, GPIOB, GPIOC, and so on.)
494  * @return The current GPIO's interrupt status flag.
495  *         '1' means the related pin's flag is set, '0' means the related pin's flag not set.
496  *          For example, the return value 0x00010001 means the pin 0 and 17 have the interrupt pending.
497  */
498 uint32_t GPIO_GpioGetInterruptFlags(GPIO_Type *base);
499 #if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) && FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT)
500 /*!
501  * @brief Read the GPIO interrupt status flags based on selected interrupt channel(IRQS).
502  *
503  * @param base GPIO peripheral base pointer. (GPIOA, GPIOB, GPIOC, and so on.)
504  * @param channel '0' means selete interrupt channel 0, '1' means selete interrupt channel 1.
505  * @return The current GPIO's interrupt status flag based on the selected interrupt channel.
506  *         '1' means the related pin's flag is set, '0' means the related pin's flag not set.
507  *          For example, the return value 0x00010001 means the pin 0 and 17 have the interrupt pending.
508  */
509 uint32_t GPIO_GpioGetInterruptChannelFlags(GPIO_Type *base, uint32_t channel);
510 #endif
511 /*!
512  * @brief Read individual pin's interrupt status flag.
513  *
514  * @param base GPIO peripheral base pointer. (GPIOA, GPIOB, GPIOC, and so on)
515  * @param pin GPIO specific pin number.
516  * @return The current selected pin's interrupt status flag.
517  */
518 uint8_t GPIO_PinGetInterruptFlag(GPIO_Type *base, uint32_t pin);
519 
520 /*!
521  * @brief Clears GPIO pin interrupt status flags.
522  *
523  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
524  * @param mask GPIO pin number macro
525  */
526 void GPIO_GpioClearInterruptFlags(GPIO_Type *base, uint32_t mask);
527 #if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) && FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT)
528 /*!
529  * @brief Clears GPIO pin interrupt status flags based on selected interrupt channel(IRQS).
530  *
531  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
532  * @param mask GPIO pin number macro
533  * @param channel '0' means selete interrupt channel 0, '1' means selete interrupt channel 1.
534  */
535 void GPIO_GpioClearInterruptChannelFlags(GPIO_Type *base, uint32_t mask, uint32_t channel);
536 #endif
537 /*!
538  * @brief Clear GPIO individual pin's interrupt status flag.
539  *
540  * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on).
541  * @param pin GPIO specific pin number.
542  */
543 void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t pin);
544 
545 /*!
546  * @brief Reads the GPIO DMA request flags.
547  *        The corresponding flag will be cleared automatically at the completion of the requested
548  *        DMA transfer
549  */
GPIO_GetPinsDMARequestFlags(GPIO_Type * base)550 static inline uint32_t GPIO_GetPinsDMARequestFlags(GPIO_Type *base)
551 {
552     assert(base);
553     return (base->ISFR[1]);
554 }
555 
556 /*!
557  * @brief Sets the GPIO interrupt configuration in PCR register for multiple pins.
558  *
559  * @param base   GPIO peripheral base pointer.
560  * @param mask   GPIO pin number macro.
561  * @param config  GPIO pin interrupt configuration.
562  *        - #kGPIO_InterruptStatusFlagDisabled: Interrupt disabled.
563  *        - #kGPIO_DMARisingEdge : DMA request on rising edge(if the DMA requests exit).
564  *        - #kGPIO_DMAFallingEdge: DMA request on falling edge(if the DMA requests exit).
565  *        - #kGPIO_DMAEitherEdge : DMA request on either edge(if the DMA requests exit).
566  *        - #kGPIO_FlagRisingEdge : Flag sets on rising edge(if the Flag states exit).
567  *        - #kGPIO_FlagFallingEdge : Flag sets on falling edge(if the Flag states exit).
568  *        - #kGPIO_FlagEitherEdge : Flag sets on either edge(if the Flag states exit).
569  *        - #kGPIO_InterruptLogicZero  : Interrupt when logic zero.
570  *        - #kGPIO_InterruptRisingEdge : Interrupt on rising edge.
571  *        - #kGPIO_InterruptFallingEdge: Interrupt on falling edge.
572  *        - #kGPIO_InterruptEitherEdge : Interrupt on either edge.
573  *        - #kGPIO_InterruptLogicOne   : Interrupt when logic one.
574  *        - #kGPIO_ActiveHighTriggerOutputEnable : Enable active high-trigger output (if the trigger states exit).
575  *        - #kGPIO_ActiveLowTriggerOutputEnable  : Enable active low-trigger output (if the trigger states exit)..
576  */
GPIO_SetMultipleInterruptPinsConfig(GPIO_Type * base,uint32_t mask,gpio_interrupt_config_t config)577 static inline void GPIO_SetMultipleInterruptPinsConfig(GPIO_Type *base, uint32_t mask, gpio_interrupt_config_t config)
578 {
579     assert(base);
580 
581     if (0UL != (mask & 0xffffUL))
582     {
583         base->GICLR = GPIO_FIT_REG((GPIO_ICR_IRQC(config)) | (mask & 0xffffU));
584     }
585     mask = mask >> 16U;
586     if (mask != 0UL)
587     {
588         base->GICHR = GPIO_FIT_REG((GPIO_ICR_IRQC(config)) | (mask & 0xffffU));
589     }
590 }
591 #endif
592 
593 #if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER
594 /*!
595  * brief The GPIO module supports a device-specific number of data ports, organized as 32-bit
596  * words/8-bit Bytes. Each 32-bit/8-bit data port includes a GACR register, which defines the byte-level
597  * attributes required for a successful access to the GPIO programming model. If the GPIO module's GACR register
598  * organized as 32-bit words, the attribute controls for the 4 data bytes in the GACR follow a standard little
599  * endian data convention.
600  *
601  * @param base      GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
602  * @param attribute GPIO checker attribute
603  */
604 void GPIO_CheckAttributeBytes(GPIO_Type *base, gpio_checker_attribute_t attribute);
605 #endif
606 
607 /*@}*/
608 /*! @} */
609 
610 /*!
611  * @addtogroup fgpio_driver
612  * @{
613  */
614 
615 /*
616  * Introduces the FGPIO feature.
617  *
618  * The FGPIO features are only support on some Kinetis MCUs. The FGPIO registers are aliased to the IOPORT
619  * interface. Accesses via the IOPORT interface occur in parallel with any instruction fetches and
620  * complete in a single cycle. This aliased Fast GPIO memory map is called FGPIO.
621  */
622 
623 #if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT
624 
625 /*! @name FGPIO Configuration */
626 /*@{*/
627 
628 #if defined(FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL) && FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL
629 /*!
630  * @brief Initializes the FGPIO peripheral.
631  *
632  * This function ungates the FGPIO clock.
633  *
634  * @param base   FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
635  */
636 void FGPIO_PortInit(FGPIO_Type *base);
637 #endif /* FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL */
638 
639 /*!
640  * @brief Initializes a FGPIO pin used by the board.
641  *
642  * To initialize the FGPIO driver, define a pin configuration, as either input or output, in the user file.
643  * Then, call the FGPIO_PinInit() function.
644  *
645  * This is an example to define an input pin or an output pin configuration:
646  * @code
647  * Define a digital input pin configuration,
648  * gpio_pin_config_t config =
649  * {
650  *   kGPIO_DigitalInput,
651  *   0,
652  * }
653  * Define a digital output pin configuration,
654  * gpio_pin_config_t config =
655  * {
656  *   kGPIO_DigitalOutput,
657  *   0,
658  * }
659  * @endcode
660  *
661  * @param base   FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
662  * @param pin    FGPIO port pin number
663  * @param config FGPIO pin configuration pointer
664  */
665 void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config);
666 
667 /*@}*/
668 
669 /*! @name FGPIO Output Operations */
670 /*@{*/
671 
672 /*!
673  * @brief Sets the output level of the multiple FGPIO pins to the logic 1 or 0.
674  *
675  * @param base    FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
676  * @param pin     FGPIO pin number
677  * @param output  FGPIOpin output logic level.
678  *        - 0: corresponding pin output low-logic level.
679  *        - 1: corresponding pin output high-logic level.
680  */
FGPIO_PinWrite(FGPIO_Type * base,uint32_t pin,uint8_t output)681 static inline void FGPIO_PinWrite(FGPIO_Type *base, uint32_t pin, uint8_t output)
682 {
683     if (output == 0U)
684     {
685         base->PCOR = 1UL << pin;
686     }
687     else
688     {
689         base->PSOR = 1UL << pin;
690     }
691 }
692 
693 /*!
694  * @brief Sets the output level of the multiple FGPIO pins to the logic 1.
695  *
696  * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
697  * @param mask FGPIO pin number macro
698  */
FGPIO_PortSet(FGPIO_Type * base,uint32_t mask)699 static inline void FGPIO_PortSet(FGPIO_Type *base, uint32_t mask)
700 {
701     base->PSOR = mask;
702 }
703 
704 /*!
705  * @brief Sets the output level of the multiple FGPIO pins to the logic 0.
706  *
707  * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
708  * @param mask FGPIO pin number macro
709  */
FGPIO_PortClear(FGPIO_Type * base,uint32_t mask)710 static inline void FGPIO_PortClear(FGPIO_Type *base, uint32_t mask)
711 {
712     base->PCOR = mask;
713 }
714 
715 /*!
716  * @brief Reverses the current output logic of the multiple FGPIO pins.
717  *
718  * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
719  * @param mask FGPIO pin number macro
720  */
FGPIO_PortToggle(FGPIO_Type * base,uint32_t mask)721 static inline void FGPIO_PortToggle(FGPIO_Type *base, uint32_t mask)
722 {
723     base->PTOR = mask;
724 }
725 /*@}*/
726 
727 /*! @name FGPIO Input Operations */
728 /*@{*/
729 
730 /*!
731  * @brief Reads the current input value of the FGPIO port.
732  *
733  * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
734  * @param pin  FGPIO pin number
735  * @retval FGPIO port input value
736  *        - 0: corresponding pin input low-logic level.
737  *        - 1: corresponding pin input high-logic level.
738  */
FGPIO_PinRead(FGPIO_Type * base,uint32_t pin)739 static inline uint32_t FGPIO_PinRead(FGPIO_Type *base, uint32_t pin)
740 {
741     return (((base->PDIR) >> pin) & 0x01U);
742 }
743 /*@}*/
744 
745 /*! @name FGPIO Interrupt */
746 /*@{*/
747 #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && \
748     defined(FSL_FEATURE_SOC_PORT_COUNT)
749 
750 /*!
751  * @brief Reads the FGPIO port interrupt status flag.
752  *
753  * If a pin is configured to generate the DMA request, the corresponding flag
754  * is cleared automatically at the completion of the requested DMA transfer.
755  * Otherwise, the flag remains set until a logic one is written to that flag.
756  * If configured for a level-sensitive interrupt that remains asserted, the flag
757  * is set again immediately.
758  *
759  * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
760  * @retval The current FGPIO port interrupt status flags, for example, 0x00010001 means the
761  *         pin 0 and 17 have the interrupt.
762  */
763 uint32_t FGPIO_PortGetInterruptFlags(FGPIO_Type *base);
764 
765 /*!
766  * @brief Clears the multiple FGPIO pin interrupt status flag.
767  *
768  * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
769  * @param mask FGPIO pin number macro
770  */
771 void FGPIO_PortClearInterruptFlags(FGPIO_Type *base, uint32_t mask);
772 #endif
773 #if defined(FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER
774 /*!
775  * @brief The FGPIO module supports a device-specific number of data ports, organized as 32-bit
776  * words. Each 32-bit data port includes a GACR register, which defines the byte-level
777  * attributes required for a successful access to the GPIO programming model. The attribute controls for the 4 data
778  * bytes in the GACR follow a standard little endian
779  * data convention.
780  *
781  * @param base      FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
782  * @param attribute FGPIO checker attribute
783  */
784 void FGPIO_CheckAttributeBytes(FGPIO_Type *base, gpio_checker_attribute_t attribute);
785 #endif /* FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER */
786 
787 /*@}*/
788 
789 #endif /* FSL_FEATURE_SOC_FGPIO_COUNT */
790 
791 #if defined(__cplusplus)
792 }
793 #endif
794 
795 /*!
796  * @}
797  */
798 
799 #endif /* _FSL_GPIO_H_*/
800