1 /*
2 * Copyright (c) 2006-2020, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2021-02-11 supperthomas first version
9 *
10 */
11
12
13 #include "drv_gpio.h"
14 #include <stdbool.h>
15 #include "gpio.h"
16
17 #ifdef RT_USING_PIN
18
19 #define DBG_LEVEL DBG_LOG
20 #include <rtdbg.h>
21 #define LOG_TAG "drv.gpio"
22
23 #define PIN_PORT_OFFSET 4
24
25 #define PIN_NUM(port, no) ((((((port) & 0xFu) << PIN_PORT_OFFSET) | ((no) & 0xFu)))
26 #define PIN_PORT(pin) ((uint8_t)(((pin) >> PIN_PORT_OFFSET) & 0xFu))
27 #define PIN_NO(pin) ((uint8_t)((pin) & 0xFu))
28
29
30 #define PIN_MCU_PORT(pin) PIN_PORT(pin)
31 #define PIN_MCU_PIN(pin) ((uint32_t)(1u << PIN_NO(pin)))
32
mcu_pin_write(rt_device_t dev,rt_base_t pin,rt_uint8_t value)33 static void mcu_pin_write(rt_device_t dev, rt_base_t pin, rt_uint8_t value)
34 {
35 gpio_cfg_t tmp_gpio_cfg;
36 tmp_gpio_cfg.port = PIN_PORT(pin);
37 tmp_gpio_cfg.mask = PIN_MCU_PIN(pin);
38 if (value)
39 {
40 GPIO_OutSet(&tmp_gpio_cfg);
41 }
42 else
43 {
44 GPIO_OutClr(&tmp_gpio_cfg);
45 }
46
47 }
48
mcu_pin_read(rt_device_t dev,rt_base_t pin)49 static rt_ssize_t mcu_pin_read(rt_device_t dev, rt_base_t pin)
50 {
51 rt_ssize_t value;
52 gpio_cfg_t tmp_gpio_cfg;
53 tmp_gpio_cfg.port = PIN_PORT(pin);
54 tmp_gpio_cfg.mask = PIN_MCU_PIN(pin);
55
56 if (GPIO_InGet(&tmp_gpio_cfg))
57 {
58 value = 1;
59 }
60 else
61 {
62 value = 0;
63 }
64
65 return value;
66 }
67
mcu_pin_mode(rt_device_t dev,rt_base_t pin,rt_uint8_t mode)68 static void mcu_pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_t mode)
69 {
70 gpio_cfg_t tmp_gpio_cfg;
71 int ret = 0;
72 tmp_gpio_cfg.port = PIN_PORT(pin);
73 tmp_gpio_cfg.mask = PIN_MCU_PIN(pin);
74
75 switch (mode)
76 {
77 case PIN_MODE_OUTPUT:
78 tmp_gpio_cfg.func = GPIO_FUNC_OUT;
79 tmp_gpio_cfg.pad = GPIO_PAD_NONE;
80 break;
81 case PIN_MODE_INPUT:
82 tmp_gpio_cfg.func = GPIO_FUNC_IN;
83 tmp_gpio_cfg.pad = GPIO_PAD_NONE;
84 break;
85 case PIN_MODE_INPUT_PULLUP:
86 tmp_gpio_cfg.func = GPIO_FUNC_IN;
87 tmp_gpio_cfg.pad = GPIO_PAD_PULL_UP;
88 break;
89 case PIN_MODE_INPUT_PULLDOWN:
90 tmp_gpio_cfg.func = GPIO_FUNC_IN;
91 tmp_gpio_cfg.pad = GPIO_PAD_PULL_DOWN;
92 break;
93 case PIN_MODE_OUTPUT_OD:
94 //not support
95 LOG_E("NOT SUPPORT");
96 break;
97 }
98 ret = GPIO_Config(&tmp_gpio_cfg);
99 if (E_NO_ERROR != ret)
100 {
101 LOG_E("GPIO_Config error :%d", ret);
102 }
103 }
104
105
mcu_pin_attach_irq(struct rt_device * device,rt_base_t pin,rt_uint8_t irq_mode,void (* hdr)(void * args),void * args)106 static rt_err_t mcu_pin_attach_irq(struct rt_device *device, rt_base_t pin,
107 rt_uint8_t irq_mode, void (*hdr)(void *args), void *args)
108 {
109 gpio_cfg_t tmp_gpio_cfg;
110 tmp_gpio_cfg.port = PIN_MCU_PORT(pin);
111 tmp_gpio_cfg.mask = PIN_MCU_PIN(pin);
112
113
114 tmp_gpio_cfg.pad = GPIO_PAD_PULL_UP;
115 tmp_gpio_cfg.func = GPIO_FUNC_IN;
116 GPIO_Config(&tmp_gpio_cfg);
117 GPIO_RegisterCallback(&tmp_gpio_cfg, hdr, args);
118
119 gpio_int_mode_t mcu_mode;
120 gpio_int_pol_t mcu_pol;
121
122 switch (irq_mode)
123 {
124 case PIN_IRQ_MODE_RISING:
125 mcu_mode = GPIO_INT_EDGE;
126 mcu_pol = GPIO_INT_RISING;
127 break;
128 case PIN_IRQ_MODE_FALLING:
129 mcu_mode = GPIO_INT_EDGE;
130 mcu_pol = GPIO_INT_FALLING;
131 break;
132 case PIN_IRQ_MODE_RISING_FALLING:
133 mcu_mode = GPIO_INT_EDGE;
134 mcu_pol = GPIO_INT_BOTH;
135 break;
136 case PIN_IRQ_MODE_HIGH_LEVEL:
137 mcu_mode = GPIO_INT_LEVEL;
138 mcu_pol = GPIO_INT_HIGH;
139 break;
140 case PIN_IRQ_MODE_LOW_LEVEL:
141 mcu_mode = GPIO_INT_LEVEL;
142 mcu_pol = GPIO_INT_LOW;
143 break;
144 }
145
146 GPIO_IntConfig(&tmp_gpio_cfg, mcu_mode, mcu_pol);
147
148
149 return RT_EOK;
150 }
151
mcu_pin_dettach_irq(struct rt_device * device,rt_base_t pin)152 static rt_err_t mcu_pin_dettach_irq(struct rt_device *device, rt_base_t pin)
153 {
154 gpio_cfg_t tmp_gpio_cfg;
155 tmp_gpio_cfg.port = PIN_MCU_PORT(pin);
156 tmp_gpio_cfg.mask = PIN_MCU_PIN(pin);
157 tmp_gpio_cfg.pad = GPIO_PAD_PULL_UP;
158 tmp_gpio_cfg.func = GPIO_FUNC_IN;
159 GPIO_Config(&tmp_gpio_cfg);
160 GPIO_IntDisable(&tmp_gpio_cfg);
161 GPIO_RegisterCallback(&tmp_gpio_cfg, RT_NULL, RT_NULL);
162 return RT_EOK;
163 }
164
mcu_pin_irq_enable(struct rt_device * device,rt_base_t pin,rt_uint8_t enabled)165 static rt_err_t mcu_pin_irq_enable(struct rt_device *device, rt_base_t pin,
166 rt_uint8_t enabled)
167 {
168 gpio_cfg_t tmp_gpio_cfg;
169 tmp_gpio_cfg.port = PIN_MCU_PORT(pin);
170 tmp_gpio_cfg.mask = PIN_MCU_PIN(pin);
171 if (enabled)
172 {
173 GPIO_IntEnable(&tmp_gpio_cfg);
174 NVIC_EnableIRQ((IRQn_Type)MXC_GPIO_GET_IRQ(PIN_MCU_PORT(pin)));
175 }
176 else
177 {
178 GPIO_IntDisable(&tmp_gpio_cfg);
179 NVIC_DisableIRQ((IRQn_Type)MXC_GPIO_GET_IRQ(PIN_MCU_PORT(pin)));
180 }
181 return RT_EOK;
182 }
183
184 const static struct rt_pin_ops _mcu_pin_ops =
185 {
186 mcu_pin_mode,
187 mcu_pin_write,
188 mcu_pin_read,
189 mcu_pin_attach_irq,
190 mcu_pin_dettach_irq,
191 mcu_pin_irq_enable,
192 RT_NULL,
193 };
194
rt_hw_pin_init(void)195 int rt_hw_pin_init(void)
196 {
197 GPIO_Init();
198 return rt_device_pin_register("pin", &_mcu_pin_ops, RT_NULL);
199 }
200 INIT_BOARD_EXPORT(rt_hw_pin_init);
201
202
GPIO0_IRQHandler(void)203 void GPIO0_IRQHandler(void)
204 {
205 GPIO_Handler(PORT_0);
206 }
207
208 #endif /* RT_USING_PIN */
209