# MI_DmaCopy*

## C Specification

      #include <nitro/mi.h>

        void MI_DmaCopy32( u32 dmaNo, const void* src, void* dest, u32 size );
        void MI_DmaCopy16( u32 dmaNo, const void* src, void* dest, u32 size );

        void MI_DmaCopy32Async( u32 dmaNo, const void* src, void* dest, u32 size,
                                                     MIDmaCallback callback, void* arg );
        void MI_DmaCopy16Async( u32 dmaNo, const void* src, void* dest, u32 size,
                                                     MIDmaCallback callback, void* arg );

## Arguments

dmaNo | DMA channel used.
`src` | The transfer source address.
`dest` | The transfer destination address.
`size` | Transfer size.
`callback` | Callback when DMA ends.
`arg` | Callback argument when DMA ends.

## Return Values

None.

## Description

Uses DMA to copy.

`MI_DmaCopy16()` and `MI_DmaCopy16Async()` copy in 16-bit units. Both the transfer source address and the transfer destination address must be 2-byte aligned. `MI_DmaCopy32()` and `MI_DmaCopy32Async()` copy in 32-bit units. Both the transfer source address and the transfer destination address must be 4-byte aligned.

`MI_DmaCopy16()` and `MI_DmaCopy32()` wait within the function until DMA completes. `MI_DmaCopy16Async()` and `MI_DmaCopy32Async()` call a callback function when DMA ends. The callback, `callback`, is a `MIDmaCallback` type (a `void` type function which takes one `void*` argument). `callback` is called from the system DMA interrupt handler and therefore is called while interrupts are prohibited.

It is necessary to understand how to use Async-type APIs in order to obtain maximum functionality.

The following is an example of a function name `Call_BackGroundJob_with_DMA()` that is placed within TCM.

The following processes are performed:

- Data transfer using DMA within the function begins.
- When the DMA ends, `TRUE` is entered in `isDmaFinished` in `callback()`.
- `isDmaFinished` is polled as an end flag and `BackGroundJob()` can be called continuously until DMA ends.

However, the following must be considered to have this process proceed as intended:

- If `isDmaFinished` is not taken inside TCM, then stalling will occur during the `while(!isDmaFinished)` check.
- Stalling will occur if `BackGroundJob()` accesses the ARM bus.
- In many cases, the stack will also need to be allocated within TCM. (The SDK default has the stack being secured within DTCM.)
- If this function is located in main memory, stalling will occur when DMA starts. Therefore, `BackGroundJob()` cannot be called continuously.

>     //--- sample code ( This code must be in ITCM )
>     void Call_BackGroundJob_with_DMA(void)
>     {
>         vu32 isDmaFinished = FALSE;

>         MI_DmaCopy32Async( dmaNo, srcArea, destArea, dataSize, callback, (void*)&isDmaFinished );
>         while( !isDmaFinished ){ BackGroundJob(); }

>     }

>     void callback( void* arg )
>     {
>         *(vu32*)arg = TRUE;
>     }

## Internal Operation

Uses the following IO registers: DMAn source register (0x40000B0 + 12n), DMAn destination register (0x40000B4 + 12n), and DMAn control register (0x40000B8 + 12n). n is the DMA channel used.)

## See Also

`MI_DmaFill*`, `MI_DmaClear*`, `MI_DmaSend*`, `MI_CpuCopy*`

## Revision History

03/08/2005 Standardized the Japanese term for "interrupt".
12/22/2004 Added a description regarding `callback`.
12/01/2003 Initial version

CONFIDENTIAL