mirror of
https://github.com/apache/nuttx.git
synced 2026-06-05 15:58:59 +08:00
Fix color format when pixels are read from STM32 LCD
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3975 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -457,6 +457,9 @@ STM3210E-EVAL-specific Configuration Options
|
|||||||
CONFIG_LCD_BACKLIGHT - Define to support an adjustable backlight
|
CONFIG_LCD_BACKLIGHT - Define to support an adjustable backlight
|
||||||
using timer 1. The granularity of the settings is determined
|
using timer 1. The granularity of the settings is determined
|
||||||
by CONFIG_LCD_MAXPOWER. Requires CONFIG_STM32_TIM1.
|
by CONFIG_LCD_MAXPOWER. Requires CONFIG_STM32_TIM1.
|
||||||
|
CONFIG_LCD_RDSHIFT - When reading 16-bit gram data, there appears
|
||||||
|
to be a shift in the returned data. This value fixes the offset.
|
||||||
|
Default 5.
|
||||||
|
|
||||||
Configurations
|
Configurations
|
||||||
==============
|
==============
|
||||||
|
|||||||
@@ -121,6 +121,19 @@
|
|||||||
# error "PA8 cannot be configured as TIM1 CH1 with full remap"
|
# error "PA8 cannot be configured as TIM1 CH1 with full remap"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* When reading 16-bit gram data, there appears to be a 5-bit shift in the returned
|
||||||
|
* data.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONFIG_LCD_RDSHIFT
|
||||||
|
# define CONFIG_LCD_RDSHIFT 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Red and green appear to be swapped on read-back as well */
|
||||||
|
|
||||||
|
#undef CONFIG_LCD_RDSWAP
|
||||||
|
#define CONFIG_LCD_RDSWAP 1
|
||||||
|
|
||||||
/* Define CONFIG_DEBUG_LCD to enable detailed LCD debug output. Verbose debug must
|
/* Define CONFIG_DEBUG_LCD to enable detailed LCD debug output. Verbose debug must
|
||||||
* also be enabled.
|
* also be enabled.
|
||||||
*/
|
*/
|
||||||
@@ -317,7 +330,14 @@ static void stm3210e_writereg(uint8_t regaddr, uint16_t regval);
|
|||||||
static uint16_t stm3210e_readreg(uint8_t regaddr);
|
static uint16_t stm3210e_readreg(uint8_t regaddr);
|
||||||
static inline void stm3210e_gramselect(void);
|
static inline void stm3210e_gramselect(void);
|
||||||
static inline void stm3210e_writegram(uint16_t rgbval);
|
static inline void stm3210e_writegram(uint16_t rgbval);
|
||||||
static inline uint16_t stm3210e_readgram(void);
|
#if CONFIG_LCD_RDSHIFT > 0
|
||||||
|
static inline void stm3210e_readsetup(FAR uint16_t *accum);
|
||||||
|
static inline uint16_t stm3210e_readgram(FAR uint16_t *accum);
|
||||||
|
#else
|
||||||
|
static inline uint16_t stm3210e_readnoshift(void);
|
||||||
|
# define stm3210e_readsetup(a,n)
|
||||||
|
# define stm3210e_readgram(a,n) stm3210e_readnoshift()
|
||||||
|
#endif
|
||||||
static void stm3210e_setcursor(uint16_t col, uint16_t row);
|
static void stm3210e_setcursor(uint16_t col, uint16_t row);
|
||||||
|
|
||||||
/* LCD Data Transfer Methods */
|
/* LCD Data Transfer Methods */
|
||||||
@@ -486,20 +506,137 @@ static inline void stm3210e_writegram(uint16_t rgbval)
|
|||||||
LCD->value = rgbval;
|
LCD->value = rgbval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************************************
|
||||||
|
* Name: stm3210e_readsetup
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Prime the operation by reading one pixel from the GRAM memory
|
||||||
|
*
|
||||||
|
**************************************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_LCD_RDSHIFT > 0
|
||||||
|
static inline void stm3210e_readsetup(FAR uint16_t *accum)
|
||||||
|
{
|
||||||
|
/* Read the value (GRAM register already selected) */
|
||||||
|
|
||||||
|
*accum = LCD->value;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**************************************************************************************
|
/**************************************************************************************
|
||||||
* Name: stm3210e_readgram
|
* Name: stm3210e_readgram
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
|
* Read one correctly aligned pixel from the GRAM memory
|
||||||
|
*
|
||||||
|
**************************************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_LCD_RDSHIFT > 0
|
||||||
|
static inline uint16_t stm3210e_readgram(FAR uint16_t *accum)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_LCD_RDSWAP
|
||||||
|
uint16_t red;
|
||||||
|
uint16_t green;
|
||||||
|
uint16_t blue;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Read the value (GRAM register already selected) */
|
||||||
|
|
||||||
|
uint16_t next = LCD->value;
|
||||||
|
|
||||||
|
/* Return previous bits 0-10 as bits 6-15 and next data bits 11-15 as bits 0-5
|
||||||
|
*
|
||||||
|
* xxxx xPPP PPPP PPPP
|
||||||
|
* NNNN Nxxx xxxx xxxx
|
||||||
|
*
|
||||||
|
* Assuming that CONFIG_LCD_RDSHIFT == 5
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint16_t value = *accum << CONFIG_LCD_RDSHIFT | next >> (16-CONFIG_LCD_RDSHIFT);
|
||||||
|
|
||||||
|
/* Save the value for the next time we are called */
|
||||||
|
|
||||||
|
*accum = next;
|
||||||
|
|
||||||
|
/* Tear the RGB655 apart. Swap read and green */
|
||||||
|
|
||||||
|
#ifdef CONFIG_LCD_RDSWAP
|
||||||
|
red = (value << (11-5)) & 0xf800; /* Move bits 5-9 to 11-15 */
|
||||||
|
green = (value >> (10-5)) & 0x07e0; /* Move bits 10-15 to bits 5-10 */
|
||||||
|
blue = value & 0x001f; /* Blue is in the right place */
|
||||||
|
|
||||||
|
/* And put the RGB565 back together */
|
||||||
|
|
||||||
|
value = red | green | blue;
|
||||||
|
|
||||||
|
/* This is wierd... If blue is zero, then red+green values are off by 0x20.
|
||||||
|
* Except that both 0x0000 and 0x0020 can map to 0x0000. Need to revisit
|
||||||
|
* this!!!!!!!!!!! I might be misinterpreting some of the data that I have.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 0 /* REVISIT */
|
||||||
|
if (value != 0 && blue == 0)
|
||||||
|
{
|
||||||
|
value += 0x20;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**************************************************************************************
|
||||||
|
* Name: stm3210e_readnoshift
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
* Read one pixel from the GRAM memory
|
* Read one pixel from the GRAM memory
|
||||||
*
|
*
|
||||||
**************************************************************************************/
|
**************************************************************************************/
|
||||||
|
|
||||||
static inline uint16_t stm3210e_readgram(void)
|
#if CONFIG_LCD_RDSHIFT <= 0
|
||||||
|
static inline uint16_t stm3210e_readnoshift(void)
|
||||||
{
|
{
|
||||||
/* Write the value (GRAM register already selected) */
|
#ifdef CONFIG_LCD_RDSWAP
|
||||||
|
uint16_t value;
|
||||||
|
uint16_t red;
|
||||||
|
uint16_t green;
|
||||||
|
uint16_t blue;
|
||||||
|
|
||||||
|
/* Read the value (GRAM register already selected) */
|
||||||
|
|
||||||
|
value = LCD->value;
|
||||||
|
|
||||||
|
/* Tear the RGB655 apart. Swap read and green */
|
||||||
|
|
||||||
|
red = (value << (11-5)) & 0xf800; /* Move bits 5-9 to 11-15 */
|
||||||
|
green = (value >> (10-5)) & 0x07e0; /* Move bits 10-15 to bits 5-10 */
|
||||||
|
blue = value & 0x001f; /* Blue is in the right place */
|
||||||
|
|
||||||
|
/* And put the RGB565 back together */
|
||||||
|
|
||||||
|
value = red | green | blue;
|
||||||
|
|
||||||
|
/* This is wierd... If blue is zero, then red+green values are off by 0x20.
|
||||||
|
* Except that both 0x0000 and 0x0020 can map to 0x0000. Need to revisit
|
||||||
|
* this!!!!!!!!!!! I might be misinterpreting some of the data that I have.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 0 /* REVISIT */
|
||||||
|
if (value != 0 && blue == 0)
|
||||||
|
{
|
||||||
|
value += 0x20;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return value;
|
||||||
|
#else
|
||||||
|
/* Read the value (GRAM register already selected) */
|
||||||
|
|
||||||
return LCD->value;
|
return LCD->value;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**************************************************************************************
|
/**************************************************************************************
|
||||||
* Name: stm3210e_setcursor
|
* Name: stm3210e_setcursor
|
||||||
@@ -654,6 +791,9 @@ static int stm3210e_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
|
|||||||
size_t npixels)
|
size_t npixels)
|
||||||
{
|
{
|
||||||
FAR uint16_t *dest = (FAR uint16_t*)buffer;
|
FAR uint16_t *dest = (FAR uint16_t*)buffer;
|
||||||
|
#if CONFIG_LCD_RDSHIFT > 0
|
||||||
|
uint16_t accum;
|
||||||
|
#endif
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Buffer must be provided and aligned to a 16-bit address boundary */
|
/* Buffer must be provided and aligned to a 16-bit address boundary */
|
||||||
@@ -677,11 +817,16 @@ static int stm3210e_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
|
|||||||
/* Then read the GRAM data, auto-decrementing Y */
|
/* Then read the GRAM data, auto-decrementing Y */
|
||||||
|
|
||||||
stm3210e_gramselect();
|
stm3210e_gramselect();
|
||||||
|
|
||||||
|
/* Prime the pump for unaligned read data */
|
||||||
|
|
||||||
|
stm3210e_readsetup(&accum);
|
||||||
|
|
||||||
for (i = 0; i < npixels; i++)
|
for (i = 0; i < npixels; i++)
|
||||||
{
|
{
|
||||||
/* Read the next pixel from this position (autoincrements to the next row) */
|
/* Read the next pixel from this position (autoincrements to the next row) */
|
||||||
|
|
||||||
*dest++ = stm3210e_readgram();
|
*dest++ = stm3210e_readgram(&accum);
|
||||||
}
|
}
|
||||||
#elif defined(CONFIG_LCD_PORTRAIT)
|
#elif defined(CONFIG_LCD_PORTRAIT)
|
||||||
/* Convert coordinates (Swap row and column. This is done implicitly). */
|
/* Convert coordinates (Swap row and column. This is done implicitly). */
|
||||||
@@ -694,7 +839,8 @@ static int stm3210e_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
|
|||||||
|
|
||||||
stm3210e_setcursor(row, col);
|
stm3210e_setcursor(row, col);
|
||||||
stm3210e_gramselect();
|
stm3210e_gramselect();
|
||||||
*dest++ = stm3210e_readgram();
|
stm3210e_readsetup(&accum);
|
||||||
|
*dest++ = stm3210e_readgram(&accum);
|
||||||
|
|
||||||
/* Increment to next column */
|
/* Increment to next column */
|
||||||
|
|
||||||
@@ -716,7 +862,8 @@ static int stm3210e_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
|
|||||||
|
|
||||||
stm3210e_setcursor(row, col);
|
stm3210e_setcursor(row, col);
|
||||||
stm3210e_gramselect();
|
stm3210e_gramselect();
|
||||||
*dest++ = stm3210e_readgram();
|
stm3210e_readsetup(&accum);
|
||||||
|
*dest++ = stm3210e_readgram(&accum);
|
||||||
|
|
||||||
/* Decrement to next column */
|
/* Decrement to next column */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user