This is an automated email from the ASF dual-hosted git repository. pkarashchenko 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 4c2edece50 Adding support for LS027B7DH01A display and MEMLCD_EXTCOMIN_MODE_HW 4c2edece50 is described below commit 4c2edece50a65ffb21325e8922b793d549f21a9f Author: jturnsek <jernej.turn...@gmail.com> AuthorDate: Mon Mar 6 10:34:32 2023 +0100 Adding support for LS027B7DH01A display and MEMLCD_EXTCOMIN_MODE_HW --- drivers/lcd/Kconfig | 5 +++ drivers/lcd/memlcd.c | 89 ++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 77 insertions(+), 17 deletions(-) diff --git a/drivers/lcd/Kconfig b/drivers/lcd/Kconfig index 860a1d97f4..80be5c59a2 100644 --- a/drivers/lcd/Kconfig +++ b/drivers/lcd/Kconfig @@ -1039,6 +1039,11 @@ config MEMLCD_LS013B7DH03 ---help--- Selects the LS013B7DH03 model +config MEMLCD_LS027B7DH01A + bool "LS027B7DH01A" + ---help--- + Selects the LS027B7DH01A model + endchoice config MEMLCD_NINTERFACES diff --git a/drivers/lcd/memlcd.c b/drivers/lcd/memlcd.c index f30e98857f..06dd88c464 100644 --- a/drivers/lcd/memlcd.c +++ b/drivers/lcd/memlcd.c @@ -33,6 +33,8 @@ #include <debug.h> #include <nuttx/arch.h> +#include <nuttx/wqueue.h> +#include <nuttx/clock.h> #include <nuttx/spi/spi.h> #include <nuttx/lcd/lcd.h> #include <nuttx/lcd/memlcd.h> @@ -63,6 +65,9 @@ #elif defined CONFIG_MEMLCD_LS013B7DH03 # define MEMLCD_XRES 128 # define MEMLCD_YRES 128 +#elif defined CONFIG_MEMLCD_LS027B7DH01A +# define MEMLCD_XRES 400 +# define MEMLCD_YRES 240 #else # error "This Memory LCD model is not supported yet." #endif @@ -70,6 +75,7 @@ /* lcd command */ #define MEMLCD_CMD_UPDATE (0x01) +#define MEMLCD_CMD_VCOM (0x02) #define MEMLCD_CMD_ALL_CLEAR (0x04) #define MEMLCD_CONTROL_BYTES (0) @@ -103,6 +109,15 @@ #define LS_BIT (1 << 0) #define MS_BIT (1 << 7) +#define MEMLCD_WORK_PERIOD MSEC2TICK(500) + +#define TOGGLE_VCOM(dev) \ + do \ + { \ + dev->vcom = dev->vcom ? 0x00 : MEMLCD_CMD_VCOM; \ + } \ + while (0); + /**************************************************************************** * Private Type Definition ****************************************************************************/ @@ -119,7 +134,12 @@ struct memlcd_dev_s FAR struct memlcd_priv_s *priv; /* Board specific structure */ uint8_t contrast; /* Current contrast setting */ uint8_t power; /* Current power setting */ - +#ifdef CONFIG_MEMLCD_EXTCOMIN_MODE_HW + struct work_s work; + uint8_t vcom; +#else + bool pol; /* Polarity for extcomisr */ +#endif /* The memlcds does not support reading the display memory in SPI mode. * Since there is 1 BPP and is byte access, it is necessary to keep a * shadow copy of the framebuffer. At 128x128, it amounts to 2KB. @@ -249,6 +269,41 @@ static inline int __test_bit(int nr, const volatile uint8_t * addr) return 1 & (addr[BIT_BYTE(nr)] >> (nr & (BITS_PER_BYTE - 1))); } +/**************************************************************************** + * Name: memlcd_worker + * + * Description: + * Toggle VCOM bit + * + * Input Parameters: + * arg - Reference to the memlcd_dev_s structure + * + * Returned Value: + * None + * + ****************************************************************************/ +#ifdef CONFIG_MEMLCD_EXTCOMIN_MODE_HW +static void memlcd_worker(FAR void *arg) +{ + FAR struct memlcd_dev_s *mlcd = arg; + uint16_t cmd = (uint16_t)mlcd->vcom; + + TOGGLE_VCOM(mlcd); + + memlcd_select(mlcd->spi); + + up_udelay(2); + + SPI_SNDBLOCK(mlcd->spi, &cmd, 2); + + up_udelay(1); + + memlcd_deselect(mlcd->spi); + + work_queue(LPWORK, &mlcd->work, memlcd_worker, mlcd, MEMLCD_WORK_PERIOD); +} +#endif + /**************************************************************************** * Name: memlcd_select * @@ -329,16 +384,16 @@ static void memlcd_deselect(FAR struct spi_dev_s *spi) static inline void memlcd_clear(FAR struct memlcd_dev_s *mlcd) { - uint16_t cmd = MEMLCD_CMD_ALL_CLEAR; + uint16_t cmd = MEMLCD_CMD_VCOM | MEMLCD_CMD_ALL_CLEAR; lcdinfo("Clear display\n"); memlcd_select(mlcd->spi); - /* XXX Ensure 2us here */ + up_udelay(2); SPI_SNDBLOCK(mlcd->spi, &cmd, 2); - /* XXX Ensure 6us here */ + up_udelay(1); memlcd_deselect(mlcd->spi); } @@ -365,15 +420,10 @@ static inline void memlcd_clear(FAR struct memlcd_dev_s *mlcd) static int memlcd_extcominisr(int irq, FAR void *context, void *arg) { - static bool pol = 0; - struct memlcd_dev_s *mlcd = &g_memlcddev; -#ifdef CONFIG_MEMLCD_EXTCOMIN_MODE_HW -# error "CONFIG_MEMLCD_EXTCOMIN_MODE_HW unsupported yet!" - /* Start a worker thread, do it in bottom half? */ - -#else - pol = !pol; - mlcd->priv->setpolarity(pol); + FAR struct memlcd_dev_s *mlcd = &g_memlcddev; +#ifndef CONFIG_MEMLCD_EXTCOMIN_MODE_HW + mlcd->pol = !mlcd->pol; + mlcd->priv->setpolarity(mlcd->pol); #endif return OK; } @@ -458,15 +508,15 @@ static int memlcd_putrun(FAR struct lcd_dev_s *dev, memlcd_select(mlcd->spi); - /* XXX Ensure 6us here */ + up_udelay(2); cmd = MEMLCD_CMD_UPDATE | row << 8; SPI_SNDBLOCK(mlcd->spi, &cmd, 2); - SPI_SNDBLOCK(mlcd->spi, pfb, MEMLCD_YRES / 8 + MEMLCD_CONTROL_BYTES); - cmd = 0xffff; + SPI_SNDBLOCK(mlcd->spi, pfb, MEMLCD_XRES / 8 + MEMLCD_CONTROL_BYTES); + cmd = 0x0000; SPI_SNDBLOCK(mlcd->spi, &cmd, 2); - /* XXX Ensure 2us here */ + up_udelay(1); memlcd_deselect(mlcd->spi); @@ -719,7 +769,12 @@ FAR struct lcd_dev_s *memlcd_initialize(FAR struct spi_dev_s *spi, mlcd->priv = priv; mlcd->spi = spi; +#ifdef CONFIG_MEMLCD_EXTCOMIN_MODE_HW + mlcd->vcom = MEMLCD_CMD_VCOM; + work_queue(LPWORK, &mlcd->work, memlcd_worker, mlcd, MEMLCD_WORK_PERIOD); +#else mlcd->priv->attachirq(memlcd_extcominisr, mlcd); +#endif lcdinfo("done\n"); return &mlcd->dev;