# CARD_ReadRomAsync

## Syntax

  `#include <nitro/card.h>`
  `void CARD_ReadRomAsync(u32 dma, const void *src, void *dst, u32 len, MIDmaCallback callback, void *arg);`

## Arguments

dma | The DMA channel to use for the transfer between 0 and `MI_DMA_MAX_NUM`. If the program is running in TWL mode, the parent DMA channel can be specified in the range of `(MI_DMA_USING_NEW+0)` to `(MI_DMA_USING_NEW+MI_DMA_MAX_NUM)`. The CPU processes the transfer directly without using DMA transfer if an out-of-range channel has been specified or if `MI_DMA_NOT_USE` has been explicitly specified.
src | The transfer source CARD ROM address.
dst | Transfer destination memory address.
len | Length of data being read, in bytes.
callback | Completion-time callback function. Specify `NULL` when not needed. This callback will be invoked from the DMA interrupt handler when a valid DMA channel is specified.
arg | Argument passed to the callback function. When `NULL` has been specified for the callback, this is simply ignored

## Return Values

None.

## Description

Asynchronously loads data from a device that has ROM. If a valid DMA channel has been specified, this function uses that channel after explicitly stopping it with the `MI_StopDma` function. The transfer will be blocked until the previous access completes.
If a CPU transfer is explicitly specified, this function behaves identically to the synchronous version, `CARD_ReadRom`.

## Note

- To use this function, you must first lock the access bus with the `CARD_LockRom` function.
- If a valid DMA channel is specified by this function, that DMA channel will not be available until transfer is complete.
- The transfer source for Card access is an IO register, so you cannot specify DMA channel 0 unless the program is running in TWL mode and the `SCFG_IsDmacFixed` function has returned `TRUE`.
- Note that this function uses interrupts internally, so processing will not complete if it continues to wait while interrupts are prohibited.

## Internal Operation

`This function operates asynchronously using DMA transfers and the IRQ handler only if the following conditions are satisfied:
In that case, transfers of card data can be done in parallel with CPU processing.`

- The destination range of the transfer is DMA-accessible and 32-byte aligned.
- The source range of the transfer is aligned to `CARD_ROM_PAGE_SIZE` bytes.
- The transfer size is aligned to `CARD_ROM_PAGE_SIZE` bytes.

If these conditions are not all met, the process is executed asynchronously by a CPU process using a CARD library internal thread regardless of whether DMA transfer has been specified or not.
For more information on this thread, see the description for the `CARD_GetThreadPriority` function. Here are some main points you need to be aware of with the application to ensure that the conditions for DMA transfer are satisfied:

- Do not specify an automatic variable as the transfer destination (the stack is allocated from DTCM by default, so DMA access is not possible).
- Specify `Align` or `AlignAll` in the RomSpec section of the RSF file and place the file so that it is 512-byte aligned.
- If the file size is not an integer multiple of 512 bytes, divide the file so that it is read in segments that are integer multiples of 512 bytes.

## See Also

`CARD_ROM_PAGE_SIZE`
`CARD_LockRom`
`CARD_ReadRom`
`CARD_TryWaitRomAsync`
`CARD_WaitRomAsync`
`CARD_GetThreadPriority`

## Revision History

2008/11/19 Added information about the relationship between the DMA channel range and the operating mode.
2008/01/24 Added a note on the range specified for DMA channels.
2006/05/10 Changed specifications so that DMA transfers are not performed unless the transfer destination range is aligned at 32-byte boundaries.
2005/08/22 Made substantial corrections to Internal Operation.
2005/06/01 Explained that the callback is invoked from the interrupt handler.
2005/04/28 Noted that DMA channel 0 cannot be specified.
2004/12/09 Changed "IO processor" to "ARM7 processor."
2004/11/02 Corrected argument names to match the header file.
2004/07/28 Corrected the callback type.
2004/07/19 Changed the explanation for internal operations.
2004/07/09 Corrected descriptions due to function format changes and added Internal Operation.
2004/07/05 Initial version.

CONFIDENTIAL