summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Hughes <tomhughes@chromium.org>2019-04-08 15:06:42 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-04-11 14:55:59 -0700
commitc10784e1fe9e93b392d4a1c8c108de11fbbb27b3 (patch)
tree6ca8c5b49e2131b9da6680534e0b0be16de6b67a
parent20dda8c1406708044b407b05659910eebaf10fca (diff)
downloadchrome-ec-c10784e1fe9e93b392d4a1c8c108de11fbbb27b3.tar.gz
hatch_fp: Fix slave select (NSS / CS) pin management
BRANCH=none BUG=b:124996507 TEST=Read HWID from fingerprint sensor (slave) on hatch_fp Change-Id: I344d7e4a5afec1f7c23f45aca593159ba67e89ed Signed-off-by: Tom Hughes <tomhughes@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1558937 Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
-rw-r--r--board/hatch_fp/gpio.inc9
-rw-r--r--chip/stm32/spi_master.c51
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);