LCD Orientation Issue

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LCD Orientation Issue

1,723 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rmoss on Mon Jan 28 08:53:50 MST 2013
I am using the LCP1788 with DisplayTech 2.8" LCD (320x240, 16bpp RGB Mode).  The screen buffer managed by emWin is located in external Static RAM at address 0x90000000.  I have an image on the screen, however it is rotated 90 degrees.  An image is attached that shows the rotation issue.  Is there a register setting that is setup incorrectly or needs to be added to correct this issue?  Here are my LCD setup register values:

#define TIMH_HBP20// Horizontal Back Porch
#define TIMH_HFP10// Horizontal Front Porch
#define TIMH_HSW10// Horizontal Synchronization pulse width
#define TIMH_PPL19// Pixels per line
#define TIMH_RSV0// Reserved

#define TIMV_VBP2// Vertical Back Porch
#define TIMV_VFP4// Vertical Front Porch
#define TIMV_VSW2// Vertical Synchronization pulse width
#define TIMV_LPP239

#define POL_PCD_HI0
#define POL_BCD    0
#define POL_CPL    319
#define POL_RSV    0
#define POL_IOE    0
#define POL_IPC    0
#define POL_IHS    1
#define POL_IVS 1
#define POL_ACB    0
#define POL_CLKSEL0
#define POL_PCD_LO1

/* LCD IO Setup */
LPC_IOCON->P2_12 = (PIN_FUNC_LCDVD_3 | PIN_MODE_PLAIN);     /* LCDVD[3] */
LPC_IOCON->P2_6 = (PIN_FUNC_LCDVD_4 | PIN_MODE_PLAIN);      /* LCDVD[4] */
LPC_IOCON->P2_7 = (PIN_FUNC_LCDVD_5 | PIN_MODE_PLAIN);      /* LCDVD[5] */
LPC_IOCON->P1_20 = (PIN_FUNC_LCDVD_6 | PIN_MODE_PLAIN);     /* LCDVD[6] */
LPC_IOCON->P1_21 = (PIN_FUNC_LCDVD_7 | PIN_MODE_PLAIN);     /* LCDVD[7] */ 
 
LPC_IOCON->P4_28 = (PIN_FUNC_LCDVD_10 | PIN_MODE_PLAIN);   /* LCDVD[10] */
LPC_IOCON->P4_29 = (PIN_FUNC_LCDVD_11 | PIN_MODE_PLAIN);   /* LCDVD[11] */
LPC_IOCON->P1_22 = (PIN_FUNC_LCDVD_12 | PIN_MODE_PLAIN);   /* LCDVD[12] */
LPC_IOCON->P1_23 = (PIN_FUNC_LCDVD_13 | PIN_MODE_PLAIN);   /* LCDVD[13] */
LPC_IOCON->P1_24 = (PIN_FUNC_LCDVD_14 | PIN_MODE_PLAIN);   /* LCDVD[14] */
LPC_IOCON->P1_25 = (PIN_FUNC_LCDVD_15 | PIN_MODE_PLAIN);   /* LCDVD[15] */
 
LPC_IOCON->P2_13 = (PIN_FUNC_LCDVD_19 | PIN_MODE_PLAIN);   /* LCDVD[19] */
LPC_IOCON->P1_26 = (PIN_FUNC_LCDVD_20 | PIN_MODE_PLAIN);   /* LCDVD[20] */
LPC_IOCON->P1_27 = (PIN_FUNC_LCDVD_21 | PIN_MODE_PLAIN);   /* LCDVD[21] */
LPC_IOCON->P1_28 = (PIN_FUNC_LCDVD_22 | PIN_MODE_PLAIN);   /* LCDVD[22] */
LPC_IOCON->P1_29 = (PIN_FUNC_LCDVD_23 | PIN_MODE_PLAIN);   /* LCDVD[23] */

LPC_IOCON->P2_0 = (PIN_FUNC_LCD_PWR | PIN_MODE_PLAIN);           /* LCD_PWR */
LPC_IOCON->P2_2 = (PIN_FUNC_LCD_DCLK | PIN_MODE_PLAIN | HYSTERESIS_MODE);          /* LCD_DCLK */
LPC_IOCON->P2_3 = (PIN_FUNC_LCD_FP | PIN_MODE_PLAIN);            /* LCD_FP - V SYNCH */
LPC_IOCON->P2_4 = (PIN_FUNC_LCD_ENAB_M | PIN_MODE_PLAIN);        /* LCD_ENAB_M */
LPC_IOCON->P2_5 = (PIN_FUNC_LCD_LP | PIN_MODE_PLAIN);            /* LCD_LP - H SYNCH*/

