Adding support for LS027B7DH01A display and MEMLCD_EXTCOMIN_MODE_HW

This commit is contained in:
jturnsek 2023-03-06 10:34:32 +01:00 committed by Petro Karashchenko
parent 34a032b486
commit 4c2edece50
2 changed files with 77 additions and 17 deletions

View file

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

View file

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