-
Notifications
You must be signed in to change notification settings - Fork 792
/
dif_gpio.h
333 lines (305 loc) · 11 KB
/
dif_gpio.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#ifndef SW_DEVICE_LIB_DIF_GPIO_H
#define SW_DEVICE_LIB_DIF_GPIO_H
#include <stddef.h>
#include <stdint.h>
#include "sw/device/lib/base/mmio.h"
/**
* Configuration for initializing a GPIO device.
*/
typedef struct dif_gpio_config { mmio_region_t base_addr; } dif_gpio_config_t;
/**
* Internal state of a GPIO device.
*
* Instances of this struct must be initialized by `dif_gpio_init()` before
* being passed to other functions.
*/
typedef struct dif_gpio { mmio_region_t base_addr; } dif_gpio_t;
/**
* Generic return codes for the functions in this library.
*
* `kDifGpioResultInvalidArgument` signals that there is a problem with the
* argument(s) but the function did not have any side effects.
* `kDifGpioResultGeneralError` covers other error cases.
*/
typedef enum dif_gpio_result {
kDifGpioResultOK,
kDifGpioResultInvalidArgument,
kDifGpioResultGeneralError,
} dif_gpio_result_t;
/**
* Set of allowed interrupt trigger configurations.
*/
typedef enum dif_gpio_irq {
kDifGpioIrqEdgeRising,
kDifGpioIrqEdgeFalling,
kDifGpioIrqLevelLow,
kDifGpioIrqLevelHigh,
kDifGpioIrqEdgeRisingFalling,
kDifGpioIrqEdgeRisingLevelLow,
kDifGpioIrqEdgeFallingLevelHigh,
} dif_gpio_irq_t;
/**
* Initialize a GPIO device using `config` and return its internal state.
*
* A particular GPIO device must first be initialized by this function
* before calling other functions of this library.
*
* @param config Configuration for initializing a GPIO device.
* @param gpio GPIO instance that will store the internal state of the
* initialized GPIO device.
* @return `kDifGpioResultInvalidArgument` if `config` or `gpio` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_init(const dif_gpio_config_t *config,
dif_gpio_t *gpio);
/**
* Reset GPIO device.
*
* Resets the given GPIO device by setting its configuration registers to
* reset values. Disables interrupts, output, and input filter.
*
* @param gpio GPIO instance
* @return `kDifGpioResultInvalidArgument` if `gpio` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_reset(const dif_gpio_t *gpio);
/**
* Read from all pins.
*
* The value returned by this function is independent of the output enable
* setting and includes the effects of the input noise filter and the load on
* the pins.
*
* @param gpio GPIO instance.
* @param pin_values Pin values.
* @return `kDifGpioResultInvalidArgument` if `gpio` or `pin_values` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_all_read(const dif_gpio_t *gpio,
uint32_t *pin_values);
/**
* Read from a pin.
*
* The value returned by this function is independent of the output enable
* setting and includes the effects of the input noise filter and the load on
* the pin.
*
* @param gpio GPIO instance.
* @param index Zero-based index of the pin to read from.
* @param pin_value Pin value.
* @return `kDifGpioResultInvalidArgument` if `gpio` or `pin_values` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_pin_read(const dif_gpio_t *gpio, uint32_t index,
bool *pin_value);
/**
* Write to all pins.
*
* The actual values on the pins depend on the output enable setting.
*
* @param gpio GPIO instance.
* @param val Value to write.
* @return `kDifGpioResultInvalidArgument` if `gpio` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_all_write(const dif_gpio_t *gpio, uint32_t val);
/**
* Write to a pin.
*
* The actual value on the pin depends on the output enable setting.
*
* @param gpio GPIO instance.
* @param index Zero-based index of the pin to write to.
* @param val Value to write.
* @return `kDifGpioResultInvalidArgument` if `gpio` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_pin_write(const dif_gpio_t *gpio, uint32_t index,
bool val);
/**
* Write to the pins identified by a mask.
*
* The actual values on the pins depend on the output enable setting.
*
* @param gpio GPIO instance
* @param mask Mask that identifies the pins to write to.
* @param val Value to write.
* @return `kDifGpioResultInvalidArgument` if `gpio` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_masked_write(const dif_gpio_t *gpio, uint32_t mask,
uint32_t val);
/**
* Set output modes of all pins.
*
* Setting `val[i]` to 1 enables output mode for pin `i`.
*
* @param gpio GPIO instance.
* @param val Output modes of the pins.
* @return `kDifGpioResultInvalidArgument` if `gpio` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_output_mode_all_set(const dif_gpio_t *gpio,
uint32_t val);
/**
* Set output mode of a pin.
*
* Setting `val` to `true` enables output mode for the pin.
*
* @param gpio GPIO instance
* @param index Zero-based index of the pin.
* @param val Output mode of the pin.
* @return `kDifGpioResultInvalidArgument` if `gpio` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_output_mode_pin_set(const dif_gpio_t *gpio,
uint32_t index, bool val);
/**
* Set the output modes of the pins identified by a mask.
*
* Setting `val[i]` to 1 enables output mode for pin `i`.
*
* @param gpio GPIO instance
* @param mask Mask that identifies the pins whose output modes will be set.
* @param val Output modes of the pins.
* @return `kDifGpioResultInvalidArgument` if `gpio` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_output_mode_masked_set(const dif_gpio_t *gpio,
uint32_t mask, uint32_t val);
/**
* Test the reporting of the interrupt of a pin.
*
* Sets the corresponding bit in the interrupt state register. The level of
* the interrupt output to the processor depends on the interrupt enable
* register.
*
* @param gpio GPIO instance.
* @param index Zero-based index of the pin.
* @return `kDifGpioResultInvalidArgument` if `gpio` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_irq_pin_test(const dif_gpio_t *gpio, uint32_t index);
/**
* Read the interrupt states of all pins.
*
* @param gpio GPIO instance.
* @param interrupt_states Interrupt states of all pins.
* @return `kDifGpioResultInvalidArgument` if `gpio` or `interrupt_states` is
* `NULL`, `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_irq_all_read(const dif_gpio_t *gpio,
uint32_t *interrupt_states);
/**
* Read the interrupt state of a pin.
*
* @param gpio GPIO instance.
* @param index Zero-based index of the pin.
* @param interrupt_state Interrupt state of the pin. True if there is a pending
* interrupt, false otherwise.
* @return `kDifGpioResultInvalidArgument` if `gpio` or `interrupt_state` is
* `NULL`, `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_irq_pin_read(const dif_gpio_t *gpio, uint32_t index,
bool *interrupt_state);
/**
* Clear the interrupt of a pin.
*
* @param gpio GPIO instance.
* @param index Zero-based index of the pin.
* @return `kDifGpioResultInvalidArgument` if `gpio` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_irq_pin_clear(const dif_gpio_t *gpio,
uint32_t index);
/**
* Enable noise filter for GPIO inputs.
*
* Setting `mask[i]` to 1 enables input noise filter for pin `i`. If enabled,
* changes in the pin value will be ignored unless stable for 16 cycles.
*
* @param gpio GPIO instance.
* @param mask Mask that identifies the pins for which input noise filter will
* be enabled.
* @return `kDifGpioResultInvalidArgument` if `gpio` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_input_noise_filter_masked_enable(
const dif_gpio_t *gpio, uint32_t mask);
/**
* Disable noise filter for GPIO inputs.
*
* Setting `mask[i]` to 1 disables input noise filter for pin `i`.
*
* @param gpio GPIO instance.
* @param mask Mask that identifies the pins for which input noise filter will
* be disabled.
* @return `kDifGpioResultInvalidArgument` if `gpio` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_input_noise_filter_masked_disable(
const dif_gpio_t *gpio, uint32_t mask);
/**
* Enable interrupts for GPIO inputs.
*
* Setting `mask[i]` to 1 enables detection of interrupt events for pin `i`.
* There are four types of interrupts per pin: rising-edge, falling-edge,
* high-level, and low-level. At least one of them must be enabled to generate
* interrupts.
*
* @param gpio GPIO instance.
* @param mask Mask that identifies the pins for which interrupts will be
* enabled.
* @return `kDifGpioResultInvalidArgument` if `gpio` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_irq_masked_enable(const dif_gpio_t *gpio,
uint32_t mask);
/**
* Disable interrupts for GPIO inputs.
*
* Setting `mask[i]` to 1 disables detection of interrupt events for pin `i`.
*
* @param gpio GPIO instance.
* @param mask Mask that identifies the pins for which interrupts will be
* disabled.
* @return `kDifGpioResultInvalidArgument` if `gpio` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_irq_masked_disable(const dif_gpio_t *gpio,
uint32_t mask);
/**
* Disable all interrupt triggers for GPIO inputs.
*
* This function disables all interrupt triggers, i.e. rising-edge,
* falling-edge, level-high, and level-low, for the pins given by the mask.
*
* @param gpio GPIO instance.
* @param mask Mask that identifies the pins whose interrupt triggers will be
* disabled.
* @return `kDifGpioResultInvalidArgument` if `gpio` is `NULL`,
* `kDifGpioResultOK` otherwise.
*/
dif_gpio_result_t dif_gpio_irq_trigger_masked_disable(const dif_gpio_t *gpio,
uint32_t mask);
/**
* Configure interrupt triggers for GPIO inputs.
*
* This function configures interrupt triggers, i.e. rising-edge, falling-edge,
* level-high, and level-low, for the pins given by the mask. Note that
* interrupt of the pin must also be enabled to generate interrupts.
*
* @param gpio GPIO instance.
* @param mask Mask that identifies the pins whose interrupt triggers will be
* configured.
* @param config New configuration of interrupt triggers.
* @return `kDifGpioResultOK` if the function is successful,
* `kDifGpioResultInvalidArgument` otherwise.
*/
dif_gpio_result_t dif_gpio_irq_trigger_masked_config(const dif_gpio_t *gpio,
uint32_t mask,
dif_gpio_irq_t config);
#endif // SW_DEVICE_LIB_DIF_GPIO_H