New rules of triggering redrawing display.

New callback redraw in lcd_framebuffer.c
SSD1680 driver (e-ink display) changes.
This commit is contained in:
Adam Kaliszan 2022-07-04 09:14:51 +02:00 committed by Xiang Xiao
parent a4e867b8d4
commit 664d45dcba
3 changed files with 89 additions and 69 deletions

View File

@ -211,43 +211,52 @@ static int lcdfb_updateearea(FAR struct fb_vtable_s *vtable,
unsigned int pixperbyte = 8 / pinfo->bpp;
startx &= ~(pixperbyte - 1);
}
}
if (pinfo->putarea != NULL)
{
/* Each Driver's callback function putarea may be optimized by checking
* if it is a full screen/full row mode or not.
* In case of full screen/row mode the memory layout of drivers memory
* and data provided to putarea function may be (or not, it depends of
* display and driver implementation) identical.
* Identical memory layout let us to use:
* - memcopy (if there is shadow buffer in driver implementation)
* - apply DMA channel to transfer data to driver memory.
*/
ret = pinfo->putarea(pinfo->dev, starty, endy, startx, endx, run);
if (ret < 0)
{
lcderr("Failed to update area");
return ret;
}
}
else
{
width = endx - startx + 1;
/* Get the starting position in the framebuffer */
run = priv->fbmem + starty * priv->stride;
run += (startx * pinfo->bpp + 7) >> 3;
}
/* Update the whole screen? */
if (startx == 0 && endx == priv->xres - 1 &&
starty == 0 && endy == priv->yres - 1)
{
/* Yes, LCD driver support putarea callback? */
if (pinfo->putarea != NULL)
for (row = starty; row <= endy; row++)
{
/* Yes, go the fast path */
ret = pinfo->putrun(pinfo->dev, row, startx, run, width);
if (ret < 0)
{
lcderr("Failed to update row");
return ret;
}
return pinfo->putarea(pinfo->dev, starty, endy, startx, endx, run);
run += priv->stride;
}
}
for (row = starty; row <= endy; row++)
if (pinfo->redraw != NULL)
{
/* REVISIT: Some LCD hardware certain alignment requirements on DMA
* memory.
*/
ret = pinfo->putrun(pinfo->dev, row, startx, run, width);
if (ret < 0)
{
return ret;
}
run += priv->stride;
pinfo->redraw(pinfo->dev);
}
return OK;

View File

