This is an automated email from the ASF dual-hosted git repository.

gnutt 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 204e84f  input: Add SPI mode for STMPE811 touch screen controller
204e84f is described below

commit 204e84f1adb547315cce4c035380a88a0174cb4b
Author: Brennan Ashton <bash...@brennanashton.com>
AuthorDate: Wed Sep 16 23:49:04 2020 -0700

    input: Add SPI mode for STMPE811 touch screen controller
    
    Signed-off-by: Brennan Ashton <bash...@brennanashton.com>
---
 drivers/input/stmpe811.h      |   6 ---
 drivers/input/stmpe811_base.c | 100 ++++++++++++++++++++++++++++++++----------
 2 files changed, 78 insertions(+), 28 deletions(-)

diff --git a/drivers/input/stmpe811.h b/drivers/input/stmpe811.h
index 5bad01e..e3a2a75 100644
--- a/drivers/input/stmpe811.h
+++ b/drivers/input/stmpe811.h
@@ -64,12 +64,6 @@
 
 #undef CONFIG_STMPE811_REFCNT
 
-/* No support for the SPI interface yet */
-
-#ifdef CONFIG_STMPE811_SPI
-#  error "Only the STMPE811 I2C interface is supported by this driver"
-#endif
-
 /* Driver support 
***************************************************************************/
 
 /* This format is used to construct the /dev/input[n] device driver path.  It 
defined here
diff --git a/drivers/input/stmpe811_base.c b/drivers/input/stmpe811_base.c
index 0e24bc6..28f0eb5 100644
--- a/drivers/input/stmpe811_base.c
+++ b/drivers/input/stmpe811_base.c
@@ -5,7 +5,7 @@
  *   Author: Gregory Nutt <gn...@nuttx.org>
  *
  * References:
- *   "STMPE811 S-Touch� advanced resistive touchscreen controller with 8-bit
+ *   "STMPE811 S-Touch advanced resistive touchscreen controller with 8-bit
  *    GPIO expander," Doc ID 14489 Rev 6, CD00186725, STMicroelectronics"
  *
  * Redistribution and use in source and binary forms, with or without
@@ -93,6 +93,7 @@ static void stmpe811_worker(FAR void *arg)
 
   /* Get the global interrupt status */
 
+  regval =  stmpe811_getreg8(priv, STMPE811_INT_EN);
   regval =  stmpe811_getreg8(priv, STMPE811_INT_STA);
 
   /* Check for a touchscreen interrupt */
@@ -206,7 +207,7 @@ static int stmpe811_checkid(FAR struct stmpe811_dev_s *priv)
 
   devid = stmpe811_getreg8(priv, STMPE811_CHIP_ID);
   devid = (uint32_t)(devid << 8);
-  devid |= (uint32_t)stmpe811_getreg8(priv, STMPE811_CHIP_ID+1);
+  devid |= (uint32_t)stmpe811_getreg8(priv, STMPE811_CHIP_ID + 1);
   iinfo("devid: %04x\n", devid);
 
   if (devid != (uint16_t)CHIP_ID)
@@ -235,7 +236,7 @@ static void stmpe811_reset(FAR struct stmpe811_dev_s *priv)
 
   /* Wait a bit */
 
-  nxsig_usleep(20*1000);
+  nxsig_usleep(20 * 1000);
 
   /* Then power on again.  All registers will be in their reset state. */
 
@@ -279,13 +280,16 @@ STMPE811_HANDLE stmpe811_instantiate(FAR struct 
i2c_master_s *dev,
   /* Allocate the device state structure */
 
 #ifdef CONFIG_STMPE811_MULTIPLE
-  priv = (FAR struct stmpe811_dev_s *)kmm_zalloc(sizeof(struct 
stmpe811_dev_s));
+  priv = (FAR struct stmpe811_dev_s *)kmm_zalloc(
+    sizeof(struct stmpe811_dev_s));
   if (!priv)
     {
       return NULL;
     }
 
-  /* And save the device structure in the list of STMPE811 so that we can find 
it later */
+  /* And save the device structure in the list of STMPE811 so that we can
+   * find it later.
+   */
 
   priv->flink   = g_stmpe811list;
   g_stmpe811list = priv;
@@ -323,7 +327,9 @@ STMPE811_HANDLE stmpe811_instantiate(FAR struct 
i2c_master_s *dev,
 
   stmpe811_reset(priv);
 
-  /* Configure the interrupt output pin to generate interrupts on high or low 
level. */
+  /* Configure the interrupt output pin to generate interrupts on high or
+   * low level.
+   */
 
   regval  = stmpe811_getreg8(priv, STMPE811_INT_CTRL);
 #ifdef CONFIG_STMPE811_ACTIVELOW
@@ -367,18 +373,20 @@ STMPE811_HANDLE stmpe811_instantiate(FAR struct 
i2c_master_s *dev,
  *
  ****************************************************************************/
 
-#ifdef CONFIG_STMPE811_I2C
 uint8_t stmpe811_getreg8(FAR struct stmpe811_dev_s *priv, uint8_t regaddr)
 {
   /* 8-bit data read sequence:
-   *
+   * i2c:
    *  Start - I2C_Write_Address - STMPE811_Reg_Address -
    *    Repeated_Start - I2C_Read_Address  - STMPE811_Read_Data - STOP
+   * spi:
+   *  [STMPE811_Reg_Address | 0x80] - Dummy Address - Read Register
    */
 
-  struct i2c_msg_s msg[2];
   uint8_t regval;
+#ifdef CONFIG_STMPE811_I2C
   int ret;
+  struct i2c_msg_s msg[2];
 
   /* Setup 8-bit STMPE811 address write message */
 
@@ -406,13 +414,26 @@ uint8_t stmpe811_getreg8(FAR struct stmpe811_dev_s *priv, 
uint8_t regaddr)
       ierr("ERROR: I2C_TRANSFER failed: %d\n", ret);
       return 0;
     }
-
+#else  /* CONFIG_STMPE811_SPI */
+  SPI_LOCK(priv->spi, true);
+
+  SPI_SETMODE(priv->spi, SPIDEV_MODE0);
+  SPI_SETBITS(priv->spi, 8);
+  SPI_HWFEATURES(priv->spi, 0);
+  SPI_SETFREQUENCY(priv->spi, priv->config->frequency);
+
+  SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN(0), true);
+  SPI_SEND(priv->spi, regaddr | 0x80);  /* Issue a read on the address */
+  SPI_SEND(priv->spi, 0);               /* Next address (not used) */
+  regval = SPI_SEND(priv->spi, 0);      /* Read register */
+  SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN(0), false);
+  SPI_LOCK(priv->spi, false);
+#endif
 #ifdef CONFIG_STMPE811_REGDEBUG
   _err("%02x->%02x\n", regaddr, regval);
 #endif
   return regval;
 }
-#endif
 
 /****************************************************************************
  * Name: stmpe811_putreg8
@@ -422,18 +443,21 @@ uint8_t stmpe811_getreg8(FAR struct stmpe811_dev_s *priv, 
uint8_t regaddr)
  *
  ****************************************************************************/
 
-#ifdef CONFIG_STMPE811_I2C
 void stmpe811_putreg8(FAR struct stmpe811_dev_s *priv,
                       uint8_t regaddr, uint8_t regval)
 {
   /* 8-bit data read sequence:
    *
-   *  Start - I2C_Write_Address - STMPE811_Reg_Address - STMPE811_Write_Data - 
STOP
+   *  Start - I2C_Write_Address - STMPE811_Reg_Address -
+   *   STMPE811_Write_Data - STOP
+   * spi:
+   *  STMPE811_Reg_Address - Dummy Address - Write Data
    */
 
+#ifdef CONFIG_STMPE811_I2C
+  int ret;
   struct i2c_msg_s msg;
   uint8_t txbuffer[2];
-  int ret;
 
 #ifdef CONFIG_STMPE811_REGDEBUG
   _err("%02x<-%02x\n", regaddr, regval);
@@ -453,7 +477,7 @@ void stmpe811_putreg8(FAR struct stmpe811_dev_s *priv,
   msg.flags     = 0;                       /* Write transaction, beginning 
with START */
   msg.buffer    = txbuffer;                /* Transfer from this address */
   msg.length    = 2;                       /* Send two byte following the 
address
-                                       * (then STOP) */
+                                            * (then STOP) */
 
   /* Perform the transfer */
 
@@ -462,8 +486,22 @@ void stmpe811_putreg8(FAR struct stmpe811_dev_s *priv,
     {
       ierr("ERROR: I2C_TRANSFER failed: %d\n", ret);
     }
-}
+#else  /* CONFIG_STMPE811_SPI */
+  SPI_LOCK(priv->spi, true);
+
+  SPI_SETMODE(priv->spi, SPIDEV_MODE0);
+  SPI_SETBITS(priv->spi, 8);
+  SPI_HWFEATURES(priv->spi, 0);
+  SPI_SETFREQUENCY(priv->spi, priv->config->frequency);
+
+  SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN(0), true);
+  SPI_SEND(priv->spi, regaddr);  /* Issue a read on the address */
+  SPI_SEND(priv->spi, 0);        /* Next address (not used) */
+  SPI_SEND(priv->spi, regval);   /* write register */
+  SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN(0), false);
+  SPI_LOCK(priv->spi, false);
 #endif
+}
 
 /****************************************************************************
  * Name: stmpe811_getreg16
@@ -473,20 +511,23 @@ void stmpe811_putreg8(FAR struct stmpe811_dev_s *priv,
  *
  ****************************************************************************/
 
-#ifdef CONFIG_STMPE811_I2C
 uint16_t stmpe811_getreg16(FAR struct stmpe811_dev_s *priv, uint8_t regaddr)
 {
   /* 16-bit data read sequence:
-   *
+   * i2c:
    *  Start - I2C_Write_Address - STMPE811_Reg_Address -
    *    Repeated_Start - I2C_Read_Address  - STMPE811_Read_Data_1 -
    *      STMPE811_Read_Data_2 - STOP
+   * spi:
+   *  16 bit registers are MSB.
+   *  [STMPE811_Reg_Address | 0x80] - [STMPE811_Reg_Address + 1 | 0x80] -
+   *    Read Register - Read Register + 1
    */
 
-
-  struct i2c_msg_s msg[2];
   uint8_t rxbuffer[2];
+#ifdef CONFIG_STMPE811_I2C
   int ret;
+  struct i2c_msg_s msg[2];
 
   /* Setup 8-bit STMPE811 address write message */
 
@@ -514,12 +555,27 @@ uint16_t stmpe811_getreg16(FAR struct stmpe811_dev_s 
*priv, uint8_t regaddr)
       ierr("ERROR: I2C_TRANSFER failed: %d\n", ret);
       return 0;
     }
-
+#else  /* CONFIG_STMPE811_SPI */
+
+  SPI_LOCK(priv->spi, true);
+
+  SPI_SETMODE(priv->spi, SPIDEV_MODE0);
+  SPI_SETBITS(priv->spi, 8);
+  SPI_HWFEATURES(priv->spi, 0);
+  SPI_SETFREQUENCY(priv->spi, priv->config->frequency);
+
+  SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN(0), true);
+  SPI_SEND(priv->spi, regaddr | 0x80);         /* Issue a read on the address 
*/
+  SPI_SEND(priv->spi, regaddr + 1);            /* Next address  */
+  rxbuffer[0] = SPI_SEND(priv->spi, 0);        /* Read MSB */
+  rxbuffer[1] = SPI_SEND(priv->spi, 0);        /* Read LSB */
+  SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN(0), true);
+  SPI_LOCK(priv->spi, false);
+#endif
 #ifdef CONFIG_STMPE811_REGDEBUG
   _err("%02x->%02x%02x\n", regaddr, rxbuffer[0], rxbuffer[1]);
 #endif
   return (uint16_t)rxbuffer[0] << 8 | (uint16_t)rxbuffer[1];
 }
-#endif
 
 #endif /* CONFIG_INPUT && CONFIG_INPUT_STMPE811 */

Reply via email to