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 <[email protected]>
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;