#26942 - ScottLininger - Wed Sep 29, 2004 10:27 pm
Does anyone know what happens if you change the DMA registers "mid transfer"? Is this even possible?
I mean, if you start a DMA copy, does the processor halt all other work until that DMA is done? If you have two transfers one after the other, is it possible that the second transfer will screw up the first one?
-Scott
#26943 - poslundc - Wed Sep 29, 2004 10:40 pm
ScottLininger wrote: |
Does anyone know what happens if you change the DMA registers "mid transfer"? Is this even possible? |
The DMA halts the CPU while it is active, so no, it's not possible.
The only thing that can preempt a DMA transfer is another, higher-priority DMA transfer, and since the DMA halts the CPU the only thing that can cause a higher-priority DMA transfer to occur is an interrupt (such as an empty sound buffer or HBlank trigger).
Quote: |
If you have two transfers one after the other, is it possible that the second transfer will screw up the first one? |
Two DMA transfers cannot execute in parallel, but because of the timings of memory accesses it is a good idea to set DMAXCNT to 0 in between consecutive transfers (if you are using the same DMA channel for both of them). eg.
Code: |
REG_DMA3SAD = src1;
REG_DMA3DAD = dst1;
REG_DMA3CNT = DMA_ENABLE | wordcount1;
REG_DMA3CNT = 0;
REG_DMA3SAD = src2;
REG_DMA3DAD = dst2;
REG_DMA3CNT = DMA_ENABLE | wordcount2; |
And always, always make sure that the registers are declared as volatile (usually vu32) in your header file.
Dan.
#26944 - sajiimori - Wed Sep 29, 2004 10:43 pm
Some people have noticed a delay of a couple cycles before DMA starts and locks the bus (thus hanging the CPU), but I haven't noticed that yet.
#26945 - poslundc - Wed Sep 29, 2004 11:08 pm
I'm not sure exactly what it is; all I know for sure is that when I tried doing consecutive DMAs or DMAs in a loop it would always fail on hardware until I started "shutting off" the DMA in between transfers.
Dan.
#26946 - DekuTree64 - Wed Sep 29, 2004 11:29 pm
Hmm, I wonder what would happen if you used a higher priority DMA to change the DMA registers in the middle of a transfer. Say, right after HBlank, do this:
Code: |
REG_DM0SAD = src2;
REG_DM0DAD = ®_DM3CNT;
REG_DM0CNT = 1 | DMA_ENABLE | DMA_MODE_HBL;
REG_DM3SAD = src;
REG_DM3DAD = dest;
REG_DM3CNT = count | DMA_ENABLE;
|
Where count is big enough that DMA3 will still be running during the next HBlank.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku
#26948 - sajiimori - Thu Sep 30, 2004 12:09 am
Deku, crunch time is getting to you. ;)
#26955 - ScottLininger - Thu Sep 30, 2004 4:35 am
Dan,
You rock.
The problem I was having had nothing to do with how and when I was initiating the DMA. It was the fact that my header file didn't have them declared as volatile. Man, that one was driving me crazy.
Is "make sure DMA registers are volatiles" on Tepple's tutorial suggestion list? I'm pretty sure I got my broken gba.h from one of the tutorials out there...
Thanks!
Scott
#26956 - sajiimori - Thu Sep 30, 2004 4:48 am
The same goes for all registers.
#26964 - tepples - Thu Sep 30, 2004 12:57 pm
in 'Testing your code' in the Beginners' FAQ, I wrote: |
Q: My program works when compiled without optimizations (-O0), but when compiled with optimizations (-O, -O2, -O3), it won't do anything. How do I fix this?
Most likely: You forgot to declare your registers as volatile.
|
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#26966 - poslundc - Thu Sep 30, 2004 1:52 pm
The volatile keyword indicates to the compiler that the variable/register's state is not related exclusively to the executing code, but is tied to external factors (such as hardware functionality). Without the keyword, GCC's optimization features may shuffle commands around or ignore them entirely if it believes they don't affect the flow or logic of the program. To an optimizing compiler:
Code: |
a = 5;
b = 2;
a = 7; |
... the first line isn't important and doesn't do anything, but needless to say when you're dealing with memory-mapped hardware registers like the DMA controls it is crucial to preserve both the ordering and the execution of every statement.
Dan.
#26974 - ampz - Thu Sep 30, 2004 5:04 pm
sajiimori wrote: |
Some people have noticed a delay of a couple cycles before DMA starts and locks the bus (thus hanging the CPU), but I haven't noticed that yet. |
Perhaps it is emptying the CPU pipeline before locking the bus?