1 /*
2 * Copyright (c) 2006-2021, YICHIP Technology Co.,Ltd.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2021-09-09 WSY first version
9 */
10
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include <board.h>
14 #include <rthw.h>
15
16 #define PIN_MAX_NUM (48)
17
18 typedef void (*pin_callback_t)(void *args);
19 struct pin
20 {
21 uint32_t package_index;
22 const char *name;
23 IRQn_Type irq;
24 rt_uint32_t irq_mode;
25 pin_callback_t callback;
26 void *callback_args;
27 };
28 typedef struct pin pin_t;
29
30
31 struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
32 {
33 {-1, 0, RT_NULL, RT_NULL},
34 {-1, 0, RT_NULL, RT_NULL},
35 {-1, 0, RT_NULL, RT_NULL},
36 {-1, 0, RT_NULL, RT_NULL},
37 {-1, 0, RT_NULL, RT_NULL},
38 {-1, 0, RT_NULL, RT_NULL},
39 {-1, 0, RT_NULL, RT_NULL},
40 {-1, 0, RT_NULL, RT_NULL},
41 {-1, 0, RT_NULL, RT_NULL},
42 {-1, 0, RT_NULL, RT_NULL},
43 {-1, 0, RT_NULL, RT_NULL},
44 {-1, 0, RT_NULL, RT_NULL},
45 {-1, 0, RT_NULL, RT_NULL},
46 {-1, 0, RT_NULL, RT_NULL},
47 {-1, 0, RT_NULL, RT_NULL},
48 {-1, 0, RT_NULL, RT_NULL},
49 {-1, 0, RT_NULL, RT_NULL},
50 {-1, 0, RT_NULL, RT_NULL},
51 {-1, 0, RT_NULL, RT_NULL},
52 {-1, 0, RT_NULL, RT_NULL},
53 {-1, 0, RT_NULL, RT_NULL},
54 {-1, 0, RT_NULL, RT_NULL},
55 {-1, 0, RT_NULL, RT_NULL},
56 {-1, 0, RT_NULL, RT_NULL},
57 {-1, 0, RT_NULL, RT_NULL},
58 {-1, 0, RT_NULL, RT_NULL},
59 {-1, 0, RT_NULL, RT_NULL},
60 {-1, 0, RT_NULL, RT_NULL},
61 {-1, 0, RT_NULL, RT_NULL},
62 {-1, 0, RT_NULL, RT_NULL},
63 {-1, 0, RT_NULL, RT_NULL},
64 {-1, 0, RT_NULL, RT_NULL},
65 {-1, 0, RT_NULL, RT_NULL},
66 {-1, 0, RT_NULL, RT_NULL},
67 {-1, 0, RT_NULL, RT_NULL},
68 {-1, 0, RT_NULL, RT_NULL},
69 {-1, 0, RT_NULL, RT_NULL},
70 {-1, 0, RT_NULL, RT_NULL},
71 {-1, 0, RT_NULL, RT_NULL},
72 {-1, 0, RT_NULL, RT_NULL},
73 {-1, 0, RT_NULL, RT_NULL},
74 {-1, 0, RT_NULL, RT_NULL},
75 {-1, 0, RT_NULL, RT_NULL},
76 {-1, 0, RT_NULL, RT_NULL},
77 {-1, 0, RT_NULL, RT_NULL},
78 {-1, 0, RT_NULL, RT_NULL},
79 {-1, 0, RT_NULL, RT_NULL},
80 {-1, 0, RT_NULL, RT_NULL},
81 };
82
yc_pin_mode(rt_device_t dev,rt_base_t pin,rt_uint8_t mode)83 static void yc_pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_t mode)
84 {
85 /* Configure GPIO_InitStructure */
86 if (mode == PIN_MODE_OUTPUT)
87 {
88 /* output setting */
89 GPIO_CONFIG(pin) = OUTPUT_LOW;
90 }
91 else if (mode == PIN_MODE_INPUT)
92 {
93 /* input setting: not pull. */
94 GPIO_CONFIG(pin) = INPUT;
95 }
96 else if (mode == PIN_MODE_INPUT_PULLUP)
97 {
98 /* input setting: pull up. */
99 GPIO_CONFIG(pin) = PULL_UP;
100 }
101 else if (mode == PIN_MODE_INPUT_PULLDOWN)
102 {
103 /* input setting: pull down. */
104 GPIO_CONFIG(pin) = PULL_DOWN;
105 }
106 else if (mode == PIN_MODE_OUTPUT_OD)
107 {
108 /* output setting: od. */
109 GPIO_CONFIG(pin) = PULL_UP;
110 }
111 }
112
yc_pin_write(rt_device_t dev,rt_base_t pin,rt_uint8_t value)113 static void yc_pin_write(rt_device_t dev, rt_base_t pin, rt_uint8_t value)
114 {
115 if (value)
116 {
117 GPIO_CONFIG(pin) = OUTPUT_HIGH;
118 }
119 else
120 {
121 GPIO_CONFIG(pin) = OUTPUT_LOW;
122 }
123 }
124
yc_pin_read(rt_device_t dev,rt_base_t pin)125 static rt_ssize_t yc_pin_read(rt_device_t dev, rt_base_t pin)
126 {
127 return GPIO_IN(pin / 16) & (1 << (pin % 16)) ? 1 : 0;
128 }
129
yc_pin_attach_irq(struct rt_device * device,rt_base_t pin,rt_uint8_t mode,pin_callback_t cb,void * args)130 static rt_err_t yc_pin_attach_irq(struct rt_device *device,
131 rt_base_t pin,
132 rt_uint8_t mode,
133 pin_callback_t cb,
134 void *args)
135 {
136 rt_int32_t index = -1;
137 rt_base_t level;
138 if (pin >= PIN_MAX_NUM)
139 {
140 return -RT_EINVAL;
141 }
142
143 index = pin;
144 level = rt_hw_interrupt_disable();
145
146 pin_irq_hdr_tab[index].pin = pin;
147 pin_irq_hdr_tab[index].hdr = cb;
148 pin_irq_hdr_tab[index].mode = mode;
149 pin_irq_hdr_tab[index].args = args;
150 rt_hw_interrupt_enable(level);
151
152 return RT_EOK;
153 }
154
yc_pin_detach_irq(struct rt_device * device,rt_base_t pin)155 static rt_err_t yc_pin_detach_irq(struct rt_device *device, rt_base_t pin)
156 {
157 rt_int32_t index = -1;
158 rt_base_t level;
159 if (pin >= PIN_MAX_NUM)
160 {
161 return -RT_EINVAL;
162 }
163
164 index = pin;
165 level = rt_hw_interrupt_disable();
166
167 pin_irq_hdr_tab[index].pin = -1;
168 pin_irq_hdr_tab[index].hdr = RT_NULL;
169 pin_irq_hdr_tab[index].mode = 0;
170 pin_irq_hdr_tab[index].args = RT_NULL;
171
172 rt_hw_interrupt_enable(level);
173 return RT_EOK;
174 }
175
yc_pin_irq_enable(struct rt_device * device,rt_base_t pin,rt_uint8_t enabled)176 static rt_err_t yc_pin_irq_enable(struct rt_device *device,
177 rt_base_t pin,
178 rt_uint8_t enabled)
179 {
180 rt_int32_t index;
181 rt_base_t level = 0;
182 if (pin >= PIN_MAX_NUM)
183 {
184 return -RT_EINVAL;
185 }
186
187 index = pin;
188
189 if (enabled == PIN_IRQ_ENABLE)
190 {
191 switch (pin_irq_hdr_tab[index].mode)
192 {
193 case PIN_IRQ_MODE_RISING:
194
195 break;
196 case PIN_IRQ_MODE_FALLING:
197
198 break;
199 case PIN_IRQ_MODE_RISING_FALLING:
200
201 break;
202 case PIN_IRQ_MODE_HIGH_LEVEL:
203 GPIO_CONFIG(pin) = PULL_DOWN;
204 GPIO_TRIG_MODE(pin / 16) &= (1 << (pin % 16));
205 break;
206 case PIN_IRQ_MODE_LOW_LEVEL:
207 GPIO_CONFIG(pin) = PULL_UP;
208 GPIO_TRIG_MODE(pin / 16) |= (1 << (pin % 16));
209 break;
210 default:
211 rt_hw_interrupt_enable(level);
212 return -RT_EINVAL;
213 }
214
215 level = rt_hw_interrupt_disable();
216 NVIC_EnableIRQ(GPIO_IRQn);
217 GPIO_INTR_EN(pin / 16) |= (1 << (pin % 16));
218 rt_hw_interrupt_enable(level);
219 }
220 else if (enabled == PIN_IRQ_DISABLE)
221 {
222 NVIC_DisableIRQ(GPIO_IRQn);
223 GPIO_INTR_EN(pin / 16) &= ~(1 << (pin % 16));
224 }
225 else
226 {
227 return -RT_ENOSYS;
228 }
229 return RT_EOK;
230 }
231
232 const static struct rt_pin_ops yc3121_pin_ops =
233 {
234 yc_pin_mode,
235 yc_pin_write,
236 yc_pin_read,
237 yc_pin_attach_irq,
238 yc_pin_detach_irq,
239 yc_pin_irq_enable,
240 RT_NULL,
241 };
242
rt_hw_pin_init(void)243 int rt_hw_pin_init(void)
244 {
245 int result;
246 result = rt_device_pin_register("pin", &yc3121_pin_ops, RT_NULL);
247 return result;
248 }
249 INIT_BOARD_EXPORT(rt_hw_pin_init);
250
GPIO_IRQHandler(void)251 void GPIO_IRQHandler(void)
252 {
253 int i;
254
255 rt_interrupt_enter();
256 for (i = 0; i < PIN_MAX_NUM; i++)
257 {
258 if ((GPIO_TRIG_MODE(i / 16) & (1 << (i % 16))) == (GPIO_IN(i / 16) & (1 << (i % 16))))
259 {
260 if (pin_irq_hdr_tab[i].hdr)
261 {
262 pin_irq_hdr_tab[i].hdr(pin_irq_hdr_tab[i].args);
263 }
264 }
265 }
266 rt_interrupt_leave();
267 }
268