# MI_DmaCopy*

## Syntax

  `#include <nitro/mi.h>`
  `void MI_DmaCopy32( u32 dmaNo,
  const void* src,
  void* dest,
  u32 size );`
  `void MI_DmaCopy32_SetUp( u32 dmaNo,
  const void* src,
  void* dest,
  u32 size );`
  `void MI_DmaCopy16( u32 dmaNo,
  const void* src,
  void* dest,
  u32 size );`
  `void MI_DmaCopy16_SetUp( 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_DmaCopy32Async_SetUp( 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 );`
  `void MI_DmaCopy16Async_SetUp( 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.

The `*_SetUp` functions only configure the given settings without actually performing DMA. To actually start DMA, call the `MI_DmaRestart` function.

The `MI_DmaCopy16*` functions copy in 16-bit units. Both the transfer source address and the transfer destination address must be 2-byte aligned.

The `MI_DmaCopy32*` functions 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. The `MI_DmaCopy16Async*` and `MI_DmaCopy32Async*` functions call a callback function when DMA ends. The callback, `callback`, is a `MIDmaCallback` type (a `void` type function that 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, `isDmaFinished` will be set to `TRUE` within `callback()`.
- It is possible to poll `isDmaFinished` as a completion flag, and call the `BackGroundJob` function repeatedly until DMA completes.

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

- If `isDmaFinished` is not in 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 stack is allocated within DTCM with the default SDK configuration.)
- If this function is located in main memory, stalling occurs when DMA starts. Therefore, the `BackGroundJob` function 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_CpuCopy*
MI_DmaClear*
MI_DmaFill*
MI_DmaRestart
MI_DmaSend*`

## Revision History

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

CONFIDENTIAL