00001
00059 #include "dma_driver.h"
00060
00061
00068 void DMA_Reset( void )
00069 {
00070 DMA.CTRL &= ~DMA_ENABLE_bm;
00071 DMA.CTRL |= DMA_RESET_bm;
00072 while (DMA.CTRL & DMA_RESET_bm);
00073 }
00074
00075
00088 void DMA_ConfigDoubleBuffering( DMA_DBUFMODE_t dbufMode )
00089 {
00090 DMA.CTRL = ( DMA.CTRL & ~DMA_DBUFMODE_gm ) | dbufMode;
00091 }
00092
00093
00105 void DMA_SetPriority( DMA_PRIMODE_t priMode )
00106 {
00107 DMA.CTRL = ( DMA.CTRL & ~DMA_PRIMODE_gm ) | priMode;
00108 }
00109
00110
00119 uint8_t DMA_CH_IsOngoing( volatile DMA_CH_t * channel )
00120 {
00121 uint8_t flagMask;
00122 flagMask = channel->CTRLB & DMA_CH_CHBUSY_bm;
00123 return flagMask;
00124 }
00125
00131 uint8_t DMA_IsOngoing( void )
00132 {
00133 uint8_t flagMask;
00134 flagMask = DMA.STATUS & 0xF0;
00135 return flagMask;
00136 }
00137
00149 uint8_t DMA_CH_IsPending( volatile DMA_CH_t * channel )
00150 {
00151 uint8_t flagMask;
00152 flagMask = channel->CTRLB & DMA_CH_CHPEND_bm;
00153 return flagMask;
00154 }
00155
00156
00166 uint8_t DMA_IsPending( void )
00167 {
00168 uint8_t flagMask;
00169 flagMask = DMA.STATUS & 0x0F;
00170 return flagMask;
00171 }
00172
00185 uint8_t DMA_ReturnStatus_non_blocking( volatile DMA_CH_t * channel )
00186 {
00187 uint8_t relevantFlags;
00188 relevantFlags = channel->CTRLB & (DMA_CH_ERRIF_bm | DMA_CH_TRNIF_bm);
00189 return relevantFlags;
00190 }
00191
00192
00207 uint8_t DMA_ReturnStatus_blocking( volatile DMA_CH_t * channel )
00208 {
00209 uint8_t flagMask;
00210 uint8_t relevantFlags;
00211
00212 flagMask = DMA_CH_ERRIF_bm | DMA_CH_TRNIF_bm;
00213
00214 do {
00215 relevantFlags = channel->CTRLB & flagMask;
00216 } while (relevantFlags == 0x00);
00217
00218 channel->CTRLB = flagMask;
00219 return relevantFlags;
00220 }
00221
00229 void DMA_EnableChannel( volatile DMA_CH_t * channel )
00230 {
00231 channel->CTRLA |= DMA_CH_ENABLE_bm;
00232 }
00233
00234
00242 void DMA_DisableChannel( volatile DMA_CH_t * channel )
00243 {
00244 channel->CTRLA &= ~DMA_CH_ENABLE_bm;
00245 }
00246
00247
00256 void DMA_ResetChannel( volatile DMA_CH_t * channel )
00257 {
00258 channel->CTRLA &= ~DMA_CH_ENABLE_bm;
00259 channel->CTRLA |= DMA_CH_RESET_bm;
00260 channel->CTRLA &= ~DMA_CH_RESET_bm;
00261 }
00262
00263
00275 void DMA_SetIntLevel( volatile DMA_CH_t * channel,
00276 DMA_CH_TRNINTLVL_t transferInt,
00277 DMA_CH_ERRINTLVL_t errorInt )
00278 {
00279 channel->CTRLB = (channel->CTRLB & ~(DMA_CH_ERRINTLVL_gm | DMA_CH_TRNINTLVL_gm)) |
00280 transferInt | errorInt;
00281 }
00282
00283
00304 void DMA_SetupBlock( volatile DMA_CH_t * channel,
00305 const void * srcAddr,
00306 DMA_CH_SRCRELOAD_t srcReload,
00307 DMA_CH_SRCDIR_t srcDirection,
00308 void * destAddr,
00309 DMA_CH_DESTRELOAD_t destReload,
00310 DMA_CH_DESTDIR_t destDirection,
00311 uint16_t blockSize,
00312 DMA_CH_BURSTLEN_t burstMode,
00313 uint8_t repeatCount,
00314 bool useRepeat )
00315 {
00316 channel->SRCADDR0 = (( (uint32_t) srcAddr) >> 0*8 ) & 0xFF;
00317 channel->SRCADDR1 = (( (uint32_t) srcAddr) >> 1*8 ) & 0xFF;
00318 channel->SRCADDR2 = (( (uint32_t) srcAddr) >> 2*8 ) & 0xFF;
00319
00320 channel->DESTADDR0 = (( (uint32_t) destAddr) >> 0*8 ) & 0xFF;
00321 channel->DESTADDR1 = (( (uint32_t) destAddr) >> 1*8 ) & 0xFF;
00322 channel->DESTADDR2 = (( (uint32_t) destAddr) >> 2*8 ) & 0xFF;
00323
00324 channel->ADDRCTRL = (uint8_t) srcReload | srcDirection |
00325 destReload | destDirection;
00326 channel->TRFCNT = blockSize;
00327 channel->CTRLA = ( channel->CTRLA & ~( DMA_CH_BURSTLEN_gm | DMA_CH_REPEAT_bm ) ) |
00328 burstMode | ( useRepeat ? DMA_CH_REPEAT_bm : 0);
00329
00330 if ( useRepeat ) {
00331 channel->REPCNT = repeatCount;
00332 }
00333 }
00334
00335
00345 void DMA_EnableSingleShot( volatile DMA_CH_t * channel )
00346 {
00347 channel->CTRLA |= DMA_CH_SINGLE_bm;
00348 }
00349
00350
00361 void DMA_DisableSingleShot( volatile DMA_CH_t * channel )
00362 {
00363 channel->CTRLA &= ~DMA_CH_SINGLE_bm;
00364 }
00365
00366
00375 void DMA_SetTriggerSource( volatile DMA_CH_t * channel, uint8_t trigger )
00376 {
00377 channel->TRIGSRC = trigger;
00378 }
00379
00380
00387 void DMA_StartTransfer( volatile DMA_CH_t * channel )
00388 {
00389 channel->CTRLA |= DMA_CH_TRFREQ_bm;
00390 }