Xmega Application Note | |||||
#include "dma_driver.h"
#include "avr_compiler.h"
Go to the source code of this file.
Defines | |
#define | MEM_BLOCK ( MEM_BLOCK_SIZE * MEM_BLOCK_COUNT ) |
#define | MEM_BLOCK_COUNT (10) |
#define | MEM_BLOCK_SIZE (10) |
Functions | |
bool | BlockMemCopy (const void *src, void *dest, uint16_t blockSize, volatile DMA_CH_t *dmaChannel) |
Example demonstrating block memory copy. | |
ISR (DMA_CH0_vect) | |
void | main (void) |
Example code using two different methods of transfer. | |
bool | MultiBlockMemCopy (const void *src, void *dest, uint16_t blockSize, uint8_t repeatCount, volatile DMA_CH_t *dmaChannel) |
Example of a repeated block memory copy operation. | |
Variables | |
volatile bool | gInterruptDone |
volatile bool | gStatus |
uint8_t | memoryBlockA [MEM_BLOCK] |
uint8_t | memoryBlockB [MEM_BLOCK] |
This file contains an example application that demonstrates the DMA driver. It shows how to set up the DMA for a memory-to-memory block copy operation. Two functions are provided, one using single block transfer and one using repeated block transfer. Single block transfers supports up to 64k bytes, while repeated blocks supports up to 255 blocks (16M - 64k bytes). Both functions are tested in the main() function.
Copyright (c) 2008, Atmel Corporation All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The name of ATMEL may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Definition in file dma_example.c.
#define MEM_BLOCK ( MEM_BLOCK_SIZE * MEM_BLOCK_COUNT ) |
Total block size. Note that MEM_BLOCK_SIZE * MEM_BLOCK_COUNT must not exceed 64k for this demo application.
Definition at line 66 of file dma_example.c.
Referenced by main().
#define MEM_BLOCK_COUNT (10) |
#define MEM_BLOCK_SIZE (10) |
bool BlockMemCopy | ( | const void * | src, | |
void * | dest, | |||
uint16_t | blockSize, | |||
volatile DMA_CH_t * | dmaChannel | |||
) |
Example demonstrating block memory copy.
Block size 0 = 64k. Enable the DMA channel to use first and it will be disabled automatically. Setup channel for copying data, increasing addresses, no address pointer reload, with 8-byte bursts.
true | if success. | |
false | if failure. |
Definition at line 88 of file dma_example.c.
References DMA_EnableChannel(), DMA_SetupBlock(), and DMA_StartTransfer().
Referenced by main().
00092 { 00093 DMA_EnableChannel( dmaChannel ); 00094 00095 DMA_SetupBlock( dmaChannel, 00096 src, 00097 DMA_CH_SRCRELOAD_NONE_gc, 00098 DMA_CH_SRCDIR_INC_gc, 00099 dest, 00100 DMA_CH_DESTRELOAD_NONE_gc, 00101 DMA_CH_DESTDIR_INC_gc, 00102 blockSize, 00103 DMA_CH_BURSTLEN_8BYTE_gc, 00104 0, 00105 false ); 00106 00107 DMA_StartTransfer( dmaChannel ); 00108 00109 return true; 00110 }
ISR | ( | DMA_CH0_vect | ) |
DMA CH0 Interrupt service routine. Clear interrupt flags after check.
Definition at line 262 of file dma_example.c.
References gInterruptDone, and gStatus.
00263 { 00264 if (DMA.CH0.CTRLB & DMA_CH_ERRIF_bm) { 00265 DMA.CH0.CTRLB |= DMA_CH_ERRIF_bm; 00266 gStatus = false; 00267 } else { 00268 DMA.CH0.CTRLB |= DMA_CH_TRNIF_bm; 00269 gStatus = true; 00270 } 00271 gInterruptDone = true; 00272 }
void main | ( | void | ) |
Example code using two different methods of transfer.
Example code using the two example functions to do a singe block memory copy and a multi block memory copy. The first test use a polling function to wait until the transfer completes or get an error. The second test use an interrupt to know when the transfer completes or get an error.
Definition at line 172 of file dma_example.c.
References BlockMemCopy(), DMA_Enable, DMA_SetIntLevel(), gInterruptDone, gStatus, MEM_BLOCK, MEM_BLOCK_COUNT, MEM_BLOCK_SIZE, memoryBlockA, memoryBlockB, and MultiBlockMemCopy().
00173 { 00174 uint32_t index; 00175 00176 volatile DMA_CH_t * Channel; 00177 Channel = &DMA.CH0; 00178 00179 DMA_Enable(); 00180 00181 /* Test 1: Copy using repeated blocks. */ 00182 00183 /* Fill memory block A with example data. */ 00184 for ( index = 0; index < MEM_BLOCK; ++index ) { 00185 memoryBlockA[index] = ( (uint8_t) index & 0xff ); 00186 } 00187 00188 /* Copy data using channel 0. */ 00189 gStatus = MultiBlockMemCopy( memoryBlockA, 00190 memoryBlockB, 00191 MEM_BLOCK_SIZE, 00192 MEM_BLOCK_COUNT, 00193 Channel ); 00194 00195 /* Compare memory blocks if status is true. */ 00196 if ( gStatus ) { 00197 for ( index = 0; index < MEM_BLOCK; ++index) { 00198 if (memoryBlockA[index] != memoryBlockB[index]) { 00199 gStatus = false; 00200 break; 00201 } 00202 } 00203 } 00204 00205 00206 /* Test 2: Copy using single block mode and use interrupt. Perform 00207 * second test only if first test succeeded. 00208 */ 00209 if ( gStatus ) { 00210 00211 /* Enable LO interrupt level for the complete transaction and 00212 * error flag on DMA channel 0. 00213 */ 00214 DMA_SetIntLevel( Channel, DMA_CH_TRNINTLVL_LO_gc, DMA_CH_ERRINTLVL_LO_gc ); 00215 PMIC.CTRL |= PMIC_LOLVLEN_bm; 00216 sei(); 00217 00218 /* Fill memory block A with example data again. */ 00219 for ( index = 0; index < MEM_BLOCK; ++index ) { 00220 memoryBlockA[index] = 0xff - ( (uint8_t) index & 0xff ); 00221 } 00222 00223 /* Set intDone to false to know when it has been executed. */ 00224 gInterruptDone = false; 00225 00226 /* Copy data using channel 0. */ 00227 gStatus = BlockMemCopy( memoryBlockA, 00228 memoryBlockB, 00229 MEM_BLOCK, 00230 Channel); 00231 00232 do { 00233 /* Do something here while waiting for the 00234 * interrupt routine to signal completion. 00235 */ 00236 } while ( gInterruptDone == false ); 00237 00238 /* Compare memory blocks. */ 00239 if ( gStatus ) { 00240 for ( index = 0; index < MEM_BLOCK; ++index ) { 00241 if (memoryBlockA[index] != memoryBlockB[index]) { 00242 gStatus = false; 00243 break; 00244 } 00245 } 00246 } 00247 } 00248 00249 if ( gStatus ) { 00250 do { 00251 /* Completed with success. */ 00252 } while (1); 00253 } else { 00254 do { 00255 /* Completed with failure. */ 00256 } while (1); 00257 } 00258 }
bool MultiBlockMemCopy | ( | const void * | src, | |
void * | dest, | |||
uint16_t | blockSize, | |||
uint8_t | repeatCount, | |||
volatile DMA_CH_t * | dmaChannel | |||
) |
Example of a repeated block memory copy operation.
Block size 0 = 64k. Enable the DMA channel to use first and the channel will be disabled automatically. A parameter check to avoid illegal values. Setup channel for copying data, increasing addresses, no address pointer reload, with 8-byte bursts.
true | if success. | |
false | if failure. |
Definition at line 128 of file dma_example.c.
References DMA_EnableChannel(), DMA_ReturnStatus_non_blocking(), DMA_SetupBlock(), and DMA_StartTransfer().
Referenced by main().
00130 { 00131 uint8_t flags; 00132 00133 DMA_EnableChannel( dmaChannel ); 00134 DMA_SetupBlock( dmaChannel, 00135 src, 00136 DMA_CH_SRCRELOAD_NONE_gc, 00137 DMA_CH_SRCDIR_INC_gc, 00138 dest, 00139 DMA_CH_DESTRELOAD_NONE_gc, 00140 DMA_CH_DESTDIR_INC_gc, 00141 blockSize, 00142 DMA_CH_BURSTLEN_8BYTE_gc, 00143 repeatCount, 00144 true ); 00145 00146 DMA_StartTransfer( dmaChannel ); 00147 00148 /* Wait until the completion or error flag is set. The flags 00149 * must be cleared manually. 00150 */ 00151 do { 00152 flags = DMA_ReturnStatus_non_blocking( dmaChannel ); 00153 } while ( flags == 0); 00154 00155 dmaChannel->CTRLB |= ( flags ); 00156 00157 /* Check if error flag is set. */ 00158 if ( ( flags & DMA_CH_ERRIF_bm ) != 0x00 ) { 00159 return false; 00160 } else { 00161 return true; 00162 } 00163 }
volatile bool gInterruptDone |
Global declared status for interrupt routine.
Definition at line 73 of file dma_example.c.
volatile bool gStatus |
uint8_t memoryBlockA[MEM_BLOCK] |
Memory blocks A and B for testing.
Definition at line 69 of file dma_example.c.
Referenced by main().
uint8_t memoryBlockB[MEM_BLOCK] |
Generated on Fri Jul 17 17:12:43 2009 for AVR1304 Using the XMEGA DMA Controller by ![]() |