diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-04-18 17:16:24 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-04-18 17:16:24 +0000 |
commit | 769fef9a363e9255551008548571c4ffdb9c9af0 (patch) | |
tree | cff6766eb78229ad6f0f1cc3022553ededcc44df /nuttx/drivers | |
parent | fe8341e08ecd746bcbbe3f61205a896670cccaac (diff) | |
download | px4-nuttx-769fef9a363e9255551008548571c4ffdb9c9af0.tar.gz px4-nuttx-769fef9a363e9255551008548571c4ffdb9c9af0.tar.bz2 px4-nuttx-769fef9a363e9255551008548571c4ffdb9c9af0.zip |
Add NX configuration for LPCXpresso
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3521 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/drivers')
-rwxr-xr-x | nuttx/drivers/lcd/Make.defs | 4 | ||||
-rwxr-xr-x | nuttx/drivers/lcd/skeleton.c | 2 | ||||
-rwxr-xr-x | nuttx/drivers/lcd/ssd1305.h | 2 | ||||
-rwxr-xr-x | nuttx/drivers/lcd/ug-9664hswag01.c | 265 |
4 files changed, 219 insertions, 54 deletions
diff --git a/nuttx/drivers/lcd/Make.defs b/nuttx/drivers/lcd/Make.defs index e93bc3188..5c9198a8f 100755 --- a/nuttx/drivers/lcd/Make.defs +++ b/nuttx/drivers/lcd/Make.defs @@ -48,8 +48,8 @@ ifeq ($(CONFIG_LCD_NOKIA6100),y) LCD_CSRCS = nokia6100.c endif -ifeq ($(CONFIG_LCD_UG9664HSWAG0),y) - LCD_CSRCS = ug-9664hswag0.c +ifeq ($(CONFIG_LCD_UG9664HSWAG01),y) + LCD_CSRCS = ug-9664hswag01.c endif endif diff --git a/nuttx/drivers/lcd/skeleton.c b/nuttx/drivers/lcd/skeleton.c index 02f868420..fd3152ff2 100755 --- a/nuttx/drivers/lcd/skeleton.c +++ b/nuttx/drivers/lcd/skeleton.c @@ -307,7 +307,7 @@ static int skel_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, * Name: skel_getpower * * Description: - * Get the LCD panel power status (0: full off - CONFIG_LCD_MAXPOWER: full on. On + * 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/nuttx/drivers/lcd/ssd1305.h b/nuttx/drivers/lcd/ssd1305.h index 8b2d13c5c..246ca63c5 100755 --- a/nuttx/drivers/lcd/ssd1305.h +++ b/nuttx/drivers/lcd/ssd1305.h @@ -100,7 +100,7 @@ # define SSD1305_SETBANK14(c) (c << 2) /* Data 4, Bits 2-3: Bank 14 color */
# define SSD1305_SETBANK15(c) (c << 4) /* Data 4, Bits 4-5: Bank 15 color */
# define SSD1305_SETBANK16(c) (c << 6) /* Data 4, Bits 6-7: Bank 16 color */
-#define SSD1305_SETBANKCOLOR1 0x93 /* 0x93: Set bank 17-32 color */
+#define SSD1305_SETBANKCOLOR2 0x93 /* 0x93: Set bank 17-32 color */
# define SSD1305_SETBANK17(c) (c) /* Data 1, Bits 0-1: Bank 17 color */
# define SSD1305_SETBANK18(c) (c << 2) /* Data 1, Bits 2-3: Bank 18 color */
# define SSD1305_SETBANK19(c) (c << 4) /* Data 1, Bits 4-5: Bank 19 color */
diff --git a/nuttx/drivers/lcd/ug-9664hswag01.c b/nuttx/drivers/lcd/ug-9664hswag01.c index 182e9b4c1..e3949d462 100755 --- a/nuttx/drivers/lcd/ug-9664hswag01.c +++ b/nuttx/drivers/lcd/ug-9664hswag01.c @@ -54,22 +54,68 @@ #include <nuttx/arch.h> #include <nuttx/spi.h> #include <nuttx/lcd/lcd.h> +#include <nuttx/lcd/ug-9664hswag01.h> -#include "up_arch.h" -#inclu;de "ssd1305.h" +#include "ssd1305.h" /************************************************************************************** * Pre-processor Definitions **************************************************************************************/ /* Configuration **********************************************************************/ +/* UG-9664HSWAG01 Configuration Settings: + * + * CONFIG_UG9664HSWAG01_SPIMODE - Controls the SPI mode + * CONFIG_UG9664HSWAG01_FREQUENCY - Define to use a different bus frequency + * CONFIG_UG9664HSWAG01_NINTERFACES - Specifies the number of physical + * UG-9664HSWAG01 devices that will be supported. NOTE: At present, this + * must be undefined or defined to be 1. + * CONFIG_UG9664HSWAG01_POWER + * If the hardware supports a controllable OLED a power supply, this + * configuration shold be defined. (See ug_power() below). + * CONFIG_LCD_UGDEBUG - Enable detailed UG-9664HSWAG01 debug output + * (CONFIG_DEBUG and CONFIG_VERBOSE must also be enabled). + * + * 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. + * CONFIG_LCD_MAXPOWER should be 2: 0=off, 1=dim, 2=normal + * + * Required SPI driver settings: + * CONFIG_SPI_CMDDATA - Include support for cmd/data selection. + */ + /* Verify that all configuration requirements have been met */ -/* Define the following to enable register-level debug output */ +/* The UG-9664HSWAG01 spec says that is supports SPI mode 0,0 only. However, somtimes + * you need to tinker with these things. + */ + +#ifndef CONFIG_UG9664HSWAG01_SPIMODE +# define CONFIG_UG9664HSWAG01_SPIMODE SPIDEV_MODE2 +#endif + +/* SPI frequency */ -#undef CONFIG_LCD_UGDEBUG +#ifndef CONFIG_UG9664HSWAG01_FREQUENCY +# define CONFIG_UG9664HSWAG01_FREQUENCY SPIDEV_MODE2 +#endif + +/* CONFIG_UG9664HSWAG01_NINTERFACES determines the number of physical interfaces + * that will be supported. + */ -/* Verbose debug must also be enabled */ +#ifndef CONFIG_UG9664HSWAG01_NINTERFACES +# define CONFIG_UG9664HSWAG01_NINTERFACES 1 +#endif + +#if CONFIG_UG9664HSWAG01_NINTERFACES != 1 +# warning "Only a single UG-9664HSWAG01 interface is supported" +# undef CONFIG_UG9664HSWAG01_NINTERFACES +# define CONFIG_UG9664HSWAG01_NINTERFACES 1 +#endif + +/* Verbose debug must also be enabled to use the extra OLED debug */ #ifndef CONFIG_DEBUG # undef CONFIG_DEBUG_VERBOSE @@ -80,6 +126,44 @@ # undef CONFIG_LCD_UGDEBUG #endif +/* Check contrast selection */ + +#ifndef CONFIG_LCD_MAXCONTRAST +# define CONFIG_LCD_MAXCONTRAST 255 +#endif + +#if CONFIG_LCD_MAXCONTRAST <= 0 || CONFIG_LCD_MAXCONTRAST > 255 +# error "CONFIG_LCD_MAXCONTRAST exceeds supported maximum" +#endif + +#if CONFIG_LCD_MAXCONTRAST < 255 +# warning "Optimal setting of CONFIG_LCD_MAXCONTRAST is 255" +#endif + +/* Check power setting */ + +#if !defined(CONFIG_LCD_MAXPOWER) +# define CONFIG_LCD_MAXPOWER 2 +#endif + +#if CONFIG_LCD_MAXPOWER != 2 +# warning "CONFIG_LCD_MAXPOWER should be 2" +# undef CONFIG_LCD_MAXPOWER +# define CONFIG_LCD_MAXPOWER 2 +#endif + +/* The OLED requires CMD/DATA SPI support */ + +#ifndef CONFIG_SPI_CMDDATA +# error "CONFIG_SPI_CMDDATA must be defined in your NuttX configuration" +#endif + +/* Color is 1bpp monochrome with leftmost column contained in bits 0 */ + +#if defined(CONFIG_NX_DISABLE_1BPP) || !defined(CONFIG_NX_PACKEDMSFIRST) +# warning "1-bit, big-endian pixel support needed" +#endif + /* Color Properties *******************************************************************/ /* The SSD1305 display controller can handle a resolution of 132x64. The OLED * on the base board is 96x64. @@ -131,6 +215,14 @@ struct ug_dev_s FAR struct spi_dev_s *spi; uint8_t contrast; + bool powered; + + /* The SSD1305 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 kee + * a shadow copy of the framebuffer memory. + */ + + uint8_t fb[UG_XRES >> 3][UG_YRES]; }; /************************************************************************************** @@ -201,13 +293,6 @@ static inline void up_clear(FAR struct ug_dev_s *priv); static uint8_t g_runbuffer[UG_XRES >> 8]; -/* The SSD1305 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 kee - * a shadow copy of the framebuffer memory. - */ - -static uint8_t g_ugfb[UG_XRES >> 3][UG_YRES]; - /* This structure describes the overall LCD video controller */ static const struct fb_videoinfo_s g_videoinfo = @@ -281,14 +366,14 @@ static inline void ug_select(FAR struct spi_dev_s *spi) #else static void ug_select(FAR struct spi_dev_s *spi) { - /* Select P14201 chip (locking the SPI bus in case there are multiple + /* Select UG-9664HSWAG01 chip (locking the SPI bus in case there are multiple * devices competing for the SPI bus */ SPI_LOCK(spi, true); SPI_SELECT(spi, SPIDEV_DISPLAY, true); - /* Now make sure that the SPI bus is configured for the P14201 (it + /* Now make sure that the SPI bus is configured for the UG-9664HSWAG01 (it * might have gotten configured for a different device while unlocked) */ @@ -326,7 +411,7 @@ static inline void ug_deselect(FAR struct spi_dev_s *spi) #else static void ug_deselect(FAR struct spi_dev_s *spi) { - /* De-select P14201 chip and relinquish the SPI bus. */ + /* De-select UG-9664HSWAG01 chip and relinquish the SPI bus. */ SPI_SELECT(spi, SPIDEV_DISPLAY, false); SPI_LOCK(spi, false); @@ -353,13 +438,12 @@ static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, /* Because of this line of code, we will only be able to support a single UG device */ FAR struct ug_dev_s *priv = &g_ugdev; - uint8_t *rowptr; + FAR uint8_t *fbptr; uint8_t devcol; uint8_t startcol; uint8_t endcol; - uint8_t addrlo; - uint8_t addrhi; uint8_t page; + uint8_t pixelno; uint8_t i; int pixlen; @@ -378,24 +462,25 @@ static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, if (pixlen <= 0 || row > UG_YRES) { - return; + return OK; } /* Update the shadow frame buffer memory */ - rowptr = &g_ugfb[0][row]; - endcol = col + pixlen; + fbptr = &priv->fb[0][row]; + pixelno = 0; + endcol = col + pixlen; for (i = col; i < endcol; i++) { /* Point to the byte to be modified */ - uint8_t *ptr = &rowptr[i >> 8]; + FAR uint8_t *ptr = &fbptr[i >> 8]; /* Set or clear the corresponding bit */ uint8_t mask = (1 << (i & 7)); - if (color > 0) + if ((*buffer & (1 << pixelno)) != 0) { *ptr |= mask; } @@ -403,6 +488,14 @@ static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, { *ptr &= ~mask; } + + /* Increment to the next source pixel */ + + if (++pixelno >= 8) + { + buffer++; + pixelno = 0; + } } /* Get the page number. The range of 64 lines is divided up into eight @@ -423,27 +516,27 @@ static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, /* Select command transfer */ - SPI_CMDDATA(spi, SPIDEV_DISPLAY, true); + SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true); /* Set the starting position for the run */ - (void)SPI_SEND(priv->spi, SSD1305_SETPAGESTART+page); /* Set the page start */ - (void)SPI_SEND(priv->spi, SSD1305_SETCOLL + (devcol & 0x0f); /* Set the low column */ - (void)SPI_SEND(priv->spi, SSD1305_SETCOLH + (devcol >> 4)); /* Set the high column */ + (void)SPI_SEND(priv->spi, SSD1305_SETPAGESTART+page); /* Set the page start */ + (void)SPI_SEND(priv->spi, SSD1305_SETCOLL + (devcol & 0x0f)); /* Set the low column */ + (void)SPI_SEND(priv->spi, SSD1305_SETCOLH + (devcol >> 4)); /* Set the high column */ /* Select data transfer */ - SPI_CMDDATA(spi, SPIDEV_DISPLAY, false); + SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, false); /* Then transfer all of the data */ startcol = col >> 3; endcol = (col + pixlen + 7) >> 3; - (void)SPI_SNDBLOCK(priv->spi, &rowptr[startcol], endcol - startcol + 1); + (void)SPI_SNDBLOCK(priv->spi, &fbptr[startcol], endcol - startcol + 1); /* Unlock and de-select the device */ - ug_deselect(spi); + ug_deselect(priv->spi); return OK; } @@ -467,7 +560,9 @@ static int ug_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, /* Because of this line of code, we will only be able to support a single UG device */ FAR struct ug_dev_s *priv = &g_ugdev; - uint8_t *rowptr; + uint8_t *fbptr; + uint8_t endcol; + uint8_t pixelno; uint8_t i; int pixlen; @@ -484,13 +579,38 @@ static int ug_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, /* Fetch the data from the shadow frame buffer memory */ - rowptr = &g_ugfb[0][row]; + fbptr = &priv->fb[0][row]; /* Then transfer all of the data */ - startcol = col >> 3; - endcol = (col + pixlen + 7) >> 3; - memcpy(buffer, &rowptr[startcol], endcol - startcol + 1); + fbptr = &priv->fb[0][row]; + pixelno = 0; + endcol = col + pixlen; + *buffer = 0; + + for (i = col; i < endcol; i++) + { + /* Point to the byte to be modified */ + + uint8_t *ptr = &fbptr[i >> 8]; + + /* Set or clear the corresponding bit */ + + if ((*ptr & (1 << (i & 7))) != 0) + { + *buffer |= (1 << pixelno); + } + + /* Increment to the next source pixel */ + + if (++pixelno >= 8) + { + pixelno = 0; + buffer++; + *buffer = 0; + } + } + return OK; } @@ -533,7 +653,7 @@ static int ug_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, * Name: ug_getpower * * Description: - * Get the LCD panel power status (0: full off - CONFIG_LCD_MAXPOWER: full on. On + * 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. * **************************************************************************************/ @@ -541,8 +661,9 @@ static int ug_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, static int ug_getpower(struct lcd_dev_s *dev) { struct ug_dev_s *priv = (struct ug_dev_s *)dev; - gvdbg("power: %d\n", 0); - return 0; + DEBUGASSERT(priv); + gvdbg("powered: %s\n", priv->powered ? "TRUE" : "FALSE"); + return priv->powered ? 1 : 0; } /************************************************************************************** @@ -558,10 +679,46 @@ static int ug_setpower(struct lcd_dev_s *dev, int power) { struct ug_dev_s *priv = (struct ug_dev_s *)dev; - gvdbg("power: %d\n", power); - DEBUGASSERT(power <= CONFIG_LCD_MAXPOWER); + gvdbg("power: %s powered: %s\n", + power != 0 ? "TRUE" : "FALSE", + priv->powered != 0 ? "TRUE" : "FALSE"); + + DEBUGASSERT(priv && (unsigned)power <= CONFIG_LCD_MAXPOWER); + + /* Select and lock the device */ + + ug_select(priv->spi); + if (power <= 0) + { + /* Turn the display off */ + + (void)SPI_SEND(priv->spi, SSD1305_DISPOFF); /* Display off */ - /* Set new power level */ + /* Remove power to the device */ + + ug_power(0, false); + priv->powered = false; + } + else + { + /* Turn the display on, dim or normal */ + + if (power == 1) + { + (void)SPI_SEND(priv->spi, SSD1305_DISPONDIM); /* Display on, dim mode */ + } + else /* if (power > 1) */ + { + (void)SPI_SEND(priv->spi, SSD1305_DISPON); /* Display on, normal mode */ + } + (void)SPI_SEND(priv->spi, SSD1305_DISPRAM); /* Resume to RAM content display */ + + /* Restore power to the device */ + + ug_power(0, true); + priv->powered = true; + } + ug_deselect(priv->spi); return OK; } @@ -578,7 +735,7 @@ static int ug_getcontrast(struct lcd_dev_s *dev) { struct ug_dev_s *priv = (struct ug_dev_s *)dev; DEBUGASSERT(priv); - return return (int)priv->contrast; + return (int)priv->contrast; } /************************************************************************************** @@ -607,7 +764,7 @@ static int ug_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) /* Select command transfer */ - SPI_CMDDATA(spi, SPIDEV_DISPLAY, true); + SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true); /* Set the contrast */ @@ -617,7 +774,7 @@ static int ug_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) /* Unlock and de-select the device */ - ug_deselect(spi); + ug_deselect(priv->spi); return OK; } @@ -638,7 +795,7 @@ static inline void up_clear(FAR struct ug_dev_s *priv) /* Clear the framebuffer */ - memset(g_ugfb, 0, UG_FBSIZE); + memset(priv->fb, UG_Y1_BLACK, UG_FBSIZE); /* Select and lock the device */ @@ -666,7 +823,7 @@ static inline void up_clear(FAR struct ug_dev_s *priv) for (j = 0; j < 8; j++, row++) { - (void)SPI_SNDBLOCK(priv->spi, &g_ugfb[0][row], UG_XRES >> 3); + (void)SPI_SNDBLOCK(priv->spi, &priv->fb[0][row], UG_XRES >> 3); } } @@ -689,19 +846,27 @@ static inline void up_clear(FAR struct ug_dev_s *priv) * **************************************************************************************/ -FAR struct lcd_dev_s *up_oledinitialize(FAR struct spi_dev_s *spi) +FAR struct lcd_dev_s *ug_initialize(FAR struct spi_dev_s *spi, unsigned int devno) { - gvdbg("Initializing\n"); - /* Configure and enable LCD */ FAR struct ug_dev_s *priv = &g_ugdev; - FAR struct spi_dev_s *spi = priv->spi; + + gvdbg("Initializing\n"); + DEBUGASSERT(spi && devno == 0); + + /* Save the reference to the SPI device */ + + priv->spi = spi; /* Select and lock the device */ ug_select(spi); + /* Make sure that the OLED off */ + + ug_power(0, false); + /* Select command transfer */ SPI_CMDDATA(spi, SPIDEV_DISPLAY, true); |