New rules of triggering redrawing display.
New callback redraw in lcd_framebuffer.c SSD1680 driver (e-ink display) changes.
This commit is contained in:
parent
a4e867b8d4
commit
664d45dcba
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user