Xmega Application Note


dma_example.c File Reference

XMEGA DMA driver example source. More...

#include "dma_driver.h"
#include "avr_compiler.h"

Include dependency graph for dma_example.c:

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]


Detailed Description

XMEGA DMA driver example source.

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.

Application note:
AVR1304: Using the XMEGA DMA Controller
Documentation
For comprehensive code documentation, supported compilers, compiler settings and supported devices see readme.html
Author:
Atmel Corporation: http://www.atmel.com
Support email: avr@atmel.com
Revision
1569
Date
2008-04-22 13:03:43 +0200 (ti, 22 apr 2008)

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 Documentation

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

Memory block count.

Definition at line 61 of file dma_example.c.

Referenced by main().

#define MEM_BLOCK_SIZE   (10)

Size of one memory block.

Definition at line 58 of file dma_example.c.

Referenced by main().


Function Documentation

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.

Note:
This function DO NOT wait for a completion, and this must be handled by the program calling this function. In this example, an interrupt.
Return values:
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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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.

Note:
This function wait until the transfer is complete and use a blocking function which also makes this function blocking, hence the function will dead-lock if the completion or error flag never get set.
Return values:
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 }

Here is the call graph for this function:


Variable Documentation

volatile bool gInterruptDone

Global declared status for interrupt routine.

Definition at line 73 of file dma_example.c.

Referenced by ISR(), and main().

volatile bool gStatus

Definition at line 74 of file dma_example.c.

Referenced by ISR(), and main().

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]

Definition at line 70 of file dma_example.c.

Referenced by main().

@DOC_TITLE@
Generated on Fri Jul 17 17:12:43 2009 for AVR1304 Using the XMEGA DMA Controller by doxygen 1.5.9