LPC_LCD->CTRL = 0;  // turn off LCD if on
LPC_LCD->INTCLR = 0x1F;  // CLEAR ANY PENDING IRQS


LPC_LCD->TIMH = (TIMH_HBP<<24) |   \
                  (TIMH_HFP<<16) | \
                  (TIMH_HSW<<8) |  \
                  (TIMH_PPL<<2) |  \
                  (TIMH_RSV<<0);
 
LPC_LCD->TIMV = (TIMV_VBP<<24) |    \
                  (TIMV_VFP<<16) |  \
                  (TIMV_VSW<<10) |  \
                  (TIMV_LPP<<0);

LPC_LCD->POL = (POL_PCD_HI<<27) | \
                 (POL_BCD<<26) |  \
                 (POL_CPL<<16) |  \
                 (POL_RSV<<15) |  \
                 (POL_IOE<<14) |  \
                 (POL_IPC<<13) |  \
                 (POL_IHS<<12) |  \
                 (POL_IVS<<11) |  \
                 (POL_ACB<<6) |   \
                 (POL_CLKSEL<<5) | \
                 (POL_PCD_LO<<0);

LPC_LCD->LE = 0;

LPC_LCD->UPBASE = 0x90000000;  // sets the frame buffer address

LPC_LCD->LPBASE = 0x00000000;
LPC_LCD->INTMSK = 0;// NO INTERRUPTS FROM LCD

LPC_LCD->CTRL = 0x0000082D;  // RGB 565

LPC_SC->LCD_CFG = 0x07;  // No panel clock prescaler

Thanks,
RMoss
Labels (1)
0 Kudos
14 Replies

998 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by studyembedded on Sat Feb 28 00:35:10 MST 2015
This post solved my LCD orientation problem...thanks Guys!
0 Kudos

998 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rmoss on Thu Feb 07 07:25:34 MST 2013
The multiple image issue was a result of the SRAM Address bus only had A0 - A15 and it is an 8 bit access only resulting in only 65kB addressable space.

Thanks,
RM
0 Kudos

998 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rmoss on Tue Feb 05 08:23:39 MST 2013
You are correct, those settings I had to change.  Now I still have these multiple images on the same screen.  I played around with the Horizontal Back porch and was able to now fill the whole screen instead of 1/3 of the image shifted off screen.  I think the multi image is with the HSYNC, VSYNC, FP, BP etc settings.  I do know the Displaytech screen can only have a 6.35 MHz pixel clk, which I have set.  I am still struggling with the other settings and will get some scope images soon.

Thanks
Rm
0 Kudos

998 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Wouter on Tue Feb 05 03:09:39 MST 2013
Good to hear it's not swapped anymore!

<a href=http://www.displaytech-us.com/2-8-inch-tft>Looking at the Displaytech website</a>, the LCD is indeed not 320 * 240, but 240 * 320.

It's not really clear to me what you did or did not change, but TIMH_PPL should be 14, TIMV_LPP should be 319, and POL_CPL should be 239.

Regards,
Wouter
0 Kudos

998 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rmoss on Mon Feb 04 08:05:14 MST 2013
I had to use the driver:
#define DISPLAY_DRIVER GUIDRV_LIN_OSY_16  // Swap X Y mirror Y

This fixed the orientation, but I still have more than once copy on the screen.  I have found this is a 240x320 display, so I had to change emWin X Define to 240 and Y Define to 320.  I also had to make the LPC1788 Registers for a 240x320 display.  This shifted the LCD contents to cover the entire screen, with multiple copies still present.  I have the pixel clock at 6.4 MHz for this ILI9341 Display.  Can Horizontal or Vertical Sync timing cause the multiple copies?

#define TIMV_LPP    319
#define POL_CPL    239

Thanks
RMoss
0 Kudos

998 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Wouter on Mon Feb 04 03:11:02 MST 2013
Hi rmoss,

Please try changing line:
<code>
#define DISPLAY_DRIVER GUIDRV_LIN_16
</code>

into:
<code>
#define DISPLAY_DRIVER GUIDRV_LIN_OS_16            /* 16bpp, X and Y swapped */
</code>

This should swap the X and Y axis.

Regards,
Wouter
0 Kudos

998 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rmoss on Thu Jan 31 14:03:49 MST 2013
I heard back from the display manufacturer, who stated:

