Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 5414

General • Re: Help with PIO fundamentals to drive matrix-based displays.

$
0
0
I have dma1 reading from my array and writing to a PIO. How does a second dma channel make that into a loop? Does it monitor and modify control channels? I just need to restart dma1 when it finishes.
This is maybe a little harder to get to grips with in Python than the C API (because the slightly higher-level API is trying to abstract details that you end up needing to dig into). Be aware that the state of a DMA channel comprises four 32-bit words: the two addresses, the transfer count, and the configuration (all that dma.config(blah blah) stuff boils down to a single 32-bit value).

There's two quite different possibilities here:

a) Two DMA channels with very similar configuration, each transfers one buffer to the PIO and then chains to the other one on completion. This is trivial to set up - just set up two channels just like you have now, set the chain_to in each one's configuration to point to the other one, and then start one of them. Huge snag with this is that only the count register in each channel gets reset at the end of the transfer: in your case, the write address doesn't increment so that's still OK, the config is probably OK, but the read address will be pointing beyond the end of your buffer and if nothing else is done will just go galloping through memory as the repeated transfers occur. If you can use ring mode - needs the transfer count to be power-of-2 and the buffer to be at an aligned address - then that can fix the read address and this scheme works. If you can't use ring mode, you could maybe take interrupts of the completion and hope for your interrupt handler to reset the read address before the next transfer gets triggered - workable but ugly.

b) One DMA channel that does the actual work, and another one that just does a very small transfer, writing the configuration of the first one
to restart it. In this scheme, the first channel is set up much as you have it now and then chains the second one on completion. The second one reads a small, constant, buffer in RAM containing the configuration for the first one and writes the register(s) of the DMA controller itself. The second channel does NOT chain the first one: instead it contrives that the last word of its transfer is written to one of the 'trigger aliases' of the control registers of the first channel. (you either use chaining or triggering, never both at the same time, and in this case you need triggering in order to get the timing right - the channel mustn't get triggered until the configuration word has actually arrived in the register, while chaining would happen a couple of clock cycles too soon).

Since the complete configuration of a channel comprises 4 words, you could have those 4 words in RAM and have your 2nd channel do a 4-word transfer. That would work fine, but in this case it's only the read address that needs changing, so you can do it with a single word transfer. Your buffer in RAM must hold (as a 32-bit value) the address of the main data buffer that the 1st channel reads. Your second channel thus has a read address the address of that little 1-word buffer, a write address of the 1st channel's READ_ADDR_TRIG register (actually AL3_READ_ADDR_TRIG), and a transfer count of 1 word.

Statistics: Posted by arg001 — Fri Apr 12, 2024 4:57 pm



Viewing all articles
Browse latest Browse all 5414

Trending Articles