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