]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_gpio0.c
Update RISCC-V-RV32-SiFive_HiFive1_FreedomStudio project to latest tools and metal...
[freertos] / FreeRTOS / Demo / RISC-V_RV32_SiFive_HiFive1_FreedomStudio / freedom-metal / src / drivers / sifive_gpio0.c
1 /* Copyright 2018 SiFive, Inc */
2 /* SPDX-License-Identifier: Apache-2.0 */
3
4 #include <metal/machine/platform.h>
5
6 #ifdef METAL_SIFIVE_GPIO0
7
8 #include <metal/drivers/sifive_gpio0.h>
9 #include <metal/io.h>
10 #include <metal/machine.h>
11
12 int __metal_driver_sifive_gpio0_enable_input(struct metal_gpio *ggpio, long source)
13 {
14     long base = __metal_driver_sifive_gpio0_base(ggpio);
15
16     __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_INPUT_EN))  |= source;
17
18     return 0;
19 }
20
21 int __metal_driver_sifive_gpio0_disable_input(struct metal_gpio *ggpio, long source)
22 {
23     long base = __metal_driver_sifive_gpio0_base(ggpio);
24
25     __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_INPUT_EN))  &= ~source;
26
27     return 0;
28 }
29
30 long __metal_driver_sifive_gpio0_input(struct metal_gpio *ggpio)
31 {
32     long base = __metal_driver_sifive_gpio0_base(ggpio);
33
34     return __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_VALUE));
35 }
36
37 long __metal_driver_sifive_gpio0_output(struct metal_gpio *ggpio)
38 {
39     long base = __metal_driver_sifive_gpio0_base(ggpio);
40
41     return __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT));
42 }
43
44
45 int __metal_driver_sifive_gpio0_disable_output(struct metal_gpio *ggpio, long source)
46 {
47     long base = __metal_driver_sifive_gpio0_base(ggpio);
48
49     __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_OUTPUT_EN))  &= ~source;
50
51     return 0;
52 }
53
54 int __metal_driver_sifive_gpio0_enable_output(struct metal_gpio *ggpio, long source)
55 {
56     long base = __metal_driver_sifive_gpio0_base(ggpio);
57
58     __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_OUTPUT_EN))  |= source;
59
60     return 0;
61 }
62
63 int __metal_driver_sifive_gpio0_output_set(struct metal_gpio *ggpio, long value)
64 {
65     long base = __metal_driver_sifive_gpio0_base(ggpio);
66
67     __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) |= value;
68
69     return 0;
70 }
71
72 int __metal_driver_sifive_gpio0_output_clear(struct metal_gpio *ggpio, long value)
73 {
74     long base = __metal_driver_sifive_gpio0_base(ggpio);
75
76     __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) &= ~value;
77
78     return 0;
79 }
80
81 int __metal_driver_sifive_gpio0_output_toggle(struct metal_gpio *ggpio, long value)
82 {
83     long base = __metal_driver_sifive_gpio0_base(ggpio);
84
85     __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) =
86         __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) ^ value;
87
88     return 0;
89 }
90
91 int __metal_driver_sifive_gpio0_enable_io(struct metal_gpio *ggpio, long source, long dest)
92 {
93     long base = __metal_driver_sifive_gpio0_base(ggpio);
94
95     __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_IOF_SEL)) &= ~source;
96     __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_IOF_EN))  |= dest;
97
98     return 0;
99 }
100
101 int __metal_driver_sifive_gpio0_disable_io(struct metal_gpio *ggpio, long source)
102 {
103     long base = __metal_driver_sifive_gpio0_base(ggpio);
104
105     __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_IOF_EN))  &= ~source;
106
107     return 0;
108 }
109
110 int __metal_driver_sifive_gpio0_config_int(struct metal_gpio *ggpio, long source, int intr_type)
111 {
112     long base = __metal_driver_sifive_gpio0_base(ggpio);
113
114     switch (intr_type)
115     {
116         case METAL_GPIO_INT_DISABLE:
117             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE))  &= ~source;
118             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE))  &= ~source;
119             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE))  &= ~source;
120             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE))  &= ~source;
121             break;
122         case METAL_GPIO_INT_RISING:
123             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE))  |= source;
124             break;
125         case METAL_GPIO_INT_FALLING:
126             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE))  |= source;
127             break;
128         case METAL_GPIO_INT_BOTH_EDGE:
129             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE))  |= source;
130             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE))  |= source;
131             break;
132         case METAL_GPIO_INT_HIGH:
133             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE))  |= source;
134             break;
135         case METAL_GPIO_INT_LOW:
136             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE))  |= source;
137             break;
138         case METAL_GPIO_INT_BOTH_LEVEL:
139             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE))  |= source;
140             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE))  |= source;
141             break;
142         case METAL_GPIO_INT_MAX:
143             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE))  |= source;
144             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE))  |= source;
145             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE))  |= source;
146             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE))  |= source;
147             break;
148     }
149     return 0;
150 }
151
152 int __metal_driver_sifive_gpio0_clear_int(struct metal_gpio *ggpio, long source, int intr_type)
153 {
154     long base = __metal_driver_sifive_gpio0_base(ggpio);
155
156     switch (intr_type)
157     {
158         case METAL_GPIO_INT_RISING:
159             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IP))  |= source;
160             break;
161         case METAL_GPIO_INT_FALLING:
162             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IP))  |= source;
163             break;
164         case METAL_GPIO_INT_BOTH_EDGE:
165             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IP))  |= source;
166             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IP))  |= source;
167             break;
168         case METAL_GPIO_INT_HIGH:
169             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IP))  |= source;
170             break;
171         case METAL_GPIO_INT_LOW:
172             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IP))  |= source;
173             break;
174         case METAL_GPIO_INT_BOTH_LEVEL:
175             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IP))  |= source;
176             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IP))  |= source;
177             break;
178         case METAL_GPIO_INT_MAX:
179             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IP))  |= source;
180             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IP))  |= source;
181             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IP))  |= source;
182             __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IP))  |= source;
183             break;
184     }
185     return 0;
186 }
187
188 struct metal_interrupt *
189 __metal_driver_gpio_interrupt_controller(struct metal_gpio *gpio)
190 {
191     return __metal_driver_sifive_gpio0_interrupt_parent(gpio);
192 }
193
194 int __metal_driver_gpio_get_interrupt_id(struct metal_gpio *gpio, int pin)
195 {
196     int irq;
197     irq = __metal_driver_sifive_gpio0_interrupt_lines(gpio, pin);
198     return irq;
199 }
200
201 __METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_gpio0) = {
202     .gpio.disable_input  = __metal_driver_sifive_gpio0_disable_input,
203     .gpio.enable_input   = __metal_driver_sifive_gpio0_enable_input,
204     .gpio.input          = __metal_driver_sifive_gpio0_input,
205     .gpio.output         = __metal_driver_sifive_gpio0_output,
206     .gpio.disable_output = __metal_driver_sifive_gpio0_disable_output,
207     .gpio.enable_output  = __metal_driver_sifive_gpio0_enable_output,
208     .gpio.output_set     = __metal_driver_sifive_gpio0_output_set,
209     .gpio.output_clear   = __metal_driver_sifive_gpio0_output_clear,
210     .gpio.output_toggle  = __metal_driver_sifive_gpio0_output_toggle,
211     .gpio.enable_io      = __metal_driver_sifive_gpio0_enable_io,
212     .gpio.disable_io     = __metal_driver_sifive_gpio0_disable_io,
213     .gpio.config_int     = __metal_driver_sifive_gpio0_config_int,
214     .gpio.clear_int      = __metal_driver_sifive_gpio0_clear_int,
215     .gpio.interrupt_controller = __metal_driver_gpio_interrupt_controller,
216     .gpio.get_interrupt_id = __metal_driver_gpio_get_interrupt_id,
217 };
218
219 #endif /* METAL_SIFIVE_GPIO0 */
220
221 typedef int no_empty_translation_units;