diff --git a/drivers/lcd/Kconfig b/drivers/lcd/Kconfig index 7ff1feb1398..b6894163a31 100644 --- a/drivers/lcd/Kconfig +++ b/drivers/lcd/Kconfig @@ -1589,6 +1589,17 @@ config LCD_LCDDRV_SPEED quite limited, but people have had success with much faster speeds than the spec sheets say. YMMV. +config LCD_LCDDRV_3WIRE + bool "Use 3-wire 9-bit SPI." + default n + depends on LCD_LCDDRV_SPIIF + ---help--- + Specifies whether 3-wire or 4-wire (default) SPI is used. + + 3-wire 9-bit SPI uses MSB to distinguish between CMD (0) or + DATA (1). 4-wire 8-bit SPI uses dedicated CMD/DATA pin to + distinguish between CMD and DATA. + config LCD_RA8875 bool "RA8875 LCD Display Controller" default n diff --git a/drivers/lcd/lcddrv_spiif.c b/drivers/lcd/lcddrv_spiif.c index 0ad4fc0b02d..9f1eea4dbe5 100644 --- a/drivers/lcd/lcddrv_spiif.c +++ b/drivers/lcd/lcddrv_spiif.c @@ -39,6 +39,13 @@ #include #include +/* Define conversions for DATA and CMD when 3-wire 9-bit SPI is used. */ + +#ifdef CONFIG_LCD_LCDDRV_3WIRE +# define LCD_LCDDRV_3WIRE_DATA(wd) ((1 << 8) | (wd)) +# define LCD_LCDDRV_3WIRE_CMD(wd) ((0 << 8) | (wd)) +#endif + /**************************************************************************** * Private Types ****************************************************************************/ @@ -117,7 +124,9 @@ static void lcddrv_spiif_deselect(FAR struct lcddrv_lcd_s *lcd) { FAR struct lcddrv_spiif_lcd_s *priv = (FAR struct lcddrv_spiif_lcd_s *)lcd; +#ifndef CONFIG_LCD_LCDDRV_3WIRE SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY(0), false); +#endif SPI_SELECT(priv->spi, SPIDEV_DISPLAY(0), false); SPI_LOCK(priv->spi, false); } @@ -144,11 +153,21 @@ static int lcddrv_spiif_sendmulti(FAR struct lcddrv_lcd_s *lcd, uint32_t t; FAR struct lcddrv_spiif_lcd_s *priv = (FAR struct lcddrv_spiif_lcd_s *)lcd; +#ifdef CONFIG_LCD_LCDDRV_3WIRE + SPI_SETBITS(priv->spi, 9); + for (t = 0; t < nwords; t++) + { + SPI_SEND(priv->spi, LCD_LCDDRV_3WIRE_DATA((*wd & 0xff00) >> 8)); + SPI_SEND(priv->spi, LCD_LCDDRV_3WIRE_DATA((*wd & 0x00ff) >> 0)); + wd++; + } +#else SPI_SETBITS(priv->spi, 16); for (t = 0; t < nwords; t++) { SPI_SEND(priv->spi, *wd++); } +#endif SPI_SETBITS(priv->spi, 8); @@ -201,7 +220,13 @@ static int lcddrv_spiif_send(FAR struct lcddrv_lcd_s *lcd, uint8_t r; FAR struct lcddrv_spiif_lcd_s *priv = (FAR struct lcddrv_spiif_lcd_s *)lcd; +#ifdef CONFIG_LCD_LCDDRV_3WIRE + SPI_SETBITS(priv->spi, 9); + r = SPI_SEND(priv->spi, LCD_LCDDRV_3WIRE_DATA(param)); + SPI_SETBITS(priv->spi, 8); +#else r = SPI_SEND(priv->spi, param); +#endif return r; } @@ -227,9 +252,15 @@ static int lcddrv_spiif_sendcmd(FAR struct lcddrv_lcd_s *lcd, FAR struct lcddrv_spiif_lcd_s *priv = (FAR struct lcddrv_spiif_lcd_s *)lcd; lcdinfo("param=%04x\n", param); +#ifdef CONFIG_LCD_LCDDRV_3WIRE + SPI_SETBITS(priv->spi, 9); + r = SPI_SEND(priv->spi, LCD_LCDDRV_3WIRE_CMD(param)); + SPI_SETBITS(priv->spi, 8); +#else SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY(0), true); r = SPI_SEND(priv->spi, param); SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY(0), false); +#endif return r; }