[En-Nut-Discussion] STM32F1 SPI

Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Fri Feb 26 16:29:35 CET 2016


>>>>> "kontais at aliyun" == kontais at aliyun com <kontais at aliyun.com> writes:

    kontais at aliyun> add attachment kontais at aliyun.com

Dear Kontais,

please use the diff tool (diff -uw) to point out your changes. Otherwise
your changes can't be deciphered.

With regard to 5.2 (SetPinSpeed): Setting the pin speed must be considered
by the board designer. So recent changes in my tree make the pin speed a
configuration item.

With regard to 5.3 (Switching of SPI in RX only mode in Mode0/3):
Can you try appended patch?

-- 
Uwe Bonnes                bon at elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik  Schlossgartenstrasse 9  64289 Darmstadt
--------- Tel. 06151 1623569 ------- Fax. 06151 1623305 ---------
>From 763f12af107084cdc34d17e54888479bcb45b397 Mon Sep 17 00:00:00 2001
From: Uwe Bonnes <bon at elektron.ikp.physik.tu-darmstadt.de>
Date: Fri, 26 Feb 2016 16:15:52 +0100
Subject: stm32_spi: Care for Mode when switching off SPI in rx-only mode.

---
 nut/arch/cm3/dev/stm/stm32_spi.c | 35 +++++++++++++++++++++++++++--------
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/nut/arch/cm3/dev/stm/stm32_spi.c b/nut/arch/cm3/dev/stm/stm32_spi.c
index ab1b1d4..8116f46 100644
--- a/nut/arch/cm3/dev/stm/stm32_spi.c
+++ b/nut/arch/cm3/dev/stm/stm32_spi.c
@@ -72,6 +72,31 @@
 #define GPIO_CRL_CM3BB   CM3BBADDR(SPIBUS_MOSI_PORT, GPIO_TypeDef, CRL, 0)
 #endif
 
+static void Stm32SpiBusStopRx(SPI_TypeDef *spi)
+{
+    /* Follow "Disabling the SPI"
+     * Disable SPE after first sampling edge and before last clock.
+     * RXNE is set with active edge of last cycle of last transfer
+     *
+     * So wait until last cycle of last transfer ends.
+     * And wait until active edge of first clock of current cycle happens.
+     */
+    uint32_t mode = spi->CR1 & (SPI_CR1_CPOL | SPI_CR1_CPHA);
+    switch (mode) {
+    case 0:
+    case 3:
+        /* Sample at rising edge */
+        while( GpioPinGet(SPIBUS_SCK_PORT,  SPIBUS_SCK_PIN));
+        while(!GpioPinGet(SPIBUS_SCK_PORT,  SPIBUS_SCK_PIN));
+        break;
+    default:
+        /* Sample at falling edge */
+        while(!GpioPinGet(SPIBUS_SCK_PORT,  SPIBUS_SCK_PIN));
+        while( GpioPinGet(SPIBUS_SCK_PORT,  SPIBUS_SCK_PIN));
+    }
+    CM3BBCLR(SPI_BASE, SPI_TypeDef, CR1, _BI32(SPI_CR1_SPE));
+}
+
 #if SPIBUS_MODE != POLLING_MODE
 static uint32_t clk_ratio;
 #if SPIBUS_MODE == IRQ_MODE
@@ -96,10 +121,7 @@ static void Stm32SpiBusInterrupt(void *arg)
                 spi_rx_len--;
                 if (spi_rx_len == 1) {
                     if (spi->CR1 & (SPI_CR1_BIDIMODE| SPI_CR1_RXONLY)) {
-                        /* Follow "Disabling the SPI" */
-                        while( GpioPinGet(SPIBUS_SCK_PORT,  SPIBUS_SCK_PIN));
-                        while(!GpioPinGet(SPIBUS_SCK_PORT,  SPIBUS_SCK_PIN));
-                        CM3BBCLR(SPI_BASE, SPI_TypeDef, CR1, _BI32(SPI_CR1_SPE));
+                        Stm32SpiBusStopRx(spi);
                     }
                 }
             }
@@ -580,10 +602,7 @@ static int Stm32SpiBusTransfer
             base->CR1 |= SPI_CR1_SPE;
             while( xlen > 0) {
                 if(xlen < 2) {
-                    /* Follow procedure "Disabling the SPI" */
-                    while(!(GpioPinGet(SPIBUS_SCK_PORT,SPIBUS_SCK_PIN)));
-                    while(GpioPinGet(SPIBUS_SCK_PORT,SPIBUS_SCK_PIN));
-                    base->CR1 &= ~SPI_CR1_SPE;
+                    Stm32SpiBusStopRx(base);
                 }
                 xlen--;
                 while ((base->SR & SPI_SR_RXNE) == 0 ); /* Wait till RXNE = 1*/
-- 
2.1.4



More information about the En-Nut-Discussion mailing list