From 9d24a480aecf368382d70c4a84328e13f8df0e1d Mon Sep 17 00:00:00 2001 From: Zachary Crockett Date: Tue, 26 Feb 2013 17:30:48 +0800 Subject: [PATCH] Implement SPI clean disable from TODO comment --- .../libopencm3/stm32/common/spi_common_all.h | 1 + lib/stm32/common/spi_common_all.c | 35 +++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/include/libopencm3/stm32/common/spi_common_all.h b/include/libopencm3/stm32/common/spi_common_all.h index 57b1465d..a3f1d5bc 100644 --- a/include/libopencm3/stm32/common/spi_common_all.h +++ b/include/libopencm3/stm32/common/spi_common_all.h @@ -350,6 +350,7 @@ void spi_reset(u32 spi_peripheral); int spi_init_master(u32 spi, u32 br, u32 cpol, u32 cpha, u32 dff, u32 lsbfirst); void spi_enable(u32 spi); void spi_disable(u32 spi); +void spi_clean_disable(u32 spi); void spi_write(u32 spi, u16 data); void spi_send(u32 spi, u16 data); u16 spi_read(u32 spi); diff --git a/lib/stm32/common/spi_common_all.c b/lib/stm32/common/spi_common_all.c index 2e6473d0..184654e8 100644 --- a/lib/stm32/common/spi_common_all.c +++ b/lib/stm32/common/spi_common_all.c @@ -163,9 +163,6 @@ void spi_enable(u32 spi) The SPI peripheral is disabled. -@todo Follow procedure from section 23.3.8 in the TRM. -(possibly create a "clean disable" function separately) - @param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. */ @@ -178,6 +175,38 @@ void spi_disable(u32 spi) SPI_CR1(spi) = reg32; } +/*-----------------------------------------------------------------------------*/ +/** @brief SPI Clean Disable. + +Disable the SPI peripheral according to the procedure in section 23.3.8 of the +reference manual. This prevents corruption of any ongoing transfers and +prevents the BSY flag from becoming unreliable. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +@returns data Unsigned int16. 8 or 16 bit data from final read. +*/ + +u16 spi_clean_disable(u32 spi) +{ + /* Wait to receive last data */ + while (!(SPI_SR(spi) & SPI_SR_RXNE)) + ; + + u16 data = SPI_DR(spi); + + /* Wait to transmit last data */ + while (!(SPI_SR(spi) & SPI_SR_TXE)) + ; + + /* Wait until not busy */ + while (SPI_SR(spi) & SPI_SR_BSY) + ; + + SPI_CR1(spi) &= ~SPI_CR1_SPE; + + return data; +} + /*-----------------------------------------------------------------------------*/ /** @brief SPI Data Write.