aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZachary Crockett2013-02-26 17:30:48 +0800
committerPiotr Esden-Tempski2013-02-26 19:59:15 -0800
commit9d24a480aecf368382d70c4a84328e13f8df0e1d (patch)
tree2e52b311c6000f0c223855bc8dacd76f8373b4ce
parent8a0b8fa9d8085a81e61f7fb2f62aacb9ef74dc07 (diff)
Implement SPI clean disable from TODO comment
-rw-r--r--include/libopencm3/stm32/common/spi_common_all.h1
-rw-r--r--lib/stm32/common/spi_common_all.c35
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 57b1465..a3f1d5b 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 2e6473d..184654e 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.
*/
@@ -179,6 +176,38 @@ void spi_disable(u32 spi)
}
/*-----------------------------------------------------------------------------*/
+/** @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.
Data is written to the SPI interface.