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/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new e09a79ece9 driver/ssd1680: Add support for 1.54 inch e-paper display
e09a79ece9 is described below
commit e09a79ece9e2ba173389f34e62270e118acdef5f
Author: Huang Qi <[email protected]>
AuthorDate: Sat Aug 3 12:59:06 2024 +0800
driver/ssd1680: Add support for 1.54 inch e-paper display
Add configuration and driver support for the SSD1681 1.54 inch e-paper
display,
including the necessary waveforms and settings for proper operation. This
extends
the existing SSD1680 e-paper driver to accommodate the new display module.
The changes involve updates to the Kconfig file for additional
configuration options,
modifications to the driver implementation in ssd1680.c to include SSD1681
specific
logic, and updates to the header file ssd1680.h to reflect the added
support.
Signed-off-by: Huang Qi <[email protected]>
---
drivers/lcd/Kconfig | 9 +++++++--
drivers/lcd/ssd1680.c | 39 +++++++++++++++++++++++++++++++++------
drivers/lcd/ssd1680.h | 14 ++++++++++++--
3 files changed, 52 insertions(+), 10 deletions(-)
diff --git a/drivers/lcd/Kconfig b/drivers/lcd/Kconfig
index 667b571b6c..35977de702 100644
--- a/drivers/lcd/Kconfig
+++ b/drivers/lcd/Kconfig
@@ -1645,11 +1645,11 @@ config LCD_FT80X_AUDIO_GPIO
endif # LCD_FT80X
config LCD_SSD1680
- bool "SSD1680 E-PAPER Single Chip Driver"
+ bool "SSD1680/SSD1681 E-PAPER Single Chip Driver"
default n
select SPI_CMDDATA
---help---
- e-paper Display Module based on SSD1680 controller.
+ e-paper Display Module based on SSD1680/SSD1681 controller.
Required SPI driver settings:
SPI_CMDDATA - Include support for cmd/data selection.
@@ -1672,6 +1672,11 @@ config LCD_SSD1680_2_90
config LCD_SSD1680_2_90_RED
bool "2.9 inch 128/296 tri color (red)"
+config LCD_SSD1681_1_54
+ bool "1.54 inch 200/200 mono"
+ ---help---
+ 1.54 inch 200x200 e-paper display module based on SSD1681
controller.
+
endchoice # Display size
config SSD1680_SPIMODE
diff --git a/drivers/lcd/ssd1680.c b/drivers/lcd/ssd1680.c
index 1079ecef05..1327714411 100644
--- a/drivers/lcd/ssd1680.c
+++ b/drivers/lcd/ssd1680.c
@@ -155,9 +155,11 @@ static void ssd1680_snd_cmd_with_data4(FAR struct
ssd1680_dev_s *priv,
uint8_t dta2, uint8_t dta3,
uint8_t dta4);
+#ifndef CONFIG_LCD_SSD1681_1_54
static void ssd1680_snd_cmd_with_data(FAR struct ssd1680_dev_s *priv,
uint8_t cmd, const uint8_t *dta,
int dta_len);
+#endif
#if !defined(CONFIG_LCD_PORTRAIT) && !defined(CONFIG_LCD_RPORTRAIT)
# if SSD1680_DEV_BPP == 1
@@ -285,6 +287,7 @@ static const struct lcd_dev_s g_lcd_epaper_dev =
static struct ssd1680_dev_s g_epaperdev;
+#if !defined(CONFIG_LCD_SSD1681_1_54)
static const uint8_t ssd1680_lut[] =
{
#if defined(CONFIG_LCD_SSD1680_2_90)
@@ -311,6 +314,7 @@ static const uint8_t ssd1680_lut[] =
# error "Missing LUT table"
#endif
};
+#endif
/****************************************************************************
* Private Functions
@@ -571,9 +575,10 @@ static int ssd1680_configuredisplay(struct ssd1680_dev_s
*priv)
* last data byte depends on connection between display and controller
*/
- lcdinfo("Set the driver output control (0x%02x): %d 0x%02x\n",
+ lcdinfo("Set the driver output control (0x%02x): %d 0x%02x, 0x%02x\n",
SSD1680_DRIVER_CONTROL,
SSD1680_DEV_NATIVE_YRES - 1,
+ (SSD1680_DEV_NATIVE_YRES - 1) >> 8,
SSD1680_DEV_GATE_LAYOUT);
ssd1680_snd_cmd_with_data3(priv, SSD1680_DRIVER_CONTROL,
(uint8_t)((SSD1680_DEV_NATIVE_YRES - 1) & 0xff),
@@ -596,6 +601,7 @@ static int ssd1680_configuredisplay(struct ssd1680_dev_s
*priv)
ssd1680_snd_cmd_with_data1(priv, SSD1680_SET_DIGITAL_BLOCK_CTRL, 0x3b);
#endif
+#ifndef CONFIG_LCD_SSD1681_1_54
/* Step 2: SSD1680_BOOST_SOFTSTART 0x0C D7 D6 9D */
lcdinfo("Set boost soft start (0x%02x): 0x%02x, 0x%02x, 0x%02x\n",
@@ -634,6 +640,7 @@ static int ssd1680_configuredisplay(struct ssd1680_dev_s
*priv)
SSD1680_VALUE_GATE_TIME);
ssd1680_snd_cmd_with_data1(priv, SSD1680_GATE_TIME,
SSD1680_VALUE_GATE_TIME);
+#endif
#if defined(CONFIG_LCD_SSD1680_2_13_V2)
/* Step 5a: Sending command write border with data 0x03:
@@ -644,9 +651,18 @@ static int ssd1680_configuredisplay(struct ssd1680_dev_s
*priv)
lcdinfo("Set Border Waveform (0x%02x): 0x%02x\n",
SSD1680_WRITE_BORDER, 0x03);
ssd1680_snd_cmd_with_data1(priv, SSD1680_WRITE_BORDER, 0x03);
+#elif defined(CONFIG_LCD_SSD1681_1_54)
+ /* Step 5a: Sending command write border with data 0x01:
+ * - Follow LUT (Output VCOM @ RED)
+ * - Transition setting for VBD: LUT0
+ */
+
+ lcdinfo("Set Border Waveform (0x%02x): 0x%02x\n",
+ SSD1680_WRITE_BORDER, 0x01);
+ ssd1680_snd_cmd_with_data1(priv, SSD1680_WRITE_BORDER, 0x05);
#endif
- /* Step 6: Data entry mode SSD1680_DATA_MODE, 0x03 */
+ /* Step 6: Data entry mode SSD1680_DATA_MODE */
lcdinfo("Set data entry mode (0x%02x): 0x%02x\n",
SSD1680_DATA_MODE, SSD1680_VAL_DATA_MODE);
@@ -681,18 +697,27 @@ static int ssd1680_configuredisplay(struct ssd1680_dev_s
*priv)
/* Step 11: Lookup table */
+#ifndef CONFIG_LCD_SSD1681_1_54
lcdinfo("Write lookup table (0x%02x): (%d bytes)\n", SSD1680_WRITE_LUT,
sizeof (ssd1680_lut));
ssd1680_snd_cmd_with_data(priv, SSD1680_WRITE_LUT, ssd1680_lut,
sizeof (ssd1680_lut));
+#endif
+
+ /* Step 12: Set temperature control */
- /* Step 12: Write sequence */
+#ifdef CONFIG_LCD_SSD1681_1_54
+ ssd1680_snd_cmd_with_data1(priv, SSD1680_TEMP_CONTROL, 0x80);
+#endif
+
+ /* Step 13: Write sequence */
lcdinfo("Write control sequence (0x%02x): 0x%02x\n", SSD1680_DISP_CTRL2,
- 0xc0);
- ssd1680_snd_cmd_with_data1(priv, SSD1680_DISP_CTRL2, 0xc7);
+ SSD1680_VALUE_UPDATE_CTRL);
+ ssd1680_snd_cmd_with_data1(priv, SSD1680_DISP_CTRL2,
+ SSD1680_VALUE_UPDATE_CTRL);
- /* Step 13: Master Activate and busy wait */
+ /* Step 14: Master Activate and busy wait */
lcdinfo("Write master activate (0x%02x) command\n",
SSD1680_MASTER_ACTIVATE);
@@ -984,6 +1009,7 @@ static void ssd1680_snd_cmd_with_data4(FAR struct
ssd1680_dev_s *priv,
ssd1680_select(priv, false);
}
+#ifndef CONFIG_LCD_SSD1681_1_54
static void ssd1680_snd_cmd_with_data(FAR struct ssd1680_dev_s *priv,
uint8_t cmd, const uint8_t *dta, int dta_len)
{
@@ -994,6 +1020,7 @@ static void ssd1680_snd_cmd_with_data(FAR struct
ssd1680_dev_s *priv,
SPI_SNDBLOCK(priv->spi, dta, dta_len);
ssd1680_select(priv, false);
}
+#endif
#if !defined(CONFIG_LCD_PORTRAIT) && !defined(CONFIG_LCD_RPORTRAIT)
diff --git a/drivers/lcd/ssd1680.h b/drivers/lcd/ssd1680.h
index 6c44fff47f..cae2cf1d64 100644
--- a/drivers/lcd/ssd1680.h
+++ b/drivers/lcd/ssd1680.h
@@ -41,7 +41,8 @@
/* Limitations of the current configuration that I hope to fix someday */
-#if !defined(CONFIG_LCD_SSD1680_2_13_V2) && !defined(CONFIG_LCD_SSD1680_2_90)
+#if !defined(CONFIG_LCD_SSD1680_2_13_V2) && \
+ !defined(CONFIG_LCD_SSD1680_2_90) && !defined(CONFIG_LCD_SSD1681_1_54)
# error "Unknown and unsupported SSD16800 LCD"
#endif
@@ -119,16 +120,21 @@
# define SSD1680_VALUE_VCOM 0x55
# define SSD1680_VALUE_DUMMY_LINE 0x30
# define SSD1680_VALUE_GATE_TIME 0x0A
+# define SSD1680_VALUE_UPDATE_CTRL 0xC7
#elif defined(CONFIG_LCD_SSD1680_2_90) || defined(CONFIG_LCD_SSD1680_2_90_RED)
# define SSD1680_VALUE_VCOM 0xA8
# define SSD1680_VALUE_DUMMY_LINE 0x1A
# define SSD1680_VALUE_GATE_TIME 0x08
+# define SSD1680_VALUE_UPDATE_CTRL 0xC7
+#elif defined(CONFIG_LCD_SSD1681_1_54)
+# define SSD1680_VALUE_UPDATE_CTRL 0xF7
#else
# error "Not supported display"
#endif
/* Color Properties *********************************************************/
-#if defined(CONFIG_LCD_SSD1680_2_13_V2) || defined(CONFIG_LCD_SSD1680_2_90)
+#if defined(CONFIG_LCD_SSD1680_2_13_V2) || \
+ defined(CONFIG_LCD_SSD1680_2_90) || defined(CONFIG_LCD_SSD1681_1_54)
/* 1 bit per pixel */
# define SSD1680_DEV_COLORFMT FB_FMT_Y1
# define SSD1680_DEV_BPP 1
@@ -169,6 +175,10 @@
# define SSD1680_DEV_GATE_LAYOUT 0x00
# define SSD1680_DEV_NATIVE_XRES 128
# define SSD1680_DEV_NATIVE_YRES 296
+#elif defined(CONFIG_LCD_SSD1681_1_54)
+# define SSD1680_DEV_GATE_LAYOUT 0x01
+# define SSD1680_DEV_NATIVE_XRES 200
+# define SSD1680_DEV_NATIVE_YRES 200
#else
# error "Unknown resolution"
#endif