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_PU;
100 }
101 else if (mode == PIN_MODE_INPUT_PULLDOWN)
102 {
103 /* input setting: pull down. */
104 GPIO_CONFIG(pin) = PULL_PD;
105 }
106 else if (mode == PIN_MODE_OUTPUT_OD)
107 {
108 /* output setting: od. */
109 GPIO_CONFIG(pin) = PULL_PU;
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 return GPIO_ReadInputDataBit((GPIO_TypeDef)(pin / 16), (GPIO_Pin_TypeDef)(1 << (pin % 16)));
129 }
130
yc_pin_attach_irq(struct rt_device * device,rt_base_t pin,rt_uint8_t mode,pin_callback_t cb,void * args)131 static rt_err_t yc_pin_attach_irq(struct rt_device *device,
132 rt_base_t pin,
133 rt_uint8_t mode,
134 pin_callback_t cb,
135 void *args)
136 {
137 rt_int32_t index = -1;
138 rt_base_t level;
139 if (pin >= PIN_MAX_NUM)
140 {
141 return -RT_EINVAL;
142 }
143
144 index = pin;
145 level = rt_hw_interrupt_disable();
146
147 pin_irq_hdr_tab[index].pin = pin;
148 pin_irq_hdr_tab[index].hdr = cb;
149 pin_irq_hdr_tab[index].mode = mode;
150 pin_irq_hdr_tab[index].args = args;
151 rt_hw_interrupt_enable(level);
152
153 return RT_EOK;
154 }
155
yc_pin_detach_irq(struct rt_device * device,rt_base_t pin)156 static rt_err_t yc_pin_detach_irq(struct rt_device *device, rt_base_t pin)
157 {
158 rt_int32_t index = -1;
159 rt_base_t level;
160 if (pin >= PIN_MAX_NUM)
161 {
162 return -RT_EINVAL;
163 }
164
165 index = pin;
166 level = rt_hw_interrupt_disable();
167
168 pin_irq_hdr_tab[index].pin = -1;
169 pin_irq_hdr_tab[index].hdr = RT_NULL;
170 pin_irq_hdr_tab[index].mode = 0;
171 pin_irq_hdr_tab[index].args = RT_NULL;
172
173 rt_hw_interrupt_enable(level);
174 return RT_EOK;
175 }
176
yc_pin_irq_enable(struct rt_device * device,rt_base_t pin,rt_uint8_t enabled)177 static rt_err_t yc_pin_irq_enable(struct rt_device *device,
178 rt_base_t pin,
179 rt_uint8_t enabled)
180 {
181 rt_int32_t index;
182 rt_base_t level = 0;
183 rt_int8_t TrigMode = 0;
184 if (pin >= PIN_MAX_NUM)
185 {
186 return -RT_EINVAL;
187 }
188
189 index = pin;
190
191 if (enabled == PIN_IRQ_ENABLE)
192 {
193 switch (pin_irq_hdr_tab[index].mode)
194 {
195 case PIN_IRQ_MODE_RISING:
196 TrigMode = EXTI_Trigger_Rising;
197 break;
198 case PIN_IRQ_MODE_FALLING:
199 TrigMode = EXTI_Trigger_Falling;
200 break;
201 case PIN_IRQ_MODE_RISING_FALLING:
202 TrigMode = EXTI_Trigger_Rising_Falling;
203 break;
204 case PIN_IRQ_MODE_HIGH_LEVEL:
205 GPIO_CONFIG(pin) = PULL_PD;
206 TrigMode = EXTI_Trigger_HighLev;
207 break;
208 case PIN_IRQ_MODE_LOW_LEVEL:
209 GPIO_CONFIG(pin) = PULL_PU;
210 TrigMode = EXTI_Trigger_LowLev;
211 break;
212 default:
213 rt_hw_interrupt_enable(level);
214 return -RT_EINVAL;
215 }
216
217 level = rt_hw_interrupt_disable();
218 NVIC_EnableIRQ(GPIO_IRQn);
219 EXTI_LineConfig((EXTI_LineTypeDef)(pin / 16), (EXTI_PIN_TypeDef)(1 << (pin % 16)), (EXTI_TriggerTypeDef)TrigMode);
220 rt_hw_interrupt_enable(level);
221 }
222 else if (enabled == PIN_IRQ_DISABLE)
223 {
224 NVIC_DisableIRQ(GPIO_IRQn);
225 MGPIO->INTR.reg[pin / 16] &= ~(1 << (pin % 16));
226 }
227 else
228 {
229 return -RT_ENOSYS;
230 }
231 return RT_EOK;
232 }
233
234 const static struct rt_pin_ops yc3122_pin_ops =
235 {
236 yc_pin_mode,
237 yc_pin_write,
238 yc_pin_read,
239 yc_pin_attach_irq,
240 yc_pin_detach_irq,
241 yc_pin_irq_enable,
242 RT_NULL,
243 };
244
rt_hw_pin_init(void)245 int rt_hw_pin_init(void)
246 {
247 int result;
248 result = rt_device_pin_register("pin", &yc3122_pin_ops, RT_NULL);
249 return result;
250 }
251 INIT_BOARD_EXPORT(rt_hw_pin_init);
252
GPIO_IRQHandler(void)253 void GPIO_IRQHandler(void)
254 {
255 // int i;
256
257 rt_interrupt_enter();
258 // for (i = 0; i < PIN_MAX_NUM; i++)
259 // {
260 // if ((GPIO_TRIG_MODE(i / 16) & (1 << (i % 16))) == (GPIO_IN(i / 16) & (1 << (i % 16))))
261 // {
262 // if (pin_irq_hdr_tab[i].hdr)
263 // {
264 // pin_irq_hdr_tab[i].hdr(pin_irq_hdr_tab[i].args);
265 // }
266 // }
267 // }
268 rt_interrupt_leave();
269 }
270