| // 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_SPI_HOST_H_ |
| #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_SPI_HOST_H_ |
| /** |
| * @file |
| * @brief <a href="/hw/ip/spi_host/doc/">SPI Host</a> Device Interface Functions |
| */ |
| |
| #include <stdint.h> |
| |
| #include "sw/device/lib/dif/autogen/dif_spi_host_autogen.h" |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif // __cplusplus |
| |
| /** |
| * Runtime configuration for SPI Host. |
| * |
| * This struct describes (SOFTWARE) runtime information for one-time |
| * configuration of the hardware. |
| */ |
| typedef struct dif_spi_host_config { |
| /** Desired SPI clock frequency (SCK). */ |
| uint32_t spi_clock; |
| /** Peripheral clock frequency (ie: kClockFreqPeripheralHz). */ |
| uint32_t peripheral_clock_freq_hz; |
| struct { |
| /** Minimum idle time between commands in SCK half-cycles. */ |
| uint8_t idle; |
| /** Chip-select trailing time in SCK half-cycles. */ |
| uint8_t trail; |
| /** Chip-select leading time in SCK half-cycles. */ |
| uint8_t lead; |
| } chip_select; |
| /** Full-cycle sampling mode. */ |
| bool full_cycle; |
| /** SPI clock phase. */ |
| bool cpha; |
| /** SPI clock polarity. */ |
| bool cpol; |
| } dif_spi_host_config_t; |
| |
| /** |
| * Width of SPI operations. |
| */ |
| typedef enum dif_spi_host_width { |
| /** Standard SPI mode (single lanes for send and recv). */ |
| kDifSpiHostWidthStandard = 0, |
| /** Dual SPI mode (use two lanes for send and recv). */ |
| kDifSpiHostWidthDual = 1, |
| /** Quad SPI mode (use four lanes for send and recv). */ |
| kDifSpiHostWidthQuad = 2, |
| } dif_spi_host_width_t; |
| |
| /** |
| * Direction of SPI operations. |
| * |
| * This describes which direction a given SPI operation will use. |
| */ |
| typedef enum dif_spi_host_direction { |
| /** The SPI host neither transmits or receives. */ |
| kDifSpiHostDirectionDummy = 0, |
| /** The SPI host receives data. */ |
| kDifSpiHostDirectionRx = 1, |
| /** The SPI host transmits data. */ |
| kDifSpiHostDirectionTx = 2, |
| /** The SPI host transmits and receives data. */ |
| kDifSpiHostDirectionBidirectional = 3, |
| } dif_spi_host_direction_t; |
| |
| /** |
| * Segment types for segments in a transaction. |
| */ |
| typedef enum dif_spi_host_segment_type { |
| /** The segment is a SPI opcode. */ |
| kDifSpiHostSegmentTypeOpcode, |
| /** The segment is a SPI address. */ |
| kDifSpiHostSegmentTypeAddress, |
| /** The segment is a SPI dummy cycle. */ |
| kDifSpiHostSegmentTypeDummy, |
| /** The segment is a SPI transmit (from a memory buffer). */ |
| kDifSpiHostSegmentTypeTx, |
| /** The segment is a SPI receive (into a memory buffer). */ |
| kDifSpiHostSegmentTypeRx, |
| /** The segment is a simultaneous transmit and receieve. */ |
| kDifSpiHostSegmentTypeBidirectional, |
| } dif_spi_host_segment_type_t; |
| |
| /** |
| * Address mode for the address segment in a transaction. |
| */ |
| typedef enum dif_spi_host_addr_mode { |
| /** The address is a 3-byte address. */ |
| kDifSpiHostAddrMode3b, |
| /** The address is a 4-byte address. */ |
| kDifSpiHostAddrMode4b, |
| } dif_spi_host_addr_mode_t; |
| |
| /** |
| * Segment descriptor for each segment in a transaction. |
| * |
| * This struct is a tagged union: the `type` field determines |
| * which field of the union is relevant. |
| */ |
| typedef struct dif_spi_host_segment { |
| /** The segment type for this segment. */ |
| dif_spi_host_segment_type_t type; |
| union { |
| uint8_t opcode; |
| struct { |
| dif_spi_host_width_t width; |
| dif_spi_host_addr_mode_t mode; |
| uint32_t address; |
| } address; |
| struct { |
| dif_spi_host_width_t width; |
| size_t length; |
| } dummy; |
| struct { |
| dif_spi_host_width_t width; |
| const void *buf; |
| size_t length; |
| } tx; |
| struct { |
| dif_spi_host_width_t width; |
| void *buf; |
| size_t length; |
| } rx; |
| struct { |
| dif_spi_host_width_t width; |
| const void *txbuf; |
| void *rxbuf; |
| size_t length; |
| } bidir; |
| }; |
| } dif_spi_host_segment_t; |
| |
| /** |
| * Configures SPI Host with runtime information. |
| * |
| * This function should only need to be called once for the lifetime of |
| * `handle`. |
| * |
| * @param spi_host A SPI Host handle. |
| * @param config Runtime configuration parameters. |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_spi_host_configure(const dif_spi_host_t *spi_host, |
| dif_spi_host_config_t config); |
| |
| /** |
| * Sets the enablement of the SPI host output buffers. |
| * |
| * @param spi_host A SPI Host handle. |
| * @param enabled Enable or disable the output buffers. |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_spi_host_output_set_enabled(const dif_spi_host_t *spi_host, |
| bool enabled); |
| |
| /** |
| * Write to the SPI Host transmit FIFO. |
| * |
| * @param spi_host A SPI Host handle. |
| * @param src A pointer to the buffer to transmit. |
| * @param len The length of the transmit buffer. |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_spi_host_fifo_write(const dif_spi_host_t *spi_host, |
| const void *src, uint16_t len); |
| |
| /** |
| * Read from the SPI Host receive FIFO. |
| * |
| * @param spi_host A SPI Host handle. |
| * @param dst A pointer to the buffer to receive the data. |
| * @param len The length of the receive buffer. |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_spi_host_fifo_read(const dif_spi_host_t *spi_host, void *dst, |
| uint16_t len); |
| |
| /** |
| * Begins a SPI Host transaction. |
| * |
| * @param spi_host A SPI Host handle. |
| * @param csid The chip-select ID of the SPI target. |
| * @param segments The SPI segments to send in this transaction. |
| * @param length The number of SPI segments in this transaction. |
| * @return The result of the operation. |
| */ |
| OT_WARN_UNUSED_RESULT |
| dif_result_t dif_spi_host_transaction(const dif_spi_host_t *spi_host, |
| uint32_t csid, |
| dif_spi_host_segment_t *segments, |
| size_t length); |
| |
| #ifdef __cplusplus |
| } // extern "C" |
| #endif // __cplusplus |
| |
| #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_SPI_HOST_H_ |