This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM335x Updating Pixel Data with LCD Controller in Raster Mode

Other Parts Discussed in Thread: AM3358

Hi!

I have an AM3358 currently successfully displaying an image where the LCDC is in Raster Mode with 800x480 uncompressed RGB888 frame buffers and both FB0 and FB1 DMA pointers point to the same frame buffer.  I may switch this to a ping-pong buffer scheme later, but had set it up this way for testing purposes -- mainly to see if updating the pixel data on the fly would cause any display problems (my system has the advantage of some reduced complexity if there is only a single frame buffer and there is no "tearing" or other distortions of the image if writing to the frame buffer works well in the displayed image).  My frame rate is 65 Hz.

However, I am running into a problem.  I have just studied the 6545.LCDC.pdf document ("Sitara ARM Processors BOOT CAMP:  LCD Controller"), but it does not describe the problem I am having or its solution, and DOES imply I should be able to do what I am doing. What has worked WELL so far is putting the base image in place and THEN turning the LCD controller on to display it.  The original image is perfect.  No pixels are missing or altered, and the colors are vibrant and exactly as designed.  However, the first test I did was trying to wipe out the entire screen to black by writing zeros across the entire frame buffer from the CPU (Cortex-A8). 

This is the loop that writes it.  The array is an array of  uint32_t's.

	fb_pixel_t  * lpixpDest, * lpixpAfterFrameBuffer;

	lpixpDest = S1D13517sim_qpixpBufferAddress(gS1D13517RegisterSet.iInputMode.iui8WriteBufferIndex);
		/* Sets 'lpixpDest' to the base of the pixel area of the frame buffer. */
	lpixpAfterFrameBuffer = lpixpDest + (sizeof(pixel_area_800x480_t) / sizeof(fb_pixel_t));
		/* Sets 'lpixpAfterFrameBuffer' to point to first 'uint32_t' after pixel area. */

	/* This process clears the screen but leaves streaks of the old colors!
	 * It's like the DMA is interfering with screen writing, or...
	 * not all the writes are making it to RAM!
	 */
	while (lpixpDest < lpixpAfterFrameBuffer) {
		*lpixpDest = apixColor;
		lpixpDest++;
	}

where this exists in the header file:

typedef  uint32_t   fb_pixel_t;

What I expected was to see my display instantly turn black.  However, what I saw instead was that some of the original image is left on the screen -- in broken horizontal bands.  Some stripes are as wide as 10-12 pixels (height), and go all the way across the LCD panel.  Others are as narrow as 1-2 pixels (height).  So basically after ONE loop, I have a black screen with horizontal bands of the original image left.  (See picture below.)

If I run that same loop under the debugger again, it converts more of the remaining image to black.  If I run that same loop (just by repeating it under the debugger) 2-3 more times, it will finally wipe all the colored pixels out and leave the whole screen black.

Here are my questions:

1.  Is DMA reading/sending to the LCD panel interfering with writing to the frame buffer (as if blocks of RAM were locked while the DMA is reading it)?

2.  What is it going to take to make the image update smoothly and reliably?

Kind regards,
Vic

  • P.S.  This is what it looks like if I use a   memset(&frame_buf_0, 0, sizeof(frame_buf_0))   function to do the same thing.

  • Hi,

    I am attaching a document which you may find useful to see how the FB system works:

    1273.LCDC.pdf

  • Hi, Biser!

    This is the document whose BUFFER MANAGEMENT section I studied regarding the above (I found this document in another Forum posting where you posted this document), and it didn't seem to indicate what the conflict might be. (At least there was no warning or mention about writing to a buffer that is being displayed. There IS a warning about not updating the DMA's frame buffer base/ceiling registers while the DMA is reading those registers, and gives excellent prediction about when that is expected to happen.)

    By the banding in my display, I can only assume that the CPU write to RAM WHILE the DMA was accessing it actually failed. However, I see now that the section in BUFFER MANAGEMENT regarding SINGLE BUFFER USAGE does not state or imply that writing to a buffer that is currently being displayed is okay, but rather updating the DMA's buffer0 base/ceiling registers after each EOF0 interrupt is how it is managed, and indeed this mode is intended to use different buffers frame to frame. Thus IMPLYING (rather than stating explicitly) that the CPU should only be writing to a frame buffer that is NOT currently being sent to the LCD panel by the LCDC DMA.

    Would you concur with this?

    Kind regards,
    Vic

  • Yes, your understanding is correct. The FB driver in the Linux SDK uses ping-pong buffering.
  • Thank you, Biser! This is going to be very satisfying to get running! :-)