"Your best bet is to adjust the orientation of the output of your controller.  There are memory scan direction controls on-board the ILI9341, although they really only apply to the parallel connection (when the device is using its internal RAM).  The reason the image is only 2/3 of the display is that the RGB signal coming out is in the opposite orientation that the ILI9341 is expecting, i.e. you are writing 320 pixels in one direction when it should be 240 and vice-versa in the other direction.

Almost all graphics controllers allow you to swap the orientation of the frame buffer with one or two register settings, doing so on the NXP should be relatively trivial as well.  If not, you will need to change your primitive graphics functions (those that write pixels to the frame buffer) to flip the orientation by which they put pixels on the screen."

I have yet to find a register setting for the LPC1788 that fits this description.  Anyone know if there is a setting for this?

Thanks,
RMoss

0 Kudos

998 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rmoss on Thu Jan 31 07:53:12 MST 2013
Here is my register setup for the SRAM.  My EMC is running at CLK/2 -> 60MHz.



static void _StaticRAM_Init(void) {
  volatile U32 CmdDly;
  volatile U32 Dummy;
  volatile U32 i;

  LPC_SC->PCONP     |= (1 << 11);   // Turn on EMC peripheral clock
  LPC_SC->EMCDLYCTL  = 0x00001010;
  LPC_EMC->Control   = 1;           // EMC enable
  LPC_EMC->Config    = 0;
  //
  // Port init
  //
  LPC_IOCON->P3_0  = 1;  // D0
  LPC_IOCON->P3_1  = 1;  // D1
  LPC_IOCON->P3_2  = 1;  // D2
  LPC_IOCON->P3_3  = 1;  // D3
  LPC_IOCON->P3_4  = 1;  // D4
  LPC_IOCON->P3_5  = 1;  // D5
  LPC_IOCON->P3_6  = 1;  // D6
  LPC_IOCON->P3_7  = 1;  // D7

  LPC_IOCON->P4_0  = 1;  // A0
  LPC_IOCON->P4_1  = 1;  // A1
  LPC_IOCON->P4_2  = 1;  // A2
  LPC_IOCON->P4_3  = 1;  // A3
  LPC_IOCON->P4_4  = 1;  // A4
  LPC_IOCON->P4_5  = 1;  // A5
  LPC_IOCON->P4_6  = 1;  // A6
  LPC_IOCON->P4_7  = 1;  // A7
  LPC_IOCON->P4_8  = 1;  // A8
  LPC_IOCON->P4_9  = 1;  // A9
  LPC_IOCON->P4_10 = 1;  // A10
  LPC_IOCON->P4_11 = 1;  // A11
  LPC_IOCON->P4_12 = 1;  // A12
  LPC_IOCON->P4_13 = 1;  // A13
  LPC_IOCON->P4_14 = 1;  // A14
  LPC_IOCON->P4_15 = 1;  // A15

  LPC_IOCON->P4_24 = 1;  // OE
  LPC_IOCON->P4_25 = 1;  // WE

  LPC_IOCON->P4_31 = 1;  // CS1


  LPC_EMC->StaticConfig1 = 0x00000080;
  LPC_EMC->StaticWaitWen1 = 0;  // clocks between CE and WR (n+1)
  LPC_EMC->StaticWaitOen1 = 0;  // clock between CE/ADDR and OE
  LPC_EMC->StaticWaitRd1 = 5;   // clocks read wait states (n + 1)
  LPC_EMC->StaticWaitPage1 = 5; // page mode wait states (n/a)
  LPC_EMC->StaticWaitWr1 = 4;   // delay from CS to write (n+2)
  LPC_EMC->StaticWaitTurn1 = 1; // turn around delay (n+1)
}

Thanks,
RMOss
0 Kudos

998 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by khall_sdg on Thu Jan 31 07:29:19 MST 2013
I'm dealing with a similar issue that uses the LPC1788FBD144 in conjunction with 4MB of SRAM (ISSI p/n S62WV5128DBLL-45HLI) Could this be a Static RAM issue with this part?
0 Kudos

998 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rmoss on Mon Jan 28 10:40:32 MST 2013
I did try the single buffer before with the same results.  The function LCD_X_Config() is being called and I can hit the breakpoint.

0 Kudos

998 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by mc on Mon Jan 28 10:16:58 MST 2013
Hi RMoss,
Put breakpoint in below function. Also try to use single buffer first. Use #define NUM_BUFFERS 1

