summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-03-31 20:48:53 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-03-31 20:48:53 +0000
commit6142f691ab69077dfe1864e11f23f47cb62c1915 (patch)
tree44aa49c909715f57c7e2ce1650a14b915721c8ec /nuttx
parent383bcc132afd8bac784c76af40002cfa38029581 (diff)
downloadpx4-nuttx-6142f691ab69077dfe1864e11f23f47cb62c1915.tar.gz
px4-nuttx-6142f691ab69077dfe1864e11f23f47cb62c1915.tar.bz2
px4-nuttx-6142f691ab69077dfe1864e11f23f47cb62c1915.zip
Apply fixes for STM3210E-EVAL LCD backlight PWM
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4547 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/configs/stm3210e-eval/src/up_lcd.c89
1 files changed, 70 insertions, 19 deletions
diff --git a/nuttx/configs/stm3210e-eval/src/up_lcd.c b/nuttx/configs/stm3210e-eval/src/up_lcd.c
index a3fe6c810..167739152 100644
--- a/nuttx/configs/stm3210e-eval/src/up_lcd.c
+++ b/nuttx/configs/stm3210e-eval/src/up_lcd.c
@@ -122,6 +122,12 @@
# error "CONFIG_LCD_MAXPOWER must be less than 256 to fit in uint8_t"
#endif
+/* PWM Frequency */
+
+#ifndef CONFIG_LCD_PWMFREQUENCY
+# define CONFIG_LCD_PWMFREQUENCY 100
+#endif
+
/* Check orientation */
#if defined(CONFIG_LCD_PORTRAIT)
@@ -294,8 +300,6 @@
#define LCD_REG_193 0xc1
#define LCD_REG_229 0xe5
-#define LCD_BL_TIMER_PERIOD 8999
-
/* LCD IDs */
#define SPFD5408B_ID 0x5408
@@ -339,6 +343,10 @@ struct stm3210e_dev_s
struct lcd_dev_s dev;
+#if defined(CONFIG_LCD_BACKLIGHT) && defined(CONFIG_LCD_PWM)
+ uint32_t reload;
+#endif
+
/* Private LCD-specific information follows */
uint8_t type; /* LCD type. See enum lcd_type_e */
@@ -970,8 +978,10 @@ static int stm3210e_getpower(struct lcd_dev_s *dev)
static int stm3210e_setpower(struct lcd_dev_s *dev, int power)
{
+ uint32_t frac;
+
gvdbg("power: %d\n", power);
- DEBUGASSERT(power <= CONFIG_LCD_MAXPOWER);
+ DEBUGASSERT((unsigned)power <= CONFIG_LCD_MAXPOWER);
/* Set new power level */
@@ -986,10 +996,11 @@ static int stm3210e_setpower(struct lcd_dev_s *dev, int power)
* maximum power setting.
*/
- duty = ((uint32_t)LCD_BL_TIMER_PERIOD * (uint32_t)power) / CONFIG_LCD_MAXPOWER;
- if (duty >= LCD_BL_TIMER_PERIOD)
+ frac = (power << 16) / CONFIG_LCD_MAXPOWER;
+ duty = (g_lcddev.reload * frac) >> 16;
+ if (duty > 0)
{
- duty = LCD_BL_TIMER_PERIOD - 1;
+ duty--;
}
putreg16((uint16_t)duty, STM32_TIM1_CCR1);
#else
@@ -1364,10 +1375,42 @@ static inline void stm3210e_lcdinitialize(void)
static void stm3210e_backlight(void)
{
#ifdef CONFIG_LCD_PWM
+ uint32_t prescaler;
+ uint32_t reload;
+ uint32_t timclk;
+ uint16_t bdtr;
uint16_t ccmr;
uint16_t ccer;
uint16_t cr2;
+ /* Calculate the TIM1 prescaler value */
+
+ prescaler = (STM32_PCLK2_FREQUENCY / CONFIG_LCD_PWMFREQUENCY + 65534) / 65535;
+ if (prescaler < 1)
+ {
+ prescaler = 1;
+ }
+ else if (prescaler > 65536)
+ {
+ prescaler = 65536;
+ }
+
+ /* Calculate the TIM1 reload value */
+
+ timclk = STM32_PCLK2_FREQUENCY / prescaler;
+ reload = timclk / CONFIG_LCD_PWMFREQUENCY;
+
+ if (reload < 1)
+ {
+ reload = 1;
+ }
+ else if (reload > 65535)
+ {
+ reload = 65535;
+ }
+
+ g_lcddev.reload = reload;
+
/* Configure PA8 as TIM1 CH1 output */
stm32_configgpio(GPIO_TIM1_CH1OUT);
@@ -1387,19 +1430,28 @@ static void stm3210e_backlight(void)
/* Set the Autoreload value */
- putreg16(LCD_BL_TIMER_PERIOD, STM32_TIM1_ARR);
+ putreg16(reload-1, STM32_TIM1_ARR);
/* Set the Prescaler value */
- putreg16(0, STM32_TIM1_PSC);
+ putreg16(prescaler-1, STM32_TIM1_PSC);
+
+ /* Generate an update event to reload the Prescaler value immediatly */
+
+ putreg16(ATIM_EGR_UG, STM32_TIM1_EGR);
/* Reset the Repetition Counter value */
putreg16(0, STM32_TIM1_RCR);
- /* Generate an update event to reload the Prescaler value immediatly */
+ /* Set the main output enable (MOE) bit and clear the OSSI and OSSR
+ * bits in the BDTR register.
+ */
- putreg16(ATIM_EGR_UG, STM32_TIM1_EGR);
+ bdtr = getreg16(STM32_TIM1_BDTR);
+ bdtr &= ~(ATIM_BDTR_OSSI | ATIM_BDTR_OSSR);
+ bdtr |= ATIM_BDTR_MOE;
+ putreg16(bdtr, STM32_TIM1_BDTR);
/* Disable the Channel 1 */
@@ -1416,15 +1468,16 @@ static void stm3210e_backlight(void)
ccmr = getreg16(STM32_TIM1_CCMR1);
ccmr &= ATIM_CCMR1_OC1M_MASK;
ccmr |= (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC1M_SHIFT);
+ ccmr |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC1S_SHIFT);
- /* Set the capture compare register value (50% duty) */
+ /* Set the power to the minimum value */
- g_lcddev.power = (CONFIG_LCD_MAXPOWER + 1) / 2;
- putreg16((LCD_BL_TIMER_PERIOD + 1) / 2, STM32_TIM1_CCR1);
+ g_lcddev.power = 0;
+ putreg16(0, STM32_TIM1_CCR1);
/* Select the output polarity level == LOW and enable */
- ccer |= (ATIM_CCER_CC1E | ATIM_CCER_CC1P);
+ ccer |= (ATIM_CCER_CC1E );
/* Reset the Output N Polarity level */
@@ -1443,11 +1496,11 @@ static void stm3210e_backlight(void)
/* 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);
+ putreg16(ccer, STM32_TIM1_CR1);
/* Dump timer1 registers */
@@ -1457,7 +1510,7 @@ static void stm3210e_backlight(void)
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("BDTR: %04x\n", getreg32(STM32_TIM1_BDTR));
lcddbg("CCMR1: %04x\n", getreg32(STM32_TIM1_CCMR1));
lcddbg("CCMR2: %04x\n", getreg32(STM32_TIM1_CCMR2));
lcddbg("CCER: %04x\n", getreg32(STM32_TIM1_CCER));
@@ -1469,8 +1522,6 @@ static void stm3210e_backlight(void)
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));
#else
stm32_configgpio(GPIO_LCD_BACKLIGHT);