00001
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
00149
00150
00151 do {
00152 flags = DMA_ReturnStatus_non_blocking( dmaChannel );
00153 } while ( flags == 0);
00154
00155 dmaChannel->CTRLB |= ( flags );
00156
00157
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
00182
00183
00184 for ( index = 0; index < MEM_BLOCK; ++index ) {
00185 memoryBlockA[index] = ( (uint8_t) index & 0xff );
00186 }
00187
00188
00189 gStatus = MultiBlockMemCopy( memoryBlockA,
00190 memoryBlockB,
00191 MEM_BLOCK_SIZE,
00192 MEM_BLOCK_COUNT,
00193 Channel );
00194
00195
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
00207
00208
00209 if ( gStatus ) {
00210
00211
00212
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
00219 for ( index = 0; index < MEM_BLOCK; ++index ) {
00220 memoryBlockA[index] = 0xff - ( (uint8_t) index & 0xff );
00221 }
00222
00223
00224 gInterruptDone = false;
00225
00226
00227 gStatus = BlockMemCopy( memoryBlockA,
00228 memoryBlockB,
00229 MEM_BLOCK,
00230 Channel);
00231
00232 do {
00233
00234
00235
00236 } while ( gInterruptDone == false );
00237
00238
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
00252 } while (1);
00253 } else {
00254 do {
00255
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 }