diff --git a/arch/arm/src/lpc54xx/chip/lpc54_lcd.h b/arch/arm/src/lpc54xx/chip/lpc54_lcd.h index ee86593fdd9..57df5902690 100644 --- a/arch/arm/src/lpc54xx/chip/lpc54_lcd.h +++ b/arch/arm/src/lpc54xx/chip/lpc54_lcd.h @@ -140,6 +140,7 @@ #define LCD_POL_PCDLO_SHIFT (0) /* Bits 0-4: Lower 5 bits of panel clock divisor */ #define LCD_POL_PCDLO_MASK (0x1f << LCD_POL_PCDLO_SHIFT) +# define LCD_POL_PCDLO(n) ((uint32_t)(n) << LCD_POL_PCDLO_SHIFT) /* Bit 5: Reserved */ #define LCD_POL_ACB_SHIFT (6) /* Bits 6-10: AC bias pin frequency */ #define LCD_POL_ACB_MASK (0x1f << LCD_POL_ACB_SHIFT) @@ -150,9 +151,11 @@ /* Bit 15: Reserved */ #define LCD_POL_CPL_SHIFT (16) /* Bit 16-25: Clocks per line */ #define LCD_POL_CPL_MASK (0x3ff << LCD_POL_CPL_SHIFT) +# define LCD_POL_CPL(n) ((uint32_t)(n) << LCD_POL_CPL_SHIFT) #define LCD_POL_BCD (1 << 26) /* Bit 26: Bypass pixel clock divider */ #define LCD_POL_PCDHI_SHIFT (27) /* Bits 27-31: Upper 5 bits of panel clock divisor */ #define LCD_POL_PCDHI_MASK (0x1f << LCD_POL_PCDHI_SHIFT) +# define LCD_POL_PCDHI(n) ((uint32_t)(n) << LCD_POL_PCDHI_SHIFT) /* LCD_LE - Line End Control Register */ diff --git a/arch/arm/src/lpc54xx/lpc54_lcd.c b/arch/arm/src/lpc54xx/lpc54_lcd.c index bba261252af..1dba8e74f7b 100644 --- a/arch/arm/src/lpc54xx/lpc54_lcd.c +++ b/arch/arm/src/lpc54xx/lpc54_lcd.c @@ -473,7 +473,8 @@ static int lpc54_setcursor(FAR struct fb_vtable_s *vtable, int up_fbinitialize(int display) { uint32_t regval; - uint32_t lcddiv; + uint32_t bcd; + uint32_t pcd; int i; /* Configure pins */ @@ -545,6 +546,12 @@ int up_fbinitialize(int display) putreg32(SYSCON_LCDCLKSEL_MAINCLK, LPC54_SYSCON_LCDCLKSEL); #endif + /* Set the LCD clock divider to one. */ + + putreg32(SYSCON_LCDCLKDIV_DIV(1), LPC54_SYSCON_LCDCLKDIV); + putreg32(SYSCON_LCDCLKDIV_DIV(1) | SYSCON_LCDCLKDIV_REQFLAG, + LPC54_SYSCON_LCDCLKDIV); + /* Reset the LCD */ lpc54_reset_lcd(); @@ -565,17 +572,6 @@ int up_fbinitialize(int display) putreg32(0, LPC54_LCD_CTRL); - /* Initialize pixel clock. Set the LCD clock divier. */ - -#ifdef CONFIG_LPC54_LCD_USE_CLKIN - lcddiv = ((uint32_t)CONFIG_LPC54_LCD_CLKIN_FREQUENCY / - (uint32_t)LPC54_LCD_PIXEL_CLOCK) + 1; -#else - lcddiv = ((uint32_t)BOARD_MAIN_CLK / (uint32_t)LPC54_LCD_PIXEL_CLOCK) + 1; -#endif - putreg32(lcddiv, LPC54_SYSCON_LCDCLKDIV); - putreg32(lcddiv | SYSCON_LCDCLKDIV_REQFLAG, LPC54_SYSCON_LCDCLKDIV); - /* Set the bits per pixel */ regval = getreg32(LPC54_LCD_CTRL); @@ -664,6 +660,37 @@ int up_fbinitialize(int display) (CONFIG_LPC54_LCD_VBACKPORCH) << LCD_TIMV_VBP_SHIFT); putreg32(regval, LPC54_LCD_TIMV); + /* Get the pixel clock divider */ + +#ifdef CONFIG_LPC54_LCD_USE_CLKIN + pcd = ((uint32_t)CONFIG_LPC54_LCD_CLKIN_FREQUENCY / + (uint32_t)LPC54_LCD_PIXEL_CLOCK) + 1; +#else + pcd = ((uint32_t)BOARD_MAIN_CLK / (uint32_t)LPC54_LCD_PIXEL_CLOCK); +#endif + + /* Check the range of pcd */ + + bcd = 0; + +#ifndef CONFIG_LPC54_LCD_TFTPANEL + DEBUGASSERT(pcd >= 2); +#else + if (pcd <= 1) + { + /* Just bypass the LCD divider */ + + pcd = 0; + bcd = LCD_POL_BCD; + } + else +#endif + { + /* The register value is PCD - 2 */ + + pcd -= 2; + } + /* Initialize clock and signal polarity. * * REVISIT: These need to be configurable. @@ -685,11 +712,36 @@ int up_fbinitialize(int display) /* Set number of clocks per line */ - regval |= ((CONFIG_LPC54_LCD_HWIDTH-1) << LCD_POL_CPL_SHIFT); + regval &= ~LCD_POL_CPL_MASK; - /* Bypass internal pixel clock divider */ +#if defined(CONFIG_LPC54_LCD_TFTPANEL) + /* TFT panel */ - regval |= LCD_POL_BCD; + regval |= LCD_POL_CPL(CONFIG_LPC54_LCD_HWIDTH - 1); +#else + /* STN panel */ + +#if defined(CONFIG_LPC54_LCD_BPP8) + /* 8-bit monochrome STN panel */ + + regval |= LCD_POL_CPL((CONFIG_LPC54_LCD_HWIDTH / 8) - 1); +#elif defined(CONFIG_LPC54_LCD_BPP4) + /* 4-bit monochrome STN panel */ + + regval |= LCD_POL_CPL((CONFIG_LPC54_LCD_HWIDTH / 4) - 1); +#else + /* Color STN panel. */ + + regval |= LCD_POL_CPL(((CONFIG_LPC54_LCD_HWIDTH * 3) / 8) - 1); +#endif +#endif /* CONFIG_LPC54_LCD_TFTPANEL */ + + /* Set pixel clock divisor (or bypass) */ + + regval &= ~(LCD_POL_PCDLO_MASK | LCD_POL_PCDHI_MASK | LCD_POL_BCD); + regval |= LCD_POL_PCDLO(pcd) & LCD_POL_PCDLO_MASK; + regval |= LCD_POL_PCDHI(pcd >> 5) & LCD_POL_PCDHI_MASK; + regval |= bcd; /* LCD_ENAB_M is active high */ diff --git a/configs/lpcxpresso-lpc54628/README.txt b/configs/lpcxpresso-lpc54628/README.txt index f266e6df317..11323f934e0 100644 --- a/configs/lpcxpresso-lpc54628/README.txt +++ b/configs/lpcxpresso-lpc54628/README.txt @@ -40,8 +40,10 @@ STATUS minor clock source setting). That port required modifications only for differences in some SYSCON and pin-related settings. 2017-12-13: Created the fb configuration for testing the LCD. Only - minimal testing has been performed. As of this writing, the system - hangs while initializing the LCD. + minimal testing has been performed. As of this writing, thre is + some framebuffer functionality. There are recognizable but corrupted + patterns on the LCD. There are color formatting problems and some + horizontal elongation. Configurations ==============