[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