I am attempting to link an ARM microcontroller (LPC2103) and a color TFT LCD screen (LP104V2 , 640x480 , TTL interface). The screen’s datasheet is found here: www.larwe.com/technical/datasheets/lp104v2-w.pdf
The code I’m using to run the screen is shown below
#include <targets/LPC210x.h>
//--------------------------------------------------------------------------
long pixel_number=0; //Horizontal position of scan
long row_number=0; //Verical position of scan
long delay_variable=0;
#define DCLK 0x00000004 //P0.2
#define HSYNC 0x00000008 //P0.3
#define VSYNC 0x00000010 //P0.4
#define DTMG 0x00000020 //P0.5
#define DATA 0x00000040 //P0.6 (This is blue data only)
#define button 0x00008000 //P0.15
//--------------------------------------------------------------------------
static void
ledInit()
{
IODIR |= 0x04000000;
IOSET = 0x04000000;
}
static void
ledOn(void)
{
IOCLR = 0x04000000;
}
static void
ledOff(void)
{
IOSET = 0x04000000;
}
void
delay(int d)
{
for(; d; --d);
}
//--------------------------------------------------------------------------
void LCD_config(void){ //Configure GPIO for LP104v2
IODIR=0xFF; //P0.0 : P0.7 set to outputs
IOCLR=0x00; //P0.0 : P0.7 LOW
pixel_number=0;
row_number=0;
IOSET=HSYNC; //H sync high
IOSET=VSYNC; //V sync high
IOSET=DATA; //Data high
}
void LCD_page(void){ //Scan a page into LP104v2
IOCLR=VSYNC; //Lower V sync
for(delay_variable=0; delay_variable<3397; delay_variable++);
//64uS delay
IOSET=VSYNC; //V sync high
for(delay_variable=0; delay_variable<554347; delay_variable++);
//1.02mS delay
do{
IOCLR=HSYNC; //Lower H sync
for(delay_variable=0; delay_variable<200; delay_variable++);
//3.77uS delay
IOSET=HSYNC; //H sync high
for(delay_variable=0; delay_variable<100; delay_variable++);
//1.89uS delay
IOSET=DTMG; //DTMG high
do{
IOSET=DCLK; //Data clock high
IOCLR=DCLK; //Data clock low
pixel_number++; //Increment pixel count
} while (pixel_number<639);
pixel_number=0;
for(delay_variable=0; delay_variable<49; delay_variable++);
//0.94uS delay
row_number++; //Increment line number
} while (row_number<478);
for(delay_variable=0; delay_variable<190217; delay_variable);
//0.35mS delay
row_number=0; //Reset line counter
}
//--------------------------------------------------------------------------
int
main(void)
{
MAMCR = 2;
ledInit();
ledOn();
delay(100000);
ledOff();
delay(100000);
LCD_config();
while (1)
{
LCD_page();
}
return 0;
}
I attached the data line to the Blue LSB on the LCD screen (Theoretically this will produce a dark blue when high). The only problem is that this is not happening. Nothing happens. I know the ARM is running and the startup code is correct because it flashes the status LED as stated in the code. Where have I gone wrong? help, anyone?
I suggest you attach an osciloscope and try and work out how the way you are driving it differ from the data sheet.
Unless you have a robot to connect the probes and a web interface on your scope there is little we can do here.
It is an interesting application for an LPC chip, most drive big LCD’s using a chip with a dedicated controller, but those chips tend to be much bigger and more complex.
I am guessing you have more than just the LPC chip in your design as it is hard to imagine doing anything useful with just the LPC chip, unless you want to code Space Invaders for it
Use the compare match/PWM hardware to do the syncs for you - this makes life MUCH easier.
LPC213x parts are a bit better as they have double-edge PWM which can do Hsync and DE with no software intervention at all, but you should be able to get something useful with 2103’s timer hardware.
As for generating patterns etc. more match outputs will give you rock-solid timing but limited by number of match pins and the match functions available, but some tricks like eloading teh match regs on a hsync interrupt should let you do some reasonable block graphics (pong etc.)
Oh, and use PWM or match outputs to generate the pixel clock as well, so this stays synced accurately to your sync timings.
Another handy trick for displaying text is to use the SPI/SSP hardware as a shift-register to output 1 bit/pixel data - with care you ught to be able to get reasonable mono text resolution.
Looking at your code, you aren’t generating a pixel clock all the time - I would expect TFT panels like to see a pixel clock all the time, i.e. during syncs, although I’ve never actually tried running one without it.
Can you explain it more? What do tou mean with the code above is not generate the pixel clock all the time? I think the code is generate the Hsync and Vsync all the time because of function LCD_page was called all the time in the main program (using while(1))
You are not generating DCLK during HSYNC/VSYNC. I suspect the TFT wants to see a continuous DCLK - use the toggle-on-match timer function to generate this in hardware.
Do you mean from the code above, when the Vsync and the Hsync is executed,the DCLK is not executed? It’s executed just after the Vsync and the Hsync executed. And you suspect the TFT LCD must have the DCLK all the time. So, the code above has a little mistake…???
But, I want to ask something.
Why I think that the code above is correct, it’s because I think that the timing (DCLK) for the TFT LCD is used to ‘put in’ the ‘data’ in every 1 clock (falling or rising–> it depends). So, if we want to start to send the data, during the Hsync or the Vsync, I think we can send the data and clock it, and so on for the other data…we don’t need to generate the DCLK every time. Is my suggestion right or not? Or, to make the TFT LCD works, we must ‘give’ a continuous clock(DCLK) like waht you suspected? If we use a timer, can you tell me when I must send the data? It’s during the high period or low period? or maybe we can send it anytime?
Sorry for the question…
Maybe it will get you confuse just to read my question. But, I hope you can help me…
All TFT data I have ever seen show DCLK present all the time. It is highly likely that it is used internally - e.g. it may be clocking the Hsync & Vsync inputs and using the clock to generate the timings required to shift data into the drivers on the. It may also be used to run charge pumps etc. to generate internal voltages.
Your best chance of getting something working is to make your timing match those in the datasheet (If you don’t have full data for ypur panel, look at data for a similar panel - chances are it will be close enough).
Read the timer part of the UM, hook up a scope and get the timings as close as you can to those specified in the display’s datasheet.