Do not use Virtual screen and multiple buffering together.
void LCD_X_Config(void) {

  GUI_MULTIBUF_Config(NUM_BUFFERS);
  //
  // Set display driver and color conversion for 1st layer
  //
  GUI_DEVICE_CreateAndLink(DISPLAY_DRIVER, COLOR_CONVERSION, 0, 0);
  //
  // Display driver configuration, required for Lin-driver
  //
  if (LCD_GetSwapXY()) {
    LCD_SetSizeEx (0, YSIZE_PHYS, XSIZE_PHYS);
    LCD_SetVSizeEx(0, YSIZE_PHYS, XSIZE_PHYS);
  } else {
    LCD_SetSizeEx (0, XSIZE_PHYS, YSIZE_PHYS);
    LCD_SetVSizeEx(0, XSIZE_PHYS, YSIZE_PHYS);
  }
  LCD_SetVRAMAddrEx(0, (void *)VRAM_ADDR);
}

--------
Thanks,
NXP Support
0 Kudos

998 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rmoss on Mon Jan 28 09:50:36 MST 2013
Attached is my LCDConf.c file.  I did try to do the GUI_SetOrientation(GUI_SWAP_XY | GUI_MIRROR_Y) but emWin crashed in GUI_Init().

Thanks,
RMoss
0 Kudos

998 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by mc on Mon Jan 28 09:44:20 MST 2013
Hi RMoss,
We do not have your emWIn LCD configuration file LCDConf.c file, but looks like you may need to swap X and Y using following hash define in this file

#define DISPLAY_ORIENTATION (GUI_SWAP_XY)

If it doesn't solve your problem, could you please post LCDConf.c file?

Thanks,
NXP Support
0 Kudos

998 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rmoss on Mon Jan 28 09:35:43 MST 2013
I would also like to add my static RAM init Regiser settings. 

static void _StaticRAM_Init(void)
{

  LPC_SC->PCONP     |= (1 << 11);   // Turn on EMC peripheral clock
  LPC_SC->EMCDLYCTL  = 0x00001010;
  LPC_EMC->Control   = 1;           // EMC enable
  LPC_EMC->Config    = 0;
  //
  // Port init
  //
  LPC_IOCON->P3_0  = 1;  // D0
  LPC_IOCON->P3_1  = 1;  // D1
  LPC_IOCON->P3_2  = 1;  // D2
  LPC_IOCON->P3_3  = 1;  // D3
  LPC_IOCON->P3_4  = 1;  // D4
  LPC_IOCON->P3_5  = 1;  // D5
  LPC_IOCON->P3_6  = 1;  // D6
  LPC_IOCON->P3_7  = 1;  // D7

  LPC_IOCON->P4_0  = 1;  // A0
  LPC_IOCON->P4_1  = 1;  // A1
  LPC_IOCON->P4_2  = 1;  // A2
  LPC_IOCON->P4_3  = 1;  // A3
  LPC_IOCON->P4_4  = 1;  // A4
  LPC_IOCON->P4_5  = 1;  // A5
  LPC_IOCON->P4_6  = 1;  // A6
  LPC_IOCON->P4_7  = 1;  // A7
  LPC_IOCON->P4_8  = 1;  // A8
  LPC_IOCON->P4_9  = 1;  // A9
  LPC_IOCON->P4_10 = 1;  // A10
  LPC_IOCON->P4_11 = 1;  // A11
  LPC_IOCON->P4_12 = 1;  // A12
  LPC_IOCON->P4_13 = 1;  // A13
  LPC_IOCON->P4_14 = 1;  // A14
  LPC_IOCON->P4_15 = 1;  // A15

  LPC_IOCON->P4_24 = 1;  // OE
  LPC_IOCON->P4_25 = 1;  // WE

  LPC_IOCON->P4_31 = 1;  // CS1


  LPC_EMC->StaticConfig1 = 0x00000080; // 8 bit memory width, BLS3:0 R/W active LOW
  LPC_EMC->StaticWaitWen1 = 0;  // clocks between CE and WR (n+1)
  LPC_EMC->StaticWaitOen1 = 0;  // clock between CE/ADDR and OE
  LPC_EMC->StaticWaitRd1 = 5;   // clocks read wait states (n + 1)
  LPC_EMC->StaticWaitPage1 = 5; // page mode wait states (n/a)
  LPC_EMC->StaticWaitWr1 = 4;   // delay from CS to write (n+2)
  LPC_EMC->StaticWaitTurn1 = 1; // turn around delay (n+1)
}
0 Kudos