You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/11/06 10:14:16 UTC
[incubator-nuttx] 02/02: stm32h7:Support SPI SPI_DELAY_CONTROL
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 4b96c28ed4b3e64ebdb4d0719426ad12d5fb1ee5
Author: David Sidrane <Da...@NscDg.com>
AuthorDate: Fri Nov 5 10:28:23 2021 -0700
stm32h7:Support SPI SPI_DELAY_CONTROL
---
arch/arm/src/stm32h7/hardware/stm32h7x3xx_spi.h | 2 +-
arch/arm/src/stm32h7/stm32_spi.c | 71 +++++++++++++++++++++++++
2 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_spi.h b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_spi.h
index edaa379..cc2f8f9 100644
--- a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_spi.h
+++ b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_spi.h
@@ -326,7 +326,7 @@
# define SPI_CFG2_MSSI_13CLK (13 << SPI_CFG2_MSSI_SHIFT)
# define SPI_CFG2_MSSI_14CLK (14 << SPI_CFG2_MSSI_SHIFT)
# define SPI_CFG2_MSSI_15CLK (15 << SPI_CFG2_MSSI_SHIFT)
-#define SPI_CFG2_MIDI_SHIFT (0) /* Bits 4-7: master Inter-Data idleness */
+#define SPI_CFG2_MIDI_SHIFT (4) /* Bits 4-7: master Inter-Data idleness */
#define SPI_CFG2_MIDI_MASK (0xf << SPI_CFG2_MIDI_SHIFT)
# define SPI_CFG2_MIDI_0CLK (0 << SPI_CFG2_MIDI_SHIFT)
# define SPI_CFG2_MIDI_1CLK (1 << SPI_CFG2_MIDI_SHIFT)
diff --git a/arch/arm/src/stm32h7/stm32_spi.c b/arch/arm/src/stm32h7/stm32_spi.c
index be8d968..e67fa5c 100644
--- a/arch/arm/src/stm32h7/stm32_spi.c
+++ b/arch/arm/src/stm32h7/stm32_spi.c
@@ -313,6 +313,11 @@ static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv);
static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
uint32_t frequency);
+#ifdef CONFIG_SPI_DELAY_CONTROL
+static int spi_setdelay(struct spi_dev_s *dev, uint32_t startdelay,
+ uint32_t stopdelay, uint32_t csdelay,
+ uint32_t ifdelay);
+#endif
static void spi_setmode(FAR struct spi_dev_s *dev,
enum spi_mode_e mode);
static void spi_setbits(FAR struct spi_dev_s *dev, int nbits);
@@ -355,6 +360,9 @@ static const struct spi_ops_s g_sp1iops =
.lock = spi_lock,
.select = stm32_spi1select,
.setfrequency = spi_setfrequency,
+#ifdef CONFIG_SPI_DELAY_CONTROL
+ .setdelay = spi_setdelay,
+#endif
.setmode = spi_setmode,
.setbits = spi_setbits,
#ifdef CONFIG_SPI_HWFEATURES
@@ -421,6 +429,9 @@ static const struct spi_ops_s g_sp2iops =
.lock = spi_lock,
.select = stm32_spi2select,
.setfrequency = spi_setfrequency,
+#ifdef CONFIG_SPI_DELAY_CONTROL
+ .setdelay = spi_setdelay,
+#endif
.setmode = spi_setmode,
.setbits = spi_setbits,
#ifdef CONFIG_SPI_HWFEATURES
@@ -487,6 +498,9 @@ static const struct spi_ops_s g_sp3iops =
.lock = spi_lock,
.select = stm32_spi3select,
.setfrequency = spi_setfrequency,
+#ifdef CONFIG_SPI_DELAY_CONTROL
+ .setdelay = spi_setdelay,
+#endif
.setmode = spi_setmode,
.setbits = spi_setbits,
#ifdef CONFIG_SPI_HWFEATURES
@@ -553,6 +567,9 @@ static const struct spi_ops_s g_sp4iops =
.lock = spi_lock,
.select = stm32_spi4select,
.setfrequency = spi_setfrequency,
+#ifdef CONFIG_SPI_DELAY_CONTROL
+ .setdelay = spi_setdelay,
+#endif
.setmode = spi_setmode,
.setbits = spi_setbits,
#ifdef CONFIG_SPI_HWFEATURES
@@ -619,6 +636,9 @@ static const struct spi_ops_s g_sp5iops =
.lock = spi_lock,
.select = stm32_spi5select,
.setfrequency = spi_setfrequency,
+#ifdef CONFIG_SPI_DELAY_CONTROL
+ .setdelay = spi_setdelay,
+#endif
.setmode = spi_setmode,
.setbits = spi_setbits,
#ifdef CONFIG_SPI_HWFEATURES
@@ -685,6 +705,9 @@ static const struct spi_ops_s g_sp6iops =
.lock = spi_lock,
.select = stm32_spi6select,
.setfrequency = spi_setfrequency,
+#ifdef CONFIG_SPI_DELAY_CONTROL
+ .setdelay = spi_setdelay,
+#endif
.setmode = spi_setmode,
.setbits = spi_setbits,
#ifdef CONFIG_SPI_HWFEATURES
@@ -1541,6 +1564,54 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
}
/****************************************************************************
+ * Name: spi_setdelay
+ *
+ * Description:
+ * Set the SPI Delays in nanoseconds. Optional.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * startdelay - The delay between CS active and first CLK
+ * stopdelay - The delay between last CLK and CS inactive
+ * csdelay - The delay between CS inactive and CS active again
+ * ifdelay - The delay between frames
+ *
+ * Returned Value:
+ * Returns zero (OK) on success; a negated errno value is return on any
+ * failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SPI_DELAY_CONTROL
+static int spi_setdelay(struct spi_dev_s *dev, uint32_t startdelay,
+ uint32_t stopdelay, uint32_t csdelay,
+ uint32_t ifdelay)
+{
+ FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
+ uint32_t setbits = 0;
+ uint32_t clrbits = SPI_CFG2_MSSI_MASK | SPI_CFG2_MIDI_MASK;
+ uint32_t nsperclk = NSEC_PER_SEC / priv->actual;
+
+ startdelay /= nsperclk;
+ ifdelay /= nsperclk;
+
+ setbits = ((ifdelay << SPI_CFG2_MIDI_SHIFT) & SPI_CFG2_MIDI_MASK) |
+ ((startdelay << SPI_CFG2_MSSI_SHIFT) & SPI_CFG2_MSSI_MASK);
+
+ spi_enable(priv, false);
+
+ /* Change SPI mode */
+
+ spi_modifyreg(priv, STM32_SPI_CFG2_OFFSET, clrbits, setbits);
+
+ /* Re-enable SPI */
+
+ spi_enable(priv, true);
+ return OK;
+}
+#endif
+
+/****************************************************************************
* Name: spi_setmode
*
* Description: