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 */