This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DMA Burst configuration issue

Other Parts Discussed in Thread: TMS320F28335

Hi, i'm working with a tms320f28335 microcontroller. I need to configure the DMA to transfer data from the ADC to a an array of certain length. The ADC is configured to sample only one channel, namely ADCINA0. The ADC is triggered by EPWM. After that, the ADC is configured to take only one measurement of such channel. The interrupt of the ADC triggers the DMA. Here's the problem: as only one measurement is taken, thus the burst size is configured as one 16bit word:

	// Configure the addresses.
	DmaRegs.CH1.SRC_BEG_ADDR_SHADOW = (Uint32)&AdcMirror.ADCRESULT0;
	DmaRegs.CH1.SRC_ADDR_SHADOW = (Uint32)&AdcMirror.ADCRESULT0;
	DmaRegs.CH1.DST_BEG_ADDR_SHADOW = (Uint32)AdcBufRaw;
	DmaRegs.CH1.DST_ADDR_SHADOW = (Uint32)AdcBufRaw;

	// Configure the bursts. Words to be transferred each burst.
	DmaRegs.CH1.BURST_SIZE.all = 0x0000; // One word per burst.
	DmaRegs.CH1.SRC_BURST_STEP = 0x0001; // Step to the next ADCRESULT register.
	DmaRegs.CH1.DST_BURST_STEP = 0x0001; // Go to the next position of the adc array.

	// Configure the transfer registers.
	DmaRegs.CH1.TRANSFER_SIZE = (ADC_BUFFER_LEN - 1);
	DmaRegs.CH1.SRC_TRANSFER_STEP = 0x0000;
	DmaRegs.CH1.DST_TRANSFER_STEP = 0x0000; // Will be ignored when WRAP occurs.

	// Configure wrap.
	DmaRegs.CH1.SRC_WRAP_SIZE = 0x000f; // Wrap after 15 words transferred (length of the ADCRESULT registers).
	DmaRegs.CH1.SRC_WRAP_STEP = 0x0000; // Go back to ADCRESULT0 and do not step.

	DmaRegs.CH1.DST_WRAP_SIZE = (ADC_BUFFER_LEN - 1);
	DmaRegs.CH1.DST_WRAP_STEP = 0x0000; // Go back to position 0 of adc array (Doesn't matter, as the array is only filled once).

But the DMA only transfers one word instead of the ADC_BUFFER_LEN (transfer size) that it is supposed to pass to the array. It only works if i change the burst size to two as follows:

DmaRegs.CH1.BURST_SIZE.all = 0x0001; // Two words per burst.

Am i missing something here?

Thanks in advanced. If i'm not being clear, please tell me so.

  • Is the data size set to 0 (16 bits) in the MODE register? Are you in continuous mode?
  • The configuration register of the DMA is as follows:

    	DmaRegs.CH1.MODE.bit.CHINTE = 1;
    	DmaRegs.CH1.MODE.bit.DATASIZE = 0;
    	DmaRegs.CH1.MODE.bit.SYNCSEL = 0;
    	DmaRegs.CH1.MODE.bit.SYNCE = 0;
    	DmaRegs.CH1.MODE.bit.CONTINUOUS = 0;
    	DmaRegs.CH1.MODE.bit.ONESHOT = 0;
    	DmaRegs.CH1.MODE.bit.CHINTMODE = 1;
    	DmaRegs.CH1.MODE.bit.PERINTE = 1;
    	DmaRegs.CH1.MODE.bit.OVRINTE = 0;
    	DmaRegs.CH1.MODE.bit.PERINTSEL = 1;

    The weird thing is that it seems to be doing the bursts correctly; 1 word (16bit), per burst, as the analyzed data seems to match the sine wave input to the ADC channel.

  • I think you need to set your transfer step sizes to 1. The burst steps are only done between words of a single burst. There's no burst step at the end of a burst. The transfer steps are done between bursts. When your transfer step sizes are zero, the DMA is probably copying the same ADC result register to the same buffer address ADC_BUFFER_LEN times.
  • You might be right. I'll test that as soon as i have a chance and i'll post you back with the results.

    Thanks!
  • You were right. I got confused. The proper configuration is as follows:

    	// Configure the addresses.
    	DmaRegs.CH1.SRC_BEG_ADDR_SHADOW = (Uint32)&AdcMirror.ADCRESULT0;
    	DmaRegs.CH1.SRC_ADDR_SHADOW = (Uint32)&AdcMirror.ADCRESULT0;
    	DmaRegs.CH1.DST_BEG_ADDR_SHADOW = (Uint32)AdcBufRaw;
    	DmaRegs.CH1.DST_ADDR_SHADOW = (Uint32)AdcBufRaw;
    
    	// Configure the bursts. Words to be transferred each burst. 
    //There is not step between bursts, as it is only one word. DmaRegs.CH1.BURST_SIZE.all = 0x0000; DmaRegs.CH1.SRC_BURST_STEP = 0x0000; DmaRegs.CH1.DST_BURST_STEP = 0x0000; // Configure the transfer registers. DmaRegs.CH1.TRANSFER_SIZE = (ADC_BUFFER_LEN - 1); DmaRegs.CH1.SRC_TRANSFER_STEP = 0x0001; // Go to the next position. Will be ignored when WRAP occurs. DmaRegs.CH1.DST_TRANSFER_STEP = 0x0001; // Go to the next position. Will be ignored when WRAP occurs. // Configure wrap. DmaRegs.CH1.SRC_WRAP_SIZE = 0x000f; // Wrap after 15 words transferred (Go back to ADCRESULT0). DmaRegs.CH1.SRC_WRAP_STEP = 0x0000; // Stay on ADCRESULT0 after wrap. DmaRegs.CH1.DST_WRAP_SIZE = (ADC_BUFFER_LEN - 1); DmaRegs.CH1.DST_WRAP_STEP = 0x0000; // Go back to position 0 in buffer.

    Thanks so much!