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()`.
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
        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);
 | 
			
		||||
        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);
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
    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 (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…
	
	Add table
		Add a link
		
	
		Reference in a new issue