1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 /**
10 * @file gpio_driver.c
11 * @brief The gpio_driver.c file contains Generic API Adaption to SDK 2.0 GPIO Driver.
12 */
13 
14 #include "gpio_driver.h"
15 
16 /*******************************************************************************
17 * Definitions
18 ******************************************************************************/
19 #define GPIO_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 0) /* driver version */
20 // ISR handler array for each gpio pin in the system
21 #define GPIO_NUMBER_OF_PIN 0x20
22 
23 /*******************************************************************************
24 * Variables
25 ******************************************************************************/
26 
27 /* Driver Version */
28 static const GENERIC_DRIVER_VERSION DriverVersion = {GPIO_API_VERSION, GPIO_DRV_VERSION};
29 static gpioIsrObj_t isrObj[TOTAL_NUMBER_PORT][GPIO_NUMBER_OF_PIN];
30 static gpioConfigKSDK_t gpioConfigDefault = {
31     .pinConfig = {kGPIO_DigitalInput, 0}, .portPinConfig = {0}, .interruptMode = kPORT_InterruptRisingEdge};
32 
33 /*******************************************************************************
34  * Code
35  ******************************************************************************/
36 
37 /***********************************************************************
38  *
39  * Function Name : ksdk_gpio_get_version
40  * Description   : get the driver version.
41  *
42  ***************************************************************************/
ksdk_gpio_get_version(void)43 GENERIC_DRIVER_VERSION ksdk_gpio_get_version(void)
44 {
45     return DriverVersion;
46 }
47 
48 /***********************************************************************
49  *
50  * Function Name : ksdk_gpio_pin_init
51  * Description   : Initialize particular GPIO pin used by board.
52  *
53  ***************************************************************************/
ksdk_gpio_pin_init(pinID_t aPinId,gpio_direction_t dir,void * apPinConfig,gpio_isr_handler_t aIsrHandler,void * apUserData)54 void ksdk_gpio_pin_init(
55     pinID_t aPinId, gpio_direction_t dir, void *apPinConfig, gpio_isr_handler_t aIsrHandler, void *apUserData)
56 {
57     gpioConfigKSDK_t *pGpioConfig = (gpioConfigKSDK_t *)apPinConfig;
58     gpioHandleKSDK_t *pinHandle = (gpioHandleKSDK_t *)aPinId;
59     if (NULL == apPinConfig)
60     {
61         pGpioConfig = &gpioConfigDefault;
62         pGpioConfig->portPinConfig.pullSelect = kPORT_PullUp;
63         pGpioConfig->portPinConfig.mux = kPORT_MuxAsGpio;
64     }
65     // Configure the clock
66     CLOCK_EnableClock(pinHandle->clockName);
67 
68     // Set the port pin configuration value
69     PORT_SetPinConfig(pinHandle->portBase, pinHandle->pinNumber, &pGpioConfig->portPinConfig);
70 
71     pGpioConfig->pinConfig.pinDirection = dir == GPIO_DIRECTION_IN ? kGPIO_DigitalInput : kGPIO_DigitalOutput;
72     // Set the pin information
73     GPIO_PinInit(pinHandle->base, pinHandle->pinNumber, &pGpioConfig->pinConfig);
74 
75     // Isr is installed
76     if (aIsrHandler)
77     {
78         // Enable the IRQ
79         EnableIRQ(pinHandle->irq);
80         isrObj[pinHandle->portNumber][pinHandle->pinNumber].isrHandle = aIsrHandler;
81         isrObj[pinHandle->portNumber][pinHandle->pinNumber].pUserData = apUserData;
82         // Enable the interrupt on a pin.
83         PORT_SetPinInterruptConfig(pinHandle->portBase, pinHandle->pinNumber, pGpioConfig->interruptMode);
84     }
85 }
86 
87 /***********************************************************************
88  *
89  * Function Name : ksdk_gpio_set_pin
90  * Description   : Set output level of individual GPIO pin to logic 1.
91  *
92  ***************************************************************************/
ksdk_gpio_set_pin(pinID_t aPinId)93 void ksdk_gpio_set_pin(pinID_t aPinId)
94 {
95     gpioHandleKSDK_t *pinHandle = (gpioHandleKSDK_t *)aPinId;
96     GPIO_PortSet(pinHandle->base, pinHandle->mask);
97 }
98 
99 /***********************************************************************
100  *
101  * Function Name : ksdk_gpio_clr_pin
102  * Description   : Set output level of individual GPIO pin to logic 0..
103  *
104  ***************************************************************************/
ksdk_gpio_clr_pin(pinID_t aPinId)105 void ksdk_gpio_clr_pin(pinID_t aPinId)
106 {
107     gpioHandleKSDK_t *pinHandle = (gpioHandleKSDK_t *)aPinId;
108     GPIO_PortClear(pinHandle->base, pinHandle->mask);
109 }
110 
111 /***********************************************************************
112  *
113  * Function Name : ksdk_gpio_toggle_pin
114  * Description   : toggle the currrent output logic of individual GPIO pin.
115  *
116  ***************************************************************************/
ksdk_gpio_toggle_pin(pinID_t aPinId)117 void ksdk_gpio_toggle_pin(pinID_t aPinId)
118 {
119     gpioHandleKSDK_t *pinHandle = (gpioHandleKSDK_t *)aPinId;
120     GPIO_PortToggle(pinHandle->base, pinHandle->mask);
121 }
122 
123 /***********************************************************************
124  *
125  * Function Name : ksdk_gpio_write_pin
126  * Description   : Set output level of individual GPIO pin to desired value, ie 1 or 0.
127  *
128  ***************************************************************************/
ksdk_gpio_write_pin(pinID_t aPinId,uint8_t aValue)129 void ksdk_gpio_write_pin(pinID_t aPinId, uint8_t aValue)
130 {
131     gpioHandleKSDK_t *pinHandle = (gpioHandleKSDK_t *)aPinId;
132     GPIO_PinWrite(pinHandle->base, pinHandle->pinNumber, aValue);
133 }
134 
135 /***********************************************************************
136  *
137  * Function Name : ksdk_gpio_read_pin
138  * Description   : Read current input value of individual GPIO pin.
139  *
140  ***************************************************************************/
ksdk_gpio_read_pin(pinID_t aPinId)141 uint32_t ksdk_gpio_read_pin(pinID_t aPinId)
142 {
143     gpioHandleKSDK_t *pinHandle = (gpioHandleKSDK_t *)aPinId;
144     return GPIO_PinRead(pinHandle->base, pinHandle->pinNumber);
145 }
146 
147 /***********************************************************************
148  *
149  * Function Name : ksdk_gpio_handle_interrupt
150  * Description   : handle the gpio interrupt in a pin.
151  *
152  ***************************************************************************/
ksdk_gpio_handle_interrupt(GPIO_Type * apBase,port_number_t aPortNumber)153 void ksdk_gpio_handle_interrupt(GPIO_Type *apBase, port_number_t aPortNumber)
154 {
155     uint32_t isfr = GPIO_PortGetInterruptFlags(apBase);
156 
157     // parse through all the pending interrupt for a PORT
158     for (uint8_t i = 0; i < GPIO_NUMBER_OF_PIN; i++)
159     {
160         if (isfr & (1 << i))
161         {
162             gpio_isr_handler_t handle = isrObj[aPortNumber][i].isrHandle;
163             if (handle == NULL)
164             {
165                 continue;
166             }
167             // call user defined handler
168             handle(isrObj[aPortNumber][i].pUserData);
169             GPIO_PortClearInterruptFlags(apBase, (1 << i));
170         }
171     }
172 }
173 
174 GENERIC_DRIVER_GPIO Driver_GPIO_KSDK = {
175     ksdk_gpio_get_version, ksdk_gpio_pin_init,  ksdk_gpio_set_pin,  ksdk_gpio_clr_pin,
176     ksdk_gpio_toggle_pin,  ksdk_gpio_write_pin, ksdk_gpio_read_pin,
177 };
178