DMA parallel output on T4.1

Status
Not open for further replies.

Rezo

Well-known member
I was provided a sample library from a forum member to drive a tft display via 8 bit parallel using digitalWriteFast() and we can get a full screen update (480x320) in roughly 5-6ms.
Performance wise it's fast, and I use it with LVGL with very good performance.
As I add more tasks to my project, I feel that I will loose out on performance at some point and therefore I was thinking of moving to DMA transfers for the screen update.
This will allow LVGL to write the next portion of the screen and/or other tasks to run while the DMA transfer happens - thus not blocking the rest of the application while the screen writes take place.

Are there any simple examples of how to do DMA transfers from an array to the one of the supported GPIOs? Specifically to match 8080 parallel interface? I don't mind trying to put something together from existing libraries but I have not come across any examples of DMA used with parallel output on the T4.1

I'm kind of lost as to where to start as there is not much info out there on this topic specifically for the T4.x, and actually this might be way more complicated and above my abilities. So if I'm way over my head, feel free to give me the painful truth :)

Thanks,
 
I have not done it, but Paul did it with the WS2812Serial library. You can look at that for an example.

I have played with it as Input pins to read in from camera, but not the other way.
With input you don't have the additional complication that you are going to screw up other IO pins that are on the same IO buss.

Although you may not have that issue on output either as you will need to convert those pins back from the faster IO buss to the normal IO buss. i.e. pins that when you are currently working with Port 6 you will be talking instead to Port 1...
 
I believe the file I should be looking into is OctoWS2811_imxrt.cpp, is that correct?
 
I believe the file I should be looking into is OctoWS2811_imxrt.cpp, is that correct?
That is the one.

Or again I could point you to the OV camera input code, which again would require changing the DMA inputs and outputs...

Also either case you will also need to figure out what is clocking the DMA in your case.
In my case on the camera it was an external clock (PIXCLK) which I wired to an XBAR pin, and used the XBAR system to connect that up the DMA channel ...

I believe in the OctoWS2811 case Paul is using one or more timers (Quad? ) and again using XBAR mapping to map the timer event into the DMA trigger...

So again you may have to figure out what triggers your DMA outputs to the display.
 
I was hoping to use code based trigger via a display flush callback from LVGL (they did it that way on an STM32F429 example with DMA)
But, this is where I feel I have far too less knowledge to even begin with DMA - I will have to put this to bed for some time, while I get familiar with all the methods, settings and peripherals associated with it
 
Coming back to this after a few weeks. @miciwans latest posts have been very helpful and getting my mind to understand how dma works on the code side and I now have a code example to build on.
One thing that I would like to know - what are valid triggers for DMA transfers? can I use a general purpose PWM or do I have to use FlexPWM and rout via xbar? I'm happy to be referred to the right chapter or page un the nxp user manual to do reading
 
The stuff describing DMA is in chapters 5 and 6 of the reference manual.

Chapter 4.4 shows you the DMAMUX sources.
You can find all of these DMAMUX sources in the imxrt.h file look at the defines that sart with DMAMUX_SOURCE_ (about line 174-)

However depending on where and how you use DMA, you may also need to look at the specific sections like SPI or LPUART or GPIO ... to see some specifics on things for that subsystem.
 
@KurtE thanks,

After going through many source codes repo's and reading the documentation, finally things are making much sense to me and I understand how the flow works.

My biggest dilemma now is which timer to use for the WRX line. miciwan's example uses flexpwm, but the problem I have with that is I cannot "stop" the pwm. I can only disable the MUX and reassign the pin to another source, but then I've had no luck toggling the pin manually with digitalWrite/digitalWriteFast.

So I went back to Paul's OctoWS2811 library and looked at how he is using the QuadTimer for his clocking of the data stream, and that makes sense, kind of.

If I use the Quad timer, can I feed it with a number of pulses I want to output? Let's say I want to to output 16 pulses and then stop, can that be configured? I'm reading the the relevant chapter in the documentation but the register names don't make a whole lot of sense to me. The lack of basic examples in the documentation make it just a little more challenging to get started.
 
Sorry, not sure if there is some specific way to tell a tell a timer like that how many pulses to do... You can probably have an interrupt or the like turn it on or off...

Another possibility for you might be with the FlexIO system, Chapter 50...
Also now a good write up about it in: https://github.com/TeensyUser/doc/wiki/FLEXIO

I have played with it some, to for example create addition Serial objects, likewise a s simple SPI object...
https://github.com/KurtE/FlexIO_t4
 
Sorry, not sure if there is some specific way to tell a tell a timer like that how many pulses to do... You can probably have an interrupt or the like turn it on or off...
I could actually do that in the DMA interrupt and stop it once the all the data as been pushed out.. I'll look into it.

Another possibility for you might be with the FlexIO system, Chapter 50...
Also now a good write up about it in: https://github.com/TeensyUser/doc/wiki/FLEXIO

I have played with it some, to for example create addition Serial objects, likewise a s simple SPI object...
https://github.com/KurtE/FlexIO_t4

I would love to try FlexIO as it can run at a much faster speed, but from reading on the NXP community no one has gotten it to work on the 1060, only the 1050 (at least per one of the application notes) and there seems to be very little to no information available as tp how to configure and use it. If you have a lead I'll be happy to play around and learn a bit more while I'm at it.
 
I would love to try FlexIO as it can run at a much faster speed, but from reading on the NXP community no one has gotten it to work on the 1060, only the 1050 (at least per one of the application notes) and there seems to be very little to no information available as tp how to configure and use it. If you have a lead I'll be happy to play around and learn a bit more while I'm at it.
Not sure what you are saying. No one has gotten what to work on 1060? Several of us have played some. I have a sketch that we used every hardware Serial port plus a lot of other Serial ports created by FlexIO, that the sketch allowed me to daisy chain on a board from Tx of one Serial port to the RX of the next... And transfer stuff through the chain...

Also at one point I was playing with a version of the Adafruit SSD1306, that I was playing with my SPI code...
https://github.com/KurtE/SSD1306_FlexIO

Again the previous post above has a ton of information, where for example recently I learned there are 8 timers/shifters. not 4...
Which started from the thread: https://forum.pjrc.com/threads/66201-Teensy-4-1-How-to-start-using-FlexIO?highlight=flexio
 
I mean that I have no seen anyone sucessfully implement the 8080 protocol with FlexIO. I'll keep reading and experimenting though
 
Status
Not open for further replies.
Back
Top