logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

spi_master.h (3543B)


  1. // Copyright 2025 QMK
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <stdint.h>
  5. #include <stdbool.h>
  6. #include "gpio.h"
  7. /**
  8. * \file
  9. *
  10. * \defgroup spi_master SPI Master API
  11. *
  12. * \brief API to communicate with SPI devices.
  13. * \{
  14. */
  15. // Hardware SS pin is defined in the header so that user code can refer to it
  16. #ifdef __AVR__
  17. # if defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
  18. # define SPI_SS_PIN B0
  19. # elif defined(__AVR_ATmega32A__)
  20. # define SPI_SS_PIN B4
  21. # elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
  22. # define SPI_SS_PIN B2
  23. # endif
  24. #endif
  25. typedef int16_t spi_status_t;
  26. #define SPI_STATUS_SUCCESS (0)
  27. #define SPI_STATUS_ERROR (-1)
  28. #define SPI_STATUS_TIMEOUT (-2)
  29. #define SPI_TIMEOUT_IMMEDIATE (0)
  30. #define SPI_TIMEOUT_INFINITE (0xFFFF)
  31. #ifdef __cplusplus
  32. extern "C" {
  33. #endif
  34. typedef struct spi_start_config_t {
  35. pin_t slave_pin;
  36. bool lsb_first;
  37. uint8_t mode;
  38. uint16_t divisor;
  39. bool cs_active_low;
  40. } spi_start_config_t;
  41. /**
  42. * \brief Initialize the SPI driver. This function must be called only once, before any of the below functions can be called.
  43. */
  44. void spi_init(void);
  45. /**
  46. * \brief Start an SPI transaction.
  47. *
  48. * \param slavePin The GPIO pin connected to the desired device's `SS` line.
  49. * \param lsbFirst Determines the endianness of the transmission. If `true`, the least significant bit of each byte is sent first.
  50. * \param mode The SPI mode to use.
  51. * \param divisor The SPI clock divisor.
  52. *
  53. * \return `true` if the operation was successful, otherwise `false` if the supplied parameters are invalid or the SPI peripheral is already in use.
  54. */
  55. bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor);
  56. bool spi_start_extended(spi_start_config_t *start_config);
  57. /**
  58. * \brief Write a byte to the selected SPI device.
  59. *
  60. * \param data The byte to write.
  61. *
  62. * \return `SPI_STATUS_TIMEOUT` if the timeout period elapses, or `SPI_STATUS_SUCCESS`.
  63. */
  64. spi_status_t spi_write(uint8_t data);
  65. /**
  66. * \brief Read a byte from the selected SPI device.
  67. *
  68. * \return `SPI_STATUS_TIMEOUT` if the timeout period elapses, otherwise the byte read from the device.
  69. */
  70. spi_status_t spi_read(void);
  71. /**
  72. * \brief Send multiple bytes to the selected SPI device.
  73. *
  74. * \param data A pointer to the data to write from.
  75. * \param length The number of bytes to write. Take care not to overrun the length of `data`.
  76. *
  77. * \return `SPI_STATUS_TIMEOUT` if the timeout period elapses, `SPI_STATUS_ERROR` if some other error occurs, otherwise `SPI_STATUS_SUCCESS`.
  78. */
  79. spi_status_t spi_transmit(const uint8_t *data, uint16_t length);
  80. /**
  81. * \brief Receive multiple bytes from the selected SPI device.
  82. *
  83. * \param data A pointer to a buffer to read into.
  84. * \param length The number of bytes to read. Take care not to overrun the length of `data`.
  85. *
  86. * \return `SPI_STATUS_TIMEOUT` if the timeout period elapses, `SPI_STATUS_ERROR` if some other error occurs, otherwise `SPI_STATUS_SUCCESS`.
  87. */
  88. spi_status_t spi_receive(uint8_t *data, uint16_t length);
  89. /**
  90. * \brief End the current SPI transaction. This will deassert the slave select pin and reset the endianness, mode and divisor configured by `spi_start()`.
  91. *
  92. */
  93. void spi_stop(void);
  94. #ifdef __cplusplus
  95. }
  96. #endif
  97. /** \} */