forked from mirrors/qmk_userspace
		
	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
					
				
			
		
					 2 changed files with 60 additions and 17 deletions
				
			
		| 
						 | 
					@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue