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 looses data between two burst transfers

Other Parts Discussed in Thread: ADS1672, TMS320C28346

Hi,

I have modified the example code "Example_2834xMCBSP_DLB_DMA.c" of the TI Delfino TMS320C28346 to acquire the data from a Ti ADS1672 EVM at 625 KSPS at 24 bits per sample. I connect the ADS1672 to the McBSP of the TI Delfino and use the DMa for transfers of consecutive bursts of 1000 data points.

By sending a linear ramp, I have noticed that between two consecutive bursts, around 3 data points are lost. I do that by checking the last sample of the precendent buffer and the first sample of the current buffer.

It seems that the DMA takes around 5 us to set up (3*sampling rate). Is there a way for avoinding loosing these 3 data points. if you need, I can send the details about the connection of the TI Delfino EVM and the ADS1672EVM.

BEST

Daniele

PS:

My code is the following.

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&  CODE  &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

  &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

//###########################################################################
//
// FILE:   Example_2834xMCBSP_DLB_DMA.c
//
// TITLE:  DSP2834x Device McBSP Digital Loop Back  with DMA program
//
// ASSUMPTIONS:
//
//    This program requires the DSP2834x header files.
//    As supplied, this project is configured for "boot to SARAM"
//    operation.  The 2834x Boot Mode table is shown below.
//    For information on configuring the boot mode of an eZdsp,
//    please refer to the documentation included with the eZdsp,
//
//       $Boot_Table:
//
//         GPIO87   GPIO86     GPIO85   GPIO84
//          XA15     XA14       XA13     XA12
//           PU       PU         PU       PU
//        ==========================================
//            1        1          1        1    TI Test Only
//            1        1          1        0    SCI-A boot
//            1        1          0        1    SPI-A boot
//            1        1          0        0    I2C-A boot timing 1
//            1        0          1        1    eCAN-A boot timing 1
//            1        0          1        0    McBSP-A boot
//            1        0          0        1    Jump to XINTF x16
//            1        0          0        0    Jump to XINTF x32
//            0        1          1        1    eCAN-A boot timing 2
//            0        1          1        0    Parallel GPIO I/O boot
//            0        1          0        1    Parallel XINTF boot
//            0        1          0        0    Jump to SARAM        <- "boot to SARAM"
//            0        0          1        1    Branch to check boot mode
//            0        0          1        0    I2C-A boot timing 2
//            0        0          0        1    Reserved
//            0        0          0        0    TI Test Only
//                                              Boot_Table_End$$
//
// DESCRIPTION:
//
// This program is a McBSP example that uses the internal loopback of
// the peripheral and utilizes the DMA to transfer data from one buffer
// to the McBSP, and then from the McBSP to another buffer.
//
// Initially, sdata[] is filled with values from 0x0000- 0x007F.  The DMA
// moves the values in sdata[] one by one to the DXRx registers of the McBSP.
// These values are transmitted and subsequently received by the McBSP.
// Then, the DMA moves each data value to rdata[] as it is received by the McBSP.
//
// Three different serial word sizes can be tested.
//
//          Before compiling this project:
//          * Select the serial word size (8/16/32) by using
//            the #define statements at the beginning of the code.
//
// The program loops forever after all values have been transferred to sdata.
// It is up to the user to stop the program.
//
//
// By default for the McBSP examples, the McBSP sample rate generator (SRG) input
// clock frequency is LSPCLK (150E6/4 or 100E6/4) assuming SYSCLKOUT = 150 MHz or
// 100 MHz respectively.  If while testing, the SRG input frequency
// is changed, the #define MCBSP_SRG_FREQ  (150E6/4 or 100E6/4) in the Mcbsp.c file must
// also be updated accordingly.  This define is used to determine the Mcbsp initialization
// delay after the SRG is enabled, which must be at least 2 SRG clock cycles.
//
//   Watch Variables:
//                sdata
//                rdata
//
//
//###########################################################################
// $TI Release: 2834x Header Files V1.12 $
// $Release Date: March 2011 $
//###########################################################################


#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

// Choose a word size.  Uncomment one of the following lines
//#define WORD_SIZE  8      // Run a loopback test in 8-bit mode
//#define WORD_SIZE 16      // Run a loopback test in 16-bit mode
#define WORD_SIZE 32      // Run a loopback test in 32-bit mode
#define BUFFER_SIZE 1000

// Prototype statements for functions found within this file.

//interrupt void local_D_INTCH1_ISR(void);
interrupt void local_D_INTCH2_ISR(void);
void mcbsp_init_dlb(void);
void init_dma_32(void);
void start_dma(void);
void error(void);
void init_buffer(void);

#pragma DATA_SECTION(rdata, "DMARAML4")



Uint16 rdata[2*BUFFER_SIZE];    // Recieved Data
Uint16 data_size;     // Word Length variable

Uint32 rdata1_ext;
Uint32 rdata2_ext;
Uint32 buffer_act;

Int32 buffer[BUFFER_SIZE];
Int32 buffer_act_signed;

Int32 buffer_averaged[BUFFER_SIZE];
Int32 buffer_test[BUFFER_SIZE];

void main(void)
{
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2833x_SysCtrl.c file.
   InitSysCtrl();

// Step 2. Initalize GPIO:
// Setup only the GP I/O only for McBSP-A functionality
   InitMcbspaGpio();

// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
   DINT;

// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP2833x_PieCtrl.c file.
   InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
   IER = 0x0000;
   IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in DSP2833x_DefaultIsr.c.
// This function is found in DSP2833x_PieVect.c.
   InitPieVectTable();

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
   EALLOW;    // Allow access to EALLOW protected registers
   PieVectTable.DINTCH2= &local_D_INTCH2_ISR;
   EDIS;   // Disable access to EALLOW protected registers


// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP2833x_InitPeripherals.c
// InitPeripherals(); // Not required for this example

// Step 5. User specific code, enable interrupts:
   data_size = WORD_SIZE;
   init_buffer();
   init_dma_32();     // DMA Initialization for 32-bit transfers
   start_dma();
   mcbsp_init_dlb();   // 2.  Then initialize and release peripheral (McBSP) from Reset.


// Enable interrupts required for this example
   PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // Enable the PIE block
   //PieCtrlRegs.PIEIER6.bit.INTx5=1;     // Enable PIE Group 6, INT 5
//   PieCtrlRegs.PIEIER6.bit.INTx6=1;     // Enable PIE Group 6, INT 6
//   PieCtrlRegs.PIEIER7.bit.INTx1 = 1;    // Enable PIE Group 7, INT 1 (DMA CH1)
   PieCtrlRegs.PIEIER7.bit.INTx2 = 1;    // Enable PIE Group 7, INT 2 (DMA CH2)

   IER=0x60;                            // Enable CPU INT groups 6 and 7
   EINT;                                // Enable Global Interrupts

// Step 6. IDLE loop. Just sit and loop forever (optional):
   for(;;);

}


// Step 7. Insert all local Interrupt Service Routines (ISRs) and functions here:


void error(void)
{
    asm("     ESTOP0"); // Test failed!! Stop!
    for (;;);
}

void init_buffer(void)
{
    Int16 i;
    for (i=0; i<BUFFER_SIZE; i++)
    {
        buffer_averaged[i] = 0;
    }
}

void mcbsp_init_dlb()
{
    McbspaRegs.SPCR2.all=0x0000;        // Reset FS generator, sample rate generator & transmitter
    McbspaRegs.SPCR1.all=0x0000;        // Reset Receiver, Right justify word

    McbspaRegs.MFFINT.all=0x0;            // Disable all interrupts

    McbspaRegs.RCR2.all=0x0;            // Single-phase frame, 1 word/frame, No companding    (Receive)
    McbspaRegs.RCR1.all=0x0;

    McbspaRegs.XCR2.all=0x0;            // Single-phase frame, 1 word/frame, No companding    (Transmit)
    McbspaRegs.XCR1.all=0x0;

    McbspaRegs.SRGR2.bit.GSYNC = 1;        // FPER = 32 CLKG periods
    McbspaRegs.SRGR1.bit.FWID = 0;      // Frame Width = 1 CLKG period

    InitMcbspa24bit();


    //************* Enable Sample rate generator
    McbspaRegs.SPCR2.bit.GRST=1; // Enable the sample rate generator
    delay_loop();                // Wait at least 2 SRG clock cycles
    //McbspaRegs.SPCR2.bit.XRST=1; // Release TX from Reset
    McbspaRegs.SPCR1.bit.RRST=1; // Release RX from Reset
    McbspaRegs.SPCR2.bit.FRST=1; // Frame Sync Generator reset
}


