blob: 6ffca25f903be49e063f7c1a36fb313ae9ce0757 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_GPIO_H_
#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_GPIO_H_
/**
* @file
* @brief <a href="/hw/ip/gpio/doc/">GPIO</a> Device Interface Functions
*/
#include <stddef.h>
#include <stdint.h>
#include "sw/device/lib/base/mmio.h"
#include "sw/device/lib/dif/dif_warn_unused_result.h"
// Header Extern Guard (so header can be used from C and C++)
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
/**
* 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.
*/
typedef enum dif_gpio_result {
/**
* The function succeeded.
*/
kDifGpioOk,
/**
* The function failed a non-specific assertion.
*
* This error is not recoverable.
*/
kDifGpioError,
/**
* There is a problem with the argument(s) to the function.
*
* This return code is only returned before the function has any side effects.
*
* This error is recoverable and the operation can be retried after correcting
* the problem with the argument(s).
*/
kDifGpioBadArg,
} 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[out] gpio GPIO instance that will store the internal state of the
* initialized GPIO device.
* @return `kDifGpioBadArg` if `config` or `gpio` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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 `kDifGpioBadArg` if `gpio` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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[out] pin_values Pin values.
* @return `kDifGpioBadArg` if `gpio` or `pin_values` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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[out] pin_value Pin value.
* @return `kDifGpioBadArg` if `gpio` or `pin_values` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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 `kDifGpioBadArg` if `gpio` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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 `kDifGpioBadArg` if `gpio` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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 `kDifGpioBadArg` if `gpio` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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 `kDifGpioBadArg` if `gpio` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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 `kDifGpioBadArg` if `gpio` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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 `kDifGpioBadArg` if `gpio` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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 `kDifGpioBadArg` if `gpio` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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[out] interrupt_states Interrupt states of all pins.
* @return `kDifGpioBadArg` if `gpio` or `interrupt_states` is
* `NULL`, `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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[out] interrupt_state Interrupt state of the pin. True if there is a
* pending interrupt, false otherwise.
* @return `kDifGpioBadArg` if `gpio` or `interrupt_state` is
* `NULL`, `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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 `kDifGpioBadArg` if `gpio` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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 `kDifGpioBadArg` if `gpio` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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 `kDifGpioBadArg` if `gpio` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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 `kDifGpioBadArg` if `gpio` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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 `kDifGpioBadArg` if `gpio` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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 `kDifGpioBadArg` if `gpio` is `NULL`,
* `kDifGpioOk` otherwise.
*/
DIF_WARN_UNUSED_RESULT
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 `kDifGpioOk` if the function is successful,
* `kDifGpioBadArg` otherwise.
*/
DIF_WARN_UNUSED_RESULT
dif_gpio_result_t dif_gpio_irq_trigger_masked_config(const dif_gpio_t *gpio,
uint32_t mask,
dif_gpio_irq_t config);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_GPIO_H_