1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2017-09-16     Haley        the first version
9  */
10 
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include <rthw.h>
14 #include "am_mcu_apollo.h"
15 
16 #ifdef RT_USING_PIN
17 
18 #define APLLO2_PIN_NUMBERS    64 //[34, 64]
19 struct rt_pin_irq_hdr am_pin_irq_hdr_tab[64];
20 
am_pin_mode(rt_device_t dev,rt_base_t pin,rt_uint8_t mode)21 void am_pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_t mode)
22 {
23     if (mode == PIN_MODE_OUTPUT)
24     {
25         /* output setting */
26         am_hal_gpio_pin_config(pin, AM_HAL_GPIO_OUTPUT);
27     }
28     else if (mode == PIN_MODE_INPUT)
29     {
30         /* input setting: not pull. */
31         am_hal_gpio_pin_config(pin, AM_HAL_GPIO_INPUT);
32     }
33     else if (mode == PIN_MODE_INPUT_PULLUP)
34     {
35         /* input setting: pull up. */
36         am_hal_gpio_pin_config(pin, AM_HAL_GPIO_INPUT);
37     }
38     else if (mode == PIN_MODE_INPUT_PULLDOWN)
39     {
40         /* input setting: pull down. */
41         am_hal_gpio_pin_config(pin, AM_HAL_GPIO_OPENDRAIN);
42     }
43     else
44     {
45         /* input setting:default. */
46         am_hal_gpio_pin_config(pin, AM_HAL_GPIO_3STATE);
47     }
48 }
49 
am_pin_write(rt_device_t dev,rt_base_t pin,rt_uint8_t value)50 void am_pin_write(rt_device_t dev, rt_base_t pin, rt_uint8_t value)
51 {
52     if (value == PIN_LOW)
53     {
54         am_hal_gpio_out_bit_clear(pin);
55     }
56     else if (value == PIN_HIGH)
57     {
58         am_hal_gpio_out_bit_set(pin);
59     }
60 }
61 
am_pin_read(rt_device_t dev,rt_base_t pin)62 rt_ssize_t am_pin_read(rt_device_t dev, rt_base_t pin)
63 {
64     rt_ssize_t value = PIN_LOW;
65 
66     if (am_hal_gpio_pin_config_read(pin) == AM_HAL_GPIO_OUTPUT)
67     {
68         if (am_hal_gpio_out_bit_read(pin) == 0)
69         {
70             value = PIN_LOW;
71         }
72         else
73         {
74             value = PIN_HIGH;
75         }
76     }
77     else
78     {
79         if (am_hal_gpio_input_bit_read(pin) == 0)
80         {
81             value = PIN_LOW;
82         }
83         else
84         {
85             value = PIN_HIGH;
86         }
87     }
88 
89     return value;
90 }
91 
am_pin_attach_irq(struct rt_device * device,rt_base_t pin,rt_uint8_t mode,void (* hdr)(void * args),void * args)92 rt_err_t am_pin_attach_irq(struct rt_device *device, rt_base_t pin,
93                 rt_uint8_t mode, void (*hdr)(void *args), void *args)
94 {
95     rt_base_t level;
96     rt_int32_t irqindex = -1;
97 
98     irqindex = pin;
99 
100     level = rt_hw_interrupt_disable();
101     if(am_pin_irq_hdr_tab[irqindex].pin == pin   &&
102        am_pin_irq_hdr_tab[irqindex].hdr == hdr   &&
103        am_pin_irq_hdr_tab[irqindex].mode == mode &&
104        am_pin_irq_hdr_tab[irqindex].args == args
105     )
106     {
107         rt_hw_interrupt_enable(level);
108         return RT_EOK;
109     }
110     if(am_pin_irq_hdr_tab[irqindex].pin != -1)
111     {
112         rt_hw_interrupt_enable(level);
113         return -RT_EBUSY;
114     }
115     am_pin_irq_hdr_tab[irqindex].pin = pin;
116     am_pin_irq_hdr_tab[irqindex].hdr = hdr;
117     am_pin_irq_hdr_tab[irqindex].mode = mode;
118     am_pin_irq_hdr_tab[irqindex].args = args;
119     rt_hw_interrupt_enable(level);
120 
121     return RT_EOK;
122 }
123 
am_pin_dettach_irq(struct rt_device * device,rt_base_t pin)124 rt_err_t am_pin_dettach_irq(struct rt_device *device, rt_base_t pin)
125 {
126     rt_base_t level;
127     rt_int32_t irqindex = -1;
128 
129     irqindex = pin;
130 
131     level = rt_hw_interrupt_disable();
132     if(am_pin_irq_hdr_tab[irqindex].pin == -1)
133     {
134         rt_hw_interrupt_enable(level);
135         return RT_EOK;
136     }
137     am_pin_irq_hdr_tab[irqindex].pin = -1;
138     am_pin_irq_hdr_tab[irqindex].hdr = RT_NULL;
139     am_pin_irq_hdr_tab[irqindex].mode = 0;
140     am_pin_irq_hdr_tab[irqindex].args = RT_NULL;
141     rt_hw_interrupt_enable(level);
142 
143     return RT_EOK;
144 }
145 
am_pin_irq_enable(struct rt_device * device,rt_base_t pin,rt_uint8_t enabled)146 rt_err_t am_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled)
147 {
148     rt_base_t level;
149     rt_int32_t irqindex = -1;
150 
151     irqindex = pin;
152 
153     if (enabled == PIN_IRQ_ENABLE)
154     {
155         level = rt_hw_interrupt_disable();
156 
157         /* Configure the GPIO/button interrupt polarity */
158         if (am_pin_irq_hdr_tab[irqindex].mode == PIN_IRQ_MODE_RISING)
159         {
160             am_hal_gpio_int_polarity_bit_set(am_pin_irq_hdr_tab[irqindex].pin, AM_HAL_GPIO_RISING);
161         }
162         else if (am_pin_irq_hdr_tab[irqindex].mode == PIN_IRQ_MODE_FALLING)
163         {
164             am_hal_gpio_int_polarity_bit_set(am_pin_irq_hdr_tab[irqindex].pin, AM_HAL_GPIO_FALLING);
165         }
166 
167         /* Clear the GPIO Interrupt (write to clear) */
168         am_hal_gpio_int_clear(AM_HAL_GPIO_BIT(am_pin_irq_hdr_tab[irqindex].pin));
169 
170         /* Enable the GPIO/button interrupt */
171         am_hal_gpio_int_enable(AM_HAL_GPIO_BIT(am_pin_irq_hdr_tab[irqindex].pin));
172 
173         rt_hw_interrupt_enable(level);
174     }
175     else if (enabled == PIN_IRQ_DISABLE)
176     {
177         if (am_hal_gpio_int_enable_get() != AM_HAL_GPIO_BIT(am_pin_irq_hdr_tab[irqindex].pin))
178         {
179             return -RT_ENOSYS;
180         }
181 
182         /* Disable the GPIO/button interrupt */
183         am_hal_gpio_int_disable(AM_HAL_GPIO_BIT(am_pin_irq_hdr_tab[irqindex].pin));
184     }
185     else
186     {
187         return -RT_ENOSYS;
188     }
189 
190     return RT_EOK;
191 }
192 
193 const static struct rt_pin_ops am_pin_ops =
194 {
195     am_pin_mode,
196     am_pin_write,
197     am_pin_read,
198     am_pin_attach_irq,
199     am_pin_dettach_irq,
200     am_pin_irq_enable,
201     RT_NULL,
202 };
203 
rt_hw_pin_init(void)204 int rt_hw_pin_init(void)
205 {
206     rt_device_pin_register("pin", &am_pin_ops, RT_NULL);
207 
208     //rt_device_pin_irq_register("pin", &am_pin_ops, RT_NULL);
209     //rt_kprintf("pin_init!\n");
210 
211     return 0;
212 }
213 
214 INIT_BOARD_EXPORT(rt_hw_pin_init);
215 #endif
216 
217 /*@}*/
218