// DMA Initialization for data size > 16-bit and <= 32-bit.

void init_dma_32()
{
    EALLOW;
    DmaRegs.DMACTRL.bit.HARDRESET = 1;
    asm(" NOP");                           // Only 1 NOP needed per Design

    // Channel 2, McBSPA Receive
    DmaRegs.CH2.BURST_SIZE.all = 1;        // 2 words/burst
    DmaRegs.CH2.SRC_BURST_STEP = 1;        // Increment 1 16-bit addr. btwn words
    DmaRegs.CH2.DST_BURST_STEP = 1;        // Increment 1 16-bit addr. btwn words
    DmaRegs.CH2.TRANSFER_SIZE = BUFFER_SIZE;        // Interrupt every 63 bursts/transfer
    DmaRegs.CH2.SRC_TRANSFER_STEP = 0xFFFF;    // Decrement  back to DRR2
    DmaRegs.CH2.DST_TRANSFER_STEP = 1;    // Move to next word in buffer after each word in a burst
    DmaRegs.CH2.SRC_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR2.all;            // Start address = McBSPA DRR
    DmaRegs.CH2.SRC_BEG_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR2.all;        // Not needed unless using wrap function
    DmaRegs.CH2.DST_ADDR_SHADOW = (Uint32) &rdata[0];        // Start address = Receive buffer (for McBSP-A)
    DmaRegs.CH2.DST_BEG_ADDR_SHADOW = (Uint32) &rdata[0];    // Not needed unless using wrap function
    DmaRegs.CH2.CONTROL.bit.SYNCCLR = 1;        // Clear sync flag
    DmaRegs.CH2.CONTROL.bit.ERRCLR = 1;    // Clear sync error flag
    DmaRegs.CH2.DST_WRAP_SIZE = 0xFFFF;        // Put to maximum - don't want destination wrap
    DmaRegs.CH2.SRC_WRAP_SIZE = 0xFFFF;        // Put to maximum - don't want source wrap
    DmaRegs.CH2.MODE.bit.CHINTE = 1;            // Enable channel interrupt
    DmaRegs.CH2.MODE.bit.CHINTMODE = 1;        // Interrupt at end of transfer
    DmaRegs.CH2.MODE.bit.PERINTE = 1;            // Enable peripheral interrupt event
    DmaRegs.CH2.MODE.bit.PERINTSEL = DMA_MREVTA;    // Peripheral interrupt select = McBSP MRSYNCA
    DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1;          // Clear any spurious interrupt flags
    EDIS;
}

void start_dma (void)
{
    EALLOW;
//  DmaRegs.CH1.CONTROL.bit.RUN = 1;             // Start DMA Transmit from McBSP-A
    DmaRegs.CH2.CONTROL.bit.RUN = 1;           // Start DMA Receive from McBSP-A
    EDIS;
}

// INT7.2


interrupt void local_D_INTCH2_ISR(void)        // DMA Ch2
{


    Uint16 i;
    EALLOW;                                    // NEED TO EXECUTE EALLOW INSIDE ISR !!!
    DmaRegs.CH2.CONTROL.bit.RUN = 0;        // Re-enable DMA CH2. Should be done every transfer
    DmaRegs.CH2.CONTROL.bit.RUN = 1;

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP7; // To receive more interrupts from this PIE group, acknowledge this interrupt

    for (i = 0; i < BUFFER_SIZE; i++)
        {
            buffer_test[i] = buffer[i];
        }

    for (i = 0; i < 2*BUFFER_SIZE; i = i + 2)
    {
        rdata2_ext = ( (Uint32) rdata[i] );
        rdata1_ext = ( (Uint32) rdata[i + 1] );

        buffer_act = ((rdata2_ext<<16) | rdata1_ext);

        buffer_act_signed = ((Int32) buffer_act);
        buffer_act_signed = (buffer_act_signed<<8);
        buffer_act_signed = (buffer_act_signed>>8);

        if (i==0)
            {buffer[i] =  buffer_act_signed;}
        else
            {buffer[i>>1] =  buffer_act_signed;}
    }
    for (i = 0; i < BUFFER_SIZE; i++)
    {
        buffer_averaged[i] = buffer_averaged[i] + buffer[i];
    }



    EDIS;
    return;

}

//===========================================================================
// No more.
//===========================================================================