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