This is the quick start guide for the DMA driver, with step-by-step instructions on how to configure and use the driver in a selection of use cases.
The use cases contain several code fragments. The code fragments in the steps for setup can be copied into a custom initialization function, while the steps for usage can be copied into, e.g., the main application function.
Advanced use cases
For more advanced use of the DMA driver, see the following use cases:
Basic use case
In this basic use case, the DMA is configured for:
- Burst length: 1 byte
- Transfer count: 1024
- Source: Buffer located in RAM
- Destination: Buffer located in RAM
- Source and destination address reload mode: End of transaction
- Source and destination address direction mode: Increment
In this use case data is copied from the source buffer to the destination buffer in 1-byte bursts, until all data in the block is transferred. This example is analogus to a memcpy(destination, source, sizeof(source))
operation performed in hardware asynchronously to the CPU.
Setup steps
Prerequisites
For the setup code of this use case to work, the following must be added to the project:
- System Clock Manager Service (sysclk)
Example code
Add to application C-file:
#define DMA_CHANNEL 0
#define DMA_BUFFER_SIZE 1024
static void dma_init(void)
{
memset(&dmach_conf, 0, sizeof(dmach_conf));
DMA_CH_SRCRELOAD_TRANSACTION_gc);
DMA_CH_DESTRELOAD_TRANSACTION_gc);
}
Add to main()
:
Workflow
- Define the DMA channel that will be used for the transfer for convenience:
- Define the array length that will be the used for the source and destination buffers located in RAM:
#define DMA_BUFFER_SIZE 1024
- Create a pair of global arrays that will hold the source and destination data copied by the DMA controller channel when it is triggered:
- Create a function
dma_init()
to intialize the DMA:
static void dma_init(void)
{
}
- Create config struct for DMA channel:
- Make sure the configuration structure is zeroed out to ensure that all values are reset to their defaults before writing new values:
memset(&dmach_conf, 0, sizeof(dmach_conf));
- Configure the DMA channel for single byte bursts, with a transfer length equal to the size of the source and destination buffers:
- Configure the DMA channel to reset the source and destination addresses at the end of the complete transaction (i.e. after
DMA_BUFFER_SIZE
bytes copied):
- Configure the DMA channel to increment the source and destination addresses after each byte transferred:
- Configure the DMA channel source and destination addresses:
- Enable the DMA module so that channels can be configured in it:
-
- Attention
- Calling dma_enable() will result in a soft-reset of the entire DMA module, clearing all channel configurations. If more than one DMA channel is to be configured, this function should be called only once in the application initialization procedure only.
- Write the DMA channel configuration to the DMA and enable it so that it can be triggered to start the transfer:
- Initialize the clock system:
- Call our DMA init function:
Usage steps
Example code
Add to, e.g., main loop in application C-file:
Workflow
- Start the DMA transfer:
- Wait for the transfer to complete: