MCF5329 LCD Frame Flip Timing, when is LCD_SSAR copied?

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

MCF5329 LCD Frame Flip Timing, when is LCD_SSAR copied?

1,105 Views
TomE
Specialist II

I'm trying to do( what is effectively) animation using the LCD controller on the MCF5329.

 

The way to do this is:

 

  1. Have a Front (memory) Buffer and a Back Buffer, both the size of the frame,
  2. The LCD controller is displaying the Front Buffer,
  3. The next frame is composed/drawn/copied in/to the Back Buffer,
  4. At "the right time", The LCD_SSAR reg is loaded with the Back Buffer's address,
  5. Wait until the controller has taken/copied LCD_SSAR and is now displaying the new frame,
  6. Compose the next frame in the new back buffer (the old front buffer)
  7. Go back to Step 4.

The problem is getting the timing right.

 

Which requires use of the LCD controller interrupts.

 

There is nothing in the Reference Manual giving the timing or the operation, apart from register descriptions.

 

Testing shows the LCD_SSAR register isn't "live". If written during a frame the screen output doesn't change. The controller copies LCD_SSAR into some internal and invisible DMA controller SOMETIME before, during or after the vertical blanking time.

 

There are four interrupts available:

  1. Last word of data read for frame,
  2. Last word of data of frame sent to LCD panel,
  3. First word read for start of (next) frame,
  4. First word of data for frame sent to LCD panel.

As far as I can tell, the first three happen pretty much within the same microsecond, at the end of the frame and before the Vertical Sync and Blanking. The fourth one happens after the vertical blanking at the start of the frame.

Also note that the LCD controller has already decided on where the data for the next frame is and the end of the previous frame.

 

So how to flip frames and do it FAST enough for animation?

 

Initially we assumed that LCD_SSAR was "live" and had to be written between frames (after a vertical interrupt). That didn't work due to it being copied somewhere.

 

Are there any documents giving the real timing of the four interrupts, the video and the loading of LCD_SSAR? I've spend days on reverse engineering and I don't know enough to guarantee reliable programming (without flashes and frame overwrites) yet.

 

That's difficult enough. If I then want to animate the cursor or pan the frames back and forth I need the timing of the operations of the panning registers (like LCD_POR and how to change it and LCD_SSAR together).

 

Thanks.

 

 

reverse engineering this hardware

 

If I wait for the interrupt and reload LCD_SSAR between frames (just after interrupts 1, 2, 3) then the hardware doesn't use that value until after the NEXT interrupt and I can only  get 30 frames/second and can only write to the back buffer half the time

Labels (1)
0 Kudos
2 Replies

275 Views
TomE
Specialist II

The operation of the LCD_SSAR register is documented, but not under the section documenting that register or anywhere a search for "LCD_SSAR" would find it:

 

22.4.3 PanningPanning offset (POS) is expressed in bits, not pixels, so when operating in
any mode other than 1 bpp, only even pixel boundaries are valid. In 12
bpp mode, the pixels are aligned to 16-bit boundaries, and POS alsomust align to these boundaries.
SSA and POS are located in isolated registers and are double buffered
because they are dynamic parameters likely to change while the LCDC
is running. New values of SSA and POS do not take effect until the
beginning of the next frame. A typical panning algorithm includes
an interrupt at the beginning of the frame. In the interrupt service
routine, POS and/or SSA are updated (the old values are internallylatched). The updates take effect on the next frame.

 So that means that the buffer could be changed during the LCD interrupt to take effect on the next frame, but that requires TRIPLE buffering of graphics.

 

Double buffering works all the way up to the frame rate if the code:

 

1 - Waits for the "back buffer busy" flag to clear,

2 - Writes to the Back Buffer,

3 - Disables interrupts

4 - Writes the Back Buffer address to LCD_SSAR

5 - Sets the "back buffer busy" flag.

6 - Enables interrupts.

 

A - The Interrupt Service Routine clears the "back buffer busy" flag, and could trigger (or perform) the next frame write pass.

 

==============

I asked this question of Freescale through our Distributor, and got the following answer that provides more details on what is happening, but is rather pessimistic:

 

 

I think the main issue here is caused by how the DMA for the LCDoperates. The descriptions of the interrupts is accurate, but the timingfor when these events occur is different than your expectation becausethe DMA interface the LCD uses to fetch data loads a buffer.The LCD controller has a 32 x 32 (32 longwords) buffer used to storedata for the LCD. The DMA will read in data as determined by thehigh mark and trigger mark settings in the LCD_DCR (DMA controlregister). The LCD will start reading data for the next frameimmediately after reading the data at the end of the previous frame inorder to keep the line buffer full and prevent the possibility ofunderruns in the LCD controller.This makes switching the LCD start address between the end of thecurrent frame and the start of the next pretty much impossible to doconsistently. Once an image starts loading from the current startaddress the value of A[31:22] is fixed. So updates to the start addresswon't take affect until the next frame. Since you mentioned panning, Ishould also mention that the LCD_POR is read in at the start of a frameand won't update with a new value until the next frame too.This means you could use any of the four available interrupt sources totrigger an interrupt handler that updates the start address. It's justthat the new start address won't actually take effect until the NEXTframe. So you can update every frame, but the catch is that you'llalways be one frame behind, which isn't detectable to a person watchingthe screen anyway as long as you keep the sequence of the framescorrect.The real issue is the bandwidth. If you want to redraw the entire screenfor each frame that can mean a lot of CPU, system bus, and external busbandwidth. The architecture and speeds of the MCF532x don't really allowthe bandwidth needed for 60fps animation unless you are only redrawingsmall portions of the screen each frame, and even then you wouldn't havemuch bandwidth left over for other functions.I hope this helps to make things clearer. Let me know if you have otherquestions.

 

 

There seems to be plenty of memory bandwidth for 60 FPS animation in QVGA screen sizes.

 

QVGA is 240 * 320 * 2 bytes, or 153600 bytes. At 60FPS the LCD controller is moving the data from RAM to the LCD panel at 9.2MB/s, or about 7% of the 128MB/s SDRAM bandwidth.To copy a frame from memory to the buffer takes twice that (half for the read, half for the write) or another 18.4MB/s.

 

I've benchmarked the normal libc memcpy() on cache-aligned copies at 38MB/s, and a movem.l-based one I got from this forum at 46MB/s, so there's plenty of bus and CPU time free for other activities.

 

Of course if all the images in an animation sequence are in memory then it is only necessary to change the LCD_SSAR pointer to the images in sequence. Building up images by copying in sections and backgrounds doesn't take much longer.

 

 

 

0 Kudos

275 Views
TomE
Specialist II

Back in early 2010 I asked our Freescale support people the following question:

 

> Date: Fri, 15 Jan 2010 10:28:11 +1100>> Are there any documents giving the real timing of the four> interrupts, the video and the loading of LCD_SSAR? I've spend> days on reverse engineering and I don't know enough to guarantee> reliable programming (without flashes and frame overwrites) yet.

 

I now have an answer, which can be summarised as:

 

                NO

 

There are no documents, and the timing is still unspecified and unknown.


Which makes it very easy to write graphics code that doesn't work accasionally, where the screen flickers and flashes when the software and hardware get out of sync. Very visible bugs.

 

While writing code to try and measure the timing, I ran across a nasty bug in the LCDC which means that you can't trust the contents of the LCDC LCD_ISR Interrupt Status Register to tell you what is going on inside the module. That is documented here:

 

https://community.freescale.com/message/88350#88350

 

But back to the SSAR reload timing. Here's what I asked Freescale through our representative a few months ago, which also explains the timing I was measiring (I've edited this slightly for the benefit of this forum):

 

Subject: Re: Freescale MCF5329 LCD Controller SSAR Load TimingDate: Mon, 23 May 2011 12:06:53 +1000    QUESTION    ========    When does the SSAR reload take place relative to the    EOF and BOF interrupts? Does it happen immediately    after (or possibly even slightly before) the EOF,    just prior to the BOF or mid-way? How many nanoseconds.    How many clock edges (and which clocks)?Here's a diagram giving the timing I'm seeing, and deriving the "4.5us" figure I'll keep mentioning:Pixel Data (8MHz)__i__i__i__i__i__i__i__i__i__i_ // I_i__i__i__i_FIFO depth pix   26 25 24 31 38 45 51 58 57 56   //  25 24 23 31DMA Read                  R4 R4 R4 R4 R4         //        R4 R4Interrupts?                        EOF ^               BOF ^LSSAR Reload     __________?????????????????????????????????______Time                      |<-- 550ns -->|<---  4.5 us ---->|The 16-bit pixel rate is 8MHz. The "screen" is 400 * 210. The video DMA is set for 20-word bursts. This means the BOF and EOF indications are 4.5us apart. "R4" above is a four-32-bit burst read of the SDRAM (at 11 80MHz clocks per burst, totaling 550ns). These happen in burst of 5, taking500ns each and spaced at 5us. The SSAR is (assumed to be) reloadedsomewhere between the EOF and BOF indications, with a 4.5us uncertainty.

 

The answer I got back from Freescale was:

 

Subject: RE: Freescale MCF5329 LCD Controller LCD_ISR Missing Signals on ReadingDate: Fri, 10 Jun 2011 08:04:33 +08001) For the SSAR reload question, the SSAR is reloaded at the exact time that the EOF interrupt occurs. This is why the recommendationin the reference manual is to load it at BOF, to ensure it won'tbe misloaded. Hopefully this information can enable you to achievethe LCD refresh that you are trying to create.

I then wrote some code to test the above, and found that the SSAR Reload happens somewhere between the time where the EOF is generated, and 1500us BEFORE that!

 

After reporting that back I now have a more definite answer:

 

Subject: RE: Freescale MCF5329 LCD Controller LCD_ISR Missing Signals on ReadingDate: Fri, 8 Jul 2011 07:04:26 +0800To close out the discussion, I was able to get some more clarificationfrom the design team. The new SSAR value takes effect when the once the current frame is finished. This is what triggers an EOF interrupt,but hence why the load could occur slightly before that. I apologizefor misunderstanding earlier when I wrote that it would occur exactly atthe same time as the EOF interrupt, it was specifically to the end of frame internal to the LCD controller instead.

Summarising:

 

The new SSAR value takes effect when the ... current frame is finished (measured at) the end of frame internal to the LCD controller.

 

Those "internal" events aren't visible externally.

 

But it seems to be like the following in our case, with different clocks and memory timing it'll be different):

 

Pixel Data (8MHz)__i__i__i__i__i__i__i__i__i__i_ // I_i__i__i__i_FIFO depth pix   26 25 24 31 38 45 51 58 57 56   //  25 24 23 31DMA Read                  R4 R4 R4 R4 R4         //        R4 R4Interrupts?                        EOF ^               BOF ^Time                      |<-- 550ns -->|<---  4.5 us ---->|LSSAR Load _?????_Somewhere_in_here_?????______________________Time        |<----- 1500ns ------------>|

 To handle the measured 1500ns of uncertainty, my graphics code reloads the SSAR and then waits (in a hard loop with interrupts disabled) for 3us (double 1500ns) to see if the EOF interrupt happens in that time. It can't read the LCD_ISR as that doesn't work, so it has to monitor the interrupt controller registers. If the interrupt has happened then the reload may or may not have worked, and this has to be signaled to the EOF interrupt code so it knows to skip to the next interrupt before allowing more writes.

 

Tom

 

0 Kudos