diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-06-24 12:37:02 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-06-24 12:37:02 -0600 |
commit | 860429a8eaaa2437d7d8e5f1cb6b2b684fbda295 (patch) | |
tree | 71600620a4fdfb47ab13390b5dd264f30dbf1efc /nuttx/drivers/lcd | |
parent | 4919eb3fd671887db91cb5e7f099fddd5a2c487c (diff) | |
download | px4-nuttx-860429a8eaaa2437d7d8e5f1cb6b2b684fbda295.tar.gz px4-nuttx-860429a8eaaa2437d7d8e5f1cb6b2b684fbda295.tar.bz2 px4-nuttx-860429a8eaaa2437d7d8e5f1cb6b2b684fbda295.zip |
Fix UG-2832HSWEG04 landscape. Add reverse landscape support to UG_2864AMBAG01 and UG-9964HSWAG01. Fixe NXHELLO default colors for 1-bit mono modes
Diffstat (limited to 'nuttx/drivers/lcd')
-rw-r--r-- | nuttx/drivers/lcd/README.txt | 40 | ||||
-rw-r--r-- | nuttx/drivers/lcd/p14201.c | 2 | ||||
-rw-r--r-- | nuttx/drivers/lcd/ssd1306.c | 110 | ||||
-rw-r--r-- | nuttx/drivers/lcd/ug-2864ambag01.c | 99 | ||||
-rw-r--r-- | nuttx/drivers/lcd/ug-9664hswag01.c | 127 |
5 files changed, 299 insertions, 79 deletions
diff --git a/nuttx/drivers/lcd/README.txt b/nuttx/drivers/lcd/README.txt index 469e2f499..d45f72b0e 100644 --- a/nuttx/drivers/lcd/README.txt +++ b/nuttx/drivers/lcd/README.txt @@ -81,7 +81,7 @@ Binding LCD Drivers binding sequence is: 1. Get an instance of struct lcd_dev_s from the hardware-specific LCD - device driver, and + device driver, and 2. Provide that instance to the initialization method of the higher level device driver. @@ -90,6 +90,8 @@ Examples: /drivers/lcd/ Re-usable LCD drivers reside in the drivers/lcd directory: + LEDs: + ---- mio283qt2.c. This is a driver for the MI0283QT-2 LCD from Multi-Inno Technology Co., Ltd. This LCD is based on the Himax HX8347-D LCD controller. @@ -97,10 +99,6 @@ Re-usable LCD drivers reside in the drivers/lcd directory: nokia6100.c. Supports the Nokia 6100 display with either the Philips PCF883 or the Epson S1D15G10 display controller. This LCD is used with the Olimex LPC1766-STK (but has not been fully integrated). - - p14201.c. Driver for RiT P14201 series display with SD1329 IC - controller. This OLED is used with older versions of the - TI/Luminary LM3S8962 Evaluation Kit. ssd12989.c. Generic LCD driver for LCDs based on the Solomon Systech SSD1289 LCD controller. Think of this as a template for an LCD driver @@ -110,18 +108,35 @@ Re-usable LCD drivers reside in the drivers/lcd directory: st7567.c. LCD Display Module, ST7567, Univision Technology Inc. Used with the LPCXpresso and Embedded Artists base board. + OLEDs: + ----- + p14201.c. Driver for RiT P14201 series display with SD1329 IC + controller. Based on the SD1329 controller. This OLED is used with + older versions of the TI/Luminary LM3S8962 Evaluation Kit. Example + usage + + configs/lm3s6965-ek/src + configs/lm3s8962-ek/src + ug-2864ambag01.c. OLED Display Module, UUG-2864AMBAG01, Univision - Technology Inc. See configs/stm32f4discovery and configs/zp214xp - for example usage. + Technology Inc. Based on the SH1101A controller. Example usage: + + configs/stm32f4discovery + configs/zp214xp ug-9664hswag01.c. OLED Display Module, UG-9664HSWAG01, Univision - Technology Inc. Used with the LPC Xpresso and Embedded Artists - base board. + Technology Inc. Based on the SSD1305 controller. Used with the + LPC Xpresso and Embedded Artists base board. Example usage: + + configs/lpcxpresso-lpc1768 ssd1306.c. OLED Display Modules based on the SSD1306 controllers. This includes the UG-2864HSWEG01 and UG2832HSWEG04, Both from Univision Technology Inc. The latter is used with the OLED1 module that comes - with the Atmel SAM4l Xplained Pro board. + with the Atmel SAM4l Xplained Pro board. Examplel usage: + + configs/stm32f4discovery + configs/sam4l-xplained Examples: configs/ ================== @@ -146,7 +161,7 @@ that makes then less re-usable: configs/shenzhou/src/up_ssd1289.c kwikstik-k40: - + configs/kwikstik-k40/src/up_lcd.c. Don't waste your time. This is just a stub. @@ -168,7 +183,7 @@ that makes then less re-usable: configs/pic32mx7mmb/src/up_mio283qt2.c. This driver is for the MI0283QT-2 LCD from Multi-Inno Technology Co., Ltd. This LCD is based on the Himax HX8347-D LCD controller. - + ILI93xx and Similar: configs/stm3210e-eval/src/up_lcd.c. This driver supports the following @@ -191,6 +206,7 @@ that makes then less re-usable: configs/stm32f4discovery/src/up_ug2864ambag01.c configs/stm32f4discovery/src/up_ug2864hsweg01.c + configs/sam4l-xplained/src/up_ug2832hsweg04.c configs/zp214xpa/src/up_ug2864ambag01.c LCD controllers built-into the MCU: diff --git a/nuttx/drivers/lcd/p14201.c b/nuttx/drivers/lcd/p14201.c index 934d251ca..c45292fed 100644 --- a/nuttx/drivers/lcd/p14201.c +++ b/nuttx/drivers/lcd/p14201.c @@ -1,6 +1,6 @@ /************************************************************************************** * drivers/lcd/p14201.c - * Driver for RiT P14201 series display (wih sd1329 IC controller) + * Driver for RiT P14201 series display (wih SD1329 IC controller) * * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> diff --git a/nuttx/drivers/lcd/ssd1306.c b/nuttx/drivers/lcd/ssd1306.c index d9d80c7e2..3fa7a34f6 100644 --- a/nuttx/drivers/lcd/ssd1306.c +++ b/nuttx/drivers/lcd/ssd1306.c @@ -158,13 +158,12 @@ #endif #if defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_RPORTRAIT) -# warning "No support yet for portrait modes" +# warning "No support for portrait modes" +# undef CONFIG_LCD_LANDSCAPE # define CONFIG_LCD_LANDSCAPE 1 # undef CONFIG_LCD_PORTRAIT # undef CONFIG_LCD_RLANDSCAPE # undef CONFIG_LCD_RPORTRAIT -#elif defined(CONFIG_LCD_RLANDSCAPE) -# warning "Reverse landscape mode is untested and, hence, probably buggy" #endif /* SSD1306 Commands *******************************************************************/ @@ -274,6 +273,26 @@ #define SSD1306_DEV_FBSIZE (SSD1306_DEV_XSTRIDE * SSD1306_DEV_YRES) #define SSD1306_DEV_ROWSIZE (SSD1306_DEV_XSTRIDE) +/* Orientation. There seem to be device differences. */ + +#if defined(CONFIG_LCD_UG2864HSWEG01) +# if defined(CONFIG_LCD_LANDSCAPE) +# undef SSD1306_DEV_REVERSEX +# undef SSD1306_DEV_REVERSEY +# elif defined(CONFIG_LCD_RLANDSCAPE) +# define SSD1306_DEV_REVERSEX 1 +# define SSD1306_DEV_REVERSEY 1 +# endif +#elif defined(CONFIG_LCD_UG2832HSWEG04) +# if defined(CONFIG_LCD_LANDSCAPE) +# define SSD1306_DEV_REVERSEX 1 +# undef SSD1306_DEV_REVERSEY +# elif defined(CONFIG_LCD_RLANDSCAPE) +# undef SSD1306_DEV_REVERSEX +# define SSD1306_DEV_REVERSEY 1 +# endif +#endif + /* Bit helpers */ #define LS_BIT (1 << 0) @@ -566,11 +585,31 @@ static int ssd1306_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buf return OK; } - /* Perform coordinate conversion for reverse landscape mode */ + /* Perform coordinate conversion for reverse landscape mode. + * If the rows are reversed then rows are are a mirror reflection of + * top to bottom. + */ -#ifdef CONFIG_LCD_RLANDSCAPE +#ifdef SSD1306_DEV_REVERSEY row = (SSD1306_DEV_YRES-1) - row; - col = (SSD1306_DEV_XRES-1) - col; +#endif + + /* If the column is switched then the start of the run is the mirror of + * the end of the run. + * + * col+pixlen-1 + * col | + * 0 | | XRES + * . S>>>>>>E . + * . E<<<<<<S . + * | | + * | `-(XRES-1)-col + * ` (XRES-1)-col-(pixlen-1) + */ + +#ifdef SSD1306_DEV_REVERSEX + col = (SSD1306_DEV_XRES-1) - col; + col -= (pixlen - 1); #endif /* Get the page number. The range of 64 lines is divided up into eight @@ -593,7 +632,7 @@ static int ssd1306_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buf * D4 | | X | | | | | * D5 | | X | | | | | * D6 | | X | | | | | - * D7 | | X | | | | | + * D7 | | X | | | | | * --------+---+---+---+---+-...-+-----+ * * So, in order to draw a white, horizontal line, at row 45. we @@ -603,11 +642,12 @@ static int ssd1306_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buf fbmask = 1 << (row & 7); fbptr = &priv->fb[page * SSD1306_DEV_XRES + col]; -#ifdef CONFIG_LCD_RLANDSCAPE - ptr = fbptr + pixlen - 1; +#ifdef SSD1306_DEV_REVERSEX + ptr = fbptr + (pixlen - 1); #else ptr = fbptr; #endif + #ifdef CONFIG_NX_PACKEDMSFIRST usrmask = MS_BIT; #else @@ -618,7 +658,7 @@ static int ssd1306_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buf { /* Set or clear the corresponding bit */ -#ifdef CONFIG_LCD_RLANDSCAPE +#ifdef SSD1306_DEV_REVERSEX if ((*buffer & usrmask) != 0) { *ptr-- |= fbmask; @@ -680,7 +720,7 @@ static int ssd1306_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buf /* Set the starting position for the run */ /* Set the column address to the XOFFSET value */ - + SPI_SEND(priv->spi, SSD1306_SETCOLL(devcol & 0x0f)); SPI_SEND(priv->spi, SSD1306_SETCOLH(devcol >> 4)); @@ -710,7 +750,7 @@ static int ssd1306_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buf * Name: ssd1306_getrun * * Description: - * This method can be used to read a partial raster line from the LCD: + * This method can be used to read a partial raster line from the LCD. * * Description: * This method can be used to write a partial raster line to the LCD. @@ -755,11 +795,30 @@ static int ssd1306_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, return -EINVAL; } - /* Perform coordinate conversion for reverse landscape mode */ + /* Perform coordinate conversion for reverse landscape mode. + * If the rows are reversed then rows are are a mirror reflection of + * top to bottom. + */ -#ifdef CONFIG_LCD_RLANDSCAPE +#ifdef SSD1306_DEV_REVERSEY row = (SSD1306_DEV_YRES-1) - row; - col = (SSD1306_DEV_XRES-1) - col; +#endif + + /* If the column is switched then the start of the run is the mirror of + * the end of the run. + * + * col+pixlen-1 + * col | + * 0 | | XRES + * . S>>>>>>E . + * . E<<<<<<S . + * | | + * | `-(XRES-1)-col + * ` (XRES-1)-col-(pixlen-1) + */ + +#ifdef SSD1306_DEV_REVERSEX + col = (SSD1306_DEV_XRES-1) - col; #endif /* Then transfer the display data from the shadow frame buffer memory */ @@ -783,7 +842,7 @@ static int ssd1306_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, * D4 | | X | | | | | * D5 | | X | | | | | * D6 | | X | | | | | - * D7 | | X | | | | | + * D7 | | X | | | | | * --------+---+---+---+---+-...-+-----+ * * So, in order to draw a white, horizontal line, at row 45. we @@ -792,11 +851,8 @@ static int ssd1306_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, */ fbmask = 1 << (row & 7); -#ifdef CONFIG_LCD_RLANDSCAPE - fbptr = &priv->fb[page * (SSD1306_DEV_XRES-1) + col + pixlen]; -#else fbptr = &priv->fb[page * SSD1306_DEV_XRES + col]; -#endif + #ifdef CONFIG_NX_PACKEDMSFIRST usrmask = MS_BIT; #else @@ -807,8 +863,8 @@ static int ssd1306_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, for (i = 0; i < pixlen; i++) { /* Set or clear the corresponding bit */ - -#ifdef CONFIG_LCD_RLANDSCAPE + +#ifdef SSD1306_DEV_REVERSEX uint8_t byte = *fbptr--; #else uint8_t byte = *fbptr++; @@ -916,7 +972,7 @@ static int ssd1306_getpower(FAR struct lcd_dev_s *dev) * **************************************************************************************/ -static int ssd1306_setpower(struct lcd_dev_s *dev, int power) +static int ssd1306_setpower(FAR struct lcd_dev_s *dev, int power) { struct ssd1306_dev_s *priv = (struct ssd1306_dev_s *)dev; DEBUGASSERT(priv && (unsigned)power <= CONFIG_LCD_MAXPOWER && priv->spi); @@ -939,7 +995,7 @@ static int ssd1306_setpower(struct lcd_dev_s *dev, int power) { /* Turn the display on */ - (void)SPI_SEND(priv->spi, SSD1306_DISPON); /* Display on, dim mode */ + (void)SPI_SEND(priv->spi, SSD1306_DISPON); priv->on = true; } @@ -1175,7 +1231,7 @@ void ssd1306_fill(FAR struct lcd_dev_s *dev, uint8_t color) SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true); /* Set the column address to the XOFFSET value */ - + SPI_SEND(priv->spi, SSD1306_SETCOLL(SSD1306_DEV_XOFFSET)); SPI_SEND(priv->spi, SSD1306_SETCOLH(0)); @@ -1189,8 +1245,8 @@ void ssd1306_fill(FAR struct lcd_dev_s *dev, uint8_t color) /* Transfer one page of the selected color */ - (void)SPI_SNDBLOCK(priv->spi, &priv->fb[page * SSD1306_DEV_XRES], - SSD1306_DEV_XRES); + (void)SPI_SNDBLOCK(priv->spi, &priv->fb[page * SSD1306_DEV_XRES], + SSD1306_DEV_XRES); } /* De-select and unlock the device */ diff --git a/nuttx/drivers/lcd/ug-2864ambag01.c b/nuttx/drivers/lcd/ug-2864ambag01.c index 6b3d6d5a8..993303b93 100644 --- a/nuttx/drivers/lcd/ug-2864ambag01.c +++ b/nuttx/drivers/lcd/ug-2864ambag01.c @@ -3,7 +3,7 @@ * Driver for Univision UG-2864AMBAG01 OLED display (wih SH1101A controller) in SPI * mode * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * References: @@ -153,8 +153,6 @@ # undef CONFIG_LCD_PORTRAIT # undef CONFIG_LCD_RLANDSCAPE # undef CONFIG_LCD_RPORTRAIT -#elif defined(CONFIG_LCD_RLANDSCAPE) -# warning "Reverse landscape mode is untested and, hence, probably buggy" #endif /* SH1101A Commands *******************************************************************/ @@ -247,6 +245,16 @@ #define UG2864AMBAG01_FBSIZE (UG2864AMBAG01_XSTRIDE * UG2864AMBAG01_YRES) #define UG2864AMBAG01_ROWSIZE (UG2864AMBAG01_XSTRIDE) +/* Orientation */ + +#if defined(CONFIG_LCD_LANDSCAPE) +# undef UG2864AMBAG01_DEV_REVERSEX +# undef UG2864AMBAG01_DEV_REVERSEY +#elif defined(CONFIG_LCD_RLANDSCAPE) +# define UG2864AMBAG01_DEV_REVERSEX 1 +# define UG2864AMBAG01_DEV_REVERSEY 1 +#endif + /* Bit helpers */ #define LS_BIT (1 << 0) @@ -539,11 +547,31 @@ static int ug2864ambag01_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_ return OK; } - /* Perform coordinate conversion for reverse landscape mode */ + /* Perform coordinate conversion for reverse landscape mode. + * If the rows are reversed then rows are are a mirror reflection of + * top to bottom. + */ -#ifdef CONFIG_LCD_RLANDSCAPE - row = (UG2864AMBAG01_YRES-1) - row; - col = (UG2864AMBAG01_XRES-1) - col; +#ifdef UG2864AMBAG01_DEV_REVERSEY + row = (UG2864AMBAG01_DEV_YRES-1) - row; +#endif + + /* If the column is switched then the start of the run is the mirror of + * the end of the run. + * + * col+pixlen-1 + * col | + * 0 | | XRES + * . S>>>>>>E . + * . E<<<<<<S . + * | | + * | `-(XRES-1)-col + * ` (XRES-1)-col-(pixlen-1) + */ + +#ifdef UG2864AMBAG01_DEV_REVERSEX + col = (UG2864AMBAG01_DEV_XRES-1) - col; + col -= (pixlen - 1); #endif /* Get the page number. The range of 64 lines is divided up into eight @@ -566,7 +594,7 @@ static int ug2864ambag01_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_ * D4 | | X | | | | | * D5 | | X | | | | | * D6 | | X | | | | | - * D7 | | X | | | | | + * D7 | | X | | | | | * --------+---+---+---+---+-...-+-----+ * * So, in order to draw a white, horizontal line, at row 45. we @@ -576,11 +604,12 @@ static int ug2864ambag01_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_ fbmask = 1 << (row & 7); fbptr = &priv->fb[page * UG2864AMBAG01_XRES + col]; -#ifdef CONFIG_LCD_RLANDSCAPE - ptr = fbptr + pixlen - 1; +#ifdef UG2864AMBAG01_DEV_REVERSEX + ptr = fbptr + (pixlen - 1); #else ptr = fbptr; #endif + #ifdef CONFIG_NX_PACKEDMSFIRST usrmask = MS_BIT; #else @@ -591,7 +620,7 @@ static int ug2864ambag01_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_ { /* Set or clear the corresponding bit */ -#ifdef CONFIG_LCD_RLANDSCAPE +#ifdef UG2864AMBAG01_DEV_REVERSEX if ((*buffer & usrmask) != 0) { *ptr-- |= fbmask; @@ -653,7 +682,7 @@ static int ug2864ambag01_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_ /* Set the starting position for the run */ /* Set the column address to the XOFFSET value */ - + SPI_SEND(priv->spi, SH1101A_SETCOLL(devcol & 0x0f)); SPI_SEND(priv->spi, SH1101A_SETCOLH(devcol >> 4)); @@ -683,7 +712,7 @@ static int ug2864ambag01_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_ * Name: ug2864ambag01_getrun * * Description: - * This method can be used to read a partial raster line from the LCD: + * This method can be used to read a partial raster line from the LCD. * * Description: * This method can be used to write a partial raster line to the LCD. @@ -698,7 +727,7 @@ static int ug2864ambag01_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_ #if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) static int ug2864ambag01_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels) + size_t npixels) { /* Because of this line of code, we will only be able to support a single UG device */ @@ -728,11 +757,30 @@ static int ug2864ambag01_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buf return -EINVAL; } - /* Perform coordinate conversion for reverse landscape mode */ + /* Perform coordinate conversion for reverse landscape mode. + * If the rows are reversed then rows are are a mirror reflection of + * top to bottom. + */ + +#ifdef UG2864AMBAG01_DEV_REVERSEY + row = (UG2864AMBAG01_DEV_YRES-1) - row; +#endif + + /* If the column is switched then the start of the run is the mirror of + * the end of the run. + * + * col+pixlen-1 + * col | + * 0 | | XRES + * . S>>>>>>E . + * . E<<<<<<S . + * | | + * | `-(XRES-1)-col + * ` (XRES-1)-col-(pixlen-1) + */ -#ifdef CONFIG_LCD_RLANDSCAPE - row = (UG2864AMBAG01_YRES-1) - row; - col = (UG2864AMBAG01_XRES-1) - col; +#ifdef UG2864AMBAG01_DEV_REVERSEX + col = (UG2864AMBAG01_DEV_XRES-1) - col; #endif /* Then transfer the display data from the shadow frame buffer memory */ @@ -756,7 +804,7 @@ static int ug2864ambag01_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buf * D4 | | X | | | | | * D5 | | X | | | | | * D6 | | X | | | | | - * D7 | | X | | | | | + * D7 | | X | | | | | * --------+---+---+---+---+-...-+-----+ * * So, in order to draw a white, horizontal line, at row 45. we @@ -765,11 +813,8 @@ static int ug2864ambag01_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buf */ fbmask = 1 << (row & 7); -#ifdef CONFIG_LCD_RLANDSCAPE - fbptr = &priv->fb[page * (UG2864AMBAG01_XRES-1) + col + pixlen]; -#else fbptr = &priv->fb[page * UG2864AMBAG01_XRES + col]; -#endif + #ifdef CONFIG_NX_PACKEDMSFIRST usrmask = MS_BIT; #else @@ -780,8 +825,8 @@ static int ug2864ambag01_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buf for (i = 0; i < pixlen; i++) { /* Set or clear the corresponding bit */ - -#ifdef CONFIG_LCD_RLANDSCAPE + +#ifdef UG2864AMBAG01_DEV_REVERSEX uint8_t byte = *fbptr--; #else uint8_t byte = *fbptr++; @@ -912,7 +957,7 @@ static int ug2864ambag01_setpower(struct lcd_dev_s *dev, int power) { /* Turn the display on */ - (void)SPI_SEND(priv->spi, SH1101A_DISPON); /* Display on, dim mode */ + (void)SPI_SEND(priv->spi, SH1101A_DISPON); priv->on = true; } @@ -1134,7 +1179,7 @@ void ug2864ambag01_fill(FAR struct lcd_dev_s *dev, uint8_t color) SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true); /* Set the column address to the XOFFSET value */ - + SPI_SEND(priv->spi, SH1101A_SETCOLL(UG2864AMBAG01_DEV_XOFFSET)); SPI_SEND(priv->spi, SH1101A_SETCOLH(0)); diff --git a/nuttx/drivers/lcd/ug-9664hswag01.c b/nuttx/drivers/lcd/ug-9664hswag01.c index 6ef78fca6..1d1e9194f 100644 --- a/nuttx/drivers/lcd/ug-9664hswag01.c +++ b/nuttx/drivers/lcd/ug-9664hswag01.c @@ -73,7 +73,7 @@ * CONFIG_UG9664HSWAG01_POWER * If the hardware supports a controllable OLED a power supply, this * configuration shold be defined. (See ug_power() below). - * + * * Required LCD driver settings: * CONFIG_LCD_UG9664HSWAG01 - Enable UG-9664HSWAG01 support * CONFIG_LCD_MAXCONTRAST should be 255, but any value >0 and <=255 will be accepted. @@ -113,6 +113,16 @@ # define CONFIG_UG9664HSWAG01_NINTERFACES 1 #endif +/* Orientation */ + +#if defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_RPORTRAIT) +# warning "No support for portrait modes" +# define CONFIG_LCD_LANDSCAPE 1 +# undef CONFIG_LCD_PORTRAIT +# undef CONFIG_LCD_RLANDSCAPE +# undef CONFIG_LCD_RPORTRAIT +#endif + /* Verbose debug must also be enabled to use the extra OLED debug */ #ifndef CONFIG_DEBUG @@ -171,8 +181,16 @@ /* Display Resolution */ -#define UG_XRES 96 -#define UG_YRES 64 +#define UG_LCD_XRES 96 +#define UG_LCD_YRES 64 + +#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) +# define UG_XRES UG_LCD_XRES +# define UG_YRES UG_LCD_YRES +#else +# define UG_XRES UG_LCD_YRES +# define UG_YRES UG_LCD_XRES +#endif /* Color depth and format */ @@ -188,6 +206,16 @@ #define UG_FBSIZE (UG_XRES * UG_YSTRIDE) +/* Orientation */ + +#if defined(CONFIG_LCD_LANDSCAPE) +# undef UG_LCD_REVERSEX +# undef UG_LCD_REVERSEY +#elif defined(CONFIG_LCD_RLANDSCAPE) +# define UG_LCD_REVERSEX 1 +# define UG_LCD_REVERSEY 1 +#endif + /* Bit helpers */ #define LS_BIT (1 << 0) @@ -307,7 +335,7 @@ static const struct fb_videoinfo_s g_videoinfo = /* This is the standard, NuttX Plane information object */ -static const struct lcd_planeinfo_s g_planeinfo = +static const struct lcd_planeinfo_s g_planeinfo = { .putrun = ug_putrun, /* Put a run into LCD memory */ .getrun = ug_getrun, /* Get a run from LCD memory */ @@ -317,12 +345,12 @@ static const struct lcd_planeinfo_s g_planeinfo = /* This is the standard, NuttX LCD driver object */ -static struct ug_dev_s g_ugdev = +static struct ug_dev_s g_ugdev = { .dev = { /* LCD Configuration */ - + .getvideoinfo = ug_getvideoinfo, .getplaneinfo = ug_getplaneinfo, @@ -496,6 +524,33 @@ static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, return OK; } + /* Perform coordinate conversion for reverse landscape mode. + * If the rows are reversed then rows are are a mirror reflection of + * top to bottom. + */ + +#ifdef UG_LCD_REVERSEY + row = (UG_YRES-1) - row; +#endif + + /* If the column is switched then the start of the run is the mirror of + * the end of the run. + * + * col+pixlen-1 + * col | + * 0 | | XRES + * . S>>>>>>E . + * . E<<<<<<S . + * | | + * | `-(XRES-1)-col + * ` (XRES-1)-col-(pixlen-1) + */ + +#ifdef UG_LCD_REVERSEX + col = (UG_XRES-1) - col; + col -= (pixlen - 1); +#endif + /* Get the page number. The range of 64 lines is divided up into eight * pages of 8 lines each. */ @@ -516,7 +571,7 @@ static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, * Bit 4 | | X | | | | | * Bit 5 | | X | | | | | * Bit 6 | | X | | | | | - * Bit 7 | | X | | | | | + * Bit 7 | | X | | | | | * --------+---+---+---+---+-...-+-----+ * * So, in order to draw a white, horizontal line, at row 45. we @@ -526,7 +581,12 @@ static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, fbmask = 1 << (row & 7); fbptr = &priv->fb[page * UG_XRES + col]; +#ifdef UG_LCD_REVERSEX + ptr = fbptr + (pixlen - 1); +#else ptr = fbptr; +#endif + #ifdef CONFIG_NX_PACKEDMSFIRST usrmask = MS_BIT; #else @@ -537,6 +597,16 @@ static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, { /* Set or clear the corresponding bit */ +#ifdef UG_LCD_REVERSEX + if ((*buffer & usrmask) != 0) + { + *ptr-- |= fbmask; + } + else + { + *ptr-- &= ~fbmask; + } +#else if ((*buffer & usrmask) != 0) { *ptr++ |= fbmask; @@ -545,6 +615,7 @@ static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, { *ptr++ &= ~fbmask; } +#endif /* Inc/Decrement to the next source pixel */ @@ -609,7 +680,7 @@ static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, * Name: ug_getrun * * Description: - * This method can be used to read a partial raster line from the LCD: + * 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) @@ -650,6 +721,32 @@ static int ug_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, return -EINVAL; } + /* Perform coordinate conversion for reverse landscape mode. + * If the rows are reversed then rows are are a mirror reflection of + * top to bottom. + */ + +#ifdef UG_LCD_REVERSEY + row = (UG_YRES-1) - row; +#endif + + /* If the column is switched then the start of the run is the mirror of + * the end of the run. + * + * col+pixlen-1 + * col | + * 0 | | XRES + * . S>>>>>>E . + * . E<<<<<<S . + * | | + * | `-(XRES-1)-col + * ` (XRES-1)-col-(pixlen-1) + */ + +#ifdef UG_LCD_REVERSEX + col = (UG_XRES-1) - col; +#endif + /* Then transfer the display data from the shadow frame buffer memory */ /* Get the page number. The range of 64 lines is divided up into eight * pages of 8 lines each. @@ -671,7 +768,7 @@ static int ug_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, * Bit 4 | | X | | | | | * Bit 5 | | X | | | | | * Bit 6 | | X | | | | | - * Bit 7 | | X | | | | | + * Bit 7 | | X | | | | | * --------+---+---+---+---+-...-+-----+ * * So, in order to draw a white, horizontal line, at row 45. we @@ -681,6 +778,7 @@ static int ug_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, fbmask = 1 << (row & 7); fbptr = &priv->fb[page * UG_XRES + col]; + #ifdef CONFIG_NX_PACKEDMSFIRST usrmask = MS_BIT; #else @@ -691,8 +789,13 @@ static int ug_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, for (i = 0; i < pixlen; i++) { /* Set or clear the corresponding bit */ - + +#ifdef UG_LCD_REVERSEX + uint8_t byte = *fbptr--; +#else uint8_t byte = *fbptr++; +#endif + if ((byte & fbmask) != 0) { *buffer |= usrmask; @@ -887,7 +990,7 @@ static int ug_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) (void)SPI_SEND(priv->spi, SSD1305_SETCONTRAST); /* Set contrast control register */ (void)SPI_SEND(priv->spi, contrast); /* Data 1: Set 1 of 256 contrast steps */ priv->contrast = contrast; - + /* Unlock and de-select the device */ ug_deselect(priv->spi); @@ -972,7 +1075,7 @@ static inline void up_clear(FAR struct ug_dev_s *priv) FAR struct lcd_dev_s *ug_initialize(FAR struct spi_dev_s *spi, unsigned int devno) { /* Configure and enable LCD */ - + FAR struct ug_dev_s *priv = &g_ugdev; gvdbg("Initializing\n"); |