diff --git a/ChangeLog b/ChangeLog index 5bcbba4a08..185f9d8967 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5041,3 +5041,9 @@ (2013-6-23). * include/debug.h: Added macro DEBUGPANIC for forces crashes when debug is enabled. + * drivers/lcd/ssd1306.c: Driver now appears to be function for the + UG-2832HSWEG04 in landscape mode (2013-6-24). + * drivers/lcd/ug-2864ambag01.c and ug-9664hswag01.c: Add/updated + support for reverse portrait mode from lessons learned with the + UG-2832HSWEG04. Untested changes! (2013-6-24). + diff --git a/configs/sam4l-xplained/README.txt b/configs/sam4l-xplained/README.txt index 506d405866..01ee7d9963 100644 --- a/configs/sam4l-xplained/README.txt +++ b/configs/sam4l-xplained/README.txt @@ -786,7 +786,7 @@ Configuration sub-directories atest.txt nsh> cat /mnt/stuff/atest.txt This is a test - nsh> + nsh> 3. If the OLED1 module is connected to the SAM4L Xplained Pro, then support for the OLED display can be enabled by making the following @@ -804,6 +804,7 @@ Configuration sub-directories Device Drivers -> LCDs CONFIG_LCD=y : Enable LCD support CONFIG_LCD_MAXCONTRAST=255 : Maximum contrast value + CONFIG_LCD_LANDSCAPE=y : Landscape orientation (see below*) CONFIG_LCD_UG2832HSWEG04=y : Enable support for the OLED CONFIG_LCD_SSD1306_SPIMODE=0 : SPI Mode 0 CONFIG_LCD_SSD1306_SPIMODE=3500000 : Pick an SPI frequency @@ -814,34 +815,46 @@ Configuration sub-directories CONFIG_SAM4L_XPLAINED_OLED1MODULE_EXT2=y The NX graphics subsystem also needs to be configured: - + CONFIG_NX=y : Enable graphics support CONFIG_NX_LCDDRIVER=y : Using an LCD driver CONFIG_NX_NPLANES=1 : With a single color plane - CONFIG_NX_WRITEONLY=y : This is a write only LCD + CONFIG_NX_WRITEONLY=n : You can read from the LCD (see below**) CONFIG_NX_DISABLE_2BPP=y : Disable all resolutions except 1BPP CONFIG_NX_DISABLE_4BPP=y CONFIG_NX_DISABLE_8BPP=y CONFIG_NX_DISABLE_16BPP=y CONFIG_NX_DISABLE_24BPP=y CONFIG_NX_DISABLE_32BPP=y - CONFIG_NX_PACKEDMSFIRST=y + CONFIG_NX_PACKEDMSFIRST=y : LSB packed first (shouldn't matter) CONFIG_NXTK_BORDERWIDTH=2 : Use a small border CONFIG_NXTK_DEFAULT_BORDERCOLORS=y : Default border colors CONFIG_NXFONTS_CHARBITS=7 : 7-bit fonts CONFIG_NXFONT_SANS17X23B=y : Pick a font (any that will fit) + * This orientation will put the buttons "above" the LCD. The + reverse landscape configuration (CONFIG_LCD_RLANDSCAPE) should + "flip" the display so that the buttons are "below" the LCD. That + configuration, however, is untested. + + ** The hardware is write only, but the driver maintains a frame buffer + to support read and read-write-modiry operations on the LCD. + Then, in order to use the OLED, you will need to build some kind of graphics application or use one of the NuttX graphics examples. Here, for example, is the setup for the graphic "Hello, World!" example: CONFIG_EXAMPLES_NXHELLO=y : Enables the example - CONFIG_EXAMPLES_NXHELLO_DEFAULT_COLORS=y : Use default colors (monochrome) + CONFIG_EXAMPLES_NXHELLO_DEFAULT_COLORS=y : Use default colors (see below *) CONFIG_EXAMPLES_NXHELLO_DEFAULT_FONT=y : Use the default font CONFIG_EXAMPLES_NXHELLO_BPP=1 : One bit per pixel CONFIG_EXAMPLES_NXHELLO_EXTERNINIT=y : Special initialization is required. + * The OLED is monochrome so the only "colors" are blacka nd white. + The default "colors" will give you while text on a black background. + You can override the faults it you want black text on a while background. + 4. If the LCD1 module is connected to the SAM4L Xplained Pro, then support for the SLCDt can be enabled by making the following changes to the configuration: diff --git a/drivers/lcd/README.txt b/drivers/lcd/README.txt index 469e2f499e..d45f72b0e2 100644 --- a/drivers/lcd/README.txt +++ b/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/drivers/lcd/p14201.c b/drivers/lcd/p14201.c index 934d251ca9..c45292fed2 100644 --- a/drivers/lcd/p14201.c +++ b/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 diff --git a/drivers/lcd/ssd1306.c b/drivers/lcd/ssd1306.c index d9d80c7e2d..3fa7a34f66 100644 --- a/drivers/lcd/ssd1306.c +++ b/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<<<<<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<<<<<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/drivers/lcd/ug-2864ambag01.c b/drivers/lcd/ug-2864ambag01.c index 6b3d6d5a84..993303b937 100644 --- a/drivers/lcd/ug-2864ambag01.c +++ b/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 * * 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<<<<<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 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<<<<<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/drivers/lcd/ug-9664hswag01.c b/drivers/lcd/ug-9664hswag01.c index 6ef78fca6e..1d1e9194f1 100644 --- a/drivers/lcd/ug-9664hswag01.c +++ b/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<<<<<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<<<<<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");