h.bugragunes

Problem in driving 7" LCD using LPC1788 MCU

Discussion created by h.bugragunes on May 8, 2017
Latest reply on Oct 9, 2017 by Ati haj

I  am recently working with a custom design board which is inspired by "μEZGUI-1788-70WVM Kit development board". My first goal with my board is to drive a RGB interface 7" LCD using LPC1788 which has an embedded LCD driver inside. Then after achieving this applying an EMWIN demo project to see the result.

 

Reading through UM10470_LPC1788 user manual for LCD interfacing, Chapter 11; it seems to me driving an LCD using LPC1788 is not a big deal, but when it comes to real world, the reality was different than I assumed. Even though I took NXP_LPC1788_emWin522_BSP codes as a reference to my coding, I could not managed to drive LCD except its backlight. I can only control its backlight right now and can only supply 30Mhz panel clock(LCD_DCLK). My problem that I verified by an oscilloscope that, even though setting TIMH and TIMV registers, LPC1788 could not create HSYNC, VSYNC and LCD_ENAB_M signals at all. So, the LCD could not display anything.

 

Anyones helps/comments are highly appreciated. Please help me to solve this problem.

 

Thanks in advance.

------------------------------------------------------------------------------------

Summary of my HW:

LPC1788,

SDRAM (MT48LC4M32B2P-7)

