diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-04-19 01:16:40 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-04-19 01:16:40 +0000 |
commit | 6307d71a343657595bac35731061dab9e9937c65 (patch) | |
tree | 662df13862b934cede2069055a7cf020eee794f4 /nuttx/drivers/lcd | |
parent | 02834f24e9ba0a19a0bd04cf345ea24e69553213 (diff) | |
download | px4-nuttx-6307d71a343657595bac35731061dab9e9937c65.tar.gz px4-nuttx-6307d71a343657595bac35731061dab9e9937c65.tar.bz2 px4-nuttx-6307d71a343657595bac35731061dab9e9937c65.zip |
Finish integration of the LPCXpresso OLED NX example
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3523 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/drivers/lcd')
-rwxr-xr-x | nuttx/drivers/lcd/ssd1305.h | 2 | ||||
-rwxr-xr-x | nuttx/drivers/lcd/ug-9664hswag01.c | 215 |
2 files changed, 149 insertions, 68 deletions
diff --git a/nuttx/drivers/lcd/ssd1305.h b/nuttx/drivers/lcd/ssd1305.h index 246ca63c5..87c955de4 100755 --- a/nuttx/drivers/lcd/ssd1305.h +++ b/nuttx/drivers/lcd/ssd1305.h @@ -118,7 +118,7 @@ # define SSD1305_SETBANK31(c) (c << 4) /* Data 4, Bits 4-5: Bank 31 color */
# define SSD1305_SETBANK32(c) (c << 6) /* Data 4, Bits 6-7: Bank 32 color */
#define SSD1305_MAPCOL0 0xa0 /* 0xa0: Column address 0 is mapped to SEG0 */
-#define SSD1305_MAPCOL131 0xa1 /* 0xa1: Column address 131 is mapped to SEG0*/
+#define SSD1305_MAPCOL131 0xa1 /* 0xa1: Column address 131 is mapped to SEG0 */
#define SSD1305_DISPRAM 0xa4 /* 0xa4: Resume to RAM content display */
#define SSD1305_DISPENTIRE 0xa5 /* 0xa5: Entire display ON */
#define SSD1305_DISPNORMAL 0xa6 /* 0xa6: Normal display */
diff --git a/nuttx/drivers/lcd/ug-9664hswag01.c b/nuttx/drivers/lcd/ug-9664hswag01.c index 0aecbabcf..b68aef3b8 100755 --- a/nuttx/drivers/lcd/ug-9664hswag01.c +++ b/nuttx/drivers/lcd/ug-9664hswag01.c @@ -92,13 +92,13 @@ */ #ifndef CONFIG_UG9664HSWAG01_SPIMODE -# define CONFIG_UG9664HSWAG01_SPIMODE SPIDEV_MODE2 +# define CONFIG_UG9664HSWAG01_SPIMODE SPIDEV_MODE0 #endif /* SPI frequency */ #ifndef CONFIG_UG9664HSWAG01_FREQUENCY -# define CONFIG_UG9664HSWAG01_FREQUENCY SPIDEV_MODE2 +# define CONFIG_UG9664HSWAG01_FREQUENCY 3500000 #endif /* CONFIG_UG9664HSWAG01_NINTERFACES determines the number of physical interfaces @@ -160,8 +160,8 @@ /* 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" +#ifdef CONFIG_NX_DISABLE_1BPP +# warning "1 bit-per-pixel support needed" #endif /* Color Properties *******************************************************************/ @@ -182,14 +182,19 @@ #define UG_BPP 1 #define UG_COLORFMT FB_FMT_Y1 -/* Bytes per visible and actual device row */ +/* Bytes per logical row andactual device row */ -#define UG_STRIDE (UG_XRES >> 3) -#define UG_DEV_STRIDE (UG_DEV_XRES >> 3) +#define UG_XSTRIDE (UG_XRES >> 3) /* Pixels arrange "horizontally for user" */ +#define UG_YSTRIDE (UG_YRES >> 3) /* But actual device arrangement is "vertical" */ /* The size of the shadow frame buffer */ -#define UG_FBSIZE (UG_STRIDE * UG_YRES) +#define UG_FBSIZE (UG_XRES * UG_YSTRIDE) + +/* Bit helpers */ + +#define LS_BIT (1 << 0) +#define MS_BIT (1 << 7) /* Debug ******************************************************************************/ @@ -291,7 +296,7 @@ static inline void up_clear(FAR struct ug_dev_s *priv); * if there are multiple LCD devices, they must each have unique run buffers. */ -static uint8_t g_runbuffer[UG_STRIDE]; +static uint8_t g_runbuffer[UG_XSTRIDE]; /* This structure describes the overall LCD video controller */ @@ -468,11 +473,11 @@ static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, FAR struct ug_dev_s *priv = &g_ugdev; FAR uint8_t *fbptr; + FAR uint8_t *ptr; uint8_t devcol; - uint8_t startcol; - uint8_t endcol; + uint8_t fbmask; uint8_t page; - uint8_t pixelno; + uint8_t usrmask; uint8_t i; int pixlen; @@ -494,45 +499,81 @@ static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, return OK; } - /* Update the shadow frame buffer memory */ + /* Get the page number. The range of 64 lines is divided up into eight + * pages of 8 lines each. + */ - fbptr = &priv->fb[row * UG_STRIDE]; - pixelno = 0; - endcol = col + pixlen; + page = row >> 3; - for (i = col; i < endcol; i++) - { - /* Point to the byte to be modified */ + /* Update the shadow frame buffer memory. First determine the pixel + * position in the frame buffer memory. Pixels are organized like + * this: + * + * --------+---+---+---+---+-...-+-----+ + * Segment | 0 | 1 | 2 | 3 | ... | 131 | + * --------+---+---+---+---+-...-+-----+ + * Bit 0 | | X | | | | | + * Bit 1 | | X | | | | | + * Bit 2 | | X | | | | | + * Bit 3 | | X | | | | | + * Bit 4 | | X | | | | | + * Bit 5 | | X | | | | | + * Bit 6 | | X | | | | | + * Bit 7 | | X | | | | | + * --------+---+---+---+---+-...-+-----+ + * + * So, in order to draw a white, horizontal line, at row 45. we + * would have to modify all of the bytes in page 45/8 = 5. We + * would have to set bit 45%8 = 5 in every byte in the page. + */ - FAR uint8_t *ptr = &fbptr[i >> 3]; + fbmask = 1 << (row & 7); + fbptr = &priv->fb[page * UG_XRES + col]; + ptr = fbptr; +#ifdef CONFIG_NX_PACKEDMSFIRST + usrmask = MS_BIT; +#else + usrmask = LS_BIT; +#endif + for (i = 0; i < pixlen; i++) + { /* Set or clear the corresponding bit */ - uint8_t mask = (1 << (i & 7)); - if ((*buffer & (1 << pixelno)) != 0) + if ((*buffer & usrmask) != 0) { - *ptr |= mask; + *ptr++ |= fbmask; } else { - *ptr &= ~mask; + *ptr++ &= ~fbmask; } - /* Increment to the next source pixel */ + /* Inc/Decrement to the next source pixel */ - if (++pixelno >= 8) +#ifdef CONFIG_NX_PACKEDMSFIRST + if (usrmask == LS_BIT) + { + buffer++; + usrmask = MS_BIT; + } + else + { + usrmask >>= 1; + } +#else + if (usrmask == MS_BIT) { buffer++; - pixelno = 0; + usrmask = LS_BIT; + } + else + { + usrmask <<= 1; } +#endif } - /* Get the page number. The range of 64 lines is divided up into eight - * pages or 8 lines each. - */ - - page = row >> 3; - /* Offset the column position to account for smaller horizontal * display range. */ @@ -559,9 +600,7 @@ static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, /* Then transfer all of the data */ - startcol = col >> 3; - endcol = (col + pixlen + 7) >> 3; - (void)SPI_SNDBLOCK(priv->spi, &fbptr[startcol], endcol - startcol + 1); + (void)SPI_SNDBLOCK(priv->spi, fbptr, pixlen); /* Unlock and de-select the device */ @@ -589,9 +628,10 @@ 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 *fbptr; - uint8_t endcol; - uint8_t pixelno; + FAR uint8_t *fbptr; + uint8_t page; + uint8_t fbmask; + uint8_t usrmask; uint8_t i; int pixlen; @@ -614,33 +654,77 @@ static int ug_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, } /* Then transfer the display data from the shadow frame buffer memory */ + /* Get the page number. The range of 64 lines is divided up into eight + * pages of 8 lines each. + */ - fbptr = &priv->fb[row * UG_STRIDE]; - pixelno = 0; - endcol = col + pixlen; - *buffer = 0; - - for (i = col; i < endcol; i++) - { - /* Point to the byte to be modified */ + page = row >> 3; - uint8_t *ptr = &fbptr[i >> 8]; + /* Update the shadow frame buffer memory. First determine the pixel + * position in the frame buffer memory. Pixels are organized like + * this: + * + * --------+---+---+---+---+-...-+-----+ + * Segment | 0 | 1 | 2 | 3 | ... | 131 | + * --------+---+---+---+---+-...-+-----+ + * Bit 0 | | X | | | | | + * Bit 1 | | X | | | | | + * Bit 2 | | X | | | | | + * Bit 3 | | X | | | | | + * Bit 4 | | X | | | | | + * Bit 5 | | X | | | | | + * Bit 6 | | X | | | | | + * Bit 7 | | X | | | | | + * --------+---+---+---+---+-...-+-----+ + * + * So, in order to draw a white, horizontal line, at row 45. we + * would have to modify all of the bytes in page 45/8 = 5. We + * would have to set bit 45%8 = 5 in every byte in the page. + */ - /* Set or clear the corresponding bit */ + fbmask = 1 << (row & 7); + fbptr = &priv->fb[page * UG_XRES + col]; +#ifdef CONFIG_NX_PACKEDMSFIRST + usrmask = MS_BIT; +#else + usrmask = LS_BIT; +#endif - if ((*ptr & (1 << (i & 7))) != 0) + *buffer = 0; + for (i = 0; i < pixlen; i++) + { + /* Set or clear the corresponding bit */ + + uint8_t byte = *fbptr++; + if ((byte & fbmask) != 0) { - *buffer |= (1 << pixelno); + *buffer |= usrmask; } - /* Increment to the next source pixel */ + /* Inc/Decrement to the next destination pixel */ - if (++pixelno >= 8) +#ifdef CONFIG_NX_PACKEDMSFIRST + if (usrmask == LS_BIT) { - pixelno = 0; buffer++; - *buffer = 0; + usrmask = MS_BIT; } + else + { + usrmask >>= 1; + } +#else + if (usrmask == MS_BIT) + { + buffer++; + *buffer = 0; + usrmask = LS_BIT; + } + else + { + usrmask <<= 1; + } +#endif } return OK; @@ -820,9 +904,8 @@ static int ug_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) static inline void up_clear(FAR struct ug_dev_s *priv) { FAR struct spi_dev_s *spi = priv->spi; - int row; + int page; int i; - int j; /* Clear the framebuffer */ @@ -834,7 +917,7 @@ static inline void up_clear(FAR struct ug_dev_s *priv) /* Go through all 8 pages */ - for (row = 0, i = 0; i < 8; i++) + for (page = 0, i = 0; i < 8; i++) { /* Select command transfer */ @@ -842,20 +925,17 @@ static inline void up_clear(FAR struct ug_dev_s *priv) /* Set the starting position for the run */ - (void)SPI_SEND(priv->spi, SSD1305_SETPAGESTART+i); /* Set the page start */ - (void)SPI_SEND(priv->spi, SSD1305_SETCOLL); /* Set the low column=0 */ - (void)SPI_SEND(priv->spi, SSD1305_SETCOLH); /* Set the high column=0 */ + (void)SPI_SEND(priv->spi, SSD1305_SETPAGESTART+i); + (void)SPI_SEND(priv->spi, SSD1305_SETCOLL + (UG_XOFFSET & 0x0f)); + (void)SPI_SEND(priv->spi, SSD1305_SETCOLH + (UG_XOFFSET >> 4)); /* Select data transfer */ SPI_CMDDATA(spi, SPIDEV_DISPLAY, false); - /* Then transfer all of the data */ + /* Then transfer all 96 columns of data */ - for (j = 0; j < 8; j++, row++) - { - (void)SPI_SNDBLOCK(priv->spi, &priv->fb[row * UG_STRIDE], UG_STRIDE); - } + (void)SPI_SNDBLOCK(priv->spi, &priv->fb[page * UG_XRES], UG_XRES); } /* Unlock and de-select the device */ @@ -918,7 +998,7 @@ FAR struct lcd_dev_s *ug_initialize(FAR struct spi_dev_s *spi, unsigned int devn (void)SPI_SEND(spi, SSD1305_SETCOLL + 2); /* Set low column address */ (void)SPI_SEND(spi, SSD1305_SETCOLH + 2); /* Set high column address */ (void)SPI_SEND(spi, SSD1305_SETSTARTLINE+0); /* Display start set */ - (void)SPI_SEND(spi, SSD1305_SCROLL_STOP); /* Stop horzontal scroll */ + (void)SPI_SEND(spi, SSD1305_SCROLL_STOP); /* Stop horizontal scroll */ (void)SPI_SEND(spi, SSD1305_SETCONTRAST); /* Set contrast control register */ (void)SPI_SEND(spi, 0x32); /* Data 1: Set 1 of 256 contrast steps */ (void)SPI_SEND(spi, SSD1305_SETBRIGHTNESS); /* Brightness for color bank */ @@ -941,6 +1021,7 @@ FAR struct lcd_dev_s *ug_initialize(FAR struct spi_dev_s *spi, unsigned int devn (void)SPI_SEND(spi, SSD1305_COLORMODE_MONO | SSD1305_POWERMODE_LOW); (void)SPI_SEND(spi, SSD1305_SETPRECHARGE); /* Set pre-charge period */ (void)SPI_SEND(spi, 15 << SSD1305_PHASE2_SHIFT | 1 << SSD1305_PHASE1_SHIFT); + (void)SPI_SEND(spi, SSD1305_SETCOMCONFIG); /* Set COM configuration */ (void)SPI_SEND(spi, SSD1305_COMCONFIG_ALT); /* Data 1, Bit 4: 1=Alternative COM pin configuration */ (void)SPI_SEND(spi, SSD1305_SETVCOMHDESEL); /* Set VCOMH deselect level */ (void)SPI_SEND(spi, SSD1305_VCOMH_x7p7); /* Data 1: ~0.77 x Vcc */ |