Fix UG-2832HSWEG04 landscape. Add reverse landscape support to UG_2864AMBAG01 and UG-9964HSWAG01. Fixe NXHELLO default colors for 1-bit mono modes

This commit is contained in:
Gregory Nutt
2013-06-24 12:37:02 -06:00
parent d971650440
commit 3d975e0a08
7 changed files with 323 additions and 84 deletions
+6
View File
@@ -5041,3 +5041,9 @@
(2013-6-23). (2013-6-23).
* include/debug.h: Added macro DEBUGPANIC for forces crashes when debug * include/debug.h: Added macro DEBUGPANIC for forces crashes when debug
is enabled. 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).
+18 -5
View File
@@ -786,7 +786,7 @@ Configuration sub-directories
atest.txt atest.txt
nsh> cat /mnt/stuff/atest.txt nsh> cat /mnt/stuff/atest.txt
This is a test This is a test
nsh> nsh>
3. If the OLED1 module is connected to the SAM4L Xplained Pro, then 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 support for the OLED display can be enabled by making the following
@@ -804,6 +804,7 @@ Configuration sub-directories
Device Drivers -> LCDs Device Drivers -> LCDs
CONFIG_LCD=y : Enable LCD support CONFIG_LCD=y : Enable LCD support
CONFIG_LCD_MAXCONTRAST=255 : Maximum contrast value 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_UG2832HSWEG04=y : Enable support for the OLED
CONFIG_LCD_SSD1306_SPIMODE=0 : SPI Mode 0 CONFIG_LCD_SSD1306_SPIMODE=0 : SPI Mode 0
CONFIG_LCD_SSD1306_SPIMODE=3500000 : Pick an SPI frequency CONFIG_LCD_SSD1306_SPIMODE=3500000 : Pick an SPI frequency
@@ -814,34 +815,46 @@ Configuration sub-directories
CONFIG_SAM4L_XPLAINED_OLED1MODULE_EXT2=y CONFIG_SAM4L_XPLAINED_OLED1MODULE_EXT2=y
The NX graphics subsystem also needs to be configured: The NX graphics subsystem also needs to be configured:
CONFIG_NX=y : Enable graphics support CONFIG_NX=y : Enable graphics support
CONFIG_NX_LCDDRIVER=y : Using an LCD driver CONFIG_NX_LCDDRIVER=y : Using an LCD driver
CONFIG_NX_NPLANES=1 : With a single color plane 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_2BPP=y : Disable all resolutions except 1BPP
CONFIG_NX_DISABLE_4BPP=y CONFIG_NX_DISABLE_4BPP=y
CONFIG_NX_DISABLE_8BPP=y CONFIG_NX_DISABLE_8BPP=y
CONFIG_NX_DISABLE_16BPP=y CONFIG_NX_DISABLE_16BPP=y
CONFIG_NX_DISABLE_24BPP=y CONFIG_NX_DISABLE_24BPP=y
CONFIG_NX_DISABLE_32BPP=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_BORDERWIDTH=2 : Use a small border
CONFIG_NXTK_DEFAULT_BORDERCOLORS=y : Default border colors CONFIG_NXTK_DEFAULT_BORDERCOLORS=y : Default border colors
CONFIG_NXFONTS_CHARBITS=7 : 7-bit fonts CONFIG_NXFONTS_CHARBITS=7 : 7-bit fonts
CONFIG_NXFONT_SANS17X23B=y : Pick a font (any that will fit) 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 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. graphics application or use one of the NuttX graphics examples.
Here, for example, is the setup for the graphic "Hello, World!" Here, for example, is the setup for the graphic "Hello, World!"
example: example:
CONFIG_EXAMPLES_NXHELLO=y : Enables the 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_DEFAULT_FONT=y : Use the default font
CONFIG_EXAMPLES_NXHELLO_BPP=1 : One bit per pixel CONFIG_EXAMPLES_NXHELLO_BPP=1 : One bit per pixel
CONFIG_EXAMPLES_NXHELLO_EXTERNINIT=y : Special initialization is required. 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 4. If the LCD1 module is connected to the SAM4L Xplained Pro, then
support for the SLCDt can be enabled by making the following support for the SLCDt can be enabled by making the following
changes to the configuration: changes to the configuration:
+28 -12
View File
@@ -81,7 +81,7 @@ Binding LCD Drivers
binding sequence is: binding sequence is:
1. Get an instance of struct lcd_dev_s from the hardware-specific LCD 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 2. Provide that instance to the initialization method of the higher
level device driver. level device driver.
@@ -90,6 +90,8 @@ Examples: /drivers/lcd/
Re-usable LCD drivers reside in the drivers/lcd directory: 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 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 Technology Co., Ltd. This LCD is based on the Himax HX8347-D LCD
controller. 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 nokia6100.c. Supports the Nokia 6100 display with either the Philips
PCF883 or the Epson S1D15G10 display controller. This LCD is used PCF883 or the Epson S1D15G10 display controller. This LCD is used
with the Olimex LPC1766-STK (but has not been fully integrated). 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 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 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 st7567.c. LCD Display Module, ST7567, Univision Technology Inc. Used
with the LPCXpresso and Embedded Artists base board. 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 ug-2864ambag01.c. OLED Display Module, UUG-2864AMBAG01, Univision
Technology Inc. See configs/stm32f4discovery and configs/zp214xp Technology Inc. Based on the SH1101A controller. Example usage:
for example usage.
configs/stm32f4discovery
configs/zp214xp
ug-9664hswag01.c. OLED Display Module, UG-9664HSWAG01, Univision ug-9664hswag01.c. OLED Display Module, UG-9664HSWAG01, Univision
Technology Inc. Used with the LPC Xpresso and Embedded Artists Technology Inc. Based on the SSD1305 controller. Used with the
base board. LPC Xpresso and Embedded Artists base board. Example usage:
configs/lpcxpresso-lpc1768
ssd1306.c. OLED Display Modules based on the SSD1306 controllers. ssd1306.c. OLED Display Modules based on the SSD1306 controllers.
This includes the UG-2864HSWEG01 and UG2832HSWEG04, Both from Univision This includes the UG-2864HSWEG01 and UG2832HSWEG04, Both from Univision
Technology Inc. The latter is used with the OLED1 module that comes 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/ Examples: configs/
================== ==================
@@ -146,7 +161,7 @@ that makes then less re-usable:
configs/shenzhou/src/up_ssd1289.c configs/shenzhou/src/up_ssd1289.c
kwikstik-k40: kwikstik-k40:
configs/kwikstik-k40/src/up_lcd.c. Don't waste your time. This is configs/kwikstik-k40/src/up_lcd.c. Don't waste your time. This is
just a stub. 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 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 LCD from Multi-Inno Technology Co., Ltd. This LCD is based on the Himax
HX8347-D LCD controller. HX8347-D LCD controller.
ILI93xx and Similar: ILI93xx and Similar:
configs/stm3210e-eval/src/up_lcd.c. This driver supports the following 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_ug2864ambag01.c
configs/stm32f4discovery/src/up_ug2864hsweg01.c configs/stm32f4discovery/src/up_ug2864hsweg01.c
configs/sam4l-xplained/src/up_ug2832hsweg04.c
configs/zp214xpa/src/up_ug2864ambag01.c configs/zp214xpa/src/up_ug2864ambag01.c
LCD controllers built-into the MCU: LCD controllers built-into the MCU:
+1 -1
View File
@@ -1,6 +1,6 @@
/************************************************************************************** /**************************************************************************************
* drivers/lcd/p14201.c * 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. * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
+83 -27
View File
@@ -158,13 +158,12 @@
#endif #endif
#if defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_RPORTRAIT) #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 # define CONFIG_LCD_LANDSCAPE 1
# undef CONFIG_LCD_PORTRAIT # undef CONFIG_LCD_PORTRAIT
# undef CONFIG_LCD_RLANDSCAPE # undef CONFIG_LCD_RLANDSCAPE
# undef CONFIG_LCD_RPORTRAIT # undef CONFIG_LCD_RPORTRAIT
#elif defined(CONFIG_LCD_RLANDSCAPE)
# warning "Reverse landscape mode is untested and, hence, probably buggy"
#endif #endif
/* SSD1306 Commands *******************************************************************/ /* SSD1306 Commands *******************************************************************/
@@ -274,6 +273,26 @@
#define SSD1306_DEV_FBSIZE (SSD1306_DEV_XSTRIDE * SSD1306_DEV_YRES) #define SSD1306_DEV_FBSIZE (SSD1306_DEV_XSTRIDE * SSD1306_DEV_YRES)
#define SSD1306_DEV_ROWSIZE (SSD1306_DEV_XSTRIDE) #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 */ /* Bit helpers */
#define LS_BIT (1 << 0) #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; 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; 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 #endif
/* Get the page number. The range of 64 lines is divided up into eight /* 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 | | | | | * D4 | | X | | | | |
* D5 | | X | | | | | * D5 | | X | | | | |
* D6 | | X | | | | | * D6 | | X | | | | |
* D7 | | X | | | | | * D7 | | X | | | | |
* --------+---+---+---+---+-...-+-----+ * --------+---+---+---+---+-...-+-----+
* *
* So, in order to draw a white, horizontal line, at row 45. we * 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); fbmask = 1 << (row & 7);
fbptr = &priv->fb[page * SSD1306_DEV_XRES + col]; fbptr = &priv->fb[page * SSD1306_DEV_XRES + col];
#ifdef CONFIG_LCD_RLANDSCAPE #ifdef SSD1306_DEV_REVERSEX
ptr = fbptr + pixlen - 1; ptr = fbptr + (pixlen - 1);
#else #else
ptr = fbptr; ptr = fbptr;
#endif #endif
#ifdef CONFIG_NX_PACKEDMSFIRST #ifdef CONFIG_NX_PACKEDMSFIRST
usrmask = MS_BIT; usrmask = MS_BIT;
#else #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 */ /* Set or clear the corresponding bit */
#ifdef CONFIG_LCD_RLANDSCAPE #ifdef SSD1306_DEV_REVERSEX
if ((*buffer & usrmask) != 0) if ((*buffer & usrmask) != 0)
{ {
*ptr-- |= fbmask; *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 starting position for the run */
/* Set the column address to the XOFFSET value */ /* Set the column address to the XOFFSET value */
SPI_SEND(priv->spi, SSD1306_SETCOLL(devcol & 0x0f)); SPI_SEND(priv->spi, SSD1306_SETCOLL(devcol & 0x0f));
SPI_SEND(priv->spi, SSD1306_SETCOLH(devcol >> 4)); 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 * Name: ssd1306_getrun
* *
* Description: * 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: * Description:
* This method can be used to write a partial raster line to the LCD. * 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; 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; 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 #endif
/* Then transfer the display data from the shadow frame buffer memory */ /* 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 | | | | | * D4 | | X | | | | |
* D5 | | X | | | | | * D5 | | X | | | | |
* D6 | | X | | | | | * D6 | | X | | | | |
* D7 | | X | | | | | * D7 | | X | | | | |
* --------+---+---+---+---+-...-+-----+ * --------+---+---+---+---+-...-+-----+
* *
* So, in order to draw a white, horizontal line, at row 45. we * 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); 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]; fbptr = &priv->fb[page * SSD1306_DEV_XRES + col];
#endif
#ifdef CONFIG_NX_PACKEDMSFIRST #ifdef CONFIG_NX_PACKEDMSFIRST
usrmask = MS_BIT; usrmask = MS_BIT;
#else #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++) for (i = 0; i < pixlen; i++)
{ {
/* Set or clear the corresponding bit */ /* Set or clear the corresponding bit */
#ifdef CONFIG_LCD_RLANDSCAPE #ifdef SSD1306_DEV_REVERSEX
uint8_t byte = *fbptr--; uint8_t byte = *fbptr--;
#else #else
uint8_t byte = *fbptr++; 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; struct ssd1306_dev_s *priv = (struct ssd1306_dev_s *)dev;
DEBUGASSERT(priv && (unsigned)power <= CONFIG_LCD_MAXPOWER && priv->spi); 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 */ /* 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; 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); SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true);
/* Set the column address to the XOFFSET value */ /* Set the column address to the XOFFSET value */
SPI_SEND(priv->spi, SSD1306_SETCOLL(SSD1306_DEV_XOFFSET)); SPI_SEND(priv->spi, SSD1306_SETCOLL(SSD1306_DEV_XOFFSET));
SPI_SEND(priv->spi, SSD1306_SETCOLH(0)); 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 */ /* Transfer one page of the selected color */
(void)SPI_SNDBLOCK(priv->spi, &priv->fb[page * SSD1306_DEV_XRES], (void)SPI_SNDBLOCK(priv->spi, &priv->fb[page * SSD1306_DEV_XRES],
SSD1306_DEV_XRES); SSD1306_DEV_XRES);
} }
/* De-select and unlock the device */ /* De-select and unlock the device */
+72 -27
View File
@@ -3,7 +3,7 @@
* Driver for Univision UG-2864AMBAG01 OLED display (wih SH1101A controller) in SPI * Driver for Univision UG-2864AMBAG01 OLED display (wih SH1101A controller) in SPI
* mode * mode
* *
* Copyright (C) 2012 Gregory Nutt. All rights reserved. * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* References: * References:
@@ -153,8 +153,6 @@
# undef CONFIG_LCD_PORTRAIT # undef CONFIG_LCD_PORTRAIT
# undef CONFIG_LCD_RLANDSCAPE # undef CONFIG_LCD_RLANDSCAPE
# undef CONFIG_LCD_RPORTRAIT # undef CONFIG_LCD_RPORTRAIT
#elif defined(CONFIG_LCD_RLANDSCAPE)
# warning "Reverse landscape mode is untested and, hence, probably buggy"
#endif #endif
/* SH1101A Commands *******************************************************************/ /* SH1101A Commands *******************************************************************/
@@ -247,6 +245,16 @@
#define UG2864AMBAG01_FBSIZE (UG2864AMBAG01_XSTRIDE * UG2864AMBAG01_YRES) #define UG2864AMBAG01_FBSIZE (UG2864AMBAG01_XSTRIDE * UG2864AMBAG01_YRES)
#define UG2864AMBAG01_ROWSIZE (UG2864AMBAG01_XSTRIDE) #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 */ /* Bit helpers */
#define LS_BIT (1 << 0) #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; 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 UG2864AMBAG01_DEV_REVERSEY
row = (UG2864AMBAG01_YRES-1) - row; row = (UG2864AMBAG01_DEV_YRES-1) - row;
col = (UG2864AMBAG01_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 UG2864AMBAG01_DEV_REVERSEX
col = (UG2864AMBAG01_DEV_XRES-1) - col;
col -= (pixlen - 1);
#endif #endif
/* Get the page number. The range of 64 lines is divided up into eight /* 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 | | | | | * D4 | | X | | | | |
* D5 | | X | | | | | * D5 | | X | | | | |
* D6 | | X | | | | | * D6 | | X | | | | |
* D7 | | X | | | | | * D7 | | X | | | | |
* --------+---+---+---+---+-...-+-----+ * --------+---+---+---+---+-...-+-----+
* *
* So, in order to draw a white, horizontal line, at row 45. we * 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); fbmask = 1 << (row & 7);
fbptr = &priv->fb[page * UG2864AMBAG01_XRES + col]; fbptr = &priv->fb[page * UG2864AMBAG01_XRES + col];
#ifdef CONFIG_LCD_RLANDSCAPE #ifdef UG2864AMBAG01_DEV_REVERSEX
ptr = fbptr + pixlen - 1; ptr = fbptr + (pixlen - 1);
#else #else
ptr = fbptr; ptr = fbptr;
#endif #endif
#ifdef CONFIG_NX_PACKEDMSFIRST #ifdef CONFIG_NX_PACKEDMSFIRST
usrmask = MS_BIT; usrmask = MS_BIT;
#else #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 */ /* Set or clear the corresponding bit */
#ifdef CONFIG_LCD_RLANDSCAPE #ifdef UG2864AMBAG01_DEV_REVERSEX
if ((*buffer & usrmask) != 0) if ((*buffer & usrmask) != 0)
{ {
*ptr-- |= fbmask; *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 starting position for the run */
/* Set the column address to the XOFFSET value */ /* Set the column address to the XOFFSET value */
SPI_SEND(priv->spi, SH1101A_SETCOLL(devcol & 0x0f)); SPI_SEND(priv->spi, SH1101A_SETCOLL(devcol & 0x0f));
SPI_SEND(priv->spi, SH1101A_SETCOLH(devcol >> 4)); 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 * Name: ug2864ambag01_getrun
* *
* Description: * 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: * Description:
* This method can be used to write a partial raster line to the LCD. * 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) #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, 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 */ /* 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; 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 UG2864AMBAG01_DEV_REVERSEY
row = (UG2864AMBAG01_YRES-1) - row; row = (UG2864AMBAG01_DEV_YRES-1) - row;
col = (UG2864AMBAG01_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 UG2864AMBAG01_DEV_REVERSEX
col = (UG2864AMBAG01_DEV_XRES-1) - col;
#endif #endif
/* Then transfer the display data from the shadow frame buffer memory */ /* 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 | | | | | * D4 | | X | | | | |
* D5 | | X | | | | | * D5 | | X | | | | |
* D6 | | X | | | | | * D6 | | X | | | | |
* D7 | | X | | | | | * D7 | | X | | | | |
* --------+---+---+---+---+-...-+-----+ * --------+---+---+---+---+-...-+-----+
* *
* So, in order to draw a white, horizontal line, at row 45. we * 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); 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]; fbptr = &priv->fb[page * UG2864AMBAG01_XRES + col];
#endif
#ifdef CONFIG_NX_PACKEDMSFIRST #ifdef CONFIG_NX_PACKEDMSFIRST
usrmask = MS_BIT; usrmask = MS_BIT;
#else #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++) for (i = 0; i < pixlen; i++)
{ {
/* Set or clear the corresponding bit */ /* Set or clear the corresponding bit */
#ifdef CONFIG_LCD_RLANDSCAPE #ifdef UG2864AMBAG01_DEV_REVERSEX
uint8_t byte = *fbptr--; uint8_t byte = *fbptr--;
#else #else
uint8_t byte = *fbptr++; uint8_t byte = *fbptr++;
@@ -912,7 +957,7 @@ static int ug2864ambag01_setpower(struct lcd_dev_s *dev, int power)
{ {
/* Turn the display on */ /* 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; 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); SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true);
/* Set the column address to the XOFFSET value */ /* Set the column address to the XOFFSET value */
SPI_SEND(priv->spi, SH1101A_SETCOLL(UG2864AMBAG01_DEV_XOFFSET)); SPI_SEND(priv->spi, SH1101A_SETCOLL(UG2864AMBAG01_DEV_XOFFSET));
SPI_SEND(priv->spi, SH1101A_SETCOLH(0)); SPI_SEND(priv->spi, SH1101A_SETCOLH(0));
+115 -12
View File
@@ -73,7 +73,7 @@
* CONFIG_UG9664HSWAG01_POWER * CONFIG_UG9664HSWAG01_POWER
* If the hardware supports a controllable OLED a power supply, this * If the hardware supports a controllable OLED a power supply, this
* configuration shold be defined. (See ug_power() below). * configuration shold be defined. (See ug_power() below).
* *
* Required LCD driver settings: * Required LCD driver settings:
* CONFIG_LCD_UG9664HSWAG01 - Enable UG-9664HSWAG01 support * CONFIG_LCD_UG9664HSWAG01 - Enable UG-9664HSWAG01 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.
@@ -113,6 +113,16 @@
# define CONFIG_UG9664HSWAG01_NINTERFACES 1 # define CONFIG_UG9664HSWAG01_NINTERFACES 1
#endif #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 */ /* Verbose debug must also be enabled to use the extra OLED debug */
#ifndef CONFIG_DEBUG #ifndef CONFIG_DEBUG
@@ -171,8 +181,16 @@
/* Display Resolution */ /* Display Resolution */
#define UG_XRES 96 #define UG_LCD_XRES 96
#define UG_YRES 64 #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 */ /* Color depth and format */
@@ -188,6 +206,16 @@
#define UG_FBSIZE (UG_XRES * UG_YSTRIDE) #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 */ /* Bit helpers */
#define LS_BIT (1 << 0) #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 */ /* 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 */ .putrun = ug_putrun, /* Put a run into LCD memory */
.getrun = ug_getrun, /* Get a run from 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 */ /* This is the standard, NuttX LCD driver object */
static struct ug_dev_s g_ugdev = static struct ug_dev_s g_ugdev =
{ {
.dev = .dev =
{ {
/* LCD Configuration */ /* LCD Configuration */
.getvideoinfo = ug_getvideoinfo, .getvideoinfo = ug_getvideoinfo,
.getplaneinfo = ug_getplaneinfo, .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; 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 /* Get the page number. The range of 64 lines is divided up into eight
* pages of 8 lines each. * 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 4 | | X | | | | |
* Bit 5 | | X | | | | | * Bit 5 | | X | | | | |
* Bit 6 | | X | | | | | * Bit 6 | | X | | | | |
* Bit 7 | | X | | | | | * Bit 7 | | X | | | | |
* --------+---+---+---+---+-...-+-----+ * --------+---+---+---+---+-...-+-----+
* *
* So, in order to draw a white, horizontal line, at row 45. we * 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); fbmask = 1 << (row & 7);
fbptr = &priv->fb[page * UG_XRES + col]; fbptr = &priv->fb[page * UG_XRES + col];
#ifdef UG_LCD_REVERSEX
ptr = fbptr + (pixlen - 1);
#else
ptr = fbptr; ptr = fbptr;
#endif
#ifdef CONFIG_NX_PACKEDMSFIRST #ifdef CONFIG_NX_PACKEDMSFIRST
usrmask = MS_BIT; usrmask = MS_BIT;
#else #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 */ /* Set or clear the corresponding bit */
#ifdef UG_LCD_REVERSEX
if ((*buffer & usrmask) != 0)
{
*ptr-- |= fbmask;
}
else
{
*ptr-- &= ~fbmask;
}
#else
if ((*buffer & usrmask) != 0) if ((*buffer & usrmask) != 0)
{ {
*ptr++ |= fbmask; *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; *ptr++ &= ~fbmask;
} }
#endif
/* Inc/Decrement to the next source pixel */ /* 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 * Name: ug_getrun
* *
* Description: * 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) * 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)
@@ -650,6 +721,32 @@ static int ug_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
return -EINVAL; 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 */ /* 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 /* Get the page number. The range of 64 lines is divided up into eight
* pages of 8 lines each. * 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 4 | | X | | | | |
* Bit 5 | | X | | | | | * Bit 5 | | X | | | | |
* Bit 6 | | X | | | | | * Bit 6 | | X | | | | |
* Bit 7 | | X | | | | | * Bit 7 | | X | | | | |
* --------+---+---+---+---+-...-+-----+ * --------+---+---+---+---+-...-+-----+
* *
* So, in order to draw a white, horizontal line, at row 45. we * 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); fbmask = 1 << (row & 7);
fbptr = &priv->fb[page * UG_XRES + col]; fbptr = &priv->fb[page * UG_XRES + col];
#ifdef CONFIG_NX_PACKEDMSFIRST #ifdef CONFIG_NX_PACKEDMSFIRST
usrmask = MS_BIT; usrmask = MS_BIT;
#else #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++) for (i = 0; i < pixlen; i++)
{ {
/* Set or clear the corresponding bit */ /* Set or clear the corresponding bit */
#ifdef UG_LCD_REVERSEX
uint8_t byte = *fbptr--;
#else
uint8_t byte = *fbptr++; uint8_t byte = *fbptr++;
#endif
if ((byte & fbmask) != 0) if ((byte & fbmask) != 0)
{ {
*buffer |= usrmask; *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, SSD1305_SETCONTRAST); /* Set contrast control register */
(void)SPI_SEND(priv->spi, contrast); /* Data 1: Set 1 of 256 contrast steps */ (void)SPI_SEND(priv->spi, contrast); /* Data 1: Set 1 of 256 contrast steps */
priv->contrast = contrast; priv->contrast = contrast;
/* Unlock and de-select the device */ /* Unlock and de-select the device */
ug_deselect(priv->spi); 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) FAR struct lcd_dev_s *ug_initialize(FAR struct spi_dev_s *spi, unsigned int devno)
{ {
/* Configure and enable LCD */ /* Configure and enable LCD */
FAR struct ug_dev_s *priv = &g_ugdev; FAR struct ug_dev_s *priv = &g_ugdev;
gvdbg("Initializing\n"); gvdbg("Initializing\n");