aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/drivers/spi.md8
-rw-r--r--drivers/spi_master.h116
-rw-r--r--keyboards/darkproject/kd83a_bfg_edition/config.h3
-rw-r--r--keyboards/darkproject/kd87a_bfg_edition/config.h3
-rw-r--r--keyboards/gmmk/gmmk2/p96/config.h3
-rw-r--r--keyboards/jukaie/jk01/config.h3
-rw-r--r--keyboards/projectd/65/projectd_65_ansi/config.h3
-rw-r--r--keyboards/projectd/75/ansi/config.h3
-rw-r--r--keyboards/projectd/75/iso/config.h3
-rw-r--r--platforms/avr/drivers/spi_master.h68
-rw-r--r--platforms/chibios/drivers/spi_master.c43
-rw-r--r--platforms/chibios/drivers/spi_master.h102
12 files changed, 183 insertions, 175 deletions
diff --git a/docs/drivers/spi.md b/docs/drivers/spi.md
index 43d2a056d5..140b204945 100644
--- a/docs/drivers/spi.md
+++ b/docs/drivers/spi.md
@@ -88,7 +88,7 @@ Start an SPI transaction.
#### Arguments {#api-spi-start-arguments}
- `pin_t slavePin`
- The QMK pin to assert as the slave select pin, eg. `B4`.
+ The GPIO pin connected to the desired device's `SS` line.
- `bool lsbFirst`
Determines the endianness of the transmission. If `true`, the least significant bit of each byte is sent first.
- `uint8_t mode`
@@ -106,7 +106,7 @@ Start an SPI transaction.
#### Return Value {#api-spi-start-return}
-`false` if the supplied parameters are invalid or the SPI peripheral is already in use, or `true`.
+`true` if the operation was successful, otherwise `false` if the supplied parameters are invalid or the SPI peripheral is already in use.
---
@@ -131,7 +131,7 @@ Read a byte from the selected SPI device.
#### Return Value {#api-spi-read-return}
-`SPI_STATUS_TIMEOUT` if the timeout period elapses, or the byte read from the device.
+`SPI_STATUS_TIMEOUT` if the timeout period elapses, otherwise the byte read from the device.
---
@@ -159,7 +159,7 @@ Receive multiple bytes from the selected SPI device.
#### Arguments {#api-spi-receive-arguments}
- `uint8_t *data`
- A pointer to the buffer to read into.
+ A pointer to a buffer to read into.
- `uint16_t length`
The number of bytes to read. Take care not to overrun the length of `data`.
diff --git a/drivers/spi_master.h b/drivers/spi_master.h
new file mode 100644
index 0000000000..d206b812bf
--- /dev/null
+++ b/drivers/spi_master.h
@@ -0,0 +1,116 @@
+// Copyright 2025 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "gpio.h"
+
+/**
+ * \file
+ *
+ * \defgroup spi_master SPI Master API
+ *
+ * \brief API to communicate with SPI devices.
+ * \{
+ */
+
+// Hardware SS pin is defined in the header so that user code can refer to it
+#ifdef __AVR__
+# 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__)
+# define SPI_SS_PIN B0
+# elif defined(__AVR_ATmega32A__)
+# define SPI_SS_PIN B4
+# elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
+# define SPI_SS_PIN B2
+# endif
+#endif
+
+typedef int16_t spi_status_t;
+
+#define SPI_STATUS_SUCCESS (0)
+#define SPI_STATUS_ERROR (-1)
+#define SPI_STATUS_TIMEOUT (-2)
+
+#define SPI_TIMEOUT_IMMEDIATE (0)
+#define SPI_TIMEOUT_INFINITE (0xFFFF)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spi_start_config_t {
+ pin_t slave_pin;
+ bool lsb_first;
+ uint8_t mode;
+ uint16_t divisor;
+ bool cs_active_low;
+} spi_start_config_t;
+
+/**
+ * \brief Initialize the SPI driver. This function must be called only once, before any of the below functions can be called.
+ */
+void spi_init(void);
+
+/**
+ * \brief Start an SPI transaction.
+ *
+ * \param slavePin The GPIO pin connected to the desired device's `SS` line.
+ * \param lsbFirst Determines the endianness of the transmission. If `true`, the least significant bit of each byte is sent first.
+ * \param mode The SPI mode to use.
+ * \param divisor The SPI clock divisor.
+ *
+ * \return `true` if the operation was successful, otherwise `false` if the supplied parameters are invalid or the SPI peripheral is already in use.
+ */
+bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor);
+
+bool spi_start_extended(spi_start_config_t *start_config);
+
+/**
+ * \brief Write a byte to the selected SPI device.
+ *
+ * \param data The byte to write.
+ *
+ * \return `SPI_STATUS_TIMEOUT` if the timeout period elapses, or `SPI_STATUS_SUCCESS`.
+ */
+spi_status_t spi_write(uint8_t data);
+
+/**
+ * \brief Read a byte from the selected SPI device.
+ *
+ * \return `SPI_STATUS_TIMEOUT` if the timeout period elapses, otherwise the byte read from the device.
+ */
+spi_status_t spi_read(void);
+
+/**
+ * \brief Send multiple bytes to the selected SPI device.
+ *
+ * \param data A pointer to the data to write from.
+ * \param length The number of bytes to write. Take care not to overrun the length of `data`.
+ *
+ * \return `SPI_STATUS_TIMEOUT` if the timeout period elapses, `SPI_STATUS_ERROR` if some other error occurs, otherwise `SPI_STATUS_SUCCESS`.
+ */
+spi_status_t spi_transmit(const uint8_t *data, uint16_t length);
+
+/**
+ * \brief Receive multiple bytes from the selected SPI device.
+ *
+ * \param data A pointer to a buffer to read into.
+ * \param length The number of bytes to read. Take care not to overrun the length of `data`.
+ *
+ * \return `SPI_STATUS_TIMEOUT` if the timeout period elapses, `SPI_STATUS_ERROR` if some other error occurs, otherwise `SPI_STATUS_SUCCESS`.
+ */
+spi_status_t spi_receive(uint8_t *data, uint16_t length);
+
+/**
+ * \brief End the current SPI transaction. This will deassert the slave select pin and reset the endianness, mode and divisor configured by `spi_start()`.
+ *
+ */
+void spi_stop(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** \} */
diff --git a/keyboards/darkproject/kd83a_bfg_edition/config.h b/keyboards/darkproject/kd83a_bfg_edition/config.h
index 880aabd5d7..fce00d29ab 100644
--- a/keyboards/darkproject/kd83a_bfg_edition/config.h
+++ b/keyboards/darkproject/kd83a_bfg_edition/config.h
@@ -22,8 +22,11 @@
/* SPI Config for LED Driver */
#define SPI_DRIVER SPIDQ
#define SPI_SCK_PIN A5
+#define SPI_SCK_PAL_MODE 5
#define SPI_MOSI_PIN A7
+#define SPI_MOSI_PAL_MODE 5
#define SPI_MISO_PIN A6
+#define SPI_MISO_PAL_MODE 5
#define AW20216S_CS_PIN_1 A15
#define AW20216S_CS_PIN_2 B15
diff --git a/keyboards/darkproject/kd87a_bfg_edition/config.h b/keyboards/darkproject/kd87a_bfg_edition/config.h
index a32f712231..9e68844daf 100644
--- a/keyboards/darkproject/kd87a_bfg_edition/config.h
+++ b/keyboards/darkproject/kd87a_bfg_edition/config.h
@@ -22,8 +22,11 @@
/* SPI Config for LED Driver */
#define SPI_DRIVER SPIDQ
#define SPI_SCK_PIN A5
+#define SPI_SCK_PAL_MODE 5
#define SPI_MOSI_PIN A7
+#define SPI_MOSI_PAL_MODE 5
#define SPI_MISO_PIN A6
+#define SPI_MISO_PAL_MODE 5
#define AW20216S_CS_PIN_1 A15
#define AW20216S_CS_PIN_2 B15
diff --git a/keyboards/gmmk/gmmk2/p96/config.h b/keyboards/gmmk/gmmk2/p96/config.h
index 1b246e4f3f..852d29df65 100644
--- a/keyboards/gmmk/gmmk2/p96/config.h
+++ b/keyboards/gmmk/gmmk2/p96/config.h
@@ -22,8 +22,11 @@
/* SPI Config for LED Driver */
#define SPI_DRIVER SPIDQ
#define SPI_SCK_PIN A5
+#define SPI_SCK_PAL_MODE 5
#define SPI_MOSI_PIN A7
+#define SPI_MOSI_PAL_MODE 5
#define SPI_MISO_PIN A6
+#define SPI_MISO_PAL_MODE 5
#define AW20216S_CS_PIN_1 A15
#define AW20216S_CS_PIN_2 B15
diff --git a/keyboards/jukaie/jk01/config.h b/keyboards/jukaie/jk01/config.h
index d8dfb9f535..41534ce6c4 100644
--- a/keyboards/jukaie/jk01/config.h
+++ b/keyboards/jukaie/jk01/config.h
@@ -22,8 +22,11 @@
/* SPI Config for LED Driver */
#define SPI_DRIVER SPIDQ
#define SPI_SCK_PIN A5
+#define SPI_SCK_PAL_MODE 5
#define SPI_MOSI_PIN A7
+#define SPI_MOSI_PAL_MODE 5
#define SPI_MISO_PIN A6
+#define SPI_MISO_PAL_MODE 5
#define AW20216S_CS_PIN_1 A15
#define AW20216S_CS_PIN_2 B15
diff --git a/keyboards/projectd/65/projectd_65_ansi/config.h b/keyboards/projectd/65/projectd_65_ansi/config.h
index c8da5c42a7..6e23afc902 100644
--- a/keyboards/projectd/65/projectd_65_ansi/config.h
+++ b/keyboards/projectd/65/projectd_65_ansi/config.h
@@ -22,8 +22,11 @@
/* SPI Config for LED Driver */
#define SPI_DRIVER SPIDQ
#define SPI_SCK_PIN A5
+#define SPI_SCK_PAL_MODE 5
#define SPI_MOSI_PIN A7
+#define SPI_MOSI_PAL_MODE 5
#define SPI_MISO_PIN A6
+#define SPI_MISO_PAL_MODE 5
#define AW20216S_CS_PIN_1 A15
#define AW20216S_EN_PIN C13
diff --git a/keyboards/projectd/75/ansi/config.h b/keyboards/projectd/75/ansi/config.h
index 282e20a8e2..acbe853949 100644
--- a/keyboards/projectd/75/ansi/config.h
+++ b/keyboards/projectd/75/ansi/config.h
@@ -22,8 +22,11 @@
/* SPI Config for LED Driver */
#define SPI_DRIVER SPIDQ
#define SPI_SCK_PIN A5
+#define SPI_SCK_PAL_MODE 5
#define SPI_MOSI_PIN A7
+#define SPI_MOSI_PAL_MODE 5
#define SPI_MISO_PIN A6
+#define SPI_MISO_PAL_MODE 5
#define AW20216S_CS_PIN_1 A15
#define AW20216S_CS_PIN_2 B15
diff --git a/keyboards/projectd/75/iso/config.h b/keyboards/projectd/75/iso/config.h
index 282e20a8e2..acbe853949 100644
--- a/keyboards/projectd/75/iso/config.h
+++ b/keyboards/projectd/75/iso/config.h
@@ -22,8 +22,11 @@
/* SPI Config for LED Driver */
#define SPI_DRIVER SPIDQ
#define SPI_SCK_PIN A5
+#define SPI_SCK_PAL_MODE 5
#define SPI_MOSI_PIN A7
+#define SPI_MOSI_PAL_MODE 5
#define SPI_MISO_PIN A6
+#define SPI_MISO_PAL_MODE 5
#define AW20216S_CS_PIN_1 A15
#define AW20216S_CS_PIN_2 B15
diff --git a/platforms/avr/drivers/spi_master.h b/platforms/avr/drivers/spi_master.h
deleted file mode 100644
index ebbf7ddeab..0000000000
--- a/platforms/avr/drivers/spi_master.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright 2020
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#include <stdbool.h>
-
-#include "gpio.h"
-
-typedef int16_t spi_status_t;
-
-// Hardware SS pin is defined in the header so that user code can refer to it
-#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__)
-# define SPI_SS_PIN B0
-#elif defined(__AVR_ATmega32A__)
-# define SPI_SS_PIN B4
-#elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
-# define SPI_SS_PIN B2
-#endif
-
-#define SPI_STATUS_SUCCESS (0)
-#define SPI_STATUS_ERROR (-1)
-#define SPI_STATUS_TIMEOUT (-2)
-
-#define SPI_TIMEOUT_IMMEDIATE (0)
-#define SPI_TIMEOUT_INFINITE (0xFFFF)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-typedef struct spi_start_config_t {
- pin_t slave_pin;
- bool lsb_first;
- uint8_t mode;
- uint16_t divisor;
- bool cs_active_low;
-} spi_start_config_t;
-
-void spi_init(void);
-
-bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor);
-bool spi_start_extended(spi_start_config_t *start_config);
-
-spi_status_t spi_write(uint8_t data);
-
-spi_status_t spi_read(void);
-
-spi_status_t spi_transmit(const uint8_t *data, uint16_t length);
-
-spi_status_t spi_receive(uint8_t *data, uint16_t length);
-
-void spi_stop(void);
-#ifdef __cplusplus
-}
-#endif
diff --git a/platforms/chibios/drivers/spi_master.c b/platforms/chibios/drivers/spi_master.c
index 414e5b10a3..f5e48edfda 100644
--- a/platforms/chibios/drivers/spi_master.c
+++ b/platforms/chibios/drivers/spi_master.c
@@ -15,8 +15,49 @@
*/
#include "spi_master.h"
+#include "chibios_config.h"
+#include <ch.h>
+#include <hal.h>
-#include "timer.h"
+#ifndef SPI_DRIVER
+# define SPI_DRIVER SPID2
+#endif
+
+#ifndef SPI_SCK_PIN
+# define SPI_SCK_PIN B13
+#endif
+
+#ifndef SPI_SCK_PAL_MODE
+# ifdef USE_GPIOV1
+# define SPI_SCK_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL
+# else
+# define SPI_SCK_PAL_MODE 5
+# endif
+#endif
+
+#ifndef SPI_MOSI_PIN
+# define SPI_MOSI_PIN B15
+#endif
+
+#ifndef SPI_MOSI_PAL_MODE
+# ifdef USE_GPIOV1
+# define SPI_MOSI_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL
+# else
+# define SPI_MOSI_PAL_MODE 5
+# endif
+#endif
+
+#ifndef SPI_MISO_PIN
+# define SPI_MISO_PIN B14
+#endif
+
+#ifndef SPI_MISO_PAL_MODE
+# ifdef USE_GPIOV1
+# define SPI_MISO_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL
+# else
+# define SPI_MISO_PAL_MODE 5
+# endif
+#endif
static bool spiStarted = false;
#if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE
diff --git a/platforms/chibios/drivers/spi_master.h b/platforms/chibios/drivers/spi_master.h
deleted file mode 100644
index 4ad6144091..0000000000
--- a/platforms/chibios/drivers/spi_master.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Copyright 2020 Nick Brassel (tzarc)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#include <ch.h>
-#include <hal.h>
-#include <stdbool.h>
-
-#include "gpio.h"
-#include "chibios_config.h"
-
-#ifndef SPI_DRIVER
-# define SPI_DRIVER SPID2
-#endif
-
-#ifndef SPI_SCK_PIN
-# define SPI_SCK_PIN B13
-#endif
-
-#ifndef SPI_SCK_PAL_MODE
-# if defined(USE_GPIOV1)
-# define SPI_SCK_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL
-# else
-# define SPI_SCK_PAL_MODE 5
-# endif
-#endif
-
-#ifndef SPI_MOSI_PIN
-# define SPI_MOSI_PIN B15
-#endif
-
-#ifndef SPI_MOSI_PAL_MODE
-# if defined(USE_GPIOV1)
-# define SPI_MOSI_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL
-# else
-# define SPI_MOSI_PAL_MODE 5
-# endif
-#endif
-
-#ifndef SPI_MISO_PIN
-# define SPI_MISO_PIN B14
-#endif
-
-#ifndef SPI_MISO_PAL_MODE
-# if defined(USE_GPIOV1)
-# define SPI_MISO_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL
-# else
-# define SPI_MISO_PAL_MODE 5
-# endif
-#endif
-
-typedef int16_t spi_status_t;
-
-#define SPI_STATUS_SUCCESS (0)
-#define SPI_STATUS_ERROR (-1)
-#define SPI_STATUS_TIMEOUT (-2)
-
-#define SPI_TIMEOUT_IMMEDIATE (0)
-#define SPI_TIMEOUT_INFINITE (0xFFFF)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-typedef struct spi_start_config_t {
- pin_t slave_pin;
- bool lsb_first;
- uint8_t mode;
- uint16_t divisor;
- bool cs_active_low;
-} spi_start_config_t;
-
-void spi_init(void);
-
-bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor);
-bool spi_start_extended(spi_start_config_t *start_config);
-
-spi_status_t spi_write(uint8_t data);
-
-spi_status_t spi_read(void);
-
-spi_status_t spi_transmit(const uint8_t *data, uint16_t length);
-
-spi_status_t spi_receive(uint8_t *data, uint16_t length);
-
-void spi_stop(void);
-#ifdef __cplusplus
-}
-#endif