summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-07-06 21:18:34 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-07-06 21:18:34 +0000
commit98dcf81241c8ea176634617af8c4d3146c914eb3 (patch)
treefbadffe522ddfab36e0fc1558c80d1940d67824d
parentafe2554a0862674921f5334fd9c34d2e3c17391a (diff)
downloadnuttx-98dcf81241c8ea176634617af8c4d3146c914eb3.tar.gz
nuttx-98dcf81241c8ea176634617af8c4d3146c914eb3.tar.bz2
nuttx-98dcf81241c8ea176634617af8c4d3146c914eb3.zip
Add support for the STM3210E-EVAL LCD backlight
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3748 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_tim.c2
-rwxr-xr-xnuttx/configs/stm3210e-eval/README.txt4
-rw-r--r--nuttx/configs/stm3210e-eval/nx/defconfig5
-rwxr-xr-xnuttx/configs/stm3210e-eval/src/up_lcd.c198
4 files changed, 192 insertions, 17 deletions
diff --git a/nuttx/arch/arm/src/stm32/stm32_tim.c b/nuttx/arch/arm/src/stm32/stm32_tim.c
index d996a7af1..5ce495178 100644
--- a/nuttx/arch/arm/src/stm32/stm32_tim.c
+++ b/nuttx/arch/arm/src/stm32/stm32_tim.c
@@ -578,7 +578,7 @@ struct stm32_tim_priv_s stm32_tim7_priv = {
#if STM32_NATIM > 0
-#if CONFIG_STM32_TIM7
+#if CONFIG_STM32_TIM1
struct stm32_tim_priv_s stm32_tim1_priv = {
.ops = &stm32_tim_ops,
.mode = STM32_TIM_MODE_UNUSED,
diff --git a/nuttx/configs/stm3210e-eval/README.txt b/nuttx/configs/stm3210e-eval/README.txt
index 848133b1b..3f050e32f 100755
--- a/nuttx/configs/stm3210e-eval/README.txt
+++ b/nuttx/configs/stm3210e-eval/README.txt
@@ -414,6 +414,9 @@ STM3210E-EVAL-specific Configuration Options
Default is 320x240 (this setting is informative only... not used).
CONFIG_LCD_PORTRAIT - Define for 240x320 display support.
Default is 320x240.
+ CONFIG_LCD_BACKLIGHT - Define to support an adjustable backlight
+ using timer 1. The granularity of the settings is determined
+ by CONFIG_LCD_MAXPOWER. Requires CONFIG_STM32_TIM1.
Configurations
==============
@@ -465,6 +468,7 @@ Where <subdir> is one of the following:
uses the Nokia 6100 LCD driver.
CONFIG_STM32_CODESOURCERYW=y : CodeSourcery under Windows
+ CONFIG_LCD_PORTRAIT=y : 240x320
ostest:
------
diff --git a/nuttx/configs/stm3210e-eval/nx/defconfig b/nuttx/configs/stm3210e-eval/nx/defconfig
index 8210f04a5..63e362f32 100644
--- a/nuttx/configs/stm3210e-eval/nx/defconfig
+++ b/nuttx/configs/stm3210e-eval/nx/defconfig
@@ -326,6 +326,7 @@ CONFIG_HAVE_LIBM=n
CONFIG_DEBUG=n
CONFIG_DEBUG_VERBOSE=n
CONFIG_DEBUG_GRAPHICS=n
+CONFIG_DEBUG_LCD=n
CONFIG_DEBUG_SYMBOLS=n
CONFIG_MM_REGIONS=1
CONFIG_ARCH_LOWPUTC=y
@@ -775,9 +776,13 @@ CONFIG_NX_MXCLIENTMSGS=16
# Default is 320x240 (this setting is informative only... not necessary).
# CONFIG_LCD_PORTRAIT - Define for 240x320 display support.
# Default is 320x240.
+# CONFIG_LCD_BACKLIGHT - Define to support an adjustable backlight
+# using timer 1. The granularity of the settings is determined
+# by CONFIG_LCD_MAXPOWER. Requires CONFIG_STM32_TIM1.
#
CONFIG_LCD_LANDSCAPE=n
CONFIG_LCD_PORTRAIT=y
+CONFIG_LCD_BACKLIGHT=n
#
# Settings for examples/uip
diff --git a/nuttx/configs/stm3210e-eval/src/up_lcd.c b/nuttx/configs/stm3210e-eval/src/up_lcd.c
index fe2c6ac23..83c8fa693 100755
--- a/nuttx/configs/stm3210e-eval/src/up_lcd.c
+++ b/nuttx/configs/stm3210e-eval/src/up_lcd.c
@@ -52,6 +52,8 @@
#include <nuttx/lcd/lcd.h>
#include "up_arch.h"
+#include "stm32.h"
+#include "stm32_internal.h"
#include "stm3210e-internal.h"
/**************************************************************************************
@@ -67,14 +69,17 @@
/* Check power setting */
-#if !defined(CONFIG_LCD_MAXPOWER)
-# define CONFIG_LCD_MAXPOWER 1
+#if !defined(CONFIG_LCD_MAXPOWER) || CONFIG_LCD_MAXPOWER < 1
+# undef CONFIG_LCD_MAXPOWER
+# ifdef CONFIG_LCD_BACKLIGHT
+# define CONFIG_LCD_MAXPOWER 100
+# else
+# define CONFIG_LCD_MAXPOWER 1
+# endif
#endif
-#if CONFIG_LCD_MAXPOWER != 1
-# warning "CONFIG_LCD_MAXPOWER exceeds supported maximum"
-# undef CONFIG_LCD_MAXPOWER
-# define CONFIG_LCD_MAXPOWER 1
+#if CONFIG_LCD_MAXPOWER > 255
+# error "CONFIG_LCD_MAXPOWER must be less than 256 to fit in uint8_t"
#endif
/* Check orientation */
@@ -87,6 +92,21 @@
# define CONFIG_LCD_LANDSCAPE 1
#endif
+/* Backlight */
+
+#ifdef CONFIG_LCD_BACKLIGHT
+# ifndef CONFIG_STM32_TIM1
+# error "CONFIG_STM32_TIM1 to use the LCD backlight controls"
+# endif
+# if CONFIG_LCD_MAXPOWER < 2
+# warning "A larger value of CONFIG_LCD_MAXPOWER is recommended"
+# endif
+#endif
+
+#if defined(CONFIG_STM32_TIM1_FULL_REMAP)
+# error "PA8 cannot be configured as TIM1 CH1 with full remap"
+#endif
+
/* Define CONFIG_DEBUG_LCD to enable detailed LCD debug output. Verbose debug must
* also be enabled.
*/
@@ -233,6 +253,8 @@
#define LCD_REG_193 0xc1
#define LCD_REG_229 0xe5
+#define LCD_BL_TIMER_PERIOD 8999
+
/* Debug ******************************************************************************/
#ifdef CONFIG_DEBUG_LCD
@@ -263,8 +285,8 @@ struct stm3210e_dev_s
/* Private LCD-specific information follows */
- bool spfd5408b; /* TRUE: LCD is SPFD5408B Controller */
- bool powered; /* TRUE: display on */
+ bool spfd5408b; /* TRUE: LCD is SPFD5408B Controller */
+ uint8_t power; /* Current power setting */
};
/**************************************************************************************
@@ -316,6 +338,11 @@ static int stm3210e_setcontrast(struct lcd_dev_s *dev, unsigned int contrast);
static inline void stm3210e_lcdinitialize(void);
static inline void stm3210e_lcdclear(void);
+#ifdef CONFIG_LCD_BACKLIGHT
+static void stm3210e_backlight(void);
+#else
+# define stm3210e_backlight()
+#endif
/**************************************************************************************
* Private Data
@@ -489,9 +516,6 @@ static int stm3210e_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *bu
size_t npixels)
{
FAR const uint16_t *src = (FAR const uint16_t*)buffer;
-#ifndef CONFIG_LCD_LANDSCAPE
- fb_coord_t tmp;
-#endif
int i;
/* Buffer must be provided and aligned to a 16-bit address boundary */
@@ -664,7 +688,7 @@ static int stm3210e_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno
static int stm3210e_getpower(struct lcd_dev_s *dev)
{
gvdbg("power: %d\n", 0);
- return g_lcddev.powered ? 1 : 0;
+ return g_lcddev.power;
}
/**************************************************************************************
@@ -683,17 +707,31 @@ static int stm3210e_setpower(struct lcd_dev_s *dev, int power)
/* Set new power level */
- if (power)
+ if (power > 0)
{
- /* Turn the display on: 262K color and display ON */
+ uint32_t duty;
+
+ /* Caclulate the new backlight duty. It is a faction of the timer1
+ * period based on the ration of the current power setting to the
+ * maximum power setting.
+ */
+
+ duty = ((uint32_t)LCD_BL_TIMER_PERIOD * (uint32_t)power) / CONFIG_LCD_MAXPOWER;
+ if (duty >= LCD_BL_TIMER_PERIOD)
+ {
+ duty = LCD_BL_TIMER_PERIOD - 1;
+ }
+ putreg16((uint16_t)duty, STM32_TIM1_CCR1);
+
+ /* Then turn the display on */
stm3210e_writereg(LCD_REG_7, g_lcddev.spfd5408b ? 0x0112 : 0x0173);
- g_lcddev.powered = true;
+ g_lcddev.power = power;
}
else
{
stm3210e_writereg(LCD_REG_7, 0);
- g_lcddev.powered = false;
+ g_lcddev.power = 0;
}
return OK;
@@ -949,6 +987,130 @@ static inline void stm3210e_lcdclear(void)
}
/**************************************************************************************
+ * Name: stm3210e_backlight
+ *
+ * Description:
+ * The LCD backlight is driven from PA8 which must be configured as TIM1
+ * CH1. TIM1 must then be configured to output a clock on PA8; the duty
+ * of the clock determineds the backlight level.
+ *
+ **************************************************************************************/
+
+#ifdef CONFIG_LCD_BACKLIGHT
+static void stm3210e_backlight(void)
+{
+ uint16_t ccmr;
+ uint16_t ccer;
+ uint16_t cr2;
+
+ /* Configure PA8 as TIM1 CH1 output */
+
+ stm32_configgpio(GPIO_TIM1_CH1OUT);
+
+ /* Enabled timer 1 clocking */
+
+ modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM1EN);
+
+ /* Reset timer 1 */
+
+ modifyreg32(STM32_RCC_APB2RSTR, 0, RCC_APB2RSTR_TIM1RST);
+ modifyreg32(STM32_RCC_APB2RSTR, RCC_APB2RSTR_TIM1RST, 0);
+
+ /* Reset the Counter Mode and set the clock division */
+
+ putreg16(0, STM32_TIM1_CR1);
+
+ /* Set the Autoreload value */
+
+ putreg16(LCD_BL_TIMER_PERIOD, STM32_TIM1_ARR);
+
+ /* Set the Prescaler value */
+
+ putreg16(0, STM32_TIM1_PSC);
+
+ /* Reset the Repetition Counter value */
+
+ putreg16(0, STM32_TIM1_RCR);
+
+ /* Generate an update event to reload the Prescaler value immediatly */
+
+ putreg16(ATIM_EGR_UG, STM32_TIM1_EGR);
+
+ /* Disable the Channel 1 */
+
+ ccer = getreg16(STM32_TIM1_CCER);
+ ccer &= ~ATIM_CCER_CC1E;
+ putreg16(ccer, STM32_TIM1_CCER);
+
+ /* Get the TIM1 CR2 register value */
+
+ cr2 = getreg16(STM32_TIM1_CR2);
+
+ /* Select the Output Compare Mode Bits */
+
+ ccmr = getreg16(STM32_TIM1_CCMR1);
+ ccmr &= ATIM_CCMR1_OC1M_MASK;
+ ccmr |= (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC1M_SHIFT);
+
+ /* Set the capture compare register value (50% duty) */
+
+ g_lcddev.power = (CONFIG_LCD_MAXPOWER + 1) / 2;
+ putreg16((LCD_BL_TIMER_PERIOD + 1) / 2, STM32_TIM1_CCR1);
+
+ /* Select the output polarity level == LOW and enable */
+
+ ccer |= (ATIM_CCER_CC1E | ATIM_CCER_CC1P);
+
+ /* Reset the Output N Polarity level */
+
+ ccer &= ~(ATIM_CCER_CC1NP|ATIM_CCER_CC1NE);
+
+ /* Reset the Ouput Compare and Output Compare N IDLE State */
+
+ cr2 &= ~(ATIM_CR2_OIS1|ATIM_CR2_OIS1N);
+
+ /* Write the timer configuration */
+
+ putreg16(cr2, STM32_TIM1_CR2);
+ putreg16(ccmr, STM32_TIM1_CCMR1);
+ putreg16(ccer, STM32_TIM1_CCER);
+
+ /* Set the auto preload enable bit */
+
+ modifyreg16(STM32_TIM1_CR1, 0, ATIM_CR1_ARPE);
+
+ /* Enable Backlight Timer */
+
+ ccer |= ATIM_CR1_CEN;
+ putreg16(ccer, STM32_TIM1_CCER);
+
+ /* Dump timer1 registers */
+
+ lcddbg("APB2ENR: %08x\n", getreg32(STM32_RCC_APB2ENR));
+ lcddbg("CR1: %04x\n", getreg32(STM32_TIM1_CR1));
+ lcddbg("CR2: %04x\n", getreg32(STM32_TIM1_CR2));
+ lcddbg("SMCR: %04x\n", getreg32(STM32_TIM1_SMCR));
+ lcddbg("DIER: %04x\n", getreg32(STM32_TIM1_DIER));
+ lcddbg("SR: %04x\n", getreg32(STM32_TIM1_SR));
+ lcddbg("EGR: %04x\n", getreg32(STM32_TIM1_EGR));
+ lcddbg("CCMR1: %04x\n", getreg32(STM32_TIM1_CCMR1));
+ lcddbg("CCMR2: %04x\n", getreg32(STM32_TIM1_CCMR2));
+ lcddbg("CCER: %04x\n", getreg32(STM32_TIM1_CCER));
+ lcddbg("CNT: %04x\n", getreg32(STM32_TIM1_CNT));
+ lcddbg("PSC: %04x\n", getreg32(STM32_TIM1_PSC));
+ lcddbg("ARR: %04x\n", getreg32(STM32_TIM1_ARR));
+ lcddbg("RCR: %04x\n", getreg32(STM32_TIM1_RCR));
+ lcddbg("CCR1: %04x\n", getreg32(STM32_TIM1_CCR1));
+ lcddbg("CCR2: %04x\n", getreg32(STM32_TIM1_CCR2));
+ lcddbg("CCR3: %04x\n", getreg32(STM32_TIM1_CCR3));
+ lcddbg("CCR4: %04x\n", getreg32(STM32_TIM1_CCR4));
+ lcddbg("CCR4: %04x\n", getreg32(STM32_TIM1_CCR4));
+ lcddbg("CCR4: %04x\n", getreg32(STM32_TIM1_CCR4));
+ lcddbg("DMAR: %04x\n", getreg32(STM32_TIM1_DMAR));
+}
+#endif
+
+/**************************************************************************************
* Public Functions
**************************************************************************************/
@@ -978,6 +1140,10 @@ int up_lcdinitialize(void)
/* Clear the display */
stm3210e_lcdclear();
+
+ /* Configure the backlight */
+
+ stm3210e_backlight();
return OK;
}