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 * The type and variable names have been kept aligned to Kinetis family for compatibility of examples.
13 */
14
15 #include "gpio_driver.h"
16
17 /*******************************************************************************
18 * Definitions
19 ******************************************************************************/
20 #define GPIO_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 2) /* driver version */
21 #define GINT_COUNT (sizeof(gintBases) / sizeof(void *)) /* Number of GINTs*/
22 #define GINT_NUMBER_OF_PIN 32 /* Each Port has 32 Pins */
23
24 /*******************************************************************************
25 * Prototypes
26 ******************************************************************************/
27 GINT_Type *const gintBases[] = GINT_BASE_PTRS;
28 #if defined(GINT0)
29 extern void PORT0_IRQHandler(void);
30 #endif
31 #if defined(GINT1)
32 extern void PORT1_IRQHandler(void);
33 #endif
34 #if defined(GINT2)
35 extern void PORT2_IRQHandler(void);
36 #endif
37 #if defined(GINT3)
38 extern void PORT3_IRQHandler(void);
39 #endif
40 #if defined(GINT4)
41 extern void PORT4_IRQHandler(void);
42 #endif
43 #if defined(GINT5)
44 extern void PORT5_IRQHandler(void);
45 #endif
46 #if defined(GINT6)
47 extern void PORT6_IRQHandler(void);
48 #endif
49 #if defined(GINT7)
50 extern void PORT7_IRQHandler(void);
51 #endif
52
53 /*******************************************************************************
54 * Variables
55 ******************************************************************************/
56
57 /* Driver Version */
58 static const GENERIC_DRIVER_VERSION DriverVersion = {GPIO_API_VERSION, GPIO_DRV_VERSION};
59 /* ISR handler array for each gpio pin in the system */
60 static gpioIsrObj_t isrObj[GINT_COUNT][GINT_NUMBER_OF_PIN];
61 /* GPIO Pin characteristic */
62 static gpioConfigKSDK_t gpioConfigDefault = {
63 .pinConfig = {kGPIO_DigitalInput, 0}, .interruptMode = kGINT_TrigEdge, .interruptPolarity = kGINT_InterruptLogic_1,
64 };
65 /* GINT base specific ISR callback list */
66 static gint_cb_t gintIsrCb[GINT_COUNT] = {
67 #if defined(GINT0)
68 PORT0_IRQHandler,
69 #endif
70 #if defined(GINT1)
71 PORT1_IRQHandler,
72 #endif
73 #if defined(GINT2)
74 PORT2_IRQHandler,
75 #endif
76 #if defined(GINT3)
77 PORT3_IRQHandler,
78 #endif
79 #if defined(GINT4)
80 PORT4_IRQHandler,
81 #endif
82 #if defined(GINT5)
83 PORT5_IRQHandler,
84 #endif
85 #if defined(GINT6)
86 PORT6_IRQHandler,
87 #endif
88 #if defined(GINT7)
89 PORT7_IRQHandler,
90 #endif
91 };
92
93 /*******************************************************************************
94 * Code
95 ******************************************************************************/
96
97 /***********************************************************************
98 *
99 * Function Name : ksdk_gpio_get_version
100 * Description : get the driver version.
101 *
102 ***************************************************************************/
ksdk_gpio_get_version(void)103 GENERIC_DRIVER_VERSION ksdk_gpio_get_version(void)
104 {
105 return DriverVersion;
106 }
107
108 /***********************************************************************
109 *
110 * Function Name : ksdk_gpio_pin_init
111 * Description : Initialize particular GPIO pin used by board.
112 *
113 ***************************************************************************/
ksdk_gpio_pin_init(pinID_t aPinId,gpio_direction_t dir,void * apPinConfig,gpio_isr_handler_t aIsrHandler,void * apUserData)114 void ksdk_gpio_pin_init(
115 pinID_t aPinId, gpio_direction_t dir, void *apPinConfig, gpio_isr_handler_t aIsrHandler, void *apUserData)
116 {
117 uint32_t polarityMask, enableMask;
118
119 gpioConfigKSDK_t *pGpioConfig;
120 gpioHandleKSDK_t *pinHandle = (gpioHandleKSDK_t *)aPinId;
121 if (NULL == apPinConfig)
122 {
123 pGpioConfig = &gpioConfigDefault;
124 }
125 else
126 {
127 pGpioConfig = (gpioConfigKSDK_t *)apPinConfig;
128 }
129
130 // Configure as GPIO
131 CLOCK_EnableClock(pinHandle->clockName);
132 pGpioConfig->pinConfig.pinDirection = (dir == GPIO_DIRECTION_IN) ? kGPIO_DigitalInput : kGPIO_DigitalOutput;
133 GPIO_PinInit(pinHandle->base, pinHandle->portNumber, pinHandle->pinNumber, &pGpioConfig->pinConfig);
134
135 // Configure is GINT if ISR requested (There should be as many GINTs as there are GPIO Ports).
136 if (aIsrHandler && pinHandle->portNumber < GINT_COUNT)
137 {
138 /* Initialize GINT device for the associated Port */
139 GINT_Init(gintBases[pinHandle->portNumber]);
140
141 // Enable the IRQ
142 isrObj[pinHandle->portNumber][pinHandle->pinNumber].isrHandle = aIsrHandler;
143 isrObj[pinHandle->portNumber][pinHandle->pinNumber].pUserData = apUserData;
144
145 /* Setup GINT trigger mode and "OR" mode */
146 GINT_SetCtrl(gintBases[pinHandle->portNumber], kGINT_CombineOr, pGpioConfig->interruptMode,
147 gintIsrCb[pinHandle->portNumber]);
148
149 /* Get current pins & polarity for GINT */
150 GINT_GetConfigPins(gintBases[pinHandle->portNumber], pinHandle->portNumber, &polarityMask, &enableMask);
151
152 /* Update Polarity for this PIN */
153 if (pGpioConfig->interruptPolarity == kGINT_InterruptLogic_1)
154 {
155 polarityMask |= pinHandle->mask; /* Logic 1 for : Level High or Rising Edge */
156 }
157 else
158 {
159 polarityMask &= ~(pinHandle->mask); /* Logic 0 for : Level Low or Falling Edge */
160 }
161 enableMask |= pinHandle->mask;
162
163 /* Select pins & polarity for GINT */
164 GINT_ConfigPins(gintBases[pinHandle->portNumber], pinHandle->portNumber, polarityMask, enableMask);
165
166 /* Enable callbacks for GINT */
167 GINT_EnableCallback(gintBases[pinHandle->portNumber]);
168 }
169 }
170
171 /***********************************************************************
172 *
173 * Function Name : ksdk_gpio_set_pin
174 * Description : Set output level of individual GPIO pin to logic 1.
175 *
176 ***************************************************************************/
ksdk_gpio_set_pin(pinID_t aPinId)177 void ksdk_gpio_set_pin(pinID_t aPinId)
178 {
179 gpioHandleKSDK_t *pinHandle = (gpioHandleKSDK_t *)aPinId;
180 GPIO_PortSet(pinHandle->base, pinHandle->portNumber, pinHandle->mask);
181 }
182
183 /***********************************************************************
184 *
185 * Function Name : ksdk_gpio_clr_pin
186 * Description : Set output level of individual GPIO pin to logic 0..
187 *
188 ***************************************************************************/
ksdk_gpio_clr_pin(pinID_t aPinId)189 void ksdk_gpio_clr_pin(pinID_t aPinId)
190 {
191 gpioHandleKSDK_t *pinHandle = (gpioHandleKSDK_t *)aPinId;
192 GPIO_PortClear(pinHandle->base, pinHandle->portNumber, pinHandle->mask);
193 }
194
195 /***********************************************************************
196 *
197 * Function Name : ksdk_gpio_toggle_pin
198 * Description : toggle the currrent output logic of individual GPIO pin.
199 *
200 ***************************************************************************/
ksdk_gpio_toggle_pin(pinID_t aPinId)201 void ksdk_gpio_toggle_pin(pinID_t aPinId)
202 {
203 gpioHandleKSDK_t *pinHandle = (gpioHandleKSDK_t *)aPinId;
204 GPIO_PortToggle(pinHandle->base, pinHandle->portNumber, pinHandle->mask);
205 }
206
207 /***********************************************************************
208 *
209 * Function Name : ksdk_gpio_write_pin
210 * Description : Set output level of individual GPIO pin to desired value, ie 1 or 0.
211 *
212 ***************************************************************************/
ksdk_gpio_write_pin(pinID_t aPinId,uint8_t aValue)213 void ksdk_gpio_write_pin(pinID_t aPinId, uint8_t aValue)
214 {
215 gpioHandleKSDK_t *pinHandle = (gpioHandleKSDK_t *)aPinId;
216 GPIO_PinWrite(pinHandle->base, pinHandle->portNumber, pinHandle->pinNumber, aValue);
217 }
218
219 /***********************************************************************
220 *
221 * Function Name : ksdk_gpio_read_pin
222 * Description : Read current input value of individual GPIO pin.
223 *
224 ***************************************************************************/
ksdk_gpio_read_pin(pinID_t aPinId)225 uint32_t ksdk_gpio_read_pin(pinID_t aPinId)
226 {
227 gpioHandleKSDK_t *pinHandle = (gpioHandleKSDK_t *)aPinId;
228 return GPIO_PinRead(pinHandle->base, pinHandle->portNumber, pinHandle->pinNumber);
229 }
230
231 /***********************************************************************
232 *
233 * Function Name : ksdk_gpio_handle_interrupt
234 * Description : handle the gint interrupt of a port.
235 *
236 ***************************************************************************/
issdk_gpio_handle_interrupt(GINT_Type * apBase,gint_port_t aPortNumber)237 void issdk_gpio_handle_interrupt(GINT_Type *apBase, gint_port_t aPortNumber)
238 {
239 uint32_t enableMask, polarityMask;
240
241 GINT_GetConfigPins(apBase, aPortNumber, &polarityMask, &enableMask);
242 // parse through all the pending interrupt for a PORT
243 for (uint8_t i = 0; i < GINT_NUMBER_OF_PIN; i++)
244 {
245 if (enableMask & (1 << i))
246 {
247 gpio_isr_handler_t handle = isrObj[aPortNumber][i].isrHandle;
248 if (handle == NULL)
249 {
250 continue;
251 }
252 // call user defined handler
253 handle(isrObj[aPortNumber][i].pUserData);
254 }
255 }
256 }
257
258 GENERIC_DRIVER_GPIO Driver_GPIO_KSDK = {
259 ksdk_gpio_get_version, ksdk_gpio_pin_init, ksdk_gpio_set_pin, ksdk_gpio_clr_pin,
260 ksdk_gpio_toggle_pin, ksdk_gpio_write_pin, ksdk_gpio_read_pin,
261 };
262