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


The following commit(s) were added to refs/heads/master by this push:
     new e4752fb  S32K1xx arch: Add (optional) support for SPI native/hardware 
chip select
e4752fb is described below

commit e4752fbaee8f1a0de63fffcedadc1bf1f5f3d891
Author: Jari van Ewijk <jari.vanew...@nxp.com>
AuthorDate: Mon Oct 4 17:11:14 2021 +0200

    S32K1xx arch: Add (optional) support for SPI native/hardware chip select
---
 arch/arm/src/s32k1xx/Kconfig                  |  4 ++
 arch/arm/src/s32k1xx/hardware/s32k1xx_lpspi.h |  1 +
 arch/arm/src/s32k1xx/s32k1xx_lpspi.c          | 89 +++++++++++++++++++++++----
 3 files changed, 83 insertions(+), 11 deletions(-)

diff --git a/arch/arm/src/s32k1xx/Kconfig b/arch/arm/src/s32k1xx/Kconfig
index ded70be..36fa483 100644
--- a/arch/arm/src/s32k1xx/Kconfig
+++ b/arch/arm/src/s32k1xx/Kconfig
@@ -624,6 +624,10 @@ menu "LPSPI Configuration"
 config S32K1XX_LPSPI_DWORD
        bool "DWORD up to 64 bit transfer support"
        default n
+
+config S32K1XX_LPSPI_HWPCS
+       bool "Use native hardware peripheral chip selects instead of GPIO pins"
+       default n
        
 endmenu # LPSPI Configuration
 
diff --git a/arch/arm/src/s32k1xx/hardware/s32k1xx_lpspi.h 
b/arch/arm/src/s32k1xx/hardware/s32k1xx_lpspi.h
index 0750d94..8e4c32d 100644
--- a/arch/arm/src/s32k1xx/hardware/s32k1xx_lpspi.h
+++ b/arch/arm/src/s32k1xx/hardware/s32k1xx_lpspi.h
@@ -299,6 +299,7 @@
 #    define LPSPI_TCR_MSBF             (0 << 23) /* MSB First */
 #define LPSPI_TCR_PCS_SHIFT            (24)      /* Bits 24-25: Peripheral 
Chip Select */
 #define LPSPI_TCR_PCS_MASK             (3 << LPSPI_TCR_PCS_SHIFT)
+#    define LPSPI_TCR_PCS(n)           (((n) << LPSPI_TCR_PCS_SHIFT) & 
LPSPI_TCR_PCS_MASK)
 #    define LPSPI_TCR_PCS_0            (0 << LPSPI_TCR_PCS_SHIFT)  /* Transfer 
using LPSPI_PCS[0] */
 #    define LPSPI_TCR_PCS_1            (1 << LPSPI_TCR_PCS_SHIFT)  /* Transfer 
using LPSPI_PCS[1] */
 #    define LPSPI_TCR_PCS_2            (2 << LPSPI_TCR_PCS_SHIFT)  /* Transfer 
using LPSPI_PCS[2] */
diff --git a/arch/arm/src/s32k1xx/s32k1xx_lpspi.c 
b/arch/arm/src/s32k1xx/s32k1xx_lpspi.c
index 60ea04d..87d9cc5 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_lpspi.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_lpspi.c
@@ -19,19 +19,19 @@
  ****************************************************************************/
 
 /****************************************************************************
- * The external functions, s32k1xx_lpspi0/1/2select and
- * s32k1xx_lpspi0/1/2status must be provided by board-specific logic.  They
- * are implementations of the select and status methods of the SPI interface
- * defined by struct s32k1xx_lpspi_ops_s (see include/nuttx/spi/spi.h).
- * All other methods (including s32k1xx_lpspibus_initialize()) are provided
- * by common S32K1XX logic.  To use this common SPI logic on your board:
+ * The external functions, s32k1xx_lpspiNselect* and s32k1xx_lpspiNstatus
+ * must be provided by board-specific logic.  They are implementations of the
+ * select and status methods of the SPI interface defined by struct
+ * s32k1xx_lpspi_ops_s (see include/nuttx/spi/spi.h).  All other methods
+ * (including s32k1xx_lpspibus_initialize()) are provided by common S32K1XX
+ * logic.  To use this common SPI logic on your board:
  *
  *   1. Provide logic in s32k1xx_boardinitialize() to configure SPI chip
  *      select pins.
- *   2. Provide s32k1xx_lpspi0/1/2select() and s32k1xx_lpspi0/1/2status()
- *      functions in your board-specific logic.  These functions will perform
- *      chip selection and status operations using GPIOs in the way your
- *      board is configured.
+ *   2. Provide s32k1xx_lpspiNselect() and s32k1xx_lpspiNstatus() functions
+ *      in your board-specific logic.  These functions will perform chip
+ *      selection and status operations using GPIOs in the way your board is
+ *      configured.
  *   3. Add a calls to s32k1xx_lpspibus_initialize() in your low level
  *      application initialization logic
  *   4. The handle returned by s32k1xx_lpspibus_initialize() may then be
@@ -39,6 +39,12 @@
  *      mmcsd_lpspislotinitialize(), for example, will bind the SPI driver
  *      to the SPI MMC/SD driver).
  *
+ * NOTE*: If CONFIG_S32K1XX_LPSPI_HWPCS is selected, s32k1xx_lpspiNselect()
+ *        does NOT need to provided by board-specific logic.  In this case a
+ *        generic implementation is used that switches between native
+ *        hardware chip select pins.  It is important that all pins are
+ *        configured when the SPI bus is initialized.
+ *
  ****************************************************************************/
 
 /****************************************************************************
@@ -135,6 +141,9 @@ struct s32k1xx_lpspidev_s
   uint32_t actual;            /* Actual clock frequency */
   int8_t nbits;               /* Width of word in bits */
   uint8_t mode;               /* Mode 0,1,2,3 */
