Почти всё верно, или может всё верно. DMA.CH0.REPCNT = 1;
Если в DMA.CH0.CTRLA бит REPEAT равен 0, то DMA.CH0.REPCNT можно не настраивать - он будет проигнорирован (прерывание и запрет канала ДМА произойдёт после передачи блока).
Еще проще, прерывания ДМА вообще не разрешать (DMA.CH0.CTRLB |= DMA_CH_TRNINTLVL_OFF_gc)
DMA.CH0.CTRLB |= DMA_CH_TRNINTLVL_OFF_gc;
тоже самое что и
DMA.CH0.CTRLB |= 0; // DMA_CH_TRNINTLVL_OFF_gc - равно 0
Правильно так:
DMA.CH0.CTRLB &= ~DMA_CH_TRNINTLVL_gm;
DMA.CTRL = DMA_RESET_bm;
while ((DMA.CTRL & DMA_RESET_bm) != 0)
;
Можно без while? В мануале не нашёл через сколько он сбрасывается. Всегда так делал:
void EnableDma()
{
DMA.CTRL=DMA_RESET_bm;
DMA.CTRL=0
| (1<<DMA_ENABLE_bp)
| (0<<DMA_RESET_bp)
| ((uint8_t)DMA_DBUFMODE_DISABLED_gc)
| ((uint8_t)DMA_PRIMODE_CH0123_gc)
;
}
Работает.