1 /*
2  * Copyright (c) 2006-2022, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2017-11-24     勤为本          first version
9  * 2018-05-11     zhuangwei    add gpio interrupt ops
10  */
11 
12 #include <rtthread.h>
13 #include <drivers/dev_pin.h>
14 #include "ls1c_gpio.h"
15 #include "ls1c.h"
16 #include <rthw.h>
17 
18 #ifdef RT_USING_PIN
19 
ls1c_pin_mode(struct rt_device * device,rt_base_t pin,rt_uint8_t mode)20 void ls1c_pin_mode(struct rt_device *device, rt_base_t pin, rt_uint8_t mode)
21 {
22     unsigned int gpio = pin;
23 
24     if (PIN_MODE_OUTPUT == mode)
25     {
26         gpio_init(gpio, gpio_mode_output);
27     }
28     else
29     {
30         gpio_init(gpio, gpio_mode_input);
31     }
32 
33     return ;
34 }
35 
36 
ls1c_pin_write(struct rt_device * device,rt_base_t pin,rt_uint8_t value)37 void ls1c_pin_write(struct rt_device *device, rt_base_t pin, rt_uint8_t value)
38 {
39     unsigned int gpio = pin;
40 
41     if (PIN_LOW == value)
42     {
43         gpio_set(gpio, gpio_level_low);
44     }
45     else
46     {
47         gpio_set(gpio, gpio_level_high);
48     }
49 
50     return ;
51 }
52 
53 
ls1c_pin_read(struct rt_device * device,rt_base_t pin)54 rt_ssize_t ls1c_pin_read(struct rt_device *device, rt_base_t pin)
55 {
56     unsigned int gpio = pin;
57     rt_ssize_t value = PIN_LOW;
58 
59     if (0 == gpio_get(gpio))
60     {
61         value = PIN_LOW;
62     }
63     else
64     {
65         value = PIN_HIGH;
66     }
67 
68     return value;
69 }
70 
ls1c_pin_attach_irq(struct rt_device * device,rt_base_t pin,rt_uint8_t mode,void (* hdr)(void * args),void * args)71 rt_err_t ls1c_pin_attach_irq(struct rt_device *device, rt_base_t pin,
72                              rt_uint8_t mode, void (*hdr)(void *args), void *args)
73 {
74     unsigned int gpio = pin;
75     char irq_name[10];
76     rt_uint32_t type;
77     switch (mode)
78     {
79       case PIN_IRQ_MODE_RISING:
80       type=IRQ_TYPE_EDGE_RISING;
81       break;
82       case PIN_IRQ_MODE_FALLING:
83       type=IRQ_TYPE_EDGE_FALLING;
84       break;
85       case PIN_IRQ_MODE_HIGH_LEVEL:
86       type=IRQ_TYPE_LEVEL_HIGH;
87       break;
88       case PIN_IRQ_MODE_LOW_LEVEL:
89       type=IRQ_TYPE_LEVEL_LOW;
90       break;
91     }
92     gpio_set_irq_type(gpio, type);
93 
94     rt_sprintf(irq_name, "PIN_%d", gpio);
95     rt_hw_interrupt_install(LS1C_GPIO_TO_IRQ(gpio), (rt_isr_handler_t)hdr, args, irq_name);
96 
97     return RT_EOK;
98 }
99 
ls1c_pin_detach_irq(struct rt_device * device,rt_base_t pin)100 rt_err_t ls1c_pin_detach_irq(struct rt_device *device, rt_base_t pin)
101 {
102     return RT_EOK;
103 }
104 
ls1c_pin_irq_enable(struct rt_device * device,rt_base_t pin,rt_uint8_t enabled)105 rt_err_t ls1c_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled)
106 {
107     unsigned int gpio = pin;
108 
109     if (enabled)
110         rt_hw_interrupt_umask(LS1C_GPIO_TO_IRQ(gpio));
111     else
112         rt_hw_interrupt_mask(LS1C_GPIO_TO_IRQ(gpio));
113     return RT_EOK;
114 }
115 
116 
117 const static struct rt_pin_ops _ls1c_pin_ops =
118 {
119     ls1c_pin_mode,
120     ls1c_pin_write,
121     ls1c_pin_read,
122     ls1c_pin_attach_irq,
123     ls1c_pin_detach_irq,
124     ls1c_pin_irq_enable,
125     RT_NULL,
126 };
127 
128 
hw_pin_init(void)129 int hw_pin_init(void)
130 {
131     int ret = RT_EOK;
132 
133     ret = rt_device_pin_register("pin", &_ls1c_pin_ops, RT_NULL);
134 
135     return ret;
136 }
137 INIT_BOARD_EXPORT(hw_pin_init);
138 
139 #endif /*RT_USING_PIN */
140 
141 
142