From 28fe4b8653fc1067f0d06fce1119c438e5c6f9e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Wed, 27 Jun 2018 19:21:39 +0200 Subject: [PATCH] kinetis: Clean up SPI module power handling Fixes a problem with hardware CS when using slow SPI speeds, mentioned in https://github.com/RIOT-OS/RIOT/issues/6437#issuecomment-283114795 --- cpu/kinetis/periph/spi.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/cpu/kinetis/periph/spi.c b/cpu/kinetis/periph/spi.c index 34ba38853784..15d4ef83e829 100644 --- a/cpu/kinetis/periph/spi.c +++ b/cpu/kinetis/periph/spi.c @@ -62,10 +62,16 @@ static inline void poweron(spi_t bus) break; #endif } + + /* Enable the module */ + dev(bus)->MCR &= ~(SPI_MCR_MDIS_MASK); } static inline void poweroff(spi_t bus) { + /* Disable the module */ + dev(bus)->MCR |= SPI_MCR_MDIS_MASK; + switch((uint32_t)dev(bus)) { case (uint32_t)SPI0: case (uint32_t)SPI1: @@ -96,11 +102,14 @@ void spi_init(spi_t bus) dev(bus)->MCR = (SPI_MCR_MSTR_MASK | SPI_MCR_PCSIS_MASK | SPI_MCR_CLR_RXF_MASK | SPI_MCR_CLR_TXF_MASK | SPI_MCR_DIS_RXF_MASK | SPI_MCR_DIS_TXF_MASK | - SPI_MCR_DOZE_MASK | SPI_MCR_HALT_MASK | SPI_MCR_MDIS_MASK); + SPI_MCR_DOZE_MASK | SPI_MCR_HALT_MASK); /* disable all DMA and interrupt requests */ dev(bus)->RSER = 0; + /* Wait for the hardware to acknowledge the halt command */ + while (dev(bus)->SR & SPI_SR_TXRXS_MASK) {} + /* and power off the bus until it is actually used */ poweroff(bus); } @@ -153,8 +162,13 @@ int spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk) void spi_release(spi_t bus) { - /* disable, power off, and unlock the bus */ - dev(bus)->MCR |= (SPI_MCR_HALT_MASK | SPI_MCR_MDIS_MASK); + /* Halt transfers */ + dev(bus)->MCR |= SPI_MCR_HALT_MASK; + + /* Wait for the module to acknowledge the stop */ + while (dev(bus)->SR & SPI_SR_TXRXS_MASK) {} + + /* Disable the module */ poweroff(bus); mutex_unlock(&locks[bus]); }