Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:59

0001 /*
0002  * Copyright (c) 2016, Freescale Semiconductor, Inc.
0003  * Copyright 2016-2017, 2020-2021 NXP
0004  * All rights reserved.
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #include "fsl_gpio.h"
0010 
0011 /* Component ID definition, used by tools. */
0012 #ifndef FSL_COMPONENT_ID
0013 #define FSL_COMPONENT_ID "platform.drivers.igpio"
0014 #endif
0015 
0016 /*******************************************************************************
0017  * Variables
0018  ******************************************************************************/
0019 
0020 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0021 /* Array of GPIO peripheral base address. */
0022 static GPIO_Type *const s_gpioBases[] = GPIO_BASE_PTRS;
0023 #endif
0024 
0025 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0026 /* Array of GPIO clock name. */
0027 static const clock_ip_name_t s_gpioClock[] = GPIO_CLOCKS;
0028 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0029 
0030 /*******************************************************************************
0031  * Prototypes
0032  ******************************************************************************/
0033 
0034 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0035 /*!
0036  * @brief Gets the GPIO instance according to the GPIO base
0037  *
0038  * @param base    GPIO peripheral base pointer(PTA, PTB, PTC, etc.)
0039  * @retval GPIO instance
0040  */
0041 static uint32_t GPIO_GetInstance(GPIO_Type *base);
0042 
0043 /*******************************************************************************
0044  * Code
0045  ******************************************************************************/
0046 
0047 static uint32_t GPIO_GetInstance(GPIO_Type *base)
0048 {
0049     uint32_t instance;
0050 
0051     /* Find the instance index from base address mappings. */
0052     for (instance = 0U; instance < ARRAY_SIZE(s_gpioBases); instance++)
0053     {
0054         if (s_gpioBases[instance] == base)
0055         {
0056             break;
0057         }
0058     }
0059 
0060     assert(instance < ARRAY_SIZE(s_gpioBases));
0061 
0062     return instance;
0063 }
0064 #endif
0065 
0066 /*!
0067  * brief Initializes the GPIO peripheral according to the specified
0068  *        parameters in the initConfig.
0069  *
0070  * param base GPIO base pointer.
0071  * param pin Specifies the pin number
0072  * param initConfig pointer to a ref gpio_pin_config_t structure that
0073  *        contains the configuration information.
0074  */
0075 void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *Config)
0076 {
0077 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0078     /* Enable GPIO clock. */
0079     uint32_t instance = GPIO_GetInstance(base);
0080 
0081     /* If The clock IP is valid, enable the clock gate. */
0082     if ((instance < ARRAY_SIZE(s_gpioClock)) && (kCLOCK_IpInvalid != s_gpioClock[instance]))
0083     {
0084         (void)CLOCK_EnableClock(s_gpioClock[instance]);
0085     }
0086 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0087 
0088     /* Register reset to default value */
0089     base->IMR &= ~(1UL << pin);
0090 
0091     /* Configure GPIO pin direction */
0092     if (Config->direction == kGPIO_DigitalInput)
0093     {
0094         base->GDIR &= ~(1UL << pin);
0095     }
0096     else
0097     {
0098         GPIO_PinWrite(base, pin, Config->outputLogic);
0099         base->GDIR |= (1UL << pin);
0100     }
0101 
0102     /* Configure GPIO pin interrupt mode */
0103     GPIO_SetPinInterruptConfig(base, pin, Config->interruptMode);
0104 }
0105 
0106 /*!
0107  * brief Sets the output level of the individual GPIO pin to logic 1 or 0.
0108  *
0109  * param base GPIO base pointer.
0110  * param pin GPIO port pin number.
0111  * param output GPIOpin output logic level.
0112  *        - 0: corresponding pin output low-logic level.
0113  *        - 1: corresponding pin output high-logic level.
0114  */
0115 void GPIO_PinWrite(GPIO_Type *base, uint32_t pin, uint8_t output)
0116 {
0117     assert(pin < 32U);
0118     if (output == 0U)
0119     {
0120 #if (defined(FSL_FEATURE_IGPIO_HAS_DR_CLEAR) && FSL_FEATURE_IGPIO_HAS_DR_CLEAR)
0121         base->DR_CLEAR = (1UL << pin);
0122 #else
0123         base->DR &= ~(1UL << pin); /* Set pin output to low level.*/
0124 #endif
0125     }
0126     else
0127     {
0128 #if (defined(FSL_FEATURE_IGPIO_HAS_DR_SET) && FSL_FEATURE_IGPIO_HAS_DR_SET)
0129         base->DR_SET = (1UL << pin);
0130 #else
0131         base->DR |= (1UL << pin);  /* Set pin output to high level.*/
0132 #endif
0133     }
0134 }
0135 
0136 /*!
0137  * brief Sets the current pin interrupt mode.
0138  *
0139  * param base GPIO base pointer.
0140  * param pin GPIO port pin number.
0141  * param pininterruptMode pointer to a ref gpio_interrupt_mode_t structure
0142  *        that contains the interrupt mode information.
0143  */
0144 void GPIO_PinSetInterruptConfig(GPIO_Type *base, uint32_t pin, gpio_interrupt_mode_t pinInterruptMode)
0145 {
0146     volatile uint32_t *icr;
0147     uint32_t icrShift;
0148 
0149     icrShift = pin;
0150 
0151     /* Register reset to default value */
0152     base->EDGE_SEL &= ~(1UL << pin);
0153 
0154     if (pin < 16U)
0155     {
0156         icr = &(base->ICR1);
0157     }
0158     else
0159     {
0160         icr = &(base->ICR2);
0161         icrShift -= 16U;
0162     }
0163     switch (pinInterruptMode)
0164     {
0165         case (kGPIO_IntLowLevel):
0166             *icr &= ~(3UL << (2UL * icrShift));
0167             break;
0168         case (kGPIO_IntHighLevel):
0169             *icr = (*icr & (~(3UL << (2UL * icrShift)))) | (1UL << (2UL * icrShift));
0170             break;
0171         case (kGPIO_IntRisingEdge):
0172             *icr = (*icr & (~(3UL << (2UL * icrShift)))) | (2UL << (2UL * icrShift));
0173             break;
0174         case (kGPIO_IntFallingEdge):
0175             *icr |= (3UL << (2UL * icrShift));
0176             break;
0177         case (kGPIO_IntRisingOrFallingEdge):
0178             base->EDGE_SEL |= (1UL << pin);
0179             break;
0180         default:; /* Intentional empty default */
0181             break;
0182     }
0183 }