summaryrefslogtreecommitdiff
path: root/nuttx/configs/stm3210e-eval
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-10-07 17:21:16 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-10-07 17:21:16 +0000
commit3ae6dd3bf850269d0b55c842d463d028071cd496 (patch)
tree4e08a9a8fb1c16df0a2de35e3e53d0f71e5c6d40 /nuttx/configs/stm3210e-eval
parent7481e9b333eab4e325898f8b5f0f9423f315bd18 (diff)
downloadpx4-nuttx-3ae6dd3bf850269d0b55c842d463d028071cd496.tar.gz
px4-nuttx-3ae6dd3bf850269d0b55c842d463d028071cd496.tar.bz2
px4-nuttx-3ae6dd3bf850269d0b55c842d463d028071cd496.zip
Fix STM32 build with with no RTC; Fix STM3210E-EVAL color correction for the RenesasSP LCD
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4030 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/configs/stm3210e-eval')
-rw-r--r--nuttx/configs/stm3210e-eval/src/up_lcd.c241
1 files changed, 149 insertions, 92 deletions
diff --git a/nuttx/configs/stm3210e-eval/src/up_lcd.c b/nuttx/configs/stm3210e-eval/src/up_lcd.c
index 6ce37f390..ebe478a86 100644
--- a/nuttx/configs/stm3210e-eval/src/up_lcd.c
+++ b/nuttx/configs/stm3210e-eval/src/up_lcd.c
@@ -39,7 +39,15 @@
* 2. Orise Tech SPFD5408B
* 3. RenesasSP R61580
*
- * The driver dynamically selects the LCD based on the reported LCD ID value.
+ * The driver dynamically selects the LCD based on the reported LCD ID value. However,
+ * code size can be reduced by suppressing support for individual LCDs using:
+ *
+ * CONFIG_STM32_AM240320_DISABLE
+ * CONFIG_STM32_SPFD5408B_DISABLE
+ * CONFIG_STM32_R61580_DISABLE
+ *
+ * Omitting the above (or setting them to "n") enables support for the LCD. Setting
+ * any of the above to "y" will disable support for the corresponding LCD.
*/
/**************************************************************************************
@@ -69,7 +77,6 @@
/**************************************************************************************
* Pre-processor Definitions
**************************************************************************************/
-
/* Configuration **********************************************************************/
/* Check contrast selection */
@@ -121,18 +128,16 @@
# error "PA8 cannot be configured as TIM1 CH1 with full remap"
#endif
-/* When reading 16-bit gram data, there appears to be a 5-bit shift in the returned
- * data.
+/* When reading 16-bit gram data, there may some shifts in the returned data
+ * and/or there may be some colors in the incorrect posisions:
+ *
+ * - SPFD5408B: There appears to be a 5-bit shift in the returned data.
+ * Red and green appear to be swapped on read-back as well
+ * - R61580: There is a 16-bit (1 pixel) shift in the returned data.
+ * - AM240320: Unknown -- assume colors are correct for now.
*/
-#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 SPFD5408B_RDSHIFT 5
/* Define CONFIG_DEBUG_LCD to enable detailed LCD debug output. Verbose debug must
* also be enabled.
@@ -299,6 +304,16 @@
* Private Type Definition
**************************************************************************************/
+/* LCD type */
+
+enum lcd_type_e
+{
+ LCD_TYPE_UNKNOWN = 0,
+ LCD_TYPE_SPFD5408B,
+ LCD_TYPE_R61580,
+ LCD_TYPE_AM240320
+};
+
/* This structure describes the LCD registers */
struct lcd_regs_s
@@ -317,7 +332,7 @@ struct stm3210e_dev_s
/* Private LCD-specific information follows */
- bool spfd5408b; /* TRUE: LCD is SPFD5408B Controller */
+ uint8_t type; /* LCD type. See enum lcd_type_e */
uint8_t power; /* Current power setting */
};
@@ -330,14 +345,10 @@ static void stm3210e_writereg(uint8_t regaddr, uint16_t regval);
static uint16_t stm3210e_readreg(uint8_t regaddr);
static inline void stm3210e_gramselect(void);
static inline void stm3210e_writegram(uint16_t rgbval);
-#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_readsetup(FAR uint16_t *accum);
+static void stm3210e_readnosetup(FAR uint16_t *accum);
+static uint16_t stm3210e_readshift(FAR uint16_t *accum);
+static uint16_t stm3210e_readnoshift(FAR uint16_t *accum);
static void stm3210e_setcursor(uint16_t col, uint16_t row);
/* LCD Data Transfer Methods */
@@ -507,38 +518,63 @@ static inline void stm3210e_writegram(uint16_t rgbval)
}
/**************************************************************************************
- * Name: stm3210e_readsetup
+ * Name: stm3210e_readsetup / stm3210e_readnosetup
*
* Description:
- * Prime the operation by reading one pixel from the GRAM memory
+ * Prime the operation by reading one pixel from the GRAM memory if necessary for
+ * this LCD type. When reading 16-bit gram data, there may be some shifts in the
+ * returned data:
+ *
+ * - SPFD5408B: There appears to be a 5-bit shift in the returned data.
+ * - R61580: There is a 16-bit (1 pixel) shift in the returned data.
+ * - AM240320: Unknown -- assuming no shift in the return data
*
**************************************************************************************/
-#if CONFIG_LCD_RDSHIFT > 0
-static inline void stm3210e_readsetup(FAR uint16_t *accum)
+/* Used for SPFD5408B and R61580 */
+
+#if !defined(CONFIG_STM32_SPFD5408B_DISABLE) || !defined(CONFIG_STM32_R61580_DISABLE)
+static void stm3210e_readsetup(FAR uint16_t *accum)
{
- /* Read the value (GRAM register already selected) */
+ /* Read-ahead one pixel */
*accum = LCD->value;
}
#endif
+/* Used only for AM240320 */
+
+#ifndef CONFIG_STM32_AM240320_DISABLE
+static void stm3210e_readnosetup(FAR uint16_t *accum)
+{
+}
+#endif
+
/**************************************************************************************
- * Name: stm3210e_readgram
+ * Name: stm3210e_readshift / stm3210e_readnoshift
*
* Description:
- * Read one correctly aligned pixel from the GRAM memory
+ * Read one correctly aligned pixel from the GRAM memory. Possibly shifting the
+ * data and possibly swapping red and green components.
+ *
+ * - SPFD5408B: There appears to be a 5-bit shift in the returned data.
+ * Red and green appear to be swapped on read-back as well
+ * - R61580: There is a 16-bit (1 pixel) shift in the returned data.
+ * All colors in the normal order
+ * - AM240320: Unknown -- assuming colors are in the color order
*
**************************************************************************************/
-#if CONFIG_LCD_RDSHIFT > 0
-static inline uint16_t stm3210e_readgram(FAR uint16_t *accum)
+/* This version is used only for the SPFD5408B. It shifts the data by 5-bits and swaps
+ * red and green
+ */
+
+#ifndef CONFIG_STM32_SPFD5408B_DISABLE
+static uint16_t stm3210e_readshift(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) */
@@ -549,10 +585,10 @@ static inline uint16_t stm3210e_readgram(FAR uint16_t *accum)
* xxxx xPPP PPPP PPPP
* NNNN Nxxx xxxx xxxx
*
- * Assuming that CONFIG_LCD_RDSHIFT == 5
+ * Assuming that SPFD5408B_RDSHIFT == 5
*/
- uint16_t value = *accum << CONFIG_LCD_RDSHIFT | next >> (16-CONFIG_LCD_RDSHIFT);
+ uint16_t value = *accum << SPFD5408B_RDSHIFT | next >> (16-SPFD5408B_RDSHIFT);
/* Save the value for the next time we are called */
@@ -560,7 +596,6 @@ static inline uint16_t stm3210e_readgram(FAR uint16_t *accum)
/* 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 */
@@ -580,61 +615,21 @@ static inline uint16_t stm3210e_readgram(FAR uint16_t *accum)
value += 0x20;
}
#endif
-#endif
return value;
}
#endif
-/**************************************************************************************
- * Name: stm3210e_readnoshift
- *
- * Description:
- * Read one pixel from the GRAM memory
- *
- **************************************************************************************/
+/* This version is used for the R61580 and for the AM240320. It neither shifts nor
+ * swaps colors.
+ */
-#if CONFIG_LCD_RDSHIFT <= 0
-static inline uint16_t stm3210e_readnoshift(void)
+#if !defined(CONFIG_STM32_R61580_DISABLE) || !defined(CONFIG_STM32_AM240320_DISABLE)
+static uint16_t stm3210e_readnoshift(FAR uint16_t *accum)
{
-#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;
-#endif
}
#endif
@@ -791,9 +786,9 @@ static int stm3210e_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
size_t npixels)
{
FAR uint16_t *dest = (FAR uint16_t*)buffer;
-#if CONFIG_LCD_RDSHIFT > 0
+ void (*readsetup)(FAR uint16_t *accum);
+ uint16_t (*readgram)(FAR uint16_t *accum);
uint16_t accum;
-#endif
int i;
/* Buffer must be provided and aligned to a 16-bit address boundary */
@@ -801,6 +796,35 @@ static int stm3210e_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
lcddbg("row: %d col: %d npixels: %d\n", row, col, npixels);
DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
+ /* Configure according to the LCD type */
+
+ switch (g_lcddev.type)
+ {
+#ifndef CONFIG_STM32_SPFD5408B_DISABLE
+ case LCD_TYPE_SPFD5408B:
+ readsetup = stm3210e_readsetup;
+ readgram = stm3210e_readshift;
+ break;
+#endif
+
+#ifndef CONFIG_STM32_R61580_DISABLE
+ case LCD_TYPE_R61580:
+ readsetup = stm3210e_readsetup;
+ readgram = stm3210e_readnoshift;
+ break;
+#endif
+
+#ifndef CONFIG_STM32_AM240320_DISABLE
+ case LCD_TYPE_AM240320:
+ readsetup = stm3210e_readnosetup;
+ readgram = stm3210e_readnoshift;
+ break;
+#endif
+
+ default: /* Shouldn't happen */
+ return -ENOSYS;
+ }
+
/* Read the run from GRAM. */
#ifdef CONFIG_LCD_LANDSCAPE
@@ -820,13 +844,13 @@ static int stm3210e_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
/* Prime the pump for unaligned read data */
- stm3210e_readsetup(&accum);
+ readsetup(&accum);
for (i = 0; i < npixels; i++)
{
/* Read the next pixel from this position (autoincrements to the next row) */
- *dest++ = stm3210e_readgram(&accum);
+ *dest++ = readgram(&accum);
}
#elif defined(CONFIG_LCD_PORTRAIT)
/* Convert coordinates (Swap row and column. This is done implicitly). */
@@ -839,8 +863,8 @@ static int stm3210e_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
stm3210e_setcursor(row, col);
stm3210e_gramselect();
- stm3210e_readsetup(&accum);
- *dest++ = stm3210e_readgram(&accum);
+ readsetup(&accum);
+ *dest++ = readgram(&accum);
/* Increment to next column */
@@ -862,8 +886,8 @@ static int stm3210e_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
stm3210e_setcursor(row, col);
stm3210e_gramselect();
- stm3210e_readsetup(&accum);
- *dest++ = stm3210e_readgram(&accum);
+ readsetup(&accum);
+ *dest++ = readgram(&accum);
/* Decrement to next column */
@@ -959,7 +983,15 @@ static int stm3210e_setpower(struct lcd_dev_s *dev, int power)
#endif
/* Then turn the display on */
- stm3210e_writereg(LCD_REG_7, g_lcddev.spfd5408b ? 0x0112 : 0x0173);
+#ifndef CONFIG_STM32_AM240320_DISABLE
+# if !defined (CONFIG_STM32_SPFD5408B_DISABLE) || !defined(CONFIG_STM32_R61580_DISABLE)
+ stm3210e_writereg(LCD_REG_7, g_lcddev.type == LCD_TYPE_AM240320 ? 0x0173 : 0x0112);
+# else
+ stm3210e_writereg(LCD_REG_7, 0x0173);
+# endif
+#else
+ stm3210e_writereg(LCD_REG_7, 0x0112);
+#endif
g_lcddev.power = power;
}
else
@@ -1016,11 +1048,30 @@ static inline void stm3210e_lcdinitialize(void)
*/
id = stm3210e_readreg(LCD_REG_0);
- lcddbg("ID: %04x\n", id);
+ lcddbg("LCD ID: %04x\n", id);
+ /* Check if the ID is for the SPFD5408B or the almost compatible R61580 */
+
+#if !defined(CONFIG_STM32_SPFD5408B_DISABLE) || !defined(CONFIG_STM32_R61580_DISABLE)
+#if !defined(CONFIG_STM32_SPFD5408B_DISABLE) && !defined(CONFIG_STM32_R61580_DISABLE)
if (id == SPFD5408B_ID || id == R61580_ID)
+#elif !defined(CONFIG_STM32_SPFD5408B_DISABLE)
+ if (id == SPFD5408B_ID)
+#else
+ if (id == R61580_ID)
+#endif
{
- g_lcddev.spfd5408b = true;
+ /* Set the LCD type for the SPFD5408B or the R61580 */
+
+#if !defined(CONFIG_STM32_SPFD5408B_DISABLE) && !defined(CONFIG_STM32_R61580_DISABLE)
+ g_lcddev.type = (id == SPFD5408B_ID ? LCD_TYPE_SPFD5408B : LCD_TYPE_R61580);
+#elif !defined(CONFIG_STM32_SPFD5408B_DISABLE)
+ g_lcddev.type = SPFD5408B_ID;
+#else
+ g_lcddev.type = LCD_TYPE_R61580;
+#endif
+
+ lcddbg("LCD type: %d\n", g_lcddev.type);
/* Start Initial Sequence */
@@ -1115,8 +1166,11 @@ static inline void stm3210e_lcdinitialize(void)
stm3210e_writereg(LCD_REG_7, 0); /* Display OFF */
}
else
+#endif
{
- g_lcddev.spfd5408b = false;
+#ifndef CONFIG_STM32_AM240320_DISABLE
+ g_lcddev.type = LCD_TYPE_AM240320;
+ lcddbg("LCD type: %d\n", g_lcddev.type);
/* Start Initial Sequence */
@@ -1204,6 +1258,9 @@ static inline void stm3210e_lcdinitialize(void)
stm3210e_writereg(LCD_REG_3, 0x1018);
stm3210e_writereg(LCD_REG_7, 0); /* Display off */
+#else
+ lcddbg("Unsupported LCD type\n");
+#endif
}
}