# 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 | Transfer source address.
dest | 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 inside 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). The callback argument is called from the system DMA interrupt handler and therefore is called even if interrupts are prohibited.

To achieve maximum functionality, you need to understand how to use Async-type APIs.

The following is an example of a function name, `Call_BackGroundJob_with_DMA`, that is placed in TCM.

The following processes are performed.

- Data transfer using DMA in 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, you must consider the following to have this process proceed as intended.

- If `isDmaFinished` is not in TCM, stalling occurs during the `while(!isDmaFinished)` check.
- Stalling occurs if the `BackGroundJob` function accesses the ARM bus.
- In many cases, the stack also needs to be allocated in TCM. (The stack is allocated in 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;
>     }

###
DMA Controller Bugs

The old DMAC exposed a hardware bug. With multiple DMAs and varying conditions, illegal read access results if the source address of DMA0 is of the form 0xmmnnnnnn (where 0xmm = 0x04 or 0x08 through 0xff, and nnnnnn = anything). The same restriction applies to the source address after the transfer is complete. For this reason, if the source address or source address when transfer terminates fall within this address range, execution stops on an `OS_Panic` function inside the library.

With the TWL, however, you can select to correct the problem with the old DMA circuit by using the `SCFG_SetDmaFixed` function. No address check is performed if you select to correct the problem.

## 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

2009/11/20 Added a description of a bug in the DMA controller.
2007/10/31 Added `_SetUp()`.
2005/03/08 Standardized the notation used for the term "interrupt" in Japanese.
2004/12/22 Added a description of calling the callback.
2005/03/08 Initial version.

CONFIDENTIAL