+#ifdef CONFIG_S32K1XX_LPSPI_HWPCS
+  uint32_t pcs;               /* Peripheral Chip Select currently used */
+#endif
 };
 
 enum s32k1xx_delay_e
@@ -176,6 +185,10 @@ void s32k1xx_lpspi_set_delay_scaler(FAR struct 
s32k1xx_lpspidev_s *priv,
 /* SPI methods */
 
 static int s32k1xx_lpspi_lock(FAR struct spi_dev_s *dev, bool lock);
+#ifdef CONFIG_S32K1XX_LPSPI_HWPCS
+static void s32k1xx_lpspi_select(FAR struct spi_dev_s *dev, uint32_t devid,
+                                 bool selected);
+#endif
 static uint32_t s32k1xx_lpspi_setfrequency(FAR struct spi_dev_s *dev,
               uint32_t frequency);
 static void s32k1xx_lpspi_setmode(FAR struct spi_dev_s *dev,
@@ -216,7 +229,11 @@ s32k1xx_lpspi_bus_initialize(FAR struct s32k1xx_lpspidev_s 
*priv);
 static const struct spi_ops_s g_spi0ops =
 {
   .lock         = s32k1xx_lpspi_lock,
+#ifdef CONFIG_S32K1XX_LPSPI_HWPCS
+  .select       = s32k1xx_lpspi_select,
+#else
   .select       = s32k1xx_lpspi0select,
+#endif
   .setfrequency = s32k1xx_lpspi_setfrequency,
   .setmode      = s32k1xx_lpspi_setmode,
   .setbits      = s32k1xx_lpspi_setbits,
@@ -262,7 +279,11 @@ static struct s32k1xx_lpspidev_s g_lpspi0dev =
 static const struct spi_ops_s g_spi1ops =
 {
   .lock         = s32k1xx_lpspi_lock,
+#ifdef CONFIG_S32K1XX_LPSPI_HWPCS
+  .select       = s32k1xx_lpspi_select,
+#else
   .select       = s32k1xx_lpspi1select,
+#endif
   .setfrequency = s32k1xx_lpspi_setfrequency,
   .setmode      = s32k1xx_lpspi_setmode,
   .setbits      = s32k1xx_lpspi_setbits,
@@ -308,7 +329,11 @@ static struct s32k1xx_lpspidev_s g_lpspi1dev =
 static const struct spi_ops_s g_spi2ops =
 {
   .lock         = s32k1xx_lpspi_lock,
+#ifdef CONFIG_S32K1XX_LPSPI_HWPCS
+  .select       = s32k1xx_lpspi_select,
+#else
   .select       = s32k1xx_lpspi2select,
+#endif
   .setfrequency = s32k1xx_lpspi_setfrequency,
   .setmode      = s32k1xx_lpspi_setmode,
   .setbits      = s32k1xx_lpspi_setbits,
@@ -944,6 +969,48 @@ static int s32k1xx_lpspi_lock(FAR struct spi_dev_s *dev, 
bool lock)
   return ret;
 }
 
+#ifdef CONFIG_S32K1XX_LPSPI_HWPCS
+/****************************************************************************
+ * Name: s32k1xx_lpspi_select
+ *
+ * Description:
+ *   Change to another SPI chip select (hardware/native, not emulated with
+ *   GPIO) to select another device.  The hardware itself controls when
+ *   the chip select is enabled or disabled.
+ *
+ * Input Parameters:
+ *   dev -      Device-specific state data
+ *   devid -    Identifies the device to select
+ *   selected - Ignored, selection is controlled by hardware
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void s32k1xx_lpspi_select(FAR struct spi_dev_s *dev, uint32_t devid,
+                                 bool selected)
+{
+  FAR struct s32k1xx_lpspidev_s *priv = (FAR struct s32k1xx_lpspidev_s *)dev;
+
+  /* LPSPI on S32K1XX supports PCS 0-3 */
+
+  DEBUGASSERT(SPIDEVID_INDEX(devid) <= 3);
+
+  /* Has the Peripheral Chip Select changed? */
+
+  if (devid != priv->pcs)
+    {
+      s32k1xx_lpspi_modifyreg32(priv, S32K1XX_LPSPI_TCR_OFFSET,
+                                LPSPI_TCR_PCS_MASK,
+                                LPSPI_TCR_PCS(SPIDEVID_INDEX(devid)));
+      priv->pcs = devid;
+    }
+
+  spiinfo("devid: %" PRId32 ", CS: hardware-controlled\n", devid);
+}
+#endif /* CONFIG_S32K1XX_LPSPI HWPCS */
+
 /****************************************************************************
  * Name: s32k1xx_lpspi_setfrequency
  *
@@ -1071,7 +1138,7 @@ static uint32_t s32k1xx_lpspi_setfrequency(FAR struct 
spi_dev_s *dev,
  *   mode - The SPI mode requested
  *
  * Returned Value:
- *   Returns the actual frequency selected
+ *   none
  *
  ****************************************************************************/
 

Reply via email to