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