Dma port control

racemaniac
Fri Apr 22, 2016 6:55 pm
Just a little brainfart i wanted to post here :). I wanted to see how fast DMA could drive the ports, so i set up a DMA memory to memory transfer to the GPIO BSRR register. The result is the pin 11 toggling at nearly 4Mhz, but you can control the entire port (all 16 pins) at that speed with the transfer :).
I was wondering about fast ways to output parallel data, and gave this a try :).

#include <dma_private.h>

uint32_t toggle[1000];
void setup()
{
pinMode(11, OUTPUT);
pinMode(33, OUTPUT);
pinMode(32, INPUT);
for(int i = 0; i < 1000; i++)
toggle[i] = i%2 ? 0x00010000 : 0x00000001;
while(!digitalRead(32)); //it waits until you press the maple mini button
dmaTransfer(toggle, (uint32_t*)&GPIOA->regs->BSRR, 1000);

}

void loop()
{

}

void dmaTransfer(uint32_t* from, uint32_t* to, uint32_t dataLength)
{
dma_init(DMA1);
dma_setup_transfer(DMA1, DMA_CH1, from, DMA_SIZE_32BITS, to, DMA_SIZE_32BITS, DMA_PINC_MODE | DMA_MEM_2_MEM);
dma_set_num_transfers(DMA1, DMA_CH1, dataLength);
dma_enable(DMA1, DMA_CH1);
}


madias
Fri Apr 22, 2016 7:29 pm
Would be a interesting project to build a DMA port driven 16-bit parallel display driver. But I assume there is no 16-bit-parallel display on the cheap market that supports 4MHZ :)
But you can build a 16 Bit resistor divider DAC with that speed, the bad thing is, that you won’t get accurate 16-bit with a home build resistor divider network.

WereCatf
Fri Apr 22, 2016 7:41 pm
madias wrote:Would be a interesting project to build a DMA port driven 16-bit parallel display driver. But I assume there is no 16-bit-parallel display on the cheap market that supports 4MHZ :)

madias
Fri Apr 22, 2016 8:46 pm
WereCatf wrote:
The ILI9341 is cheap and it does support 16-bit parallel interface, but I don’t know how to actually drive one or anything else.

WereCatf
Fri Apr 22, 2016 9:21 pm
madias wrote:But I do not see a “real life application” for a super high speed TFT on a STMF1.

martinayotte
Fri Apr 22, 2016 9:37 pm
Simply because it is the CPU that knows what to draw.
Having some DMA for transferring something means that data come from a frame buffer :
Lets says the screen is 320×480 with rgb24 = 460K of RAM.

WereCatf
Fri Apr 22, 2016 10:12 pm
martinayotte wrote:Simply because it is the CPU that knows what to draw.
Having some DMA for transferring something means that data come from a frame buffer :
Lets says the screen is 320×480 with rgb24 = 460K of RAM.

mrburnette
Fri Apr 22, 2016 11:05 pm
WereCatf wrote:
<…>
I think you missed the point: I was just saying that you don’t always need a practical reason to do something just for fun, you know..

martinayotte
Sat Apr 23, 2016 1:10 am
Lets say that there are case that DMA can be helpful and that in some other case it is completely useless !
In case of LCD, it is completely useless unless attached to some bigger system, such Raspberry Pi and similar where you can easily dedicate a FrameBuffer of 512KB or 1MB, otherwise it would be useless …

Of course, in application such NeoPixel, DMA is perfectly good fit : small buffer that needs to be send over and over.

This quite the same scenario I’ve done 25 years ago : sending DMX512 stream over RS485 at 250KB over and over using MC68302 with DMA on Serial.

Don’t try to use DMA simply to make an LED blinking … :ugeek:


RogerClark
Sat Apr 23, 2016 1:21 am
I briefly looked at the Teensy lib for the ILI9341 and I think it uses 2 line buffers

So it fills one line buffer while the other is being DMA’ed

However, this only gives a performance advantage when you are rendering something that you can efficiently do line by line.

I’m not too sure under what circumstances line by line rendering actually gives better performance. Perhaps bitmap text, where the font can be access line by line.
And of course filling the screen with the same colour in all pixels, or gradient fills even.

But, I didn’t think it was worth the effort of porting the Teensy code for amount of time and effort it was going to take.

I still like the idea of using a DMA callback and think this should be an option in the SPI DMA functions, but perhaps hardly anyone would use it.


martinayotte
Sat Apr 23, 2016 1:38 am
Of course, SPI DMA can be useful, as I’ve mentioned for such thing as NeoPixel, DMX512, or any streaming type of things.

For LCD, I’m still convince it is quite useless, even reducing the area of the framebuffer, because if you have to do drawCircle() with almost fill the screen, the CPU will have to wait probably 10+ times that DMA finished before initialize next DMA transfer, until the whole drawCircle() completed … :ugeek:


racemaniac
Sat Apr 23, 2016 8:46 am
You could dma from some external memory source to the port registers to draw the screen, but this is getting complicated XD

stevech
Sat Apr 23, 2016 11:33 pm
martinayotte wrote:
…the CPU will have to wait probably 10+ times that DMA finished before initialize next DMA transfer, until the whole drawCircle() completed … :ugeek:

Leave a Reply

Your email address will not be published. Required fields are marked *