]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/spi.h
Update RISCC-V-RV32-SiFive_HiFive1_FreedomStudio project to latest tools and metal...
[freertos] / FreeRTOS / Demo / RISC-V_RV32_SiFive_HiFive1_FreedomStudio / freedom-metal / metal / spi.h
1 /* Copyright 2018 SiFive, Inc */
2 /* SPDX-License-Identifier: Apache-2.0 */
3
4 #ifndef METAL__SPI_H
5 #define METAL__SPI_H
6
7 struct metal_spi;
8
9 /*! @brief The configuration for a SPI transfer */
10 struct metal_spi_config {
11     /*! @brief The protocol for the SPI transfer */
12     enum {
13         METAL_SPI_SINGLE,
14         METAL_SPI_DUAL,
15         METAL_SPI_QUAD
16     } protocol;
17
18     /*! @brief The polarity of the SPI transfer, equivalent to CPOL */
19     unsigned int polarity : 1;
20     /*! @brief The phase of the SPI transfer, equivalent to CPHA */
21     unsigned int phase : 1;
22     /*! @brief The endianness of the SPI transfer */
23     unsigned int little_endian : 1;
24     /*! @brief The active state of the chip select line */
25     unsigned int cs_active_high : 1;
26     /*! @brief The chip select ID to activate for the SPI transfer */
27     unsigned int csid;
28     /*! @brief The spi command frame number (cycles = num * frame_len) */
29     unsigned int cmd_num;
30     /*! @brief The spi address frame number */
31     unsigned int addr_num;
32     /*! @brief The spi dummy frame number */
33     unsigned int dummy_num;
34     /*! @brief The Dual/Quad spi mode selection.*/
35     enum {
36         MULTI_WIRE_ALL,
37         MULTI_WIRE_DATA_ONLY,
38         MULTI_WIRE_ADDR_DATA
39     } multi_wire;
40 };
41
42 struct metal_spi_vtable {
43     void (*init)(struct metal_spi *spi, int baud_rate);
44     int (*transfer)(struct metal_spi *spi, struct metal_spi_config *config, size_t len, char *tx_buf, char *rx_buf);
45     int (*get_baud_rate)(struct metal_spi *spi);
46     int (*set_baud_rate)(struct metal_spi *spi, int baud_rate);
47 };
48
49 /*! @brief A handle for a SPI device */
50 struct metal_spi {
51     const struct metal_spi_vtable *vtable;
52 };
53
54 /*! @brief Get a handle for a SPI device
55  * @param device_num The index of the desired SPI device
56  * @return A handle to the SPI device, or NULL if the device does not exist*/
57 struct metal_spi *metal_spi_get_device(unsigned int device_num);
58
59 /*! @brief Initialize a SPI device with a certain baud rate
60  * @param spi The handle for the SPI device to initialize
61  * @param baud_rate The baud rate to set the SPI device to
62  */
63 __inline__ void metal_spi_init(struct metal_spi *spi, int baud_rate) { spi->vtable->init(spi, baud_rate); }
64
65 /*! @brief Perform a SPI transfer
66  * @param spi The handle for the SPI device to perform the transfer
67  * @param config The configuration for the SPI transfer.
68  * @param len The number of bytes to transfer
69  * @param tx_buf The buffer to send over the SPI bus. Must be len bytes long. If NULL, the SPI will transfer the value 0.
70  * @param rx_buf The buffer to receive data into. Must be len bytes long. If NULL, the SPI will ignore received bytes.
71  * @return 0 if the transfer succeeds
72  */
73 __inline__ int metal_spi_transfer(struct metal_spi *spi, struct metal_spi_config *config, size_t len, char *tx_buf, char *rx_buf) {
74     return spi->vtable->transfer(spi, config, len, tx_buf, rx_buf);
75 }
76
77 /*! @brief Get the current baud rate of the SPI device
78  * @param spi The handle for the SPI device
79  * @return The baud rate in Hz
80  */
81 __inline__ int metal_spi_get_baud_rate(struct metal_spi *spi) { return spi->vtable->get_baud_rate(spi); }
82
83 /*! @brief Set the current baud rate of the SPI device
84  * @param spi The handle for the SPI device
85  * @param baud_rate The desired baud rate of the SPI device
86  * @return 0 if the baud rate is successfully changed
87  */
88 __inline__ int metal_spi_set_baud_rate(struct metal_spi *spi, int baud_rate) { return spi->vtable->set_baud_rate(spi, baud_rate); }
89
90 #endif