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.

TMDXDOCK280049M: Piccolo ADC Result Registers transfer to RAM using DMA

Part Number: TMDXDOCK280049M
Other Parts Discussed in Thread: C2000WARE

Hello TI Team,

I cannot find an ADC to RAM DMA example under C2000Ware for the Piccolo 280049 MCU.  There are a few examples for other processors but they do not use the same functions.  However the logic between examples looks very similar: init device, set addresses, set burst, set transfer, set mode, etc. and I have tried to follow the same logical flow but no luck so far.

I want to configure a DMA device to transfer ADC Result Registers to internal RAM buffers at the end of ADC conversions and have the DMA fire an interrupt when transfer is completed that I can connect to my control logic ISR.

This is what I have done so far:

  • CPU Timer 0 drives my ADC conversions at 10kHz last channel on ADC device C generates an ADC interrupt
  • This is working fine. I get the 10kHz interrupt and my ADC ISR transfer data from the result registers to internal buffers.  However this is pretty slow and want to have this done by the DMA
  • I then modified the code a bit to remove the ADC interrupt and have the last channel on the ADC C signal the DMA device
  • I configured the DMA device to generate an interrupt at the end of the transfer.
  • The signaling between ADC to DMA seems to be working fine. The last channel conversion on ADC C signals the DMA device, the DMA interrupt then fires (I monitored this with a counter and also a GPIO pin toggle to check frequency and execution time on the scope) which at the time of the interrupt I assume the data has been transferred, but I do not see any data on the destination buffer ever.

Therefore, I suspect that there is something wrong in the way I am configuring the DMA device.  I created the attached test file removing the ADC portion and simply use the DMA to move data between two RAM buffers on software trigger but still I do not see any data transferred by the DMA from the source to the destination buffer. 

Can TI provide a working sample code to do this common ADC to RAM with DMA for the Piccolo 280049 chip?

/****************************** TI 28004x *********************************\
 * @Module:       main.c
 * @Description:  Testing basic DMA transfer functionality
 ***************************************************************************/
#include "F28x_Project.h"
#include "f28004x_device.h"
#include "f28004x_globalprototypes.h"

#include "driverlib.h"  // header to TI2800

Uint32 RunCount = 0;
Uint32 dmaIntCount = 0;
Uint16 dmaXferTestSource[16]     ={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
Uint16 dmaXferTestDestination[16]={0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 0, 0};

__interrupt void adcDmaXferCompleteIsr(void);
void dmaConfig(void);

/*
 * @Function: main()
 */
void main(void)
{
    // Initialize device clock and peripherals
    InitSysCtrl();

    // Initialize GPIO
    InitGpio();

    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;

    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    InitPieVectTable();

    dmaConfig();

    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    EINT;
    ERTM;

    for (;;)
    {
        // Delay half a second
        DELAY_US(500000);

		// force DMA trigger so that the device will do a transfer
		DMA_forceTrigger(DMA_CH1_BASE);

        ++RunCount;
    }
}


// adcDmaXferCompleteIsr - this will be used to sync our control algorithm 
__interrupt void adcDmaXferCompleteIsr(void)
{
    dmaIntCount++;
	
	// if setup then signal control algorithm

    // Clear the interrupt flag and issue ACK
    DMA_clearTriggerFlag(DMA_CH1_BASE);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP7);
}


void dmaConfig(void)
{
    // Initialize DMA
    DMA_initController();

    // Configure DMA Ch1 to transfer data between two RAM buffers
    DMA_configAddresses(DMA_CH1_BASE, &dmaXferTestDestination[0], (const void *)&dmaXferTestSource[0]);
    DMA_configBurst(DMA_CH1_BASE, 15, 1, 1);   // burst of 16 words of 16 bits each therefore steps are set to 1
    DMA_configTransfer(DMA_CH1_BASE, 1, 0, 0); // transfer requires only 1 burst
    DMA_configWrap(DMA_CH1_BASE,1,-15,1,-15);  // wrap addresses back to start of buffers after a single transfer
    DMA_configMode(DMA_CH1_BASE,
                   DMA_TRIGGER_SOFTWARE,       // make this software trigger for now, should be triggered by last ADC channel interrupt
                   DMA_CFG_ONESHOT_ENABLE |    // allow the next burst to take place without additional triggers
                   DMA_CFG_CONTINUOUS_ENABLE | // leave channel enabled and ready for next trigger
                   DMA_CFG_SIZE_16BIT);        // transfer 16 bit words for now, preferably 32bit which will require adjusted steps and number of words above

    // Configure DMA Ch1 interrupt
    DMA_setInterruptMode(DMA_CH1_BASE, DMA_INT_AT_END);  // Set device interrupt mode for end of each transfer
    DMA_enableInterrupt(DMA_CH1_BASE);                   // allow this device to generate the interrupt
    DMA_enableTrigger(DMA_CH1_BASE);                     // allow trigger to fire the device
    DMA_startChannel(DMA_CH1_BASE);                      // start the device

    Interrupt_register(INT_DMA_CH1, &adcDmaXferCompleteIsr);  // map DMA interrupt to my ISR
    Interrupt_enable(INT_DMA_CH1);                             // enable DMA interrupt
}

  • Rafael,

    We are working on some of the these example for F280049 device. But, you can easily modify example listed below for F2837xS

    Path: <C2000Ware>\device_support\f2837xs\examples\cpu1\

    Projects:
    adc_soc_continuous_dma
    sdfm_filters_sync_dma
    spi_loopback_dma

    Regards,
    Manoj
  • Well telling me to look at the examples I have been looking at does not really help.
    There is evidently something fundamentally wrong on my setup.
    I would have hope that a quick look at the simple example I provided would allow you the experts to quickly see the issue.
  • I just got a email from our TI representative in Demark with the answer to my problem.

    I made the mistake of declaring my buffers in LSRAM which is not accessible by the DMA.

    A simple PRAGMA instruction to get the buffers into GSRAM solved the issue.

    // Place buffers in GSRAM
    #pragma DATA_SECTION(dmaXferTestSource, "ramgs0");
    #pragma DATA_SECTION(dmaXferTestDestination, "ramgs0");