GPIO output timings to control LCD

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

GPIO output timings to control LCD

522 Views
MikeMarynowski
Contributor III

Hi,

 

I am using the MFC52254 and loving it so far, very easy to implement Ethernet, USB, and I2C.

 

What is the recommended method to properly time GPIO output? I have an 8-bit parallel bus to an LCD, and in Release mode, the GPIO writes happen too fast for the LCD interface to keep up.

 

Let's say that the LCD timing diagram shows that after writing data to the bus I need to drop WR pin and hold a minimum of 100ns, raise WR pin and hold a minimum of 100ns, then write next byte to the bus and repeat.

 

What is the recommended method to implement these timings?

 

Thanks in advance,

 

--Mike

Labels (1)
0 Kudos
2 Replies

343 Views
TomE
Specialist II

> What is the recommended method to implement these timings?

 

There are good ways and bad ways. The "bad ways" involve NOPS and other hand-generated delays and seem to work "now" but may not survive a compiler update, a recompile or a change in the clock or memory settings.

 

These chips usually have plenty of spare timers. The chip you're using has four DMA Timers - I'd use one of these.

 

Start one of these timers free-running at 1MHz or 10MHz or whatever is most useful for your timing. Then write something like:

#define LCD_TIMEOUT_NS  (100)

#define DMA_TIMER_MHZ  (10)
#define DMA_TIMER_NS_TO_TICKS(ns) (1 + ((ns) * DMA_TIMER_MHZ / 1000))
#define LCD_TIMEOUT_TICKS   (DMA_TIMER_NS_TO_TICKS(LCD_TIMEOUT_NS))

uint32_t nTimeStart = MCF_DTIM1_DTCN;

while ((MCF_DTIM1_DTCN - nTimeStart) < LCD_TIMEOUT_TICKS)
{
    ;
}

The above assumes DMA Timer 1 is runnng. You should make the above "function" a Macro or an Inline Function and call it with an appropriate parameter. Note that the minimum time of a timer delay like the above is LESS than you expect. if you call it with a count of "1" the timer may roll over during your test giving you a short time. That's why the macro above adds "1" to guarantee the minimum time.

 

100ns is pretty short. You'll probably find the overhead in the above code longer than that. The above sort of timer is usually good for delays in the order of microseconds and not nanoseconds.

 

If speed is important you could simply put 8 NOPs in a row at 80MHz to get a 100ns delay, except for a number of things:

 

  1. This assumes the CPU is running at 80MHz, and
  2. The code is running from the Cache, and
  3. A NOP takes one clock cycle.

 The first two may or may not be true now or later, and the third is certainly false. NOPs take three clocks. The STF is the "one clock NOP" on this CPU. So you could simply use 3 NOPs to get the delay with an inline "asm" instruction. You'll have to check you compiler to see what the syntax for this is.

 

The "standard Linux way" of doing this sort of thing is to start up a "known timer" and then to calibrate a simple NOP-based delay loop against that timer and then store the resulting count in a global. Then if something changes on the system the code will accommodate it.

 

Tom

 

 

 

0 Kudos

343 Views
MikeMarynowski
Contributor III

Thanks very much for your detailed and informative reply.

 

I was trying NOPs and dummy operations before and I thought maybe I was doing something wrong because it wasn't working when running faster in Release mode. I implemented your timer method and the LCD was still flaking out, so I threw some probes on the LCD data lines and found out that it just isn't writing data in release mode! I have no idea what the problem is, the CW72 project settings are identical between release and debug, and other code works fine. As soon as I switch to release, the values on the data lines doesn't get written.

 

I will post another my problem in another thread in a minute as it is fairly unrelated to this one, make it easier for anyone who might be having a similar problem find it later.

0 Kudos