mirror of
https://github.com/Keychron/qmk_firmware.git
synced 2024-11-25 09:56:54 +06:00
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()`.
|
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
|
## API :id=api
|
||||||
|
|
||||||
### `void spi_init(void)` :id=api-spi-init
|
### `void spi_init(void)` :id=api-spi-init
|
||||||
|
|
|
@ -18,14 +18,14 @@
|
||||||
|
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
static pin_t currentSlavePin = NO_PIN;
|
static bool spiStarted = false;
|
||||||
|
|
||||||
#if defined(K20x) || defined(KL2x) || defined(RP2040)
|
#if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE
|
||||||
static SPIConfig spiConfig = {NULL, 0, 0, 0};
|
static pin_t currentSlavePin;
|
||||||
#else
|
|
||||||
static SPIConfig spiConfig = {false, NULL, 0, 0, 0, 0};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static SPIConfig spiConfig;
|
||||||
|
|
||||||
__attribute__((weak)) void spi_init(void) {
|
__attribute__((weak)) void spi_init(void) {
|
||||||
static bool is_initialised = false;
|
static bool is_initialised = false;
|
||||||
if (!is_initialised) {
|
if (!is_initialised) {
|
||||||
|
@ -33,28 +33,45 @@ __attribute__((weak)) void spi_init(void) {
|
||||||
|
|
||||||
// Try releasing special pins for a short time
|
// Try releasing special pins for a short time
|
||||||
setPinInput(SPI_SCK_PIN);
|
setPinInput(SPI_SCK_PIN);
|
||||||
setPinInput(SPI_MOSI_PIN);
|
if (SPI_MOSI_PIN != NO_PIN) {
|
||||||
setPinInput(SPI_MISO_PIN);
|
setPinInput(SPI_MOSI_PIN);
|
||||||
|
}
|
||||||
|
if (SPI_MISO_PIN != NO_PIN) {
|
||||||
|
setPinInput(SPI_MISO_PIN);
|
||||||
|
}
|
||||||
|
|
||||||
chThdSleepMilliseconds(10);
|
chThdSleepMilliseconds(10);
|
||||||
#if defined(USE_GPIOV1)
|
#if defined(USE_GPIOV1)
|
||||||
palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), SPI_SCK_PAL_MODE);
|
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);
|
if (SPI_MOSI_PIN != NO_PIN) {
|
||||||
palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), SPI_MISO_PAL_MODE);
|
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
|
#else
|
||||||
palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), SPI_SCK_FLAGS);
|
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);
|
if (SPI_MOSI_PIN != NO_PIN) {
|
||||||
palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), SPI_MISO_FLAGS);
|
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
|
#endif
|
||||||
spiStop(&SPI_DRIVER);
|
spiStop(&SPI_DRIVER);
|
||||||
currentSlavePin = NO_PIN;
|
spiStarted = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
#if SPI_SELECT_MODE != SPI_SELECT_MODE_NONE
|
||||||
|
if (slavePin == NO_PIN) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !(defined(WB32F3G71xx) || defined(WB32FQ95xx))
|
#if !(defined(WB32F3G71xx) || defined(WB32FQ95xx))
|
||||||
uint16_t roundedDivisor = 2;
|
uint16_t roundedDivisor = 2;
|
||||||
|
@ -247,13 +264,29 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
|
||||||
}
|
}
|
||||||
#endif
|
#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.ssport = PAL_PORT(slavePin);
|
||||||
spiConfig.sspad = PAL_PAD(slavePin);
|
spiConfig.sspad = PAL_PAD(slavePin);
|
||||||
|
|
||||||
setPinOutput(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);
|
spiStart(&SPI_DRIVER, &spiConfig);
|
||||||
spiSelect(&SPI_DRIVER);
|
spiSelect(&SPI_DRIVER);
|
||||||
|
#if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE
|
||||||
|
if (slavePin != NO_PIN) {
|
||||||
|
writePinLow(slavePin);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -283,9 +316,14 @@ spi_status_t spi_receive(uint8_t *data, uint16_t length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void spi_stop(void) {
|
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);
|
spiUnselect(&SPI_DRIVER);
|
||||||
spiStop(&SPI_DRIVER);
|
spiStop(&SPI_DRIVER);
|
||||||
currentSlavePin = NO_PIN;
|
spiStarted = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user