From 9266c54bc2e47ee1f35fb3a927a8ddfa1e16342b Mon Sep 17 00:00:00 2001 From: Matias N Date: Mon, 2 Nov 2020 12:56:10 -0300 Subject: [PATCH] lcd: add optional putarea()/getarea() operations --- arch/sim/src/sim/up_lcd.c | 61 ++++++++++++ drivers/lcd/lcd_dev.c | 82 ++++++++++++++-- drivers/lcd/max7219.c | 30 +++--- drivers/lcd/pcd8544.c | 191 ++++++++++++++++++++---------------- include/nuttx/lcd/lcd.h | 51 +++++++++- include/nuttx/lcd/lcd_dev.h | 27 +++-- 6 files changed, 324 insertions(+), 118 deletions(-) diff --git a/arch/sim/src/sim/up_lcd.c b/arch/sim/src/sim/up_lcd.c index 605770ba0e..b365b11962 100644 --- a/arch/sim/src/sim/up_lcd.c +++ b/arch/sim/src/sim/up_lcd.c @@ -115,6 +115,9 @@ struct sim_dev_s static int sim_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, size_t npixels); +static int sim_putarea(fb_coord_t row_start, fb_coord_t row_end, + fb_coord_t col_start, fb_coord_t col_end, + FAR const uint8_t *buffer); static int sim_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, size_t npixels); @@ -183,6 +186,7 @@ static const struct fb_videoinfo_s g_videoinfo = static struct lcd_planeinfo_s g_planeinfo = { .putrun = sim_putrun, /* Put a run into LCD memory */ + .putarea = sim_putarea, /* Put a rectangular area to LCD */ .getrun = sim_getrun, /* Get a run from LCD memory */ #ifndef CONFIG_SIM_X11FB .buffer = (FAR uint8_t *)g_runbuffer, /* Run scratch buffer */ @@ -245,6 +249,63 @@ static int sim_putrun(fb_coord_t row, fb_coord_t col, return OK; } +/**************************************************************************** + * Name: sim_putarea + * + * Description: + * This method can be used to write a partial raster line to the LCD: + * + * row_start - Starting row to write to (range: 0 <= row < yres) + * row_end - Ending row to write to (range: row_start <= row < yres) + * col_start - Starting column to write to (range: 0 <= col <= xres) + * col_end - Ending column to write to + * (range: col_start <= col_end < xres) + * buffer - The buffer containing the area to be written to the LCD + * + ****************************************************************************/ + +static int sim_putarea(fb_coord_t row_start, fb_coord_t row_end, + fb_coord_t col_start, fb_coord_t col_end, + FAR const uint8_t *buffer) +{ + fb_coord_t row; + size_t rows; + size_t cols; + size_t row_size; + + lcdinfo("row_start: %d row_end: %d col_start: %d col_end: %d\n", + row_start, row_end, col_start, col_end); + + cols = col_end - col_start + 1; + rows = row_end - row_start + 1; + row_size = cols * (g_planeinfo.bpp >> 3); + +#ifdef CONFIG_SIM_X11FB + if (col_start == 0 && col_end == (g_videoinfo.xres - 1) && + g_stride == row_size) + { + /* simpler case, we can just memcpy() the whole buffer */ + + memcpy(&g_planeinfo.buffer[row_start * g_stride], buffer, + rows * row_size); + } + else + { + /* We have to go row by row */ + + for (row = row_start; row <= row_end; row++) + { + memcpy(&g_planeinfo.buffer[row * g_stride + col_start * + (g_planeinfo.bpp >> 3)], + &buffer[(row - row_start) * row_size], + cols * (g_planeinfo.bpp >> 3)); + } + } +#endif + + return OK; +} + /**************************************************************************** * Name: sim_getrun * diff --git a/drivers/lcd/lcd_dev.c b/drivers/lcd/lcd_dev.c index 3c458d6d53..e3fade6110 100644 --- a/drivers/lcd/lcd_dev.c +++ b/drivers/lcd/lcd_dev.c @@ -123,20 +123,90 @@ static int lcddev_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { case LCDDEVIO_GETRUN: { - FAR struct lcddev_run_s *lcd_putrun = + FAR struct lcddev_run_s *lcd_run = (FAR struct lcddev_run_s *)arg; - ret = priv->planeinfo.getrun(lcd_putrun->row, lcd_putrun->col, - lcd_putrun->data, lcd_putrun->npixels); + ret = priv->planeinfo.getrun(lcd_run->row, lcd_run->col, + lcd_run->data, lcd_run->npixels); } break; case LCDDEVIO_PUTRUN: { - const FAR struct lcddev_run_s *lcd_putrun = + const FAR struct lcddev_run_s *lcd_run = (const FAR struct lcddev_run_s *)arg; - ret = priv->planeinfo.putrun(lcd_putrun->row, lcd_putrun->col, - lcd_putrun->data, lcd_putrun->npixels); + ret = priv->planeinfo.putrun(lcd_run->row, lcd_run->col, + lcd_run->data, lcd_run->npixels); + } + break; + case LCDDEVIO_GETAREA: + { + FAR struct lcddev_area_s *lcd_area = + (FAR struct lcddev_area_s *)arg; + + if (priv->planeinfo.getarea) + { + ret = priv->planeinfo.getarea(lcd_area->row_start, + lcd_area->row_end, + lcd_area->col_start, + lcd_area->col_end, + lcd_area->data); + } + else + { + /* Emulate getarea() using getrun() */ + + uint8_t *buf = lcd_area->data; + size_t npixels = (lcd_area->col_end - lcd_area->col_start + 1); + int row; + + for (row = lcd_area->row_start; row <= lcd_area->row_end; row++) + { + ret = priv->planeinfo.getrun(row, lcd_area->col_start, buf, + npixels); + if (ret < 0) + { + break; + } + + buf += npixels * (priv->planeinfo.bpp >> 3); + } + } + } + break; + case LCDDEVIO_PUTAREA: + { + const FAR struct lcddev_area_s *lcd_area = + (const FAR struct lcddev_area_s *)arg; + + if (priv->planeinfo.putarea) + { + ret = priv->planeinfo.putarea(lcd_area->row_start, + lcd_area->row_end, + lcd_area->col_start, + lcd_area->col_end, + lcd_area->data); + } + else + { + /* Emulate putarea() using putrun() */ + + uint8_t *buf = lcd_area->data; + size_t npixels = (lcd_area->col_end - lcd_area->col_start + 1); + int row; + + for (row = lcd_area->row_start; row <= lcd_area->row_end; row++) + { + ret = priv->planeinfo.putrun(row, lcd_area->col_start, buf, + npixels); + if (ret < 0) + { + break; + } + + buf += npixels * (priv->planeinfo.bpp >> 3); + } + } } break; case LCDDEVIO_GETPOWER: diff --git a/drivers/lcd/max7219.c b/drivers/lcd/max7219.c index d7b8be26a3..4b854ddf08 100644 --- a/drivers/lcd/max7219.c +++ b/drivers/lcd/max7219.c @@ -57,6 +57,7 @@ ****************************************************************************/ /* Configuration ************************************************************/ + /* MAX7219 Configuration Settings: * * CONFIG_MAX7219_NHORIZONTALBLKS - Specifies the number of physical @@ -102,6 +103,7 @@ #endif /* Color Properties *********************************************************/ + /* The MAX7219 chip can handle resolution of 8x8, 16x8, 8x16, 16x16, 24x8, * etc. */ @@ -153,9 +155,9 @@ struct max7219_dev_s uint8_t contrast; uint8_t powered; - /* The MAX7219 does not support reading from the display memory in SPI mode. - * Since there is 1 BPP and access is byte-by-byte, it is necessary to keep - * a shadow copy of the framebuffer memory. + /* The MAX7219 does not support reading from the display memory in SPI + * mode. Since there is 1 BPP and access is byte-by-byte, it is necessary + * to keep a shadow copy of the framebuffer memory. */ uint8_t fb[MAX7219_FBSIZE]; @@ -239,10 +241,10 @@ static const struct fb_videoinfo_s g_videoinfo = static const struct lcd_planeinfo_s g_planeinfo = { - max7219_putrun, /* Put a run into LCD memory */ - max7219_getrun, /* Get a run from LCD memory */ - (FAR uint8_t *)g_runbuffer, /* Run scratch buffer */ - MAX7219_BPP, /* Bits-per-pixel */ + .putrun = max7219_putrun, /* Put a run into LCD memory */ + .getrun = max7219_getrun, /* Get a run from LCD memory */ + .buffer = (FAR uint8_t *)g_runbuffer, /* Run scratch buffer */ + .bpp = MAX7219_BPP, /* Bits-per-pixel */ }; /* This is the standard, NuttX LCD driver object */ @@ -250,6 +252,7 @@ static const struct lcd_planeinfo_s g_planeinfo = static struct max7219_dev_s g_max7219dev = { /* struct lcd_dev_s */ + { /* LCD Configuration */ @@ -647,8 +650,9 @@ static int max7219_getvideoinfo(FAR struct lcd_dev_s *dev, * ****************************************************************************/ -static int max7219_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo) +static int max7219_getplaneinfo(FAR struct lcd_dev_s *dev, + unsigned int planeno, + FAR struct lcd_planeinfo_s *pinfo) { DEBUGASSERT(dev && pinfo && planeno == 0); @@ -682,8 +686,9 @@ static int max7219_getpower(struct lcd_dev_s *dev) * Name: max7219_setpower * * Description: - * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On - * backlit LCDs, this setting may correspond to the backlight setting. + * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full + * on). On backlit LCDs, this setting may correspond to the backlight + * setting. * ****************************************************************************/ @@ -898,7 +903,8 @@ FAR struct lcd_dev_s *max7219_initialize(FAR struct spi_dev_s *spi, /* Set intensity level configured by the user */ - data = (MAX7219_INTENSITY) | (DISPLAY_INTENSITY(CONFIG_LCD_MAXCONTRAST) << 8); + data = (MAX7219_INTENSITY) | + (DISPLAY_INTENSITY(CONFIG_LCD_MAXCONTRAST) << 8); SPI_SNDBLOCK(priv->spi, &data, 2); diff --git a/drivers/lcd/pcd8544.c b/drivers/lcd/pcd8544.c index e041faa28e..29f69fe651 100644 --- a/drivers/lcd/pcd8544.c +++ b/drivers/lcd/pcd8544.c @@ -1,4 +1,4 @@ -/************************************************************************************** +/**************************************************************************** * drivers/lcd/pcd8544.c * * Driver for the Philips PCD8544 Display controller @@ -41,11 +41,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - **************************************************************************************/ + ****************************************************************************/ -/************************************************************************************** +/**************************************************************************** * Included Files - **************************************************************************************/ + ****************************************************************************/ #include @@ -63,11 +63,12 @@ #include "pcd8544.h" -/************************************************************************************** +/**************************************************************************** * Pre-processor Definitions - **************************************************************************************/ + ****************************************************************************/ + +/* Configuration ************************************************************/ -/* Configuration **********************************************************************/ /* PCD8544 Configuration Settings: * * CONFIG_PCD8544_SPIMODE - Controls the SPI mode @@ -80,7 +81,8 @@ * * Required LCD driver settings: * CONFIG_LCD_PCD8544 - Enable PCD8544 support - * CONFIG_LCD_MAXCONTRAST should be 255, but any value >0 and <=255 will be accepted. + * CONFIG_LCD_MAXCONTRAST should be 255, but any value >0 and <=255 will be + * accepted. * CONFIG_LCD_MAXPOWER should be 1: 0=off, 1=normal * * Required SPI driver settings: @@ -113,7 +115,9 @@ # define CONFIG_PCD8544_NINTERFACES 1 #endif -/* Verbose debug pcd8544 must also be enabled to use the extra OLED debug pcd8544 */ +/* Verbose debug pcd8544 must also be enabled to use the extra OLED debug + * pcd8544 + */ #ifndef CONFIG_DEBUG_FEATURES # undef CONFIG_DEBUG_INFO @@ -156,9 +160,10 @@ # error "CONFIG_SPI_CMDDATA must be defined in your NuttX configuration" #endif -/* Color Properties *******************************************************************/ -/* The PCD8544 display controller can handle a resolution of 84x48. - */ +/* Color Properties *********************************************************/ + +/* The PCD8544 display controller can handle a resolution of 84x48. */ + /* Display Resolution */ #ifdef CONFIG_PCD8544_XRES @@ -192,9 +197,9 @@ #define LS_BIT (1 << 0) #define MS_BIT (1 << 7) -/************************************************************************************** +/**************************************************************************** * Private Type Definition - **************************************************************************************/ + ****************************************************************************/ /* This structure describes the state of this driver */ @@ -210,17 +215,17 @@ struct pcd8544_dev_s uint8_t contrast; uint8_t powered; - /* The PCD8544 does not support reading from the display memory in SPI mode. - * Since there is 1 BPP and access is byte-by-byte, it is necessary to keep - * a shadow copy of the framebuffer memory. + /* The PCD8544 does not support reading from the display memory in SPI + * mode. Since there is 1 BPP and access is byte-by-byte, it is necessary + * to keep a shadow copy of the framebuffer memory. */ uint8_t fb[PCD8544_FBSIZE]; }; -/************************************************************************************** +/**************************************************************************** * Private Function Protototypes - **************************************************************************************/ + ****************************************************************************/ /* SPI helpers */ @@ -229,17 +234,18 @@ static void pcd8544_deselect(FAR struct spi_dev_s *spi); /* LCD Data Transfer Methods */ -static int pcd8544_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels); -static int pcd8544_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels); +static int pcd8544_putrun(fb_coord_t row, fb_coord_t col, + FAR const uint8_t *buffer, size_t npixels); +static int pcd8544_getrun(fb_coord_t row, fb_coord_t col, + FAR uint8_t *buffer, size_t npixels); /* LCD Configuration */ static int pcd8544_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo); -static int pcd8544_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo); + FAR struct fb_videoinfo_s *vinfo); +static int pcd8544_getplaneinfo(FAR struct lcd_dev_s *dev, + unsigned int planeno, + FAR struct lcd_planeinfo_s *pinfo); /* LCD RGB Mapping */ @@ -264,9 +270,9 @@ static int pcd8544_setcontrast(struct lcd_dev_s *dev, unsigned int contrast); static inline void up_clear(FAR struct pcd8544_dev_s *priv); -/************************************************************************************** +/**************************************************************************** * Private Data - **************************************************************************************/ + ****************************************************************************/ /* This is working memory allocated by the LCD driver for each LCD device * and for each color plane. This memory will hold one raster line of data. @@ -279,7 +285,7 @@ static inline void up_clear(FAR struct pcd8544_dev_s *priv); * if there are multiple LCD devices, they must each have unique run buffers. */ -static uint8_t g_runbuffer[PCD8544_XSTRIDE+1]; +static uint8_t g_runbuffer[PCD8544_XSTRIDE + 1]; /* This structure describes the overall LCD video controller */ @@ -295,10 +301,10 @@ static const struct fb_videoinfo_s g_videoinfo = static const struct lcd_planeinfo_s g_planeinfo = { - pcd8544_putrun, /* Put a run into LCD memory */ - pcd8544_getrun, /* Get a run from LCD memory */ - (FAR uint8_t *)g_runbuffer, /* Run scratch buffer */ - PCD8544_BPP, /* Bits-per-pixel */ + .putrun = pcd8544_putrun, /* Put a run into LCD memory */ + .getrun = pcd8544_getrun, /* Get a run from LCD memory */ + .buffer = (FAR uint8_t *)g_runbuffer, /* Run scratch buffer */ + .bpp = PCD8544_BPP, /* Bits-per-pixel */ }; /* This is the standard, NuttX LCD driver object */ @@ -306,6 +312,7 @@ static const struct lcd_planeinfo_s g_planeinfo = static struct pcd8544_dev_s g_pcd8544dev = { /* struct lcd_dev_s */ + { /* LCD Configuration */ @@ -333,17 +340,17 @@ static struct pcd8544_dev_s g_pcd8544dev = }, }; -/************************************************************************************** +/**************************************************************************** * Private Functions - **************************************************************************************/ + ****************************************************************************/ -/************************************************************************************** +/**************************************************************************** * Name: pcd8544_powerstring * * Description: * Convert the power setting to a string. * - **************************************************************************************/ + ****************************************************************************/ static inline FAR const char *pcd8544_powerstring(uint8_t power) { @@ -361,7 +368,7 @@ static inline FAR const char *pcd8544_powerstring(uint8_t power) } } -/************************************************************************************** +/**************************************************************************** * Name: pcd8544_select * * Description: @@ -375,7 +382,7 @@ static inline FAR const char *pcd8544_powerstring(uint8_t power) * * Assumptions: * - **************************************************************************************/ + ****************************************************************************/ static void pcd8544_select(FAR struct spi_dev_s *spi) { @@ -396,7 +403,7 @@ static void pcd8544_select(FAR struct spi_dev_s *spi) SPI_SETFREQUENCY(spi, CONFIG_PCD8544_FREQUENCY); } -/************************************************************************************** +/**************************************************************************** * Name: pcd8544_deselect * * Description: @@ -410,7 +417,7 @@ static void pcd8544_select(FAR struct spi_dev_s *spi) * * Assumptions: * - **************************************************************************************/ + ****************************************************************************/ static void pcd8544_deselect(FAR struct spi_dev_s *spi) { @@ -420,7 +427,7 @@ static void pcd8544_deselect(FAR struct spi_dev_s *spi) SPI_LOCK(spi, false); } -/************************************************************************************** +/**************************************************************************** * Name: pcd8544_putrun * * Description: @@ -432,12 +439,14 @@ static void pcd8544_deselect(FAR struct spi_dev_s *spi) * npixels - The number of pixels to write to the LCD * (range: 0 < npixels <= xres-col) * - **************************************************************************************/ + ****************************************************************************/ -static int pcd8544_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels) +static int pcd8544_putrun(fb_coord_t row, fb_coord_t col, + FAR const uint8_t *buffer, size_t npixels) { - /* Because of this line of code, we will only be able to support a single PCD8544 device */ + /* Because of this line of code, we will only be able to support a single + * PCD8544 device + */ FAR struct pcd8544_dev_s *priv = &g_pcd8544dev; FAR uint8_t *fbptr; @@ -551,7 +560,7 @@ static int pcd8544_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buf /* Set the starting position for the run */ - SPI_SEND(priv->spi, PCD8544_SET_Y_ADDR+page); /* Set the page start */ + SPI_SEND(priv->spi, PCD8544_SET_Y_ADDR + page); /* Set the page start */ SPI_SEND(priv->spi, PCD8544_SET_X_ADDR + (col & 0x7f)); /* Set the low column */ /* Select data transfer */ @@ -568,7 +577,7 @@ static int pcd8544_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buf return OK; } -/************************************************************************************** +/**************************************************************************** * Name: pcd8544_getrun * * Description: @@ -580,12 +589,14 @@ static int pcd8544_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buf * npixels - The number of pixels to read from the LCD * (range: 0 < npixels <= xres-col) * - **************************************************************************************/ + ****************************************************************************/ -static int pcd8544_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels) +static int pcd8544_getrun(fb_coord_t row, fb_coord_t col, + FAR uint8_t *buffer, size_t npixels) { - /* Because of this line of code, we will only be able to support a single PCD8544 device */ + /* Because of this line of code, we will only be able to support a single + * PCD8544 device + */ FAR struct pcd8544_dev_s *priv = &g_pcd8544dev; FAR uint8_t *fbptr; @@ -614,6 +625,7 @@ static int pcd8544_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, } /* Then transfer the display data from the shadow frame buffer memory */ + /* Get the page number. The range of 48 lines is divided up into six * pages of 8 lines each. */ @@ -694,34 +706,36 @@ static int pcd8544_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, return OK; } -/************************************************************************************** +/**************************************************************************** * Name: pcd8544_getvideoinfo * * Description: * Get information about the LCD video controller configuration. * - **************************************************************************************/ + ****************************************************************************/ static int pcd8544_getvideoinfo(FAR struct lcd_dev_s *dev, FAR struct fb_videoinfo_s *vinfo) { DEBUGASSERT(dev && vinfo); ginfo("fmt: %d xres: %d yres: %d nplanes: %d\n", - g_videoinfo.fmt, g_videoinfo.xres, g_videoinfo.yres, g_videoinfo.nplanes); + g_videoinfo.fmt, g_videoinfo.xres, g_videoinfo.yres, + g_videoinfo.nplanes); memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s)); return OK; } -/************************************************************************************** +/**************************************************************************** * Name: pcd8544_getplaneinfo * * Description: * Get information about the configuration of each LCD color plane. * - **************************************************************************************/ + ****************************************************************************/ -static int pcd8544_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo) +static int pcd8544_getplaneinfo(FAR struct lcd_dev_s *dev, + unsigned int planeno, + FAR struct lcd_planeinfo_s *pinfo) { DEBUGASSERT(dev && pinfo && planeno == 0); ginfo("planeno: %d bpp: %d\n", planeno, g_planeinfo.bpp); @@ -729,14 +743,15 @@ static int pcd8544_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, return OK; } -/************************************************************************************** +/**************************************************************************** * Name: pcd8544_getpower * * Description: - * Get the LCD panel power status (0: full off - CONFIG_LCD_MAXPOWER: full on). On - * backlit LCDs, this setting may correspond to the backlight setting. + * Get the LCD panel power status (0: full off - CONFIG_LCD_MAXPOWER: full + * on). On backlit LCDs, this setting may correspond to the backlight + * setting. * - **************************************************************************************/ + ****************************************************************************/ static int pcd8544_getpower(struct lcd_dev_s *dev) { @@ -746,14 +761,15 @@ static int pcd8544_getpower(struct lcd_dev_s *dev) return priv->powered; } -/************************************************************************************** +/**************************************************************************** * Name: pcd8544_setpower * * Description: - * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On - * backlit LCDs, this setting may correspond to the backlight setting. + * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full + * on). On backlit LCDs, this setting may correspond to the backlight + * setting. * - **************************************************************************************/ + ****************************************************************************/ static int pcd8544_setpower(struct lcd_dev_s *dev, int power) { @@ -799,13 +815,13 @@ static int pcd8544_setpower(struct lcd_dev_s *dev, int power) return OK; } -/************************************************************************************** +/**************************************************************************** * Name: pcd8544_getcontrast * * Description: * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST). * - **************************************************************************************/ + ****************************************************************************/ static int pcd8544_getcontrast(struct lcd_dev_s *dev) { @@ -814,13 +830,13 @@ static int pcd8544_getcontrast(struct lcd_dev_s *dev) return (int)priv->contrast; } -/************************************************************************************** +/**************************************************************************** * Name: pcd8544_setcontrast * * Description: * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST). * - **************************************************************************************/ + ****************************************************************************/ static int pcd8544_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) { @@ -852,7 +868,7 @@ static int pcd8544_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) /* Set the contrast */ - SPI_SEND(priv->spi, (PCD8544_WRITE_VOP | contrast) ); + SPI_SEND(priv->spi, (PCD8544_WRITE_VOP | contrast)); /* Return to normal mode */ @@ -869,13 +885,13 @@ static int pcd8544_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) return OK; } -/************************************************************************************** +/**************************************************************************** * Name: up_clear * * Description: * Clear the display. * - **************************************************************************************/ + ****************************************************************************/ static inline void up_clear(FAR struct pcd8544_dev_s *priv) { @@ -901,17 +917,16 @@ static inline void up_clear(FAR struct pcd8544_dev_s *priv) /* Set the starting position for the run */ - SPI_SEND(priv->spi, PCD8544_SET_Y_ADDR+i); /* Set the page start */ + SPI_SEND(priv->spi, PCD8544_SET_Y_ADDR + i); /* Set the page start */ SPI_SEND(priv->spi, PCD8544_SET_X_ADDR + page); /* Set the column */ - /* Select data transfer */ SPI_CMDDATA(spi, SPIDEV_DISPLAY(0), false); - /* Then transfer all 84 columns of data */ + /* Then transfer all 84 columns of data */ - SPI_SNDBLOCK(priv->spi, &priv->fb[page * PCD8544_XRES], PCD8544_XRES); + SPI_SNDBLOCK(priv->spi, &priv->fb[page * PCD8544_XRES], PCD8544_XRES); } /* Unlock and de-select the device */ @@ -919,11 +934,11 @@ static inline void up_clear(FAR struct pcd8544_dev_s *priv) pcd8544_deselect(spi); } -/************************************************************************************** +/**************************************************************************** * Public Functions - **************************************************************************************/ + ****************************************************************************/ -/************************************************************************************** +/**************************************************************************** * Name: pcd8544_initialize * * Description: @@ -934,17 +949,19 @@ static inline void up_clear(FAR struct pcd8544_dev_s *priv) * Input Parameters: * * spi - A reference to the SPI driver instance. - * devno - A value in the range of 0 thropcd8544h CONFIG_PCD8544_NINTERFACES-1. - * This allows support for multiple OLED devices. + * devno - A value in the range of 0 thropcd8544h + * CONFIG_PCD8544_NINTERFACES-1. This allows support for multiple + * OLED devices. * * Returned Value: * - * On success, this function returns a reference to the LCD object for the specified - * OLED. NULL is returned on any failure. + * On success, this function returns a reference to the LCD object for the + * specified OLED. NULL is returned on any failure. * - **************************************************************************************/ + ****************************************************************************/ -FAR struct lcd_dev_s *pcd8544_initialize(FAR struct spi_dev_s *spi, unsigned int devno) +FAR struct lcd_dev_s *pcd8544_initialize(FAR struct spi_dev_s *spi, + unsigned int devno) { /* Configure and enable LCD */ diff --git a/include/nuttx/lcd/lcd.h b/include/nuttx/lcd/lcd.h index 0358f6de53..9dca541993 100644 --- a/include/nuttx/lcd/lcd.h +++ b/include/nuttx/lcd/lcd.h @@ -70,6 +70,7 @@ struct lcd_planeinfo_s { /* LCD Data Transfer ******************************************************/ + /* This method can be used to write a partial raster line to the LCD: * * row - Starting row to write to (range: 0 <= row < yres) @@ -82,10 +83,29 @@ struct lcd_planeinfo_s int (*putrun)(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, size_t npixels); + /* This method can be used to write a rectangular area to the LCD: + * + * row_start - Starting row to write to (range: 0 <= row < yres) + * row_end - Ending row to write to (range: row_start <= row < yres) + * col_start - Starting column to write to (range: 0 <= col <= xres) + * col_end - Ending column to write to + * (range: col_start <= col_end < xres) + * buffer - The buffer containing the area to be written to the LCD + * + * NOTE: this operation may not be supported by the device, in which case + * the callback pointer will be NULL. In that case, putrun() should be + * used. + */ + + int (*putarea)(fb_coord_t row_start, fb_coord_t row_end, + fb_coord_t col_start, fb_coord_t col_end, + FAR const uint8_t *buffer); + /* This method can be used to read a partial raster line from the LCD: * * row - Starting row to read from (range: 0 <= row < yres) - * col - Starting column to read read (range: 0 <= col <= xres-npixels) + * col - Starting column to read read + * (range: 0 <= col <= xres-npixels) * buffer - The buffer in which to return the run read from the LCD * npixels - The number of pixels to read from the LCD * (range: 0 < npixels <= xres-col) @@ -94,17 +114,36 @@ struct lcd_planeinfo_s int (*getrun)(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, size_t npixels); + /* This method can be used to read a rectangular area from the LCD: + * + * row_start - Starting row to read from (range: 0 <= row < yres) + * row_end - Ending row to read from (range: row_start <= row < yres) + * col_start - Starting column to read from (range: 0 <= col <= xres) + * col_end - Ending column to read from + * (range: col_start <= col_end < xres) + * buffer - The buffer where the data will be written + * + * NOTE: this operation may not be supported by the device, in which case + * the callback pointer will be NULL. In that case, getrun() should be + * used. + */ + + int (*getarea)(fb_coord_t row_start, fb_coord_t row_end, + fb_coord_t col_start, fb_coord_t col_end, + FAR uint8_t *buffer); + /* Plane color characteristics ********************************************/ /* This is working memory allocated by the LCD driver for each LCD device - * and for each color plane. This memory will hold one raster line of data. - * The size of the allocated run buffer must therefore be at least + * and for each color plane. This memory will hold one raster line of + * data. The size of the allocated run buffer must therefore be at least * (bpp * xres / 8). Actual alignment of the buffer must conform to the * bitwidth of the underlying pixel type. * * If there are multiple planes, they may share the same working buffer * because different planes will not be operate on concurrently. However, - * if there are multiple LCD devices, they must each have unique run buffers. + * if there are multiple LCD devices, they must each have unique run + * buffers. */ uint8_t *buffer; @@ -122,6 +161,7 @@ struct lcd_planeinfo_s struct lcd_dev_s { /* LCD Configuration ******************************************************/ + /* Get information about the LCD video controller configuration and the * configuration of each LCD color plane. */ @@ -132,6 +172,7 @@ struct lcd_dev_s FAR struct lcd_planeinfo_s *pinfo); /* LCD RGB Mapping ********************************************************/ + /* The following are provided only if the video hardware supports RGB color * mapping */ @@ -143,6 +184,7 @@ struct lcd_dev_s #endif /* Cursor Controls ********************************************************/ + /* The following are provided only if the video hardware supports a * hardware cursor */ @@ -155,6 +197,7 @@ struct lcd_dev_s #endif /* LCD Specific Controls **************************************************/ + /* Get the LCD panel power status (0: full off - CONFIG_LCD_MAXPOWER: full * on). On backlit LCDs, this setting may correspond to the backlight * setting. diff --git a/include/nuttx/lcd/lcd_dev.h b/include/nuttx/lcd/lcd_dev.h index 85fa67b852..92cd1c5077 100644 --- a/include/nuttx/lcd/lcd_dev.h +++ b/include/nuttx/lcd/lcd_dev.h @@ -37,15 +37,17 @@ * Type Definitions ****************************************************************************/ -#define LCDDEVIO_PUTRUN _LCDIOC(0) /* Arg: const struct lcddev_putrun_s* */ -#define LCDDEVIO_GETRUN _LCDIOC(1) /* Arg: struct lcddev_putrun_s* */ -#define LCDDEVIO_GETPOWER _LCDIOC(2) /* Arg: int* */ -#define LCDDEVIO_SETPOWER _LCDIOC(3) /* Arg: int */ -#define LCDDEVIO_GETCONTRAST _LCDIOC(4) /* Arg: int* */ -#define LCDDEVIO_SETCONTRAST _LCDIOC(5) /* Arg: unsigned int */ -#define LCDDEVIO_GETPLANEINFO _LCDIOC(6) /* Arg: struct lcd_planeinfo_s* */ -#define LCDDEVIO_GETVIDEOINFO _LCDIOC(7) /* Arg: struct fb_videoinfo_s* */ -#define LCDDEVIO_SETPLANENO _LCDIOC(8) /* Arg: int */ +#define LCDDEVIO_PUTRUN _LCDIOC(0) /* Arg: const struct lcddev_run_s* */ +#define LCDDEVIO_PUTAREA _LCDIOC(1) /* Arg: const struct lcddev_area_s* */ +#define LCDDEVIO_GETRUN _LCDIOC(2) /* Arg: struct lcddev_run_s* */ +#define LCDDEVIO_GETAREA _LCDIOC(3) /* Arg: struct lcddev_area_s* */ +#define LCDDEVIO_GETPOWER _LCDIOC(4) /* Arg: int* */ +#define LCDDEVIO_SETPOWER _LCDIOC(5) /* Arg: int */ +#define LCDDEVIO_GETCONTRAST _LCDIOC(6) /* Arg: int* */ +#define LCDDEVIO_SETCONTRAST _LCDIOC(7) /* Arg: unsigned int */ +#define LCDDEVIO_GETPLANEINFO _LCDIOC(8) /* Arg: struct lcd_planeinfo_s* */ +#define LCDDEVIO_GETVIDEOINFO _LCDIOC(9) /* Arg: struct fb_videoinfo_s* */ +#define LCDDEVIO_SETPLANENO _LCDIOC(10) /* Arg: int */ #ifdef CONFIG_FB_CMAP #define LCDDEVIO_GETCMAP _LCDIOC(9) /* Arg: struct fb_cmap_s* */ @@ -76,6 +78,13 @@ struct lcddev_run_s size_t npixels; }; +struct lcddev_area_s +{ + fb_coord_t row_start, row_end; + fb_coord_t col_start, col_end; + FAR uint8_t *data; +}; + /**************************************************************************** * Public Function Prototypes ****************************************************************************/