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;

Reply via email to