| // 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_UART_H_ |
| #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_UART_H_ |
| |
| /** |
| * @file |
| * @brief <a href="/hw/ip/uart/doc/">UART</a> Device Interface Functions |
| */ |
| |
| #include <stdint.h> |
| |
| #include "sw/device/lib/base/mmio.h" |
| |
| #include "sw/device/lib/dif/autogen/dif_uart_autogen.h" |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif // __cplusplus |
| |
| /** |
| * A parity state: odd, or even. |
| */ |
| typedef enum dif_uart_parity { |
| /** |
| * Indicates the "odd" parity. |
| */ |
| kDifUartParityOdd = 0, |
| /** |
| * Indicates the "even" parity. |
| */ |
| kDifUartParityEven, |
| } dif_uart_parity_t; |
| |
| /** |
| * Runtime configuration for UART. |
| * |
| * This struct describes runtime information for one-time configuration of the |
| * hardware. |
| */ |
| typedef struct dif_uart_config { |
| /** |
| * The UART baudrate. |
| */ |
| uint32_t baudrate; |
| /** |
| * The frequency of the clock driving the UART. |
| */ |
| uint32_t clk_freq_hz; |
| /** |
| * Whether to enable parity checking. |
| */ |
| dif_toggle_t parity_enable; |
| /** |
| * The parity to set. |
| */ |
| dif_uart_parity_t parity; |
| /** |
| * Whether to enable TX datapath. |
| */ |
| dif_toggle_t tx_enable; |
| /** |
| * Whether to enable RX datapath. |
| */ |
| dif_toggle_t rx_enable; |
| } dif_uart_config_t; |
| |
| /** |
| * A UART FIFO watermark depth configuration. |
| */ |
| typedef enum dif_uart_watermark { |
| /** |
| * Indicates a one-byte watermark. |
| */ |
| kDifUartWatermarkByte1 = 0, |
| /** |
| * Indicates a four-byte watermark. |
| */ |
| kDifUartWatermarkByte4, |
| /** |
| * Indicates an eight-byte watermark. |
| */ |
| kDifUartWatermarkByte8, |
| /** |
| * Indicates a sixteen-byte watermark. |
| */ |
| kDifUartWatermarkByte16, |
| /** |
| * Indicates a thirty-byte watermark. |
| */ |
| kDifUartWatermarkByte30, |
| } dif_uart_watermark_t; |
| |
| /** |
| * A UART datapath to select various enables / FIFO resets. |
| */ |
| typedef enum dif_uart_datapath { |
| /** |
| * Selects the RX datapath for enablement / reset. |
| */ |
| kDifUartDatapathRx = 0, |
| /** |
| * Selects the TX datapath for enablement / reset. |
| */ |
| kDifUartDatapathTx, |
| /** |
| * Selects both the RX and TX datapaths for enablement / reset. |
| */ |
| kDifUartDatapathAll, |
| } dif_uart_datapath_t; |
| |
| /** |
| * A UART system/line loopback configuration. |
| */ |
| typedef enum dif_uart_loopback { |
| /** |
| * Indicates that outgoing TX bits should be recieved through RX. |
| */ |
| kDifUartLoopbackSystem = 0, |
| /** |
| * Indicates that incoming RX bits should be forwarded to TX. |
| */ |
| kDifUartLoopbackLine, |
| } dif_uart_loopback_t; |
| |
| /** |
| * The size of the UART TX and RX FIFOs, in bytes. |
| */ |
| extern const uint32_t kDifUartFifoSizeBytes; |
| |
| /** |
| * Configures UART with runtime information. |
| * |
| * This function should need to be called once for the lifetime of `handle`. |
| * |
| * @param uart A UART handle. |
| * @param config Runtime configuration parameters. |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_uart_configure(const dif_uart_t *uart, |
| dif_uart_config_t config); |
| |
| /** |
| * Sets the RX FIFO watermark. |
| * |
| * This function is only useful when the corresponding interrupt is enabled. |
| * When the queued RX FIFO number of bytes rises to or above this |
| * level, the RX watermark interrupt is raised. |
| * |
| * @param uart A UART handle. |
| * @param watermark RX FIFO watermark. |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_uart_watermark_rx_set(const dif_uart_t *uart, |
| dif_uart_watermark_t watermark); |
| |
| /** |
| * Sets the TX FIFO watermark. |
| * |
| * This function is only useful when the corresponding interrupt is enabled. |
| * When the queued RX FIFO number of bytes rises to or above this |
| * level, the RX watermark interrupt is raised. |
| * |
| * @param uart A UART handle. |
| * @param watermark TX FIFO watermark. |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_uart_watermark_tx_set(const dif_uart_t *uart, |
| dif_uart_watermark_t watermark); |
| |
| /** |
| * Sets the enablement state of one or both (TX/RX) datapaths. |
| * |
| * @param uart A UART handle. |
| * @param datapath The datapath to set the enablement state of (RX, TX or both). |
| * @param enabled The enablement state to set. |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_uart_set_enable(const dif_uart_t *uart, |
| dif_uart_datapath_t datapath, |
| dif_toggle_t enabled); |
| /** |
| * Sends bytes over UART. |
| * |
| * Can be used from inside an UART ISR. |
| * |
| * This function attempts to write `bytes_requested` number of bytes to the |
| * UART TX FIFO from `bytes_requested`, and passes `bytes_written` back to |
| * the caller. `bytes_written` is optional, NULL should be passed in if the |
| * value is not needed. |
| * |
| * @param uart A UART handle. |
| * @param data Data to be written. |
| * @param bytes_requested Number of bytes requested to be written by the caller. |
| * @param[out] bytes_written Number of bytes written (optional). |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_uart_bytes_send(const dif_uart_t *uart, const uint8_t *data, |
| size_t bytes_requested, size_t *bytes_written); |
| |
| /** |
| * Recieves bytes over UART. |
| * |
| * Can be used from inside an UART ISR. |
| * |
| * This function attempts to read `bytes_requested` number of bytes from the |
| * UART RX FIFO into `data`, and passes `bytes_read` back to the caller. |
| * `bytes_read` is optional, NULL should be passed in if the value is not |
| * needed. |
| * |
| * @param uart A UART handle. |
| * @param bytes_requested Number of bytes requested to be read by the caller. |
| * @param[out] data Buffer for up to `bytes_requested` bytes of read data. |
| * @param[out] bytes_read Number of bytes read (optional). |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_uart_bytes_receive(const dif_uart_t *uart, |
| size_t bytes_requested, uint8_t *data, |
| size_t *bytes_read); |
| |
| /** |
| * Transmits a single UART byte (polled). |
| * |
| * This operation is polled, and will busy wait until a byte has been sent. |
| * |
| * Must not be used inside an ISR. |
| * |
| * @param uart A UART handle. |
| * @param byte Byte to be transmitted. |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_uart_byte_send_polled(const dif_uart_t *uart, uint8_t byte); |
| |
| /** |
| * Receives a single UART byte (polled). |
| * |
| * This operation is polled, and will busy wait until a byte has been read. |
| * |
| * Must not be used inside an ISR. |
| * |
| * @param uart A UART handle. |
| * @param[out] byte Received byte. |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_uart_byte_receive_polled(const dif_uart_t *uart, |
| uint8_t *byte); |
| |
| /** |
| * Gets the number of bytes available to be read from the UART RX FIFO. |
| * |
| * This function can be used to check FIFO full and empty conditions. |
| * |
| * @param uart A UART handle. |
| * @param[out] num_bytes Number of bytes available to be read. |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_uart_rx_bytes_available(const dif_uart_t *uart, |
| size_t *num_bytes); |
| |
| /** |
| * Gets the number of bytes available to be written from the UART TX FIFO. |
| * |
| * This function can be used to check FIFO full and empty conditions. |
| * |
| * @param uart A UART handle. |
| * @param[out] num_bytes Number of bytes available to be written. |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_uart_tx_bytes_available(const dif_uart_t *uart, |
| size_t *num_bytes); |
| |
| /** |
| * Resets one or both datapath FIFOs. If the byte is in transit, this function |
| * will not abort the operation. |
| * |
| * @param uart A UART handle. |
| * @param fifo The FIFO to reset (RX, TX or both). |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_uart_fifo_reset(const dif_uart_t *uart, |
| dif_uart_datapath_t fifo); |
| |
| /** |
| * Enables or disables a transmit/receive loopback. |
| * |
| * This API can be used for testing, such as to validate transmit and receive |
| * routines. |
| * |
| * Loopback should only be enabled when device is in the IDLE state to prevent |
| * data loss/coruption. Behaviour depends on the `loopback` parameter: |
| * - `kDifUartLoopbackSystem`: |
| * Receives the data that is being transmitted. No external data can be |
| * received (from the RX line). When enabled the TX line goes high. |
| * - `kDifUartLoopbackLine`: |
| * Transmits the data that is being received. No internal data can be |
| * sent out (from the TX FIFO). When enabled the RX line goes high. |
| * |
| * @param uart A UART handle. |
| * @param loopback Loopback type (transmit/receive). |
| * @param enable Enable/disable control flag. |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_uart_loopback_set(const dif_uart_t *uart, |
| dif_uart_loopback_t loopback, |
| dif_toggle_t enable); |
| |
| /** |
| * Enables the RX timeout with the given duration. |
| * |
| * @param uart A UART handle. |
| * @param duration_ticks RX timeout value in UART bit times (using the baud rate |
| * clock as reference) in the range [0,0xffffff]. |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_uart_enable_rx_timeout(const dif_uart_t *uart, |
| uint32_t duration_ticks); |
| |
| /** |
| * Disables the RX timeout. |
| * |
| * In addition to disabling the RX timeout the timeout duration is reset to 0 |
| * ticks. |
| * |
| * @param uart A UART handle. |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_uart_disable_rx_timeout(const dif_uart_t *uart); |
| |
| /** |
| * Gets the current status of the RX timeout control. |
| * |
| * @param uart A UART handle. |
| * @param[out] status The status of the RX timeout control (enabled or |
| * disabled). |
| * @param[out] duration_ticks RX timeout value in UART bit times (using the baud |
| * rate clock as reference) in the range [0,0xffffff] (optional). |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_uart_get_rx_timeout(const dif_uart_t *uart, |
| dif_toggle_t *status, |
| uint32_t *duration_ticks); |
| |
| #ifdef __cplusplus |
| } // extern "C" |
| #endif // __cplusplus |
| |
| #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_UART_H_ |