1 /*
2 * Copyright 2018 - 2022 NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_device_registers.h"
10 #include "fsl_gpio.h"
11 #include "fsl_adapter_gpio.h"
12
13 /* Component ID definition, used by tools. */
14 #ifndef FSL_COMPONENT_ID
15 #define FSL_COMPONENT_ID "component.rt_gpio_adapter"
16 #endif
17
18 /*******************************************************************************
19 * Definitions
20 ******************************************************************************/
21
22 /*! @brief The pin config struct of gpio adapter. */
23 typedef struct _hal_gpio_pin
24 {
25 uint16_t port : 3U;
26 uint16_t pin : 5U;
27 uint16_t direction : 1U;
28 uint16_t trigger : 3U;
29 uint16_t reserved : 4U;
30 } hal_gpio_pin_t;
31
32 typedef struct _hal_gpio_state
33 {
34 struct _hal_gpio_state *next;
35 hal_gpio_callback_t callback;
36 void *callbackParam;
37 hal_gpio_pin_t pin;
38 } hal_gpio_state_t;
39
40 /*******************************************************************************
41 * Prototypes
42 ******************************************************************************/
43
44 /*******************************************************************************
45 * Variables
46 ******************************************************************************/
47 static hal_gpio_state_t *s_GpioHead;
48 static uint32_t s_GPIO_PORT_initFlag = 0U;
49
50 #define SET_GPIO_PORT_INIT_FLAG(port) (s_GPIO_PORT_initFlag |= 1UL << (port))
51 #define GET_GPIO_PORT_INIT_FLAG(port) ((0U != (s_GPIO_PORT_initFlag & (1UL << (port)))) ? 1U : 0U)
52 #define CLEAR_GPIO_PORT_INIT_FLAG(port) (s_GPIO_PORT_initFlag &= ~(1UL << (port)))
53
54 /*******************************************************************************
55 * Code
56 ******************************************************************************/
57
HAL_GpioInterruptHandle(uint32_t intNum)58 static void HAL_GpioInterruptHandle(uint32_t intNum)
59 {
60 hal_gpio_state_t *head = s_GpioHead;
61 gpio_interrupt_config_t triggerConfig;
62 uint32_t portIntFlags = 0U;
63 uint8_t pinLevel;
64
65 while (NULL != head)
66 {
67 portIntFlags = GPIO_PortGetInterruptStatus(GPIO, head->pin.port, intNum);
68 if (0U != (portIntFlags & (1UL << head->pin.pin)))
69 {
70 if (NULL != head->callback)
71 {
72 head->callback(head->callbackParam);
73 }
74 GPIO_PinClearInterruptFlag(GPIO, head->pin.port, head->pin.pin, intNum);
75 if ((uint16_t)kHAL_GpioInterruptEitherEdge == head->pin.trigger)
76 {
77 pinLevel = (uint8_t)GPIO_PinRead(GPIO, head->pin.port, head->pin.pin);
78 triggerConfig.mode = (uint8_t)kGPIO_PinIntEnableEdge;
79 triggerConfig.polarity =
80 (0U != pinLevel) ? (uint8_t)kGPIO_PinIntEnableLowOrFall : (uint8_t)kGPIO_PinIntEnableHighOrRise;
81 GPIO_SetPinInterruptConfig(GPIO, head->pin.port, head->pin.pin, &triggerConfig);
82 }
83 }
84
85 head = head->next;
86 }
87 }
88
89 /*!
90 * @brief Interrupt service fuction of switch.
91 */
92 void GPIO_INTA_DriverIRQHandler(void);
GPIO_INTA_DriverIRQHandler(void)93 void GPIO_INTA_DriverIRQHandler(void)
94 {
95 HAL_GpioInterruptHandle(0);
96 SDK_ISR_EXIT_BARRIER;
97 }
98
99 void GPIO_INTB_DriverIRQHandler(void);
GPIO_INTB_DriverIRQHandler(void)100 void GPIO_INTB_DriverIRQHandler(void)
101 {
102 HAL_GpioInterruptHandle(1);
103 SDK_ISR_EXIT_BARRIER;
104 }
105
HAL_GpioConflictSearch(hal_gpio_state_t * head,uint8_t port,uint8_t pin)106 static hal_gpio_status_t HAL_GpioConflictSearch(hal_gpio_state_t *head, uint8_t port, uint8_t pin)
107 {
108 while (NULL != head)
109 {
110 if ((head->pin.port == port) && (head->pin.pin == pin))
111 {
112 return kStatus_HAL_GpioPinConflict;
113 }
114 head = head->next;
115 }
116 return kStatus_HAL_GpioSuccess;
117 }
118
HAL_GpioAddItem(hal_gpio_state_t ** head,hal_gpio_state_t * node)119 static hal_gpio_status_t HAL_GpioAddItem(hal_gpio_state_t **head, hal_gpio_state_t *node)
120 {
121 hal_gpio_state_t *p = *head;
122 uint32_t regPrimask;
123
124 regPrimask = DisableGlobalIRQ();
125
126 if (NULL == p)
127 {
128 *head = node;
129 }
130 else
131 {
132 while (NULL != p->next)
133 {
134 if (p == node)
135 {
136 EnableGlobalIRQ(regPrimask);
137 return kStatus_HAL_GpioPinConflict;
138 }
139 p = p->next;
140 }
141
142 p->next = node;
143 }
144 node->next = NULL;
145 EnableGlobalIRQ(regPrimask);
146 return kStatus_HAL_GpioSuccess;
147 }
148
HAL_GpioRemoveItem(hal_gpio_state_t ** head,hal_gpio_state_t * node)149 static hal_gpio_status_t HAL_GpioRemoveItem(hal_gpio_state_t **head, hal_gpio_state_t *node)
150 {
151 hal_gpio_state_t *p = *head;
152 hal_gpio_state_t *q = NULL;
153 uint32_t regPrimask;
154
155 regPrimask = DisableGlobalIRQ();
156 while (NULL != p)
157 {
158 if (p == node)
159 {
160 if (NULL == q)
161 {
162 *head = p->next;
163 }
164 else
165 {
166 q->next = p->next;
167 }
168 break;
169 }
170 else
171 {
172 q = p;
173 p = p->next;
174 }
175 }
176 EnableGlobalIRQ(regPrimask);
177 return kStatus_HAL_GpioSuccess;
178 }
179
HAL_GpioPreInit(void)180 void HAL_GpioPreInit(void)
181 {
182 s_GPIO_PORT_initFlag = 0U;
183 s_GpioHead = NULL;
184 }
185
HAL_GpioInit(hal_gpio_handle_t gpioHandle,hal_gpio_pin_config_t * pinConfig)186 hal_gpio_status_t HAL_GpioInit(hal_gpio_handle_t gpioHandle, hal_gpio_pin_config_t *pinConfig)
187 {
188 hal_gpio_state_t *gpioState;
189 hal_gpio_status_t status = kStatus_HAL_GpioSuccess;
190 gpio_pin_config_t gpioPinConfig = {kGPIO_DigitalInput, 0};
191 uint32_t regPrimask;
192 uint8_t portNeedInit = 0;
193
194 assert(gpioHandle);
195 assert(pinConfig);
196
197 gpioState = (hal_gpio_state_t *)gpioHandle;
198
199 /* Check if it is conflict */
200 if ((NULL != s_GpioHead) &&
201 (kStatus_HAL_GpioSuccess != HAL_GpioConflictSearch(s_GpioHead, pinConfig->port, pinConfig->pin)))
202 {
203 return kStatus_HAL_GpioPinConflict;
204 }
205
206 status = HAL_GpioAddItem(&s_GpioHead, gpioState);
207 if (kStatus_HAL_GpioSuccess != status)
208 {
209 return status;
210 }
211
212 gpioState->pin.pin = pinConfig->pin;
213 gpioState->pin.port = pinConfig->port;
214 gpioState->pin.direction = (uint16_t)pinConfig->direction;
215 gpioState->pin.trigger = (uint16_t)kHAL_GpioInterruptDisable;
216
217 if (kHAL_GpioDirectionOut == pinConfig->direction)
218 {
219 gpioPinConfig.pinDirection = kGPIO_DigitalOutput;
220 gpioPinConfig.outputLogic = pinConfig->level;
221 }
222 else
223 {
224 gpioPinConfig.pinDirection = kGPIO_DigitalInput;
225 }
226
227 /* Critical protection */
228 regPrimask = DisableGlobalIRQ();
229 if (0U == GET_GPIO_PORT_INIT_FLAG(gpioState->pin.port))
230 {
231 SET_GPIO_PORT_INIT_FLAG(gpioState->pin.port);
232 portNeedInit = 1U;
233 }
234 EnableGlobalIRQ(regPrimask);
235
236 if (1U == portNeedInit)
237 {
238 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
239 /*! @brief Array to map FGPIO instance number to clock name. */
240 const clock_ip_name_t gpioClockName[] = GPIO_CLOCKS;
241
242 assert(gpioState->pin.port < ARRAY_SIZE(gpioClockName));
243 CLOCK_EnableClock(gpioClockName[gpioState->pin.port]);
244 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
245
246 #if !(defined(FSL_FEATURE_GPIO_HAS_NO_RESET) && FSL_FEATURE_GPIO_HAS_NO_RESET)
247 /*! @brief Pointers to GPIO resets for each instance. */
248 const reset_ip_name_t gpioResets[] = GPIO_RSTS_N;
249
250 RESET_ClearPeripheralReset(gpioResets[gpioState->pin.port]);
251 #endif /* FSL_FEATURE_GPIO_HAS_NO_RESET */
252 }
253
254 GPIO_PinInit(GPIO, gpioState->pin.port, gpioState->pin.pin, &gpioPinConfig);
255
256 return kStatus_HAL_GpioSuccess;
257 }
258
HAL_GpioDeinit(hal_gpio_handle_t gpioHandle)259 hal_gpio_status_t HAL_GpioDeinit(hal_gpio_handle_t gpioHandle)
260 {
261 hal_gpio_state_t *gpioState;
262
263 assert(gpioHandle);
264
265 gpioState = (hal_gpio_state_t *)gpioHandle;
266
267 if ((uint16_t)kHAL_GpioDirectionIn == gpioState->pin.direction)
268 {
269 GPIO_PinDisableInterrupt(GPIO, gpioState->pin.port, gpioState->pin.pin, 0);
270 }
271
272 (void)HAL_GpioRemoveItem(&s_GpioHead, gpioState);
273 return kStatus_HAL_GpioSuccess;
274 }
275
HAL_GpioGetInput(hal_gpio_handle_t gpioHandle,uint8_t * pinState)276 hal_gpio_status_t HAL_GpioGetInput(hal_gpio_handle_t gpioHandle, uint8_t *pinState)
277 {
278 hal_gpio_state_t *gpioStateHandle;
279
280 assert(gpioHandle);
281
282 gpioStateHandle = (hal_gpio_state_t *)gpioHandle;
283
284 *pinState = (uint8_t)GPIO_PinRead(GPIO, gpioStateHandle->pin.port, gpioStateHandle->pin.pin);
285
286 return kStatus_HAL_GpioSuccess;
287 }
288
HAL_GpioSetOutput(hal_gpio_handle_t gpioHandle,uint8_t pinState)289 hal_gpio_status_t HAL_GpioSetOutput(hal_gpio_handle_t gpioHandle, uint8_t pinState)
290 {
291 hal_gpio_state_t *gpioStateHandle;
292
293 assert(gpioHandle);
294
295 gpioStateHandle = (hal_gpio_state_t *)gpioHandle;
296
297 GPIO_PinWrite(GPIO, gpioStateHandle->pin.port, gpioStateHandle->pin.pin, (0U != pinState) ? 1U : 0U);
298
299 return kStatus_HAL_GpioSuccess;
300 }
301
HAL_GpioInstallCallback(hal_gpio_handle_t gpioHandle,hal_gpio_callback_t callback,void * callbackParam)302 hal_gpio_status_t HAL_GpioInstallCallback(hal_gpio_handle_t gpioHandle,
303 hal_gpio_callback_t callback,
304 void *callbackParam)
305 {
306 hal_gpio_state_t *gpioStateHandle;
307
308 assert(gpioHandle);
309
310 gpioStateHandle = (hal_gpio_state_t *)gpioHandle;
311
312 gpioStateHandle->callbackParam = callbackParam;
313 gpioStateHandle->callback = callback;
314
315 return kStatus_HAL_GpioSuccess;
316 }
317
HAL_GpioGetTriggerMode(hal_gpio_handle_t gpioHandle,hal_gpio_interrupt_trigger_t * gpioTrigger)318 hal_gpio_status_t HAL_GpioGetTriggerMode(hal_gpio_handle_t gpioHandle, hal_gpio_interrupt_trigger_t *gpioTrigger)
319 {
320 hal_gpio_state_t *gpioStateHandle;
321
322 assert(gpioHandle);
323
324 gpioStateHandle = (hal_gpio_state_t *)gpioHandle;
325
326 if ((uint16_t)kHAL_GpioDirectionOut == gpioStateHandle->pin.direction)
327 {
328 return kStatus_HAL_GpioError;
329 }
330
331 *gpioTrigger = (hal_gpio_interrupt_trigger_t)gpioStateHandle->pin.trigger;
332 return kStatus_HAL_GpioSuccess;
333 }
334
HAL_GpioSetTriggerMode(hal_gpio_handle_t gpioHandle,hal_gpio_interrupt_trigger_t gpioTrigger)335 hal_gpio_status_t HAL_GpioSetTriggerMode(hal_gpio_handle_t gpioHandle, hal_gpio_interrupt_trigger_t gpioTrigger)
336 {
337 hal_gpio_state_t *gpioStateHandle;
338 gpio_interrupt_config_t triggerConfig;
339 uint32_t pinLevel = 0U;
340 uint8_t trigerDisable = 0U;
341
342 assert(gpioHandle);
343
344 gpioStateHandle = (hal_gpio_state_t *)gpioHandle;
345
346 assert((uint16_t)kHAL_GpioDirectionOut != gpioStateHandle->pin.direction);
347
348 switch (gpioTrigger)
349 {
350 case kHAL_GpioInterruptLogicZero:
351 triggerConfig.mode = (uint8_t)kGPIO_PinIntEnableLevel;
352 triggerConfig.polarity = (uint8_t)kGPIO_PinIntEnableLowOrFall;
353 break;
354 case kHAL_GpioInterruptLogicOne:
355 triggerConfig.mode = (uint8_t)kGPIO_PinIntEnableLevel;
356 triggerConfig.polarity = (uint8_t)kGPIO_PinIntEnableHighOrRise;
357 break;
358 case kHAL_GpioInterruptRisingEdge:
359 triggerConfig.mode = (uint8_t)kGPIO_PinIntEnableEdge;
360 triggerConfig.polarity = (uint8_t)kGPIO_PinIntEnableHighOrRise;
361 break;
362 case kHAL_GpioInterruptFallingEdge:
363 triggerConfig.mode = (uint8_t)kGPIO_PinIntEnableEdge;
364 triggerConfig.polarity = (uint8_t)kGPIO_PinIntEnableLowOrFall;
365 break;
366 case kHAL_GpioInterruptEitherEdge:
367 /* Here will get pin's default level to decide which edge trigger for the first time */
368 pinLevel = GPIO_PinRead(GPIO, gpioStateHandle->pin.port, gpioStateHandle->pin.pin);
369 triggerConfig.mode = (uint8_t)kGPIO_PinIntEnableEdge;
370 triggerConfig.polarity =
371 (0U != pinLevel) ? (uint8_t)kGPIO_PinIntEnableLowOrFall : (uint8_t)kGPIO_PinIntEnableHighOrRise;
372 break;
373 default:
374 trigerDisable = 1U;
375 break;
376 }
377
378 gpioStateHandle->pin.trigger = (uint16_t)gpioTrigger;
379
380 /* Set trigger interrupt */
381 if (1U != trigerDisable)
382 {
383 GPIO_SetPinInterruptConfig(GPIO, gpioStateHandle->pin.port, gpioStateHandle->pin.pin, &triggerConfig);
384 GPIO_PinEnableInterrupt(GPIO, gpioStateHandle->pin.port, gpioStateHandle->pin.pin, 0);
385 NVIC_SetPriority(GPIO_INTA_IRQn, HAL_GPIO_ISR_PRIORITY);
386 NVIC_EnableIRQ(GPIO_INTA_IRQn);
387 }
388 else
389 {
390 GPIO_PinDisableInterrupt(GPIO, gpioStateHandle->pin.port, gpioStateHandle->pin.pin, 0);
391 }
392
393 return kStatus_HAL_GpioSuccess;
394 }
395
HAL_GpioWakeUpSetting(hal_gpio_handle_t gpioHandle,uint8_t enable)396 hal_gpio_status_t HAL_GpioWakeUpSetting(hal_gpio_handle_t gpioHandle, uint8_t enable)
397 {
398 hal_gpio_state_t *gpioStateHandle;
399 assert(gpioHandle);
400
401 gpioStateHandle = (hal_gpio_state_t *)gpioHandle;
402
403 if ((uint16_t)kHAL_GpioDirectionOut == gpioStateHandle->pin.direction)
404 {
405 return kStatus_HAL_GpioError;
406 }
407
408 return kStatus_HAL_GpioSuccess;
409 }
410
HAL_GpioEnterLowpower(hal_gpio_handle_t gpioHandle)411 hal_gpio_status_t HAL_GpioEnterLowpower(hal_gpio_handle_t gpioHandle)
412 {
413 assert(gpioHandle);
414
415 return kStatus_HAL_GpioSuccess;
416 }
417
HAL_GpioExitLowpower(hal_gpio_handle_t gpioHandle)418 hal_gpio_status_t HAL_GpioExitLowpower(hal_gpio_handle_t gpioHandle)
419 {
420 assert(gpioHandle);
421
422 return kStatus_HAL_GpioSuccess;
423 }
424