summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/spi_driver.md5
-rw-r--r--platforms/chibios/drivers/spi_master.c72
2 files changed, 60 insertions, 17 deletions
diff --git a/docs/spi_driver.md b/docs/spi_driver.md
index c1c6831e73..1faa9f0773 100644
--- a/docs/spi_driver.md
+++ b/docs/spi_driver.md
@@ -49,6 +49,11 @@ Configuration-wise, you'll need to set up the peripheral as per your MCU's datas
As per the AVR configuration, you may choose any other standard GPIO as a slave select pin, which should be supplied to `spi_start()`.
+If a complete SPI interface is not required, then the following can be done to disable certain SPI pins, so they don't occupy a GPIO unnecessarily:
+ - in `config.h`: `#define SPI_MISO_PIN NO_PIN`
+ - in `config.h`: `#define SPI_MOSI_PIN NO_PIN`
+ - in `mcuconf.h`: `#define SPI_SELECT_MODE SPI_SELECT_MODE_NONE`, in this case the `slavePin` argument passed to `spi_start()` may be `NO_PIN` if the slave select pin is not used.
+
## API :id=api
### `void spi_init(void)` :id=api-spi-init
diff --git a/platforms/chibios/drivers/spi_master.c b/platforms/chibios/drivers/spi_master.c
index c3ab0623f0..481a2e422a 100644
--- a/platforms/chibios/drivers/spi_master.c
+++ b/platforms/chibios/drivers/spi_master.c
@@ -18,14 +18,14 @@
#include "timer.h"
-static pin_t currentSlavePin = NO_PIN;
+static bool spiStarted = false;
-#if defined(K20x) || defined(KL2x) || defined(RP2040)
-static SPIConfig spiConfig = {NULL, 0, 0, 0};
-#else
-static SPIConfig spiConfig = {false, NULL, 0, 0, 0, 0};
+#if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE
+static pin_t currentSlavePin;
#endif
+static SPIConfig spiConfig;
+
__attribute__((weak)) void spi_init(void) {
static bool is_initialised = false;
if (!is_initialised) {
@@ -33,28 +33,45 @@ __attribute__((weak)) void spi_init(void) {
// Try releasing special pins for a short time
setPinInput(SPI_SCK_PIN);
- setPinInput(SPI_MOSI_PIN);
- setPinInput(SPI_MISO_PIN);
+ if (SPI_MOSI_PIN != NO_PIN) {
+ setPinInput(SPI_MOSI_PIN);
+ }
+ if (SPI_MISO_PIN != NO_PIN) {
+ setPinInput(SPI_MISO_PIN);
+ }
chThdSleepMilliseconds(10);
#if defined(USE_GPIOV1)
palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), SPI_SCK_PAL_MODE);
- palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), SPI_MOSI_PAL_MODE);
- palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), SPI_MISO_PAL_MODE);
+ if (SPI_MOSI_PIN != NO_PIN) {
+ palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), SPI_MOSI_PAL_MODE);
+ }
+ if (SPI_MISO_PIN != NO_PIN) {
+ palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), SPI_MISO_PAL_MODE);
+ }
#else
palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), SPI_SCK_FLAGS);
- palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), SPI_MOSI_FLAGS);
- palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), SPI_MISO_FLAGS);
+ if (SPI_MOSI_PIN != NO_PIN) {
+ palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), SPI_MOSI_FLAGS);
+ }
+ if (SPI_MISO_PIN != NO_PIN) {
+ palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), SPI_MISO_FLAGS);
+ }
#endif
spiStop(&SPI_DRIVER);
- currentSlavePin = NO_PIN;
+ spiStarted = false;
}
}
bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
- if (currentSlavePin != NO_PIN || slavePin == NO_PIN) {
+ if (spiStarted) {
+ return false;
+ }
+#if SPI_SELECT_MODE != SPI_SELECT_MODE_NONE
+ if (slavePin == NO_PIN) {
return false;
}
+#endif
#if !(defined(WB32F3G71xx) || defined(WB32FQ95xx))
uint16_t roundedDivisor = 2;
@@ -247,13 +264,29 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
}
#endif
- currentSlavePin = slavePin;
+ spiStarted = true;
+#if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE
+ currentSlavePin = slavePin;
+#endif
+#if SPI_SELECT_MODE == SPI_SELECT_MODE_PAD
spiConfig.ssport = PAL_PORT(slavePin);
spiConfig.sspad = PAL_PAD(slavePin);
-
setPinOutput(slavePin);
+#elif SPI_SELECT_MODE == SPI_SELECT_MODE_NONE
+ if (slavePin != NO_PIN) {
+ setPinOutput(slavePin);
+ }
+#else
+# error "Unsupported SPI_SELECT_MODE"
+#endif
+
spiStart(&SPI_DRIVER, &spiConfig);
spiSelect(&SPI_DRIVER);
+#if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE
+ if (slavePin != NO_PIN) {
+ writePinLow(slavePin);
+ }
+#endif
return true;
}
@@ -283,9 +316,14 @@ spi_status_t spi_receive(uint8_t *data, uint16_t length) {
}
void spi_stop(void) {
- if (currentSlavePin != NO_PIN) {
+ if (spiStarted) {
+#if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE
+ if (currentSlavePin != NO_PIN) {
+ writePinHigh(currentSlavePin);
+ }
+#endif
spiUnselect(&SPI_DRIVER);
spiStop(&SPI_DRIVER);
- currentSlavePin = NO_PIN;
+ spiStarted = false;
}
}