diff options
-rw-r--r-- | board/hatch_fp/gpio.inc | 9 | ||||
-rw-r--r-- | chip/stm32/spi_master.c | 51 |
2 files changed, 57 insertions, 3 deletions
diff --git a/board/hatch_fp/gpio.inc b/board/hatch_fp/gpio.inc index 807a76ae47..7a9dfd152f 100644 --- a/board/hatch_fp/gpio.inc +++ b/board/hatch_fp/gpio.inc @@ -27,5 +27,10 @@ UNIMPLEMENTED(ENTERING_RW) ALTERNATE(PIN_MASK(A, 0x0600), GPIO_ALT_USART, MODULE_UART, GPIO_PULL_UP) /* SPI1 slave from the AP: PA4/5/6/7 */ ALTERNATE(PIN_MASK(A, 0x00f0), GPIO_ALT_SPI, MODULE_SPI, 0) -/* SPI2 master to sensor: PB12/13/14/15 */ -ALTERNATE(PIN_MASK(B, 0xf000), GPIO_ALT_SPI, MODULE_SPI_MASTER, 0) +/* + * SPI2 master to sensor: PB13/14/15 + * Note that we're not configuring NSS (PB12) here because we have already + * configured it as a GPIO above and the SPI_MASTER module expects to use it + * in software NSS management mode, not hardware management mode. + */ +ALTERNATE(PIN_MASK(B, 0xE000), GPIO_ALT_SPI, MODULE_SPI_MASTER, 0) diff --git a/chip/stm32/spi_master.c b/chip/stm32/spi_master.c index 76677423f2..446013a9d9 100644 --- a/chip/stm32/spi_master.c +++ b/chip/stm32/spi_master.c @@ -161,6 +161,48 @@ static int spi_master_initialize(int port) if ((spi_devices[i].port == port) && (div < spi_devices[i].div)) div = spi_devices[i].div; + + /* + * STM32F412 + * Section 26.3.5 Slave select (NSS) pin management and Figure 276 + * https://www.st.com/resource/en/reference_manual/dm00180369.pdf#page=817 + * + * The documentation in this section is a bit confusing, so here's a + * summary based on discussion with ST: + * + * Software NSS management (SSM = 1): + * - In master mode, the NSS output is deactivated. You need to use a + * GPIO in output mode for slave select. This is generally used for + * multi-slave operation, but you can also use it for single slave + * operation. In this case, you should make sure to configure a GPIO + * for NSS, but *not* activate the SPI alternate function on that + * same pin since that will enable hardware NSS management (see + * below). + * - In slave mode, the NSS input level is equal to the SSI bit value. + * + * Hardware NSS management (SSM = 0): + * - In slave mode, when NSS pin is detected low the slave (MCU) is + * selected. + * - In master mode, there are two configurations, depending on the + * SSOE bit in register SPIx_CR1. + * - NSS output enable (SSM=0, SSOE=1): + * The MCU (master) drives NSS low as soon as SPI is enabled + * (SPE=1) and releases it when SPI is disabled (SPE=0). + * + * - NSS output disable (SSM=0, SSOE=0): + * Allows multimaster capability. The MCU (master) drives NSS + * low. If another master tries to takes control of the bus and + * NSS is pulled low, a mode fault is generated and the MCU + * changes to slave mode. + * + * - NSS output disable (SSM=0, SSOE=0): if the MCU is acting as + * master on the bus, this config allows multimaster capability. If + * the NSS pin is pulled low in this mode, the SPI enters master + * mode fault state and the device is automatically reconfigured in + * slave mode. In slave mode, the NSS pin works as a standard "chip + * select" input and the slave is selected while NSS lin is at low + * level. + */ spi->cr1 = STM32_SPI_CR1_MSTR | STM32_SPI_CR1_SSM | STM32_SPI_CR1_SSI | (div << 3); @@ -170,7 +212,14 @@ static int spi_master_initialize(int port) #endif /* * Configure 8-bit datasize, set FRXTH, enable DMA, - * and enable NSS output + * and set data size (applies to STM32F0 only). + * + * STM32F412: + * https://www.st.com/resource/en/reference_manual/dm00180369.pdf#page=852 + * + * + * STM32F0: + * https://www.st.com/resource/en/reference_manual/dm00031936.pdf#page=803 */ spi->cr2 = STM32_SPI_CR2_TXDMAEN | STM32_SPI_CR2_RXDMAEN | STM32_SPI_CR2_FRXTH | STM32_SPI_CR2_DATASIZE(8); |