gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Problems with DMA...

#25605 - /*Articuno*/ - Wed Aug 25, 2004 10:28 pm

Hello World,

I'm having a strange problem when using DMA for copying...
This code:
Code:

void DMAFastCopy(void* source,void* dest,unsigned int count,unsigned int mode) {
    if (mode == DMA_16NOW || mode == DMA_32NOW) {
        REG_DMA3SAD = (unsigned int)source;
        REG_DMA3DAD = (unsigned int)dest;
        REG_DMA3CNT = count | mode;
    }
}


wasn't working (on our first versions it was working... before we started using DevKitArm, Krawall, etc...)

Then we made this "slower" version:

Code:

void DMAFastCopy(void* source,void* dest,unsigned int count,unsigned int mode) {   
    // DMASlowCopy ^_^;

    if (mode == DMA_16NOW)
        while(count--)
        *((u16*)dest + count) = *((u16*)source + count);
    else
        while(count--)
            *((u32*)dest + count) = *((u32*)source + count);
}


But, when i was told that Krawall and DMA should be working together, i made this test:

Code:

void DMAFastCopy(void* source,void* dest,unsigned int count,unsigned int mode) {
    if (mode == DMA_16NOW || mode == DMA_32NOW) {
        REG_DMA3SAD = (unsigned int)source;
        REG_DMA3DAD = (unsigned int)dest;
        REG_DMA3CNT = count | mode;
    }

    dprintf("Trying to copy %d blocks...\n", count);
    if (mode == DMA_16NOW) {
        while(count--)
            if (*((u16*)dest + count) != *((u16*)source + count)) break;
    }
    else {
        while(count--)
            if (*((u32*)dest + count) != *((u32*)source + count)) break;
    }
    dprintf("%d\n", count);
}


to check how many blocks were being correctly copied...
And then the DMA Copy started working again! Note that the loops are only comparing values!
(and dprintf is just my debug function, that prints to VisualBoyAdvance's stdout...)

When i remove this "test code", the function doesn't work at all, as if things were messed during copy (the game shows arbitrary colors, a dark and broken version of our game... some pictures missing... etc...)

Someone can tell me what is wrong ? Could Krawall be affecting DMA ? Should I use interrupts for DMA ?
_________________
Close the world, txEn eht nepO.

#25606 - poslundc - Wed Aug 25, 2004 10:38 pm

- Make sure all three DMA registers are defined as volatile.

- Try inserting REG_DMA3CNT = 0; just before the line where you assign REG_DMA3CNT.

Dan.

#25610 - FireOut - Wed Aug 25, 2004 11:14 pm

If you are using any optimization flags on your compiler (such as -O2), try setting those off.

If the code works after that change you probably didn't set the registers as volatile, like poslundc said, and the compiler is optimizing something it shouldn't ;-)

#25677 - /*Articuno*/ - Thu Aug 26, 2004 10:24 pm

Thanks poslundc !
_________________
Close the world, txEn eht nepO.