XMEGA128A1U DMA problem (solved)

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear freaks,

 

my task is to copy one (e.g. 8-byte) array to another using DMA module on XMEGA128A1U. Result: destination array gets filled with very first byte from source. In-circuit debugging confirms that SRC_ADDR register is not changing (neither INC. nor DEC). Switching between DMA channels #0..#3 gives same result. Example code is as follows

void init_dma(void)
{

    uint8_t dest_array[8], src_array[8] = {1,2,3,4,5,6,7,8};

	DMA_CTRL           = DMA_RESET_bm;

	DMA_CH0_CTRLB      = 0x00;
	DMA_CH0_DESTADDR0  = (uint16_t)&dest_array[0] >>  0;
	DMA_CH0_DESTADDR1  = (uint16_t)&dest_array[0] >>  8;
	DMA_CH0_DESTADDR2  = 0x00;
	DMA_CH0_SRCADDR0   = (uint16_t)&src_array[0]  >>  0;
	DMA_CH0_SRCADDR1   = (uint16_t)&src_array[0]  >>  8;
	DMA_CH0_SRCADDR2   = 0x00;
	DMA_CH0_ADDRCTRL   = DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc;
	DMA_CH0_TRFCNT     = 8;
// for test purposes transmission is triggered manually
//	DMA_CH0_TRIGSRC    = DMA_CH_TRIGSRC_TCC0_OVF_gc;

	DMA_CH0_CTRLA      = DMA_CH_ENABLE_bm | DMA_CH_REPEAT_bm | DMA_CH_SINGLE_bm | DMA_CH_BURSTLEN_1BYTE_gc;

	DMA_CTRL           = DMA_ENABLE_bm | DMA_PRIMODE_CH0123_gc;

    while(1)
    {
// now manually start transfer
//        DMA_CH0_CTRLA     |= DMA_CH_ENABLE_bm;
//        _delay_us(30);
    }

}

Errata on this issue is empty. Can anyone confirm that it is a hardware bug, or I am doing wrong?

 

Last Edited: Fri. Sep 29, 2017 - 09:42 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Checked once again: in simulator - works fine, in silicon - SRC_ADDR remains unchanged :(

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include <avr/io.h>
#include <avr/cpufunc.h>

uint8_t dest_array[8], src_array[8] = {1,2,3,4,5,6,7,8};

void init_dma(void){
	DMA_CTRL           = DMA_RESET_bm;
	DMA_CH0_CTRLB      = 0x00;
	DMA_CH0_DESTADDR0  = (uint16_t)&dest_array[0] >>  0;
	DMA_CH0_DESTADDR1  = (uint16_t)&dest_array[0] >>  8;
	DMA_CH0_DESTADDR2  = 0x00;
	DMA_CH0_SRCADDR0   = (uint16_t)&src_array[0]  >>  0;
	DMA_CH0_SRCADDR1   = (uint16_t)&src_array[0]  >>  8;
	DMA_CH0_SRCADDR2   = 0x00;
	DMA_CH0_ADDRCTRL   = DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc;
	DMA_CH0_TRFCNT     = 8;
	DMA_CH0_CTRLA      = DMA_CH_ENABLE_bm | DMA_CH_REPEAT_bm | DMA_CH_SINGLE_bm | DMA_CH_BURSTLEN_1BYTE_gc;
	DMA_CTRL           = DMA_ENABLE_bm | DMA_PRIMODE_CH0123_gc;
}
int main(void){
	init_dma();
	while (1){
		_NOP();	// break point
//		_NOP();
	}
}

I tried it.
If there is only one NOP in main, TRFCNT and SRCADDR are not updated at the time of the break. It is a phenomenon being asked.
In the case of two NOPs in main, everything is working properly at the time of break.

This is not a problem with the device, it's a debugger problem.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you very much for your comment.

 

So you say that you tested the code in silicon, not in simulator, and source array was successfully copied to destination. Correct?

If so, please specify what is your chip and chip revision.

 

Thanks again

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Information on the device I tested.
When it operated normally with two NOPs, the copy was also normal.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, thank you,

 

 

problem solved.

 

Same code is working fine today, so assume it was some sort of a debugger problem.