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