Chibios SPI driver: allow some SPI pins to be left unassigned (#20315)
Co-authored-by: Sergey Vlasov <sigprof@gmail.com> Co-authored-by: Nick Brassel <nick@tzarc.org>
This commit is contained in:
parent
e0eb90aba1
commit
408d61dcfb
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user