spi.h 3.4 KB

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