1 /*
2  * Copyright (c) 2019 Winner Microelectronics Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2018-09-15     flyingcys    1st version
9  */
10 
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include <rthw.h>
14 #include "wm_type_def.h"
15 #include "wm_io.h"
16 #include "wm_gpio.h"
17 #include "pin_map.h"
18 #include "drv_pin.h"
19 
20 #ifdef BSP_USING_PIN
21 
wm_pin_mode(struct rt_device * device,rt_base_t pin,rt_uint8_t mode)22 static void wm_pin_mode(struct rt_device *device, rt_base_t pin, rt_uint8_t mode)
23 {
24     rt_int16_t gpio_pin;
25     gpio_pin = wm_get_pin(pin);
26     if (gpio_pin < 0)
27     {
28         return;
29     }
30     if (mode == PIN_MODE_INPUT)
31     {
32         tls_gpio_cfg((enum tls_io_name)gpio_pin, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_FLOATING);
33     }
34     else if (mode == PIN_MODE_INPUT_PULLUP)
35     {
36         tls_gpio_cfg((enum tls_io_name)gpio_pin, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_PULLHIGH);
37     }
38     else if (mode == PIN_MODE_INPUT_PULLDOWN)
39     {
40         tls_gpio_cfg((enum tls_io_name)gpio_pin, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_PULLLOW);
41     }
42     else if (mode == PIN_MODE_OUTPUT)
43     {
44         tls_gpio_cfg((enum tls_io_name)gpio_pin, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
45     }
46     return;
47 }
48 
wm_pin_write(struct rt_device * device,rt_base_t pin,rt_uint8_t value)49 static void wm_pin_write(struct rt_device *device, rt_base_t pin, rt_uint8_t value)
50 {
51     rt_int16_t gpio_pin;
52     gpio_pin = wm_get_pin(pin);
53     if (gpio_pin < 0)
54     {
55         return;
56     }
57     tls_gpio_write((enum tls_io_name)gpio_pin, value);
58     return;
59 }
60 
wm_pin_read(struct rt_device * device,rt_base_t pin)61 static rt_ssize_t wm_pin_read(struct rt_device *device, rt_base_t pin)
62 {
63     rt_int16_t gpio_pin;
64     gpio_pin = wm_get_pin(pin);
65     if (gpio_pin < 0)
66     {
67         return PIN_LOW;
68     }
69     return tls_gpio_read((enum tls_io_name)gpio_pin);
70 }
71 
wm_pin_attach_irq(struct rt_device * device,rt_base_t pin,rt_uint8_t mode,void (* hdr)(void * args),void * args)72 static rt_err_t wm_pin_attach_irq(struct rt_device *device, rt_base_t pin,
73                                   rt_uint8_t mode, void (*hdr)(void *args), void *args)
74 {
75     rt_int16_t gpio_pin;
76     rt_base_t level;
77 
78     gpio_pin = wm_get_pin(pin);
79     if (gpio_pin < 0)
80     {
81         return -RT_ENOSYS;
82     }
83 
84     level = rt_hw_interrupt_disable();
85     /*irq mode set*/
86     switch (mode)
87     {
88     case PIN_IRQ_MODE_RISING:
89         tls_gpio_irq_cfg((enum tls_io_name)gpio_pin, WM_GPIO_IRQ_TRIG_RISING_EDGE);
90         break;
91     case PIN_IRQ_MODE_FALLING:
92         tls_gpio_irq_cfg((enum tls_io_name)gpio_pin, WM_GPIO_IRQ_TRIG_FALLING_EDGE);
93         break;
94     case PIN_IRQ_MODE_RISING_FALLING:
95         tls_gpio_irq_cfg((enum tls_io_name)gpio_pin, WM_GPIO_IRQ_TRIG_DOUBLE_EDGE);
96         break;
97     case PIN_IRQ_MODE_HIGH_LEVEL:
98         tls_gpio_irq_cfg((enum tls_io_name)gpio_pin, WM_GPIO_IRQ_TRIG_HIGH_LEVEL);
99         break;
100     case PIN_IRQ_MODE_LOW_LEVEL:
101         tls_gpio_irq_cfg((enum tls_io_name)gpio_pin, WM_GPIO_IRQ_TRIG_LOW_LEVEL);
102         break;
103     default:
104         rt_hw_interrupt_enable(level);
105         return -RT_ENOSYS;
106     }
107 
108     tls_gpio_isr_register((enum tls_io_name)gpio_pin, hdr, args);
109     rt_hw_interrupt_enable(level);
110     return RT_EOK;
111 }
112 
wm_pin_detach_irq(struct rt_device * device,rt_base_t pin)113 static rt_err_t wm_pin_detach_irq(struct rt_device *device, rt_base_t pin)
114 {
115     return RT_EOK;
116 }
117 
wm_pin_irq_enable(struct rt_device * device,rt_base_t pin,rt_uint8_t enabled)118 static rt_err_t wm_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled)
119 {
120     rt_int16_t gpio_pin;
121     rt_base_t level;
122 
123     gpio_pin = wm_get_pin(pin);
124     if (gpio_pin < 0)
125     {
126         return -RT_ENOSYS;
127     }
128     level = rt_hw_interrupt_disable();
129     if (enabled == PIN_IRQ_ENABLE)
130     {
131         tls_clr_gpio_irq_status((enum tls_io_name)gpio_pin);
132         tls_gpio_irq_enable((enum tls_io_name)gpio_pin);
133         rt_hw_interrupt_enable(level);
134         return RT_EOK;
135     }
136     else if (enabled == PIN_IRQ_DISABLE)
137     {
138         tls_gpio_irq_disable((enum tls_io_name)gpio_pin);
139         rt_hw_interrupt_enable(level);
140         return RT_EOK;
141     }
142     else
143     {
144         rt_hw_interrupt_enable(level);
145         return -RT_ENOSYS;
146     }
147 }
148 
149 struct rt_pin_ops _wm_pin_ops =
150 {
151     wm_pin_mode,
152     wm_pin_write,
153     wm_pin_read,
154     wm_pin_attach_irq,
155     wm_pin_detach_irq,
156     wm_pin_irq_enable,
157     RT_NULL,
158 };
159 
wm_hw_pin_init(void)160 int wm_hw_pin_init(void)
161 {
162     int ret = rt_device_pin_register("pin", &_wm_pin_ops, RT_NULL);
163     return ret;
164 }
165 INIT_BOARD_EXPORT(wm_hw_pin_init);
166 
WM_GPIOA_IRQHandler(void)167 void WM_GPIOA_IRQHandler(void)
168 {
169     rt_interrupt_enter();
170     GPIOA_IRQHandler();
171     rt_interrupt_leave();
172 }
173 
WM_GPIOB_IRQHandler(void)174 void WM_GPIOB_IRQHandler(void)
175 {
176     rt_interrupt_enter();
177     GPIOB_IRQHandler();
178     rt_interrupt_leave();
179 }
180 #endif /* BSP_USING_PIN */
181