1 /*
2 * Copyright (c) 2006-2024, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2023-03-24 YangXi the first version.
9 */
10 #include "drv_pin.h"
11
12 #include "fsl_common.h"
13 #include "fsl_gpio.h"
14 #include "fsl_port.h"
15 #include "fsl_pint.h"
16 #include "fsl_inputmux.h"
17
18 #ifdef RT_USING_PIN
19
20
21 #define GET_GPIO_PORT(x) ((x) / 32)
22 #define GET_GPIO_PIN(x) ((x) % 32)
23
24 static struct rt_pin_ops mcx_pin_ops;
25
26 static GPIO_Type *GPIO_TYPE_TBL[] = {GPIO0, GPIO1, GPIO2, GPIO3, GPIO4};
27 static PORT_Type *PORT_TYPE_TBL[] = {PORT0, PORT1, PORT2, PORT3, PORT4};
28 static IRQn_Type IRQ_TYPE_TBL[] = {GPIO00_IRQn, GPIO10_IRQn, GPIO20_IRQn, GPIO30_IRQn, GPIO40_IRQn};
29
30
31 #define PIN2GPIO(x) GPIO_TYPE_TBL[GET_GPIO_PORT(x)]
32 #define PIN2PORT(x) PORT_TYPE_TBL[GET_GPIO_PORT(x)]
33 #define PIN2IRQ(x) IRQ_TYPE_TBL[GET_GPIO_PORT(x)]
34
35 struct rt_pin_irq_hdr pin_irq_hdr_tab[32*5] = {0};
36
mcx_pin_mode(rt_device_t dev,rt_base_t pin,rt_uint8_t mode)37 static void mcx_pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_t mode)
38 {
39 port_pin_config_t port_pin_config = {0};
40 gpio_pin_config_t gpio_pin_config = {0};
41
42 port_pin_config.mux = kPORT_MuxAlt0;
43
44 switch (mode)
45 {
46 case PIN_MODE_OUTPUT:
47 {
48 gpio_pin_config.pinDirection = kGPIO_DigitalOutput;
49 port_pin_config.pullSelect = kPORT_PullDisable;
50 port_pin_config.inputBuffer = kPORT_InputBufferEnable;
51 }
52 break;
53
54 case PIN_MODE_INPUT:
55 {
56 gpio_pin_config.pinDirection = kGPIO_DigitalInput;
57 port_pin_config.pullSelect = kPORT_PullDisable;
58 port_pin_config.inputBuffer = kPORT_InputBufferEnable;
59 }
60 break;
61
62 case PIN_MODE_INPUT_PULLDOWN:
63 {
64 gpio_pin_config.pinDirection = kGPIO_DigitalInput;
65 port_pin_config.pullSelect = kPORT_PullDown;
66 port_pin_config.pullValueSelect = kPORT_LowPullResistor;
67 port_pin_config.inputBuffer = kPORT_InputBufferEnable;
68 }
69 break;
70
71 case PIN_MODE_INPUT_PULLUP:
72 {
73 gpio_pin_config.pinDirection = kGPIO_DigitalInput;
74 port_pin_config.pullSelect = kPORT_PullUp;
75 port_pin_config.pullValueSelect = kPORT_LowPullResistor;
76 port_pin_config.inputBuffer = kPORT_InputBufferEnable;
77 }
78 break;
79
80 case PIN_MODE_OUTPUT_OD:
81 {
82 port_pin_config.openDrainEnable = kPORT_OpenDrainEnable;
83 gpio_pin_config.pinDirection = kGPIO_DigitalOutput;
84 port_pin_config.inputBuffer = kPORT_InputBufferEnable;
85 }
86 break;
87 }
88
89 PORT_SetPinConfig(PIN2PORT(pin), GET_GPIO_PIN(pin), &port_pin_config);
90 GPIO_PinInit(PIN2GPIO(pin), GET_GPIO_PIN(pin) , &gpio_pin_config);
91 }
92
93
mcx_pin_write(rt_device_t dev,rt_base_t pin,rt_uint8_t value)94 static void mcx_pin_write(rt_device_t dev, rt_base_t pin, rt_uint8_t value)
95 {
96 GPIO_PinWrite(PIN2GPIO(pin), GET_GPIO_PIN(pin), value);
97 }
98
mcx_pin_read(rt_device_t dev,rt_base_t pin)99 static rt_ssize_t mcx_pin_read(rt_device_t dev, rt_base_t pin)
100 {
101 return GPIO_PinRead(PIN2GPIO(pin), GET_GPIO_PIN(pin));
102 }
103
104
105
pin_irq_handler(uint8_t gpio_idx)106 rt_inline void pin_irq_handler(uint8_t gpio_idx)
107 {
108 int i;
109
110 rt_interrupt_enter();
111
112 uint32_t INTFLAG = GPIO_GpioGetInterruptFlags(GPIO_TYPE_TBL[gpio_idx]);
113 GPIO_GpioClearInterruptFlags(GPIO_TYPE_TBL[gpio_idx], INTFLAG);
114
115
116 for(i=0; i<ARRAY_SIZE(pin_irq_hdr_tab); i++)
117 {
118 if((INTFLAG & (1<<GET_GPIO_PIN(pin_irq_hdr_tab[i].pin))) && pin_irq_hdr_tab[i].hdr && (GET_GPIO_PORT(pin_irq_hdr_tab[i].pin)) == gpio_idx)
119 {
120 pin_irq_hdr_tab[i].hdr(pin_irq_hdr_tab[i].args);
121 }
122 }
123
124 rt_interrupt_leave();
125 }
126
GPIO00_IRQHandler(void)127 void GPIO00_IRQHandler(void)
128 {
129 pin_irq_handler(0);
130 }
131
GPIO10_IRQHandler(void)132 void GPIO10_IRQHandler(void)
133 {
134 pin_irq_handler(1);
135 }
136
GPIO20_IRQHandler(void)137 void GPIO20_IRQHandler(void)
138 {
139 pin_irq_handler(2);
140 }
141
GPIO30_IRQHandler(void)142 void GPIO30_IRQHandler(void)
143 {
144 pin_irq_handler(3);
145 }
146
GPIO40_IRQHandler(void)147 void GPIO40_IRQHandler(void)
148 {
149 pin_irq_handler(4);
150 }
151
152
mcx_pin_attach_irq(struct rt_device * device,rt_base_t pin,rt_uint8_t mode,void (* hdr)(void * args),void * args)153 static rt_err_t mcx_pin_attach_irq(struct rt_device *device, rt_base_t pin, rt_uint8_t mode, void (*hdr)(void *args), void *args)
154 {
155 switch (mode)
156 {
157 case PIN_IRQ_MODE_RISING:
158 GPIO_SetPinInterruptConfig(PIN2GPIO(pin), GET_GPIO_PIN(pin), kGPIO_InterruptRisingEdge);
159 break;
160 case PIN_IRQ_MODE_FALLING:
161 GPIO_SetPinInterruptConfig(PIN2GPIO(pin), GET_GPIO_PIN(pin), kGPIO_InterruptFallingEdge);
162 break;
163 case PIN_IRQ_MODE_RISING_FALLING:
164 GPIO_SetPinInterruptConfig(PIN2GPIO(pin), GET_GPIO_PIN(pin), kGPIO_InterruptEitherEdge);
165 break;
166 case PIN_IRQ_MODE_HIGH_LEVEL:
167 GPIO_SetPinInterruptConfig(PIN2GPIO(pin), GET_GPIO_PIN(pin), kGPIO_InterruptLogicOne);
168 break;
169 case PIN_IRQ_MODE_LOW_LEVEL:
170 GPIO_SetPinInterruptConfig(PIN2GPIO(pin), GET_GPIO_PIN(pin), kGPIO_InterruptLogicZero);
171 break;
172 }
173
174 pin_irq_hdr_tab[pin].pin = pin;
175 pin_irq_hdr_tab[pin].mode = mode;
176 pin_irq_hdr_tab[pin].hdr = hdr;
177 pin_irq_hdr_tab[pin].args = args;
178
179 return RT_EOK;
180 }
181
mcx_pin_detach_irq(struct rt_device * device,rt_base_t pin)182 static rt_err_t mcx_pin_detach_irq(struct rt_device *device, rt_base_t pin)
183 {
184 GPIO_SetPinInterruptConfig(PIN2GPIO(pin), GET_GPIO_PIN(pin), kGPIO_InterruptStatusFlagDisabled);
185 return RT_EOK;
186 }
187
mcx_pin_irq_enable(struct rt_device * device,rt_base_t pin,rt_uint8_t enabled)188 static rt_err_t mcx_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled)
189 {
190 if(enabled)
191 {
192 EnableIRQ(PIN2IRQ(pin));
193 }
194 else
195 {
196 DisableIRQ(PIN2IRQ(pin));
197 }
198
199 return RT_EOK;
200 }
201
rt_hw_pin_init(void)202 int rt_hw_pin_init(void)
203 {
204 int ret = RT_EOK;
205
206 mcx_pin_ops.pin_mode = mcx_pin_mode;
207 mcx_pin_ops.pin_read = mcx_pin_read;
208 mcx_pin_ops.pin_write = mcx_pin_write;
209 mcx_pin_ops.pin_attach_irq = mcx_pin_attach_irq;
210 mcx_pin_ops.pin_detach_irq = mcx_pin_detach_irq;
211 mcx_pin_ops.pin_irq_enable = mcx_pin_irq_enable;
212 mcx_pin_ops.pin_get = RT_NULL,
213
214 ret = rt_device_pin_register("pin", &mcx_pin_ops, RT_NULL);
215
216 return ret;
217 }
218 INIT_BOARD_EXPORT(rt_hw_pin_init);
219
220 #endif /*RT_USING_PIN */
221
222 // end file
223