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 <huangqi3@xiaomi.com>
This commit is contained in:
Huang Qi 2024-08-03 12:59:06 +08:00 committed by Xiang Xiao
parent 88fb747091
commit e09a79ece9
3 changed files with 52 additions and 10 deletions

View File

@ -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

View File

@ -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: Write sequence */
/* Step 12: Set temperature control */
#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)

View File

@ -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