Xmega Application Note


dma_example.c

Go to the documentation of this file.
00001 /* This file has been prepared for Doxygen automatic documentation generation.*/
00054 #include "dma_driver.h"
00055 #include "avr_compiler.h"
00056 
00058 #define MEM_BLOCK_SIZE   (10)
00059 
00061 #define MEM_BLOCK_COUNT (10)
00062 
00066 #define MEM_BLOCK ( MEM_BLOCK_SIZE * MEM_BLOCK_COUNT )
00067 
00069 uint8_t memoryBlockA[MEM_BLOCK];
00070 uint8_t memoryBlockB[MEM_BLOCK];
00071 
00073 volatile bool gInterruptDone;
00074 volatile bool gStatus;
00075 
00088 bool BlockMemCopy( const void * src,
00089                    void * dest,
00090                    uint16_t blockSize,
00091                    volatile DMA_CH_t * dmaChannel )
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 }
00111 
00112 
00113 
00128 bool MultiBlockMemCopy( const void * src, void * dest, uint16_t blockSize,
00129                           uint8_t repeatCount, volatile DMA_CH_t * dmaChannel )
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 }
00164 
00172 void main( void )
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 }
00259 
00260 
00262 ISR(DMA_CH0_vect)
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 }
@DOC_TITLE@
Generated on Fri Jul 17 17:12:43 2009 for AVR1304 Using the XMEGA DMA Controller by doxygen 1.5.9