You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
3.6 KiB

  1. # SPI Master Driver
  2. The SPI Master drivers used in QMK have a set of common functions to allow portability between MCUs.
  3. ## AVR Configuration
  4. No special setup is required - just connect the `SS`, `SCK`, `MOSI` and `MISO` pins of your SPI devices to the matching pins on the MCU:
  5. |MCU |`SS`|`SCK`|`MOSI`|`MISO`|
  6. |---------------|----|-----|------|------|
  7. |ATMega16/32U2/4|`B0`|`B1` |`B2` |`B3` |
  8. |AT90USB64/128 |`B0`|`B1` |`B2` |`B3` |
  9. |ATmega32A |`B4`|`B7` |`B5` |`B6` |
  10. |ATmega328P |`B2`|`B5` |`B3` |`B4` |
  11. You may use more than one slave select pin, not just the `SS` pin. This is useful when you have multiple devices connected and need to communicate with them individually.
  12. `SPI_SS_PIN` can be passed to `spi_start()` to refer to `SS`.
  13. ## ChibiOS/ARM Configuration
  14. ARM support for this driver is not ready yet. Check back later!
  15. ## Functions
  16. ### `void spi_init(void)`
  17. Initialize the SPI driver. This function must be called only once, before any of the below functions can be called.
  18. ---
  19. ### `bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor)`
  20. Start an SPI transaction.
  21. #### Arguments
  22. - `pin_t slavePin`
  23. The QMK pin to assert as the slave select pin, eg. `B4`.
  24. - `bool lsbFirst`
  25. Determines the endianness of the transmission. If `true`, the least significant bit of each byte is sent first.
  26. - `uint8_t mode`
  27. The SPI mode to use:
  28. |Mode|Clock Polarity |Clock Phase |
  29. |----|--------------------|-----------------------|
  30. |`0` |Leading edge rising |Sample on leading edge |
  31. |`1` |Leading edge rising |Sample on trailing edge|
  32. |`2` |Leading edge falling|Sample on leading edge |
  33. |`3` |Leading edge falling|Sample on trailing edge|
  34. - `uint16_t divisor`
  35. The SPI clock divisor, will be rounded up to the nearest power of two. This number can be calculated by dividing the MCU's clock speed by the desired SPI clock speed. For example, an MCU running at 8 MHz wanting to talk to an SPI device at 4 MHz would set the divisor to `2`.
  36. #### Return Value
  37. `false` if the supplied parameters are invalid or the SPI peripheral is already in use, or `true`.
  38. ---
  39. ### `spi_status_t spi_write(uint8_t data)`
  40. Write a byte to the selected SPI device.
  41. #### Arguments
  42. - `uint8_t data`
  43. The byte to write.
  44. #### Return Value
  45. `SPI_STATUS_TIMEOUT` if the timeout period elapses, or `SPI_STATUS_SUCCESS`.
  46. ---
  47. ### `spi_status_t spi_read(void)`
  48. Read a byte from the selected SPI device.
  49. #### Return Value
  50. `SPI_STATUS_TIMEOUT` if the timeout period elapses, or the byte read from the device.
  51. ---
  52. ### `spi_status_t spi_transmit(const uint8_t *data, uint16_t length)`
  53. Send multiple bytes to the selected SPI device.
  54. #### Arguments
  55. - `const uint8_t *data`
  56. A pointer to the data to write from.
  57. - `uint16_t length`
  58. The number of bytes to write. Take care not to overrun the length of `data`.
  59. #### Return Value
  60. `SPI_STATUS_TIMEOUT` if the timeout period elapses, `SPI_STATUS_SUCCESS` on success, or `SPI_STATUS_ERROR` otherwise.
  61. ---
  62. ### `spi_status_t spi_receive(uint8_t *data, uint16_t length)`
  63. Receive multiple bytes from the selected SPI device.
  64. #### Arguments
  65. - `uint8_t *data`
  66. A pointer to the buffer to read into.
  67. - `uint16_t length`
  68. The number of bytes to read. Take care not to overrun the length of `data`.
  69. #### Return Value
  70. `SPI_STATUS_TIMEOUT` if the internal transmission timeout period elapses, `SPI_STATUS_SUCCESS` on success, or `SPI_STATUS_ERROR` otherwise.
  71. ---
  72. ### `void spi_stop(void)`
  73. End the current SPI transaction. This will deassert the slave select pin and reset the endianness, mode and divisor configured by `spi_start()`.