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.

Could anyone give me a simple DMA data transfer to Global Shared RAM code example, please?

Other Parts Discussed in Thread: CONTROLSUITE

Hi, everybody!

I am a new user of a F28377xD development kit and I am trying to use the DMA to transfer data to Globarl Shared RAM directly, but I don't know how to do this.

Could anyone give me a simple code axample about this, please?

Many thanks for your attention.

Regards,

Guillermo

  • Hello,

    Have you downloaded controlSUITE? controlSUITE contains several examples for F2837xD that can be helpful. (www.ti.com/.../controlsuite)

    Best Regards,
    Chris
  • Hello,

    Yes, I did, but I would like an easier example. The example of controlSUITE uses DMA with PWM peripherals, but I need to use DMA to write in the Global Shared RAM.

    Thank  you very much.

    Kind regards,

    Guillermo

  • Guillermo,

    I'm not sure what example you're referring to, but I know there is one in controlSUITE that uses the DMA to put data received over SPI into a buffer in RAM. Have you seen that one?

    It's under /device_support/F2837xD/v150/F2837xD_examples_Cpu1/spi_loopback_dma

    Whitney

  • Hi Whitney,

    Yes, I saw it, but I don't understand it completely -I am a beginner. So I only want to write in the Global Shared RAM by using the DMA_CPU01 and then read this data with CPU02 and modify it. The only purpose is to get familiar with DMA.

    Thanks a lot!

    Guillermo

  • Guillermo,

    I took the SPI+DMA example and tried to simplify it a bit. Instead of using the SPI, I'm triggering the burst using the PERINTFRC bit. I'm using one DMA channel to transfer the data from sdata to rdata. When it sets the PERINTFRC bit, it will transfer a burst of 8 16-bit words from sdata to rdata. It will loop and keep setting PERINTFRC until the transfer of 16 bursts has been completed. When the whole transfer is completed, it will trigger the DMA interrupt.

    The code I'm attaching to this post only runs on CPU1. It might be a good exercise for you to try to modify it to work as you've described.

    Please let us know if there's a specific issue that you're confused about, so that we can try to clarify.

    Thanks,

    Whitney

    dma_cpu01.c
    //###########################################################################
    // FILE:   Example_2837xD_Spi_dma.c
    // TITLE:  SPI Digital Loop Back with DMA Example.
    //
    //! \addtogroup cpu01_example_list
    //! <h1>SPI Digital Loop Back with DMA (spi_loopback_dma)</h1>
    //!
    //!  This program uses the internal loop back test mode of the peripheral.
    //!  Other then boot mode pin configuration, no other hardware configuration
    //!  is required. Both DMA Interrupts and the SPI FIFOs are used.
    //!
    //!  A stream of data is sent and then compared to the received stream.
    //!  The sent data looks like this: \n
    //!  0000 0001 \n
    //!  0001 0002 \n
    //!  0002 0003 \n
    //!  .... \n
    //!  007E 007F \n
    //!
    //!  \b Watch \b Variables \n
    //!  - \b sdata - Data to send
    //!  - \b rdata - Received data
    //!  - \b rdata_point - Used to keep track of the last position in
    //!    the receive stream for error checking
    //
    //###########################################################################
    // $TI Release: F2837xD Support Library v150 $
    // $Release Date: Thu Mar  5 14:18:39 CST 2015 $
    // $Copyright: Copyright (C) 2013-2015 Texas Instruments Incorporated -
    //             http://www.ti.com/ ALL RIGHTS RESERVED $
    //###########################################################################
    
    #include "F28x_Project.h"     // Device Headerfile and Examples Include File
    
    // Prototype statements for functions found within this file.
    __interrupt void local_D_INTCH6_ISR(void);
    
    void dma_init(void);
    void error();
    
    Uint16 sdata[128];     // Send data buffer
    Uint16 rdata[128];     // Receive data buffer
    Uint16 rdata_point;  // Keep track of where we are
                         // in the data stream to check received data
    // DMA data sections
    #pragma DATA_SECTION(sdata, "ramgs0");  // map the TX data to memory
    #pragma DATA_SECTION(rdata, "ramgs1");  // map the RX data to memory
    
    volatile Uint16 *DMADest;
    volatile Uint16 *DMASource;
    
    #define BURST       7               // burst size should be less than 8
    #define TRANSFER    15              // [(MEM_BUFFER_SIZE/(BURST + 1))-1]
    
    volatile Uint16 done;
    
    
    void main(void)
    {
       Uint16 i;
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xD_SysCtrl.c file.
       InitSysCtrl();
    
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xD_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();  // Skipped for this example
    // Setup only the GP I/O only for SPI-A functionality
    //   InitSpiaGpio();
    
    // Step 3. Initialize PIE vector table:
    // Disable and clear all CPU interrupts
       DINT;
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize PIE control registers to their default state:
    // This function is found in the F2837xD_PieCtrl.c file.
       InitPieCtrl();
    
    // 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 F2837xD_DefaultIsr.c.
    // This function is found in F2837xD_PieVect.c.
       InitPieVectTable();
    
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
       EALLOW;  // This is needed to write to EALLOW protected registers
       PieVectTable.DMA_CH6_INT= &local_D_INTCH6_ISR;
       EDIS;   // This is needed to disable write to EALLOW protected registers
    
    // Step 4. Initialize the Device Peripherals:
       dma_init();          // set up dma for SPI configuration
    
        // Ensure DMA is connected to Peripheral Frame 2 bridge (EALLOW protected)
        EALLOW;
        CpuSysRegs.SECMSEL.bit.PF2SEL = 1;
        EDIS;
    
    
    // Step 5. User specific code, enable interrupts:
    
        // Initialize the data buffers
        for(i=0; i<128; i++)
        {
            sdata[i] = i;
            rdata[i]= 0;
        }
        rdata_point = 0;
    
    // Enable interrupts required for this example
       PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // Enable the PIE block
       PieCtrlRegs.PIEIER7.bit.INTx6 = 1;   // Enable PIE Group 7, INT 2 (DMA CH2)
       IER= M_INT7;                         // Enable CPU INT6
       EINT;                                // Enable Global Interrupts
    
       StartDMACH6();       // Start SPI RX DMA channel
    
       done = 0;            // Test is not done yet
    
       while(!done)        // wait until the DMA transfer is complete
       {
           EALLOW;
           DmaRegs.CH6.CONTROL.bit.PERINTFRC = 1;
           EDIS;
    
           DELAY_US(1000);
       }
    
       // when the DMA transfer is complete the program will stop here
       ESTOP0;
    
    }
    
    void error(void)
    {
       asm("     ESTOP0");  //Test failed!! Stop!
        for (;;);
    }
    
    // DMA setup for both TX and RX channels.
    void dma_init()
    {
        // refer to dma.c for the descriptions of the following functions.
    
        //Initialize DMA
        DMAInitialize();
    
        DMASource = (volatile Uint16 *)sdata;
        DMADest = (volatile Uint16 *)rdata;
    
        // configure DMA CH6
        DMACH6AddrConfig(DMADest,DMASource);
        DMACH6BurstConfig(BURST,1,1);
        DMACH6TransferConfig(TRANSFER,1,1);
        DMACH6ModeConfig(0,PERINT_ENABLE,ONESHOT_DISABLE,CONT_DISABLE,
                SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,CHINT_END,CHINT_ENABLE);
    
    }
    
    // INT7.2
    __interrupt void local_D_INTCH6_ISR(void)       // DMA Ch6
    {
        Uint16 i;
        EALLOW;                                 // NEED TO EXECUTE EALLOW INSIDE ISR !!!
        DmaRegs.CH6.CONTROL.bit.HALT = 1;
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP7; // ACK to receive more interrupts from this PIE group
        EDIS;
    
        for( i = 0; i<128; i++ )
        {
            // check for data integrity
            if (rdata[i] != i)
            {
                error();
            }
        }
    
        done =1;        // test done.
        return;
    }
    
    

  • Hi, Whitney.

    Excuse me for the delay. Many thanks for your aid, it was so useful!

    Kind regards,

    Guillermo