Xmega64a3 DMA problem

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

Hello,

I'm trying to set up a data acquisition device with a external AD converter using the SPID port.

The AD converter is working correct but if I try to send the data to a USB controller I found out that the ATxmega64a3 doens't have enough instructions to read the SPI data and transfer it to the USB controller using the 245FIFO protocol (USB controller is the FTDI FT2232H chip).

To solve this problem i came up with the idea to use the DMA controller. But I'm facing strange problems...

First of all I faced a problem with the DMA.CH0.TRFCNT register. After initialising this register and write a "256" to it the system is nearly crashing; the AD Converters aren't working anymore and I'm not able to toggle any pins anymore (PORTD.OUT ^= 0x01;).
So I tried to initialise this register seperate; the DMA.CH0.TRFCNTH (8 MSB's) and the DMA.CHO.TRFCNTL register (8 LSB's). The problem was in the TRFCNTH register when I only initialise the TRFCNTL register it's working (even though I'm not getting any data in the destination adress).

Could someone please help me! Here's the code:

void DMA_init(void)
{
DMA_CTRL = 0x80; //DMA controller enable, 
DMA.CH0.ADDRCTRL = (DMA_CH_SRCRELOAD_BURST_gc | DMA_CH_SRCDIR_FIXED_gc | DMA_CH_DESTRELOAD_BLOCK_gc | DMA_CH_DESTDIR_INC_gc); //No source reload, fixed position, destination reload, increment
DMA.CH0.TRIGSRC = 0x6A; //SPID trigger
//DMA.CH0.TRFCNTH = 0x00;
DMA.CH0.TRFCNTL = 0xFF; //255 byte block size 
//DMA.CH0.TRFCNT = 256;  <-- is not working!
DMA.CH0.DESTADDR0 = ad1data;
DMA.CH0.SRCADDR0 = &SPID.DATA;
DMA.CH0.CTRLA = 0b10000100;
DMA.CH0.CTRLB = 0x01;

}

ISR (DMA_CH0_vect) {
	channel0_done = true;
	PORTD.OUT ^= 0x01; //    <-- The program is going into this interrupt!
	}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What can I say about your code is that you should clear DMA Channel 0 transaction complete interrupt flag in DMA CH0 isr:

if (DMA.CH0.CTRLB & DMA_CH_ERRIF_bm)DMA.CH0.CTRLB |= DMA_CH_ERRIF_bm;
else 
{
 DMA.CH0.CTRLB |= DMA_CH_TRNIF_bm;
 channel0_done = true; 
}

Ozhan KD
Knowledge is POWER

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

electronic.designer wrote:
What can I say about your code is that you should clear DMA Channel 0 transaction complete interrupt flag in DMA CH0 isr:

if (DMA.CH0.CTRLB & DMA_CH_ERRIF_bm)DMA.CH0.CTRLB |= DMA_CH_ERRIF_bm;
else 
{
 DMA.CH0.CTRLB |= DMA_CH_TRNIF_bm;
 channel0_done = true; 
}

Thanks for your reply! But after implementing your provided code my interrupt is executed just one, after that not anymore!

So I think I made a big mistake but I can't find it!

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

JelleN wrote:
after implementing your provided code my interrupt is executed just one, after that not anymore!

This is a true result. Because DMA channel enable is automatically cleared when the transaction is completed. If you want to have a nonlimited number of interrupts, use repeat mode with DMA.CH0.REPCNT=0.

Ozhan KD
Knowledge is POWER

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

electronic.designer wrote:
JelleN wrote:
after implementing your provided code my interrupt is executed just one, after that not anymore!

This is a true result. Because DMA channel enable is automatically cleared when the transaction is completed. If you want to have a nonlimited number of interrupts, use repeat mode with DMA.CH0.REPCNT=0.

Ofcourse! Your absolutely right! The DMA.CH0.REPCNT=0; setting doesn't work but I tried to enable the DMA in the interrupt again with DMA.CH0.CTRLA |= DMA_CH_ENABLE_bm;.

Now it works and I finally see some data! Hopefully good enough. Thank you very much for your help!

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

JelleN wrote:
The DMA.CH0.REPCNT=0; setting doesn't work

For enabling repeat mode, you must also set Bit 5 of DMA.CH0.CTRLA.

Ozhan KD
Knowledge is POWER

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

electronic.designer wrote:
JelleN wrote:
The DMA.CH0.REPCNT=0; setting doesn't work

For enabling repeat mode, you must also set Bit 5 of DMA.CH0.CTRLA.

Yes it's working now! Thanks again!