@ -126,33 +126,38 @@ struct ssd1680_dev_s
/* Libc extension */
FAR void *bitscpy_ds(FAR void *dest, int dest_offset, FAR const void *src,
size_t nbits);
static FAR void *bitscpy_ds(FAR void *dest, int dest_offset,
FAR const void *src, size_t nbits);
FAR void *bitscpy_ss(FAR void *dest, FAR const void *src, int src_offset,
size_t nbits);
static FAR void *bitscpy_ss(FAR void *dest, FAR const void *src,
int src_offset, size_t nbits);
/* LCD Data Transfer Methods */
static int ssd1680_busy_wait(FAR struct ssd1680_dev_s *priv);
static void ssd1680_snd_cmd_with_data0(FAR struct ssd1680_dev_s *priv,
uint8_t cmd);
uint8_t cmd);
static void ssd1680_snd_cmd_with_data1(FAR struct ssd1680_dev_s *priv,
uint8_t cmd, uint8_t dta1);
uint8_t cmd, uint8_t dta1);
static void ssd1680_snd_cmd_with_data2(FAR struct ssd1680_dev_s *priv,
uint8_t cmd, uint8_t dta1, uint8_t dta2);
uint8_t cmd, uint8_t dta1,
uint8_t dta2);
static void ssd1680_snd_cmd_with_data3(FAR struct ssd1680_dev_s *priv,
uint8_t cmd, uint8_t dta1, uint8_t dta2, uint8_t dta3);
uint8_t cmd, uint8_t dta1,
uint8_t dta2, uint8_t dta3);
static void ssd1680_snd_cmd_with_data4(FAR struct ssd1680_dev_s *priv,
uint8_t cmd, uint8_t dta1, uint8_t dta2, uint8_t dta3, uint8_t dta4);
uint8_t cmd, uint8_t dta1,
uint8_t dta2, uint8_t dta3,
uint8_t dta4);
static void ssd1680_snd_cmd_with_data(FAR struct ssd1680_dev_s *priv,
uint8_t cmd, const uint8_t *dta, int dta_len);
uint8_t cmd, const uint8_t *dta,
int dta_len);
#if !defined(CONFIG_LCD_PORTRAIT) && !defined(CONFIG_LCD_RPORTRAIT)
# if SSD1680_DEV_BPP == 1
@ -179,6 +184,8 @@ static int ssd1680_getrun(FAR struct lcd_dev_s *dev, fb_coord_t row,
fb_coord_t col, FAR uint8_t *buffer,
size_t npixels);
static int ssd1680_redraw(FAR struct lcd_dev_s *dev);
/* LCD Configuration */
static int ssd1680_getvideoinfo(FAR struct lcd_dev_s *dev,
@ -207,7 +214,7 @@ static int ssd1680_setpower(struct lcd_dev_s *dev, int power);
static int ssd1680_configuredisplay(struct ssd1680_dev_s *priv);
static int ssd1680_redraw_display(struct ssd1680_dev_s *priv);
static int ssd1680_update_row(struct ssd1680_dev_s *priv, int row);
static int ssd1680_update_all(struct ssd1680_dev_s *priv);
static int ssd1680_update_all_and_redraw(struct ssd1680_dev_s *priv);
/****************************************************************************
* Private Data
@ -244,6 +251,7 @@ static const struct lcd_planeinfo_s g_planeinfo =
.putarea = NULL, /* Not need to implement */
.getrun = ssd1680_getrun, /* Read content of shadow memory */
.getarea = NULL, /* Not need to implement */
.redraw = ssd1680_redraw, /* Update drivers memory and redraw */
.buffer = (FAR uint8_t *)g_runbuffer, /* Run scratch buffer */
.bpp = SSD1680_DEV_BPP, /* Bits-per-pixel */
};
@ -331,16 +339,6 @@ static int ssd1680_putrun(FAR struct lcd_dev_s *dev, fb_coord_t row,
{
FAR struct ssd1680_dev_s *priv = (FAR struct ssd1680_dev_s *)dev;
/* TODO Special IOCTL function in lcd_framebuf has to be implemented.
* Those function would call ssd1680_putrun with npixels = 0
*/
if (npixels == 0)
{
ssd1680_redraw_display(priv);
return OK;
}
uint8_t *dst = priv->shadow_fb +
row * SSD1680_DEV_ROWSIZE + (col >> SSD1680_PDF);
@ -350,17 +348,6 @@ static int ssd1680_putrun(FAR struct lcd_dev_s *dev, fb_coord_t row,
bitscpy_ds(dst, dst_start_bitshift, buffer, npixels);
/* Write data to memory of display driver */
ssd1680_update_row(priv, row);
/* TODO Remove it after IOCTL refresh implementation */
if (row == SSD1680_DEV_FB_YRES / 2)
{
ssd1680_redraw_display(priv);
}
return OK;
}
@ -385,7 +372,6 @@ static int ssd1680_getrun(FAR struct lcd_dev_s *dev, fb_coord_t row,
fb_coord_t col, FAR uint8_t *buffer,
size_t npixels)
{
lcdinfo("(%d, %d, %d)\n", row, col, npixels);
FAR struct ssd1680_dev_s *priv = (FAR struct ssd1680_dev_s *)dev;
bitscpy_ss(buffer,
@ -396,6 +382,12 @@ static int ssd1680_getrun(FAR struct lcd_dev_s *dev, fb_coord_t row,
return OK;
}
static int ssd1680_redraw(FAR struct lcd_dev_s *dev)
{
FAR struct ssd1680_dev_s *priv = (FAR struct ssd1680_dev_s *)dev;
return ssd1680_update_all_and_redraw(priv);
}
/****************************************************************************
* Name: ssd1680_getvideoinfo
*
@ -529,17 +521,18 @@ static int ssd1680_setpower(FAR struct lcd_dev_s *dev, int power)
ret = ssd1680_configuredisplay(priv);
if (ret != OK)
{
lcderr("Failed to configure display\n");
return ret;
}
/* Draw the framebuffer */
ret = ssd1680_update_all(priv);
}
if (ret < 0)
{
return ret;
ret = ssd1680_update_all_and_redraw(priv);
if (ret != OK)
{
lcderr("Failed to update and redraw\n");
return ret;
}
}
priv->on = true;
@ -722,10 +715,11 @@ static int ssd1680_configuredisplay(struct ssd1680_dev_s *priv)
}
/****************************************************************************
* Name: ssd1680_update_all
* Name: ssd1680_update_all_and_redraw
*
* Description:
* Redraw full framebuffer to display
* Copy content of shadow buffer to drivers memory.
* Redraws the display
*
* Input Parameters:
* priv - Reference to private driver structure
@ -738,7 +732,7 @@ static int ssd1680_configuredisplay(struct ssd1680_dev_s *priv)
*
****************************************************************************/
static int ssd1680_update_all(struct ssd1680_dev_s *priv)
static int ssd1680_update_all_and_redraw(struct ssd1680_dev_s *priv)
{
int row;
for (row = 0; row < SSD1680_DEV_FB_YRES; row++)
@ -752,6 +746,8 @@ static int ssd1680_update_all(struct ssd1680_dev_s *priv)
static int ssd1680_redraw_display(struct ssd1680_dev_s *priv)
{
/* Synchronize shadow buffer with drivers memory */
int ret;
/* Step 15:
* Set control register 2.
@ -1312,8 +1308,8 @@ FAR struct lcd_dev_s *ssd1680_initialize(FAR struct spi_dev_s *dev,
return &priv->dev;
}
FAR void *bitscpy_ds(FAR void *dest, int dest_offset, FAR const void *src,
size_t nbits)
static FAR void *bitscpy_ds(FAR void *dest, int dest_offset,
FAR const void *src, size_t nbits)
{
FAR unsigned char *pout = (FAR unsigned char *)dest;
FAR unsigned char *pin = (FAR unsigned char *)src;
@ -1371,8 +1367,8 @@ FAR void *bitscpy_ds(FAR void *dest, int dest_offset, FAR const void *src,
return dest;
}
FAR void *bitscpy_ss(FAR void *dest, FAR const void *src, int src_offset,
size_t nbits)
static FAR void *bitscpy_ss(FAR void *dest, FAR const void *src,
int src_offset, size_t nbits)
{
FAR unsigned char *pout = (FAR unsigned char *)dest;
FAR unsigned char *pin = (FAR unsigned char *)src;

View File

@ -123,6 +123,21 @@ struct lcd_planeinfo_s
fb_coord_t row_end, fb_coord_t col_start,
fb_coord_t col_end, FAR uint8_t *buffer);
/* This method can be used to redraw display's content.
*
* dev - LCD interface to redraw its memory content
*
* NOTE: In case of non e-ink dispalys redrawing is cheap and can be done
* after each memory modification. Redrawing e-ink display is time and
* energy consuming.
* In order to avoid such operation (time and energy consumption) we can
* implement callback function putrun without redrawing the screen.
* Function putrun is called many times unless the function putarea is
* implemented.
*/
int (*redraw)(FAR struct lcd_dev_s *dev);
/* Plane color characteristics ********************************************/
/* This is working memory allocated by the LCD driver for each LCD device