LCD (NHD-7.0-800480EF-ATXL#-CTP)

The first thing that I've suspected is the SDRAM. Hence, I also minimized my coding by removing SDRAM routines and defining a small videoRAM (aVRAM, 5KB in size) within MCU RAM. But the result is the same. There is not HSYNC, VSYNC and LCD_ENAB_M signals. But LCD clock which is 30MHZ is successfully generated. And the backlight is successfully operating.

 

You can find the code as an attachment to this post (main.c) which is also exist below:

 

 

<

----

#ifndef _WINDOWS
#include "HWConf.h"
#include "Timers.h"
#include "74HC595.h"
#include "TypeDefs.h"
#include "LPC177x_8x.h" // Device specific header file, contains CMSIS
#include "system_LPC177x_8x.h" // Device specific header file, contains CMSIS
#endif

#ifdef __CROSSWORKS_ARM
extern void __low_level_init(); // hwconf.c

#endif

 

static volatile unsigned int _Continue1;
void HardFault_Handler(void) {
_Continue1 = 0u;
//
// When stuck here, change the variable value to != 0 in order to step out
//
while (_Continue1 == 0u);
}

 


static U32 _FindClockDivisor(U32 TargetClock) {
U32 Divider;
U32 r;

Divider = 1;
while (((SystemCoreClock / Divider) > TargetClock) && (Divider <= 0x3F)) {
Divider++;
}
if (Divider <= 1) {
r = (1 << 26); // Skip divider logic if clock divider is 1
} else {
//
// Use found divider
//
Divider -= 2;
r = 0
| (((Divider >> 0) & 0x1F)
| (((Divider >> 5) & 0x1F) << 27))
;
}
return r;
}

typedef struct {
U8 HBP; // Horizontal back porch in clocks
U8 HFP; // Horizontal front porch in clocks
U8 HSW; // HSYNC pulse width in clocks
U16 PPL; // Pixels per line
U8 VBP; // Vertical back porch in clocks
U8 VFP; // Vertical front porch in clocks
U8 VSW; // VSYNC pulse width in clocks
U16 LPP; // Lines per panel
U8 IOE; // Invert output enable, 1 = invert
U8 IPC; // Invert panel clock, 1 = invert
U8 IHS; // Invert HSYNC, 1 = invert
U8 IVS; // Invert VSYNC, 1 = invert
U8 ACB; // AC bias frequency in clocks (not used)
U8 BPP; // Maximum bits per pixel the display supports
U32 Clk; // Optimal clock rate (Hz)
U8 LCD; // LCD panel type
U8 Dual; // Dual panel, 1 = dual panel display
} LCD_PARAM;

 

#define MATRIX_ARB (*(volatile U32*)(0x400FC188))
static LCD_PARAM _LcdParams;
static U8 _Display;

#define VRAM_ADDR (U32)&aVRAM[0]

U32 aVRAM[200 * 100];// __attribute__ ((section ("0x10001000")));

static void _InitLCDC(void) {
U32 i;

//
// Translate and check params
//
if (_LcdParams.BPP == 16) {
_LcdParams.BPP = 6;
} else {
while (1); // Error, display mode not yet supported
}
if (_LcdParams.LCD == 0) {
_LcdParams.LCD = 1;
} else {
while (1); // Error, display type not yet supported
}
//
// Init LCDC
//
LPC_SC->PCONP |= (1UL << 0); // Power the LCDC
LPC_LCD->CTRL &= ~(1UL << 0); // Disable the LCDC
LPC_LCD->TIMH = 0 // Configure horizontal axis
| ((((U32)_LcdParams.PPL / 16) - 1) << 2)
| (((U32)_LcdParams.HSW - 1) << 8)
| (((U32)_LcdParams.HFP - 1) << 16)
| (((U32)_LcdParams.HBP - 1) << 24)
;
LPC_LCD->TIMV = 0 // Configure vertical axis
| (((U32)_LcdParams.LPP - 1) << 0)
| (((U32)_LcdParams.VSW - 1) << 10)
| (((U32)_LcdParams.VFP) << 16)
| (((U32)_LcdParams.VBP) << 24)
;
LPC_LCD->POL = 0 // Configure clock and signal polarity
| (_FindClockDivisor(_LcdParams.Clk) << 0)
| (((U32)_LcdParams.ACB - 1) << 6)
| (((U32)_LcdParams.IVS) << 11)
| (((U32)_LcdParams.IHS) << 12)
| (((U32)_LcdParams.IPC) << 13)
| ((((U32)_LcdParams.PPL+176) - 1) << 16)
;
LPC_LCD->CTRL = 0 // Configure operating mode and panel parameters
| ((U32)_LcdParams.BPP << 1)
| ((U32)1 << 8)
| ((U32)_LcdParams.LCD << 5)
;
for (i = 0; i < GUI_COUNTOF(LPC_LCD->PAL); i++) {
LPC_LCD->PAL[i] = 0; // Clear the color palette with black
}
LPC_SC->LCD_CFG = 0x0; // No panel clock prescaler
//
// Enable LCDC
//

LPC_LCD->UPBASE = VRAM_ADDR;
LPC_LCD->LPBASE = VRAM_ADDR;

LPC_LCD->CTRL |= (1 << 0); // Enable LCD signals
LPC_LCD->CTRL |= (1 << 11); // Enable LCD power

LPC_GPIO1->SET |= (1 << 2); // Set backlight to on
}
static void initram (void)
{
U32 i;


for (i = 0; i < 12000; i++) {
aVRAM[i] = 0x7E0 + (0x7E0<<16); // Set the color palette with green (RGB565)
}

}
static void _InitLCDPorts(void) {
LPC_IOCON->P0_4 = 7; // LCD_VD_0 R0
LPC_IOCON->P0_5 = 7; // LCD_VD_1 R1
LPC_IOCON->P4_28 = 7; // LCD_VD_2 R2
LPC_IOCON->P4_29 = 7; // LCD_VD_3 R3
LPC_IOCON->P2_6 = 7; // LCD_VD_4 R4
LPC_IOCON->P2_7 = 7; // LCD_VD_5 R5
LPC_IOCON->P2_8 = 7; // LCD_VD_6 R6
LPC_IOCON->P2_9 = 7; // LCD_VD_7 R7

LPC_IOCON->P0_6 = 7; // LCD_VD_8 G0
LPC_IOCON->P0_7 = 7; // LCD_VD_9 G1
LPC_IOCON->P1_20 = 7; // LCD_VD_10 G2
LPC_IOCON->P1_21 = 7; // LCD_VD_11 G3
LPC_IOCON->P1_22 = 7; // LCD_VD_12 G4
LPC_IOCON->P1_23 = 7; // LCD_VD_13 G5
LPC_IOCON->P1_24 = 7; // LCD_VD_14 G6
LPC_IOCON->P1_25 = 7; // LCD_VD_15 G7

LPC_IOCON->P0_8 = 7; // LCD_VD_16 B0
LPC_IOCON->P0_9 = 7; // LCD_VD_17 B1
LPC_IOCON->P2_12 = 7; // LCD_VD_18 B2
LPC_IOCON->P2_13 = 7; // LCD_VD_19 B3
LPC_IOCON->P1_26 = 7; // LCD_VD_20 B4
LPC_IOCON->P1_27 = 7; // LCD_VD_21 B5
LPC_IOCON->P1_28 = 7; // LCD_VD_22 B6
LPC_IOCON->P1_29 = 7; // LCD_VD_23 B7

LPC_IOCON->P2_0 = 7;// | 1 <<10 ; // LCD_PWR; set 1<<10 for OpenDrain output
LPC_IOCON->P2_2 = 7; // LCD_DCLK
LPC_IOCON->P2_3 = 7; // LCD_FP VSYNC
LPC_IOCON->P2_4 = 7; // LCD_ENAB_M DEN
LPC_IOCON->P2_5 = 7; // LCD_LP HSYNC

LPC_GPIO1->DIR |= (1 << 2);
LPC_GPIO1->CLR |= (1 << 2); // Initially set backlight to off
}
#define HBP_NEWHAVEN_7 88 // Horizontal back porch in clocks
#define HFP_NEWHAVEN_7 40 // Horizontal front porch in clocks
#define HSW_NEWHAVEN_7 48 // HSYNC pulse width in clocks
#define PPL_NEWHAVEN_7 800 // Pixels per line
#define VBP_NEWHAVEN_7 10 // Vertical back porch in clocks
#define VFP_NEWHAVEN_7 5 // Vertical front porch in clocks
#define VSW_NEWHAVEN_7 3 // VSYNC pulse width in clocks
#define LPP_NEWHAVEN_7 50 // Lines per panel
#define IOE_NEWHAVEN_7 0 // Invert output enable, 1 = invert
#define IPC_NEWHAVEN_7 1 // Invert panel clock, 1 = invert
#define IHS_NEWHAVEN_7 1 // Invert HSYNC, 1 = invert
#define IVS_NEWHAVEN_7 1 // Invert VSYNC, 1 = invert
#define ACB_NEWHAVEN_7 1 // AC bias frequency in clocks (not used)
#define BPP_NEWHAVEN_7 16 // Bits per pixel b110 = 16 bpp 5:6:5 mode
#define CLK_NEWHAVEN_7 30000000 // Optimal clock rate (Hz) according to datasheet
#define LCD_NEWHAVEN_7 0 // Panel type; 0: LCD TFT panel
#define DUAL_NEWHAVEN_7 0 // No dual panel
enum {
DISPLAY_TRULY_240_320,
DISPLAY_BOARD_480_272,
DISPLAY_BOARD_800_480
};

static void _UpdateDisplayConfig(void) {

 

_Display = DISPLAY_BOARD_800_480; //DISPLAY_TRULY_240_320;
//
// Setup display settings for display
//
_LcdParams.HBP = HBP_NEWHAVEN_7;
_LcdParams.HFP = HFP_NEWHAVEN_7;
_LcdParams.HSW = HSW_NEWHAVEN_7;
_LcdParams.PPL = PPL_NEWHAVEN_7;
_LcdParams.VBP = VBP_NEWHAVEN_7;
_LcdParams.VFP = VFP_NEWHAVEN_7;
_LcdParams.VSW = VSW_NEWHAVEN_7;
_LcdParams.LPP = LPP_NEWHAVEN_7;
_LcdParams.IOE = IOE_NEWHAVEN_7;
_LcdParams.IPC = IPC_NEWHAVEN_7;
_LcdParams.IHS = IHS_NEWHAVEN_7;
_LcdParams.IVS = IVS_NEWHAVEN_7;
_LcdParams.ACB = ACB_NEWHAVEN_7;
_LcdParams.BPP = BPP_NEWHAVEN_7;
_LcdParams.Clk = CLK_NEWHAVEN_7;
_LcdParams.LCD = LCD_NEWHAVEN_7;
_LcdParams.Dual = DUAL_NEWHAVEN_7;

}

static void _InitLCDbugra(void) {
_InitLCDPorts();
//
// Setup BUS priorities
//
MATRIX_ARB = 0 // Set AHB Matrix priorities [0..3] with 3 being highest priority
| (1 << 0) // PRI_ICODE : I-Code bus priority. Should be lower than PRI_DCODE for proper operation.
| (2 << 2) // PRI_DCODE : D-Code bus priority.
| (0 << 4) // PRI_SYS : System bus priority.
| (0 << 6) // PRI_GPDMA : General Purpose DMA controller priority.
| (0 << 8) // PRI_ETH : Ethernet: DMA priority.
| (3 << 10) // PRI_LCD : LCD DMA priority.
| (0 << 12) // PRI_USB : USB DMA priority.
;

_InitLCDC();

}


/*********************************************************************
*
* main
*/
int main(void) {
U32 i;
#ifdef __CROSSWORKS_ARM
__low_level_init();
#endif
#ifndef _WINDOWS
HW_X_Config(); // Initialization of Hardware
configureTimer1(1000); // Configure an interrupt using Timer1

#endif
//MainTask(); // emWin application

initram();
_UpdateDisplayConfig();
_InitLCDbugra();

// main loop
while(1)
{

//do nothing
}

}

>

Attachments

Outcomes