DMAChannel Confusion

Status
Not open for further replies.

awesome101

Well-known member
So I read up on DMAChannels and my question is, can I have a buffer full of pixel data (the source buffer) and send this data to the GPIOC_PDOR register one byte at a time via a DMAChannel (maybe even many DMAChannels)?
 
Yes, you can. But there are important details to consider, especially what will trigger the DMA channel to send each byte. Perhaps a transition on a pin? Or maybe a timer?
 
To me the real question is why? That is I assume you are talking about the ili9341 8 bit mode code you were debugging.

That is you are not simply wanting to write each byte out to the GPIO port, but also for each byte you need to play with another IO pin. In particular you need the WRITE strobe to happen and there are some timing constraints on when the write pin should go high and low. Also depending on your memory layout for pixels, the order of bytes per pixel in memory may not match the order of bytes you need to output to the display.

Personally I think it would be much easier to use the SPI mode. I have seen 3 implementations using DMA to update the ILI9341 display.
a)Frank's version - which works great with his flex board and for updating the memory for video... ili9241_T3DMA
b) My version derived from Frank's in ili9341_t3n - Fixed an issue from Frank's earlier code that no longer need to redraw the screen first without DMA before entering continuous DMA mode...
c) An experimental mode I did based off of b) that uses some proposed Async SPI transfer functions, I have in my SPI library that may or may not get incorperated in main one. The byte ordering issue I mentioned above is one reason I added SPI.transfer16(buf, retbuf, cnt) - Multiple 16 bit writes SYNC... and SPI.transfer16(buf, retbuf, cnt, callback) - for ASYNC... But again these are not in current released (beta) SPI library.
 
The problem is my library is still too slow for a decent refresh rate in my gaming library. I can see the screen flickering. I'm looking for ways to clear the screen faster
 
That does not solve the problem. It will flicker faster, thats all. Dont clear the screen and redraw only updated areas. Thats still not good, but will be a lot better.
 
Do your ILI9341 display have the TE signal available? Most I've seen don't bring this out to any user-accessible pin. :(
 
I agree with Frank,

With the flicker, I often have noticed it is not necessarily the refresh rate that is the issue, it has more to do with how the screen is updated.

That is if your code is setup to do something like:
Code:
    tft.fillscreen(ILI9341_BLACK);
    <Draw new screen>
You will see flicker... unless of course you can exactly time it such that each pixel data is only touched and updated in one pass of the screen update (TE signal as Paul mentioned, I think?)

However if you are running a board that has enough memory to do a backing frame buffer (currently only T3.6), then you can do tricks to make it better. i.e Frank's DMA version or mine which I modeled after his.
In mine, you can turn on Frame buffer, then in the code.
You could do the above, but add a call to update... That is in my ili9341_t3n I have:
Code:
    tft.fillscreen(ILI9341_BLACK);
    <Draw new screen>
    updateScreen();   // which says do the update now.
I also have a version of the updateScreen (updateScreenDMA) which can do the update async using DMA... Either one shot or continuous...

But again I am not sure this fully solves your issue as, you might still see parts of one screen and then parts of another screen (tearing? ), but my guess is it would make your flicker look a lot better... I also have the ability to set clipping rectangle, so if you are only updating a portion of the display, it will do only that portion.

But again only good for T3.6 as this requires 320*240*2 (153,600) bytes, and only T3.6 has this much... I have thought about ways to make it work somewhat on lesser memory, but have not done so. Could setup logical clipping rectangle that at max is size of memory and build offsets into memory... Could convert from 16 bits per pixel to maybe 8 or 4 with color lookup...
 
Hmm. Having 4 bit color for the frame buffer would work (320/2 = 160. 160*240 = 38400 bytes). I can then store a color palette in RAM and then index it with the buffer data
 
I am only making small simple games so 4 bit color is fine. The only problem would be if it still is too slow and flickers/tears
 
Status
Not open for further replies.
Back
Top