/* * Copyright (c) 2020-2021 Huawei Device Co., Ltd. * * HDF is dual licensed: you can use it either under the terms of * the GPL, or the BSD license, at your option. * See the LICENSE file in the root of this repository for complete details. */ /** * @addtogroup SPI * @{ * * @brief Defines standard APIs of the Serial Peripheral Interface (SPI) capabilities. * * The SPI module abstracts the SPI capabilities of different system platforms to provide stable APIs * for driver development. * This module can create and destroy SPI device handles, read and write SPI data, * and obtain and set configuration parameters. * * @since 1.0 */ /** * @file spi_if.h * * @brief Defines standard SPI-specific interfaces for driver development. * * A driver needs to use the SPI-specific interfaces for data writing and reading * before performing any operations on an SPI-compliant device. * * @since 1.0 */ #ifndef SPI_IF_H #define SPI_IF_H #include "platform_if.h" #ifdef __cplusplus #if __cplusplus extern "C" { #endif #endif /* __cplusplus */ /** * @brief Indicates the SPI clock phase. The value 0 indicates that data will be sampled on the first clock edge, * and 1 indicates that data will be sampled on the second clock edge. * * @since 1.0 */ #define SPI_CLK_PHASE (1 << 0) /** * @brief Indicates the SPI clock polarity. The value 0 indicates a low-level clock signal in the idle state, * and 1 indicates a high-level clock signal in the idle state. * * @since 1.0 */ #define SPI_CLK_POLARITY (1 << 1) /** * @brief Indicates that a single data line is used for both input and output. * * @since 1.0 */ #define SPI_MODE_3WIRE (1 << 2) /** * @brief Indicates the SPI loopback mode. * * @since 1.0 */ #define SPI_MODE_LOOP (1 << 3) /** * @brief Indicates the SPI data transfer order. The value 0 indicates that data is transferred from the most * significant bit (MSB) to the least significant bit (LSB), and 1 indicates the opposite. * * @since 1.0 */ #define SPI_MODE_LSBFE (1 << 4) /** * @brief Indicates that there is only one SPI device, and no chip select (CS) is required. * * @since 1.0 */ #define SPI_MODE_NOCS (1 << 5) /** * @brief Indicates that the CS level is high when an SPI device is selected. * * @since 1.0 */ #define SPI_MODE_CS_HIGH (1 << 6) /** * @brief Indicates that the SPI device is set to low for pausing data transfer. * * @since 1.0 */ #define SPI_MODE_READY (1 << 7) /** * @brief Enumerates transfer modes of SPI data. * * @attention The specific SPI controller determines which variables in this structure are supported. * * @since 1.0 */ enum SpiTransferMode { SPI_INTERRUPT_TRANSFER = 0, /**< Interrupt transfer mode */ SPI_POLLING_TRANSFER, /**< Polling transfer mode */ SPI_DMA_TRANSFER, /**< Direct Memory Access (DMA) transfer mode */ }; /** * @brief Defines the general SPI device descriptor, which can be used as the unique identifier of an SPI device. * When operating an SPI device, you need to specify a descriptor of the {@link SpiDevInfo} type, and obtain the * handle of the SPI device by calling {@link SpiOpen}. * * @since 1.0 */ struct SpiDevInfo { uint32_t busNum; /**< SPI bus number */ uint32_t csNum; /**< SPI device chip select (CS) */ }; /** * @brief Defines the custom SPI transfer message. * * @attention The specific SPI controller determines whether speed, delayUs, * and csChange are supported. * * @since 1.0 */ struct SpiMsg { uint8_t *wbuf; /**< Address of the write buffer */ uint8_t *rbuf; /**< Address of the read buffer */ uint32_t len; /**< Length of the read and write buffers. The read buffer and the write * buffer have the same length. */ uint32_t speed; /**< Current message transfer speed */ uint16_t delayUs; /**< Delay (in microseconds) before starting the next transfer. * The value 0 indicates there is no delay between transfers. */ uint8_t csChange; /**< Whether to switch off the CS before the next transfer when the current transfer has been * completed. 1 indicates to switch off the CS; 0 indicates to switch on the CS. */ }; /** * @brief Defines the configuration of an SPI device. * * @attention The specific SPI controller determines which variables in this structure are supported. * * @since 1.0 */ struct SpiCfg { uint32_t maxSpeedHz; /**< Maximum clock frequency */ uint16_t mode; /**< Input and output mode of SPI data | Description * -----------------| ----------------------- * SPI_CLK_PHASE | SPI clock phase. * SPI_CLK_POLARITY | SPI clock polarity. * SPI_MODE_3WIRE | A single data line is used for both input and output. * SPI_MODE_LOOP | SPI loopback mode. * SPI_MODE_LSBFE | SPI data transfer order * SPI_MODE_NOCS | There is only one SPI device, and no CS is required. * SPI_MODE_CS_HIGH | The CS level is high when an SPI device is selected. * SPI_MODE_READY | The SPI device is set to low for pausing data transfer. */ uint8_t transferMode; /**< Data transfer mode, as defined in {@link SpiTransferMode}. */ uint8_t bitsPerWord; /**< Data transfer bit width */ }; /** * @brief Obtains the handle of an SPI device. * * @param info Indicates the pointer to the SPI device information. * * @return Returns the pointer to the handle of the SPI device if the operation is successful; * returns NULL otherwise. * * @since 1.0 */ DevHandle SpiOpen(const struct SpiDevInfo *info); /** * @brief Releases the handle of an SPI device. * * @param handle Indicates the pointer to the SPI device handle obtained via {@link SpiOpen}. * * @since 1.0 */ void SpiClose(DevHandle handle); /** * @brief Launches a custom transfer to an SPI device. * * @param handle Indicates the pointer to the SPI device handle obtained via {@link SpiOpen}. * @param msgs Indicates the pointer to the data to transfer. * @param count Indicates the length of the message structure array. * * @return Returns 0 if the operation is successful; returns a negative value otherwise. * @see SpiMsg * @since 1.0 */ int32_t SpiTransfer(DevHandle handle, struct SpiMsg *msgs, uint32_t count); /** * @brief Reads data of a specified length from an SPI device. * * @param handle Indicates the pointer to the SPI device handle obtained via {@link SpiOpen}. * @param buf Indicates the pointer to the buffer for receiving the data. * @param len Indicates the length of the data to read. * * @return Returns 0 if the operation is successful; returns a negative value otherwise. * * @since 1.0 */ int32_t SpiRead(DevHandle handle, uint8_t *buf, uint32_t len); /** * @brief Writes data of a specified length to an SPI device. * * @param handle Indicates the pointer to the SPI device handle obtained via {@link SpiOpen}. * @param buf Indicates the pointer to the data to write. * @param len Indicates the length of the data to write. * * @return Returns 0 if the operation is successful; returns a negative value otherwise. * * @since 1.0 */ int32_t SpiWrite(DevHandle handle, uint8_t *buf, uint32_t len); /** * @brief Sets configuration parameters for an SPI device. * * @param handle Indicates the pointer to the SPI device handle obtained via {@link SpiOpen}. * @param cfg Indicates the pointer to the configuration parameters. * * @return Returns 0 if the operation is successful; returns a negative value otherwise. * * @since 1.0 */ int32_t SpiSetCfg(DevHandle handle, struct SpiCfg *cfg); /** * @brief Obtains the configuration parameters of an SPI device. * * @param handle Indicates the pointer to the SPI device handle obtained via {@link SpiOpen}. * @param cfg Indicates the pointer to the configuration parameters. * * @return Returns 0 if the operation is successful; returns a negative value otherwise. * * @since 1.0 */ int32_t SpiGetCfg(DevHandle handle, struct SpiCfg *cfg); /** * @brief Enumerates SPI I/O commands. * * @since 1.0 */ enum SpiIoCmd { SPI_IO_OPEN = 0, /**< Open the SPI device. */ SPI_IO_CLOSE, /**< Close the SPI device. */ SPI_IO_TRANSFER, /**< Execute one or more SPI messages. */ SPI_IO_SET_CONFIG, /**< Set the configurations. */ SPI_IO_GET_CONFIG, /**< Get the configurations. */ }; #ifdef __cplusplus #if __cplusplus } #endif #endif /* __cplusplus */ #endif /* SPI_IF_H */ /** @} */