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.

TMS320F28377S: MCBSP SPI Slave DMA Rx

Part Number: TMS320F28377S
Other Parts Discussed in Thread: TMS320F28386D, C2000WARE

Hello,

I am trying to use TMS320F28377S MCBSP A port as an SPI slave and use DMA CH6 to receive data.  Is DMA supported for MCBSP SPI slave on the TMS320F28377S?  I notice the MCBSP register DRR1 does get the first 16-bit word in a transfer from the master but it seems like the DMA controller is not moving the data.  I am using 16-bit words for data transfer.  If I use a transfer size of 1 and burst size of 1 I will get a DMA interrupt but the data isn't read from DRR1.

Other key points

  • I'm able to send and receive data on the TMS320F28377S over the MCBSP A SPI port as a slave using interrupts without DMA. This works fine.
  • I am able to use the TMS320F28386D MCBSP B port as a SPI master with tx/rx DMA transfers.  It works fine.

void main(void)
{
    //
    // Initialize device clock and peripherals
    //
    Device_init();

    GPIO_Setup();

    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

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

    McBSP_SPI_DMA_Setup();

    IER = 0x60;

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

    while(true)
    {
        //Loop forever
    }
}

#include "driverlib.h"
#include "device.h"
#include <stdint.h>
#include <string.h>


#pragma DATA_SECTION(txData, "ramgs0");  // map the TX data to memory
#pragma DATA_SECTION(rxData, "ramgs0");  // map the RX data to memory


#define MCBSP_PING_PONG_SIZE                2
#define BURST                               1
//#define TRANSFER                          512
//#define TRANSFER                          5         //For Testing to See 5 uint16_t on the scope
#define TRANSFER                            1         //Transfer size of 1 causes an interrupt

volatile uint16_t txData[TRANSFER];
volatile uint16_t rxData[TRANSFER];

uint32_t base_mcbsp=MCBSPA_BASE;
uint32_t base_dma_tx=DMA_CH5_BASE;
uint32_t base_dma_rx=DMA_CH6_BASE;


//
// Define to select delay in clock cycles.
//
#define MCBSP_CYCLE_NOP0(n)  __asm(" RPT #(" #n ") || NOP")
#define MCBSP_CYCLE_NOP(n)   MCBSP_CYCLE_NOP0(n)


__interrupt void DMA_CH5_ISR();
__interrupt void DMA_CH6_ISR();

static void McBSP_SPI_DMA_Setup_McBSP()
{

    //
    // Reset FS generator, sample rate generator, transmitter, receiver.
    //
    McBSP_resetFrameSyncLogic(base_mcbsp);
    McBSP_resetSampleRateGenerator(base_mcbsp);
    McBSP_resetTransmitter(base_mcbsp);
    McBSP_resetReceiver(base_mcbsp);

    //
    // Set Rx sign-extension and justification mode.
    //
    McBSP_setRxSignExtension(base_mcbsp, MCBSP_RIGHT_JUSTIFY_FILL_ZERO);

    //
    // Enable clock stop mode.
    //
    McBSP_setClockStopMode(base_mcbsp, MCBSP_CLOCK_SPI_MODE_NO_DELAY);

    //
    // Set Rx & Tx delay to 0 cycle.
    //
    McBSP_setRxDataDelayBits(base_mcbsp, MCBSP_DATA_DELAY_BIT_0);
    McBSP_setTxDataDelayBits(base_mcbsp, MCBSP_DATA_DELAY_BIT_0);

    //
    // Set CLKX & FSX as inputs
    //
    McBSP_setTxClockSource(base_mcbsp, MCBSP_EXTERNAL_TX_CLOCK_SOURCE);
    McBSP_setTxFrameSyncSource(base_mcbsp, MCBSP_TX_EXTERNAL_FRAME_SYNC_SOURCE);

    //
    // Set Tx and Rx clock and frame-sync polarity.
    //
    McBSP_setTxFrameSyncPolarity(base_mcbsp, MCBSP_TX_FRAME_SYNC_POLARITY_LOW);
    McBSP_setTxClockPolarity(base_mcbsp, MCBSP_TX_POLARITY_RISING_EDGE);
    McBSP_setRxClockPolarity(base_mcbsp, MCBSP_RX_POLARITY_FALLING_EDGE);

    //
    // Initialize McBSP data length.
    //
    McBSP_setRxDataSize(base_mcbsp, MCBSP_PHASE_ONE_FRAME, MCBSP_BITS_PER_WORD_16, 0);
    McBSP_setTxDataSize(base_mcbsp, MCBSP_PHASE_ONE_FRAME, MCBSP_BITS_PER_WORD_16, 0);

    //
    // Set LSPCLK as input source for sample rate generator.
    //
    McBSP_setTxSRGClockSource(base_mcbsp, MCBSP_SRG_TX_CLOCK_SOURCE_LSPCLK);

    //
    // Set Divide down value for CLKG.
    //
    McBSP_setSRGDataClockDivider(base_mcbsp, 1);

    //
    // Enable Rx interrupt
    //
    //McBSP_enableRxInterrupt(base_mcbsp);

    //McBSP_enableTxInterrupt(base);
    //
    // Set no external clock sync for CLKG.
    //
    McBSP_disableSRGSyncFSR(base_mcbsp);

    //
    // Wait for CPU cycles equivalent to 2 SRG cycles-init delay.
    // Total cycles required = 2*(SYSCLK/LSPCLK). In this example
    // LSPCLK = SYSCLK/4.
    //
    MCBSP_CYCLE_NOP(8);

    //
    // Enable Sample rate generator and wait for at least 2 CLKG clock cycles.
    //
    McBSP_enableSampleRateGenerator(base_mcbsp);
    McBSP_enableFrameSyncLogic(base_mcbsp);

    //
    // Wait for CPU cycles equivalent to 2 CLKG cycles-init delay.
    // Total cycles required = 2*(SYSCLK/(LSPCLK/(1+CLKGDV_VAL))). In this
    // example LSPCLK = SYSCLK/4 and CLKGDV_VAL = 1.
    //
    MCBSP_CYCLE_NOP(16);

    //
    // Release Rx, Tx and frame-sync generator from reset.
    //
    McBSP_enableTransmitter(base_mcbsp);
    McBSP_enableReceiver(base_mcbsp);

    //
    // Wait for CPU cycles equivalent to 2 SRG cycles-init delay.
    // Total cycles required = 2*(SYSCLK/LSPCLK). In this example
    // LSPCLK = SYSCLK/4.
    //
    MCBSP_CYCLE_NOP(8);

    //Interrupt_register(INT_MCBSPA_RX, McBSP_SPI_Rx_Interrupt);
    //Interrupt_enable(INT_MCBSPA_RX);

}


static void McBSP_SPI_DMA_Setup_DMA_Tx()
{
    //
    // Configure DMA Channel 1 (16 - bit datasize).
    //
    DMA_disableInterrupt(base_dma_tx);

    //
    // Configure 1 word per burst.
    //
    DMA_configBurst(base_dma_tx, BURST, 0U, 0U);

    //
    // Configure 127 bursts per transfer.
    //
    DMA_configTransfer(base_dma_tx, TRANSFER, 1, 0);

    //
    // Src start address = buffer & dest start address = MCBSPA DXR
    //
    DMA_configAddresses(base_dma_tx, (const void*)(base_mcbsp + MCBSP_O_DXR1), (const void*)(&(txData[0])));

    //
    // Clear peripheral interrupt event flag.
    //
    DMA_clearTriggerFlag(base_dma_tx);

    //
    // Clear sync error flag.
    //
    DMA_clearErrorFlag(base_dma_tx);

    //
    // Configure wrap size to maximum to avoid wrapping.
    //
    DMA_configWrap(base_dma_tx, 0x10000U, 0, 0x10000U, 0);


    Interrupt_register(INT_DMA_CH5, DMA_CH5_ISR);

    //
    // Enable channel interrupt.
    //
    DMA_enableInterrupt(base_dma_tx);

    //
    // Interrupt at end of the transfer.
    //
    DMA_setInterruptMode(base_dma_tx, DMA_INT_AT_END);

    //
    // Enable selected peripheral trigger to start a DMA transfer on DMA
    // channel 1.
    //
    DMA_enableTrigger(base_dma_tx);

    //
    // Configure DMA trigger source as McBSPA Tx EVT.
    //
    //DMA_configMode(base_dma_tx, DMA_TRIGGER_MCBSPAMXEVT, DMA_CFG_ONESHOT_ENABLE);
    DMA_configMode(base_dma_tx, DMA_TRIGGER_MCBSPAMXEVT, DMA_CFG_ONESHOT_DISABLE);

    //
    // Clear any spurious Peripheral interrupts flags.
    //
    DMA_clearTriggerFlag(base_dma_tx);

    //
    // Enable interrupts in PIE block.
    //
    Interrupt_enable(INT_DMA_CH5);
}


static void McBSP_SPI_DMA_Setup_DMA_Rx()
{
    //
    // Configure DMA Channel 2 (16 - bit datasize).
    //
    DMA_disableInterrupt(base_dma_rx);

    //
    // Configure 1 word per burst.
    //
    DMA_configBurst(base_dma_rx, BURST, 0U, 0U);

    //
    // Configure 127 bursts per transfer.
    //
    DMA_configTransfer(base_dma_rx, TRANSFER, 0, 1);

    //
    // Dest start address = buffer & Src start address = MCBSPA DRR
    //
    DMA_configAddresses(base_dma_rx,(const void*)(&(rxData[0])), (const void*)(MCBSPA_BASE + MCBSP_O_DRR2));

    //
    // Clear peripheral interrupt event flag.
    //
    DMA_clearTriggerFlag(base_dma_rx);

    //
    // Clear sync error flag.
    //
    DMA_clearErrorFlag(base_dma_rx);

    //
    // Configure wrap size to maximum to avoid wrapping.
    //
    DMA_configWrap(base_dma_rx, 0x10000U, 0, 0x10000U, 0);


    Interrupt_register(INT_DMA_CH6, DMA_CH6_ISR);

    //
    // Enable channel interrupt.
    //
    DMA_enableInterrupt(base_dma_rx);

    //
    // Interrupt at end of the transfer.
    //
    DMA_setInterruptMode(base_dma_rx, DMA_INT_AT_END);

    //
    // Enable selected peripheral trigger to start a DMA transfer on DMA
    // channel 2.
    //
    DMA_enableTrigger(base_dma_rx);

    //
    // Configure DMA trigger source as McBSPA Tx EVT.
    //
    //DMA_configMode(base_dma_rx, DMA_TRIGGER_MCBSPAMREVT, 0);
    DMA_configMode(base_dma_rx, DMA_TRIGGER_MCBSPAMREVT, DMA_CFG_ONESHOT_DISABLE);
    //DMA_configMode(base_dma_rx, DMA_TRIGGER_MCBSPAMREVT, DMA_CFG_ONESHOT_ENABLE);
    //DMA_configMode(base_dma_rx, DMA_TRIGGER_MCBSPAMREVT, DMA_CFG_CONTINUOUS_ENABLE);

    //DMA_configMode(DMA_CH6_BASE, DMA_TRIGGER_SOFTWARE, DMA_CFG_ONESHOT_ENABLE);

    //
    // Clear any spurious Peripheral interrupts flags.
    //
    DMA_clearTriggerFlag(base_dma_rx);

    //
    // Enable interrupts in PIE block.
    //
    Interrupt_enable(INT_DMA_CH6);

}



void McBSP_SPI_DMA_Setup()
{

    McBSP_SPI_DMA_Setup_McBSP();

    McBSP_SPI_DMA_Setup_DMA_Rx();
    McBSP_SPI_DMA_Setup_DMA_Tx();

    txData[0]=1;
    txData[1]=2;
    txData[2]=3;
    txData[3]=4;
    txData[4]=5;

    DMA_startChannel(base_dma_rx);
    DMA_startChannel(base_dma_tx);
}





__interrupt void DMA_CH5_ISR()
{
    //DMA_clearTriggerFlag(base_dma_tx);
    //done=1;
    DMA_stopChannel(base_dma_tx);
}



__interrupt void DMA_CH6_ISR()
{
    volatile uint16_t rx_count=0;
    volatile uint16_t r0, r1, r2, r3, r4;
    rx_count=1;
    r0=rxData[0];
    r1=rxData[1];
    r2=rxData[2];
    r3=rxData[3];
    r4=rxData[4];


    DMA_stopChannel(base_dma_rx);


    //
    // Dest start address = buffer & Src start address = MCBSPA DRR
    //
    DMA_configAddresses(base_dma_rx,(const void*)(&(rxData[0])), (const void*)(base_mcbsp + MCBSP_O_DRR1));

    DMA_startChannel(base_dma_rx);
    DMA_clearTriggerFlag(base_dma_rx);
}

  • Hello Nicholas,

    Is DMA supported for MCBSP SPI slave on the TMS320F28377S?

    I believe the McBSP should have DMA access support to the registers, the F2838x has DMA access to these registers and both devices have the same DMA type. Also, the register description for DRR1 does state that it can be read by CPU or DMA, when you say the McBSP register DRR1 does get the first 16-bit word in a transfer are you saying the DMA does read the first word but not later words?

  • I transmit 5 uint16s over SPI from master(TMS320F28386D) to slave(TMS320F28377S).  0x0004, 0x0005, 0x0006, 0x0007, 0x0008.  I see 0x0004 in the MCBSP DRR1 of the slave.  However, nothing is copied over to my DMA rx buffer which is in global shared RAM.  Pics attached.

    If I set my slave BURST and TRANSFER to 1 I will get a DMA interrupt but no data is copied from DRR1 to RAM.

    I'm not sure why the DMA isn't doing the copy.  I'm going to try just transferring data from RAM to RAM using DMA on the TMS320F28377S just to make the DMA is configured correctly on the TMS320F28377S and I can narrow it down to something with MCBSP Slave/DMA. Let me know if you have any suggestions.  Thanks

  • Hello Nicholas,

    I'm going to try just transferring data from RAM to RAM using DMA on the TMS320F28377S just to make the DMA is configured correctly on the TMS320F28377S and I can narrow it down to something with MCBSP Slave/DMA.

    Yes, I think this would be a good thing to test out. There's actually a DMA example provided in C2000Ware for the F2837xS if you don't want to re-write a whole different project.

    Also, try changing your transfer size and burst count so that there is a single transfer of 5 bursts rather than 5 transfers of 1 burst. Let me know if you find out anything.

  • Hello Omer,

    I have been able to transfer within RAM using DMA on the TMS320F28377S.  However, I have had no luck on the getting DMA to work with MCBSP SPI on the TMS320F28377S.  I have a TMS320F28386D connected to a TMS320F28377S through MCBSP SPI.  The TMS320F28386D works with MCBSP SPI DMA as a master.  I tried to switch roles and make the TMS320F28377S a master using MCBSP SPI DMA and it did not work.  Almost identical code as what I was running on the TMS320F28386D ( I do use SYS/BIOS on the TMS320F28386D).  So the TMS320F2877S MCBSP SPI DMA does not work for me as a master or slave.  If I take DMA out of the picture MCBSP SPI works.  Also, I have an oscilloscope on the chip select, clock, and data lines so I can see what is happening on the bus.  I use DMA CH5 and DMA CH6.

    I've included a summary table of my tests below.

    Here are my questions.

    1.  Can TI confirm 100% that using MCBSP SPI with DMA works on the TMS320F28377S?  Can we bubble this question up to someone who may know?

    2.  If yes to question 1, can TI modify the C2000ware example mcbsp_ex6_spi_ext_loopback.c to use DMA?

    Thanks

    //#############################################################################
    //
    // FILE:   mcbsp_ex6_spi_ext_loopback.c
    //
    // TITLE:  McBSP external loopback example using SPI mode.
    //
    //! \addtogroup driver_example_list
    //! <h1> McBSP external loopback example using SPI mode </h1>
    //!
    //! This example demonstrates the McBSP operation in SPI mode using external
    //! loopback. This example configures McBSP instances available on the device
    //! as SPI master and slave and demonstrates transfer of 32-bit word size data
    //! with external loopback.
    //!
    //! \b External \b Connections \n
    //! \b SPI Master(McBSPA)            \b SPI Slave(McBSPB)    \n
    //! -  MCLKXA(SPICLK) (GPIO22)    -     MCLKXB(SPICLK) (GPIO26)
    //! -  MFSXA (SPISTE) (GPIO23)    -     MFSXB (SPISTE) (GPIO27)
    //! -  MDXA  (SPISIMO)(GPIO20)    -     MDRB  (SPISIMO)(GPIO25)
    //! -  MDRA  (SPISOMI)(GPIO21)    -     MDXB  (SPISOMI)(GPIO24)
    //!
    //! \b Watch \b Variables: \n
    //! - \b txData1 - Sent data word:     8 or 16-bit or low half of 32-bit
    //! - \b txData2 - Sent data word:     upper half of 32-bit
    //! - \b rxData1 - Received data word: 8 or 16-bit or low half of 32-bit
    //! - \b rxData2 - Received data word: upper half of 32-bit
    //! - \b errCountGlobal   - Error counter
    //
    //#############################################################################
    // $TI Release: F2837xS Support Library v3.12.00.00 $
    // $Release Date: Fri Feb 12 19:06:50 IST 2021 $
    // $Copyright:
    // Copyright (C) 2014-2021 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    //#############################################################################
    
    //
    // Included Files
    //
    #include "device.h"
    #include "driverlib.h"
    
    //
    // Defines
    //
    
    //
    // Define to select delay in clock cycles.
    //
    #define MCBSP_CYCLE_NOP0(n)  __asm(" RPT #(" #n ") || NOP")
    #define MCBSP_CYCLE_NOP(n)   MCBSP_CYCLE_NOP0(n)
    
    //
    // Globals
    //
    uint32_t errCountGlobal   = 0;
    
    //
    // Variables for transmitting, receiving and testing the data.
    //
    uint16_t txData1 = 0x0000;
    uint16_t txData2 = 0x0000;
    uint16_t rxData1 = 0x0000;
    uint16_t rxData2 = 0x0000;
    
    //
    // Function Prototypes
    //
    extern void setupMcBSPAPinmux(void);
    extern void setupMcBSPBPinmux(void);
    void initSPIMasterMode(uint32_t masterBase);
    void initSPISlaveMode(uint32_t slaveBase);
    
    //
    // Main
    //
    void main(void)
    {
        uint32_t tempData;
        errCountGlobal = 0x0;
    
        //
        // Initialize device clock and peripherals.
        //
        Device_init();
    
        //
        // Disable all the interrupts.
        //
        DINT;
    
        //
        // Setup GPIO by disabling pin locks and enabling pullups.
        //
        Device_initGPIO();
    
        //
        // Initialize GPIO.
        //
        setupMcBSPAPinmux();
        setupMcBSPBPinmux();
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Initialize and release McBSPA and McBSPB from reset.
        //
        initSPIMasterMode(MCBSPA_BASE);
        initSPISlaveMode(MCBSPB_BASE);
        txData1 = 0x55aa;
        txData2 = 0xaa55;
    
        //
        // Main loop to transfer 32-bit words through McBSP in SPI mode
        // periodically.
        //
        while(1)
        {
            //
            // Write data to be transmitted from SPI master
            //
            tempData = (txData1|(((uint32_t)txData2) << 16U));
            while(!McBSP_isTxReady(MCBSPA_BASE));
            McBSP_write32bitData(MCBSPA_BASE, tempData);
    
            //
            // Check if data is received as SPI slave
            //
            while(!McBSP_isRxReady(MCBSPB_BASE));
            tempData = McBSP_read32bitData(MCBSPB_BASE);
            rxData1 = (uint16_t)(tempData & 0xFFFF);
            rxData2 = (uint16_t)(tempData >> 16U);
            if((rxData1 != txData1) || (rxData2 != txData2))
            {
                errCountGlobal++;
                Example_Fail = 1;
                ESTOP0;
            }
            txData1 ^= 0xFFFF;
            txData2 ^= 0xFFFF;
            NOP;
    
            Example_PassCount++;
        }
    }
    
    //
    // Init SPI Master Mode - This function initializes McBSP in SPI master mode.
    //
    void initSPIMasterMode(uint32_t masterBase)
    {
        //
        // Reset FS generator, sample rate generator, transmitter, receiver.
        //
        McBSP_resetFrameSyncLogic(masterBase);
        McBSP_resetSampleRateGenerator(masterBase);
        McBSP_resetTransmitter(masterBase);
        McBSP_resetReceiver(masterBase);
    
        //
        // Set Rx sign-extension and justification mode.
        //
        McBSP_setRxSignExtension(masterBase, MCBSP_RIGHT_JUSTIFY_FILL_ZERO);
    
        //
        // Enable clock stop mode.
        //
        McBSP_setClockStopMode(masterBase, MCBSP_CLOCK_SPI_MODE_NO_DELAY);
    
        //
        // Set Rx & Tx delay to 1 cycle.
        //
        McBSP_setRxDataDelayBits(masterBase, MCBSP_DATA_DELAY_BIT_1);
        McBSP_setTxDataDelayBits(masterBase, MCBSP_DATA_DELAY_BIT_1);
    
        //
        // Set CLKX & FSX source as sample rate generator.
        //
        McBSP_setTxClockSource(masterBase, MCBSP_INTERNAL_TX_CLOCK_SOURCE);
        McBSP_setRxClockSource(masterBase, MCBSP_INTERNAL_RX_CLOCK_SOURCE);
        McBSP_setTxFrameSyncSource(masterBase, MCBSP_TX_INTERNAL_FRAME_SYNC_SOURCE);
        McBSP_setRxFrameSyncSource(masterBase, MCBSP_RX_INTERNAL_FRAME_SYNC_SOURCE);
    
        //
        // Set Tx and Rx clock and frame-sync polarity.
        //
        McBSP_setTxFrameSyncPolarity(masterBase, MCBSP_TX_FRAME_SYNC_POLARITY_LOW);
        McBSP_setTxClockPolarity(masterBase, MCBSP_TX_POLARITY_RISING_EDGE);
        McBSP_setRxClockPolarity(masterBase, MCBSP_RX_POLARITY_FALLING_EDGE);
    
        //
        // Initialize McBSP data length.
        //
        McBSP_setRxDataSize(masterBase, MCBSP_PHASE_ONE_FRAME,
                            MCBSP_BITS_PER_WORD_32, 0);
        McBSP_setTxDataSize(masterBase, MCBSP_PHASE_ONE_FRAME,
                            MCBSP_BITS_PER_WORD_32, 0);
    
        //
        // Set frame synchronization pulse period to 1 CLKG cycle.
        //
        McBSP_setFrameSyncPulsePeriod(masterBase, 0);
    
        //
        // Set frame-sync pulse width to 1 CLKG cycle.
        //
        McBSP_setFrameSyncPulseWidthDivider(masterBase, 0);
    
        //
        // Set the trigger source for internally generated frame-sync pulse.
        //
        McBSP_setTxInternalFrameSyncSource(masterBase,
                                           MCBSP_TX_INTERNAL_FRAME_SYNC_DATA);
    
        //
        // Set LSPCLK as input source for sample rate generator.
        //
        McBSP_setTxSRGClockSource(masterBase, MCBSP_SRG_TX_CLOCK_SOURCE_LSPCLK);
    
        //
        // Set Divide down value for CLKG.
        //
        McBSP_setSRGDataClockDivider(masterBase, 16);
    
        //
        // Set no external clock sync for CLKG.
        //
        McBSP_disableSRGSyncFSR(masterBase);
    
        //
        // Wait for CPU cycles equivalent to 2 SRG cycles-init delay.
        // Total cycles required = 2*(SYSCLK/LSPCLK). In this example
        // LSPCLK = SYSCLK/4.
        //
        MCBSP_CYCLE_NOP(8);
    
        //
        // Enable Sample rate generator and wait for at least 2 CLKG clock cycles.
        //
        McBSP_enableSampleRateGenerator(masterBase);
        McBSP_enableFrameSyncLogic(masterBase);
    
        //
        // Wait for CPU cycles equivalent to 2 CLKG cycles-init delay.
        // Total cycles required = 2*(SYSCLK/(LSPCLK/(1+CLKGDV_VAL))). In this
        // example LSPCLK = SYSCLK/4 and CLKGDV_VAL = 1.
        //
        MCBSP_CYCLE_NOP(16);
    
        //
        // Release Rx, Tx and frame-sync generator from reset.
        //
        McBSP_enableTransmitter(masterBase);
        McBSP_enableReceiver(masterBase);
    
        //
        // Wait for CPU cycles equivalent to 2 SRG cycles-init delay.
        // Total cycles required = 2*(SYSCLK/LSPCLK). In this example
        // LSPCLK = SYSCLK/4.
        //
        MCBSP_CYCLE_NOP(8);
    }
    
    
    //
    // Init SPI Slave Mode - This function initializes McBSP in SPI slave mode.
    //
    void initSPISlaveMode(uint32_t slaveBase)
    {
        //
        // Reset FS generator, sample rate generator, transmitter, receiver.
        //
        McBSP_resetFrameSyncLogic(slaveBase);
        McBSP_resetSampleRateGenerator(slaveBase);
        McBSP_resetTransmitter(slaveBase);
        McBSP_resetReceiver(slaveBase);
    
        //
        // Set Rx sign-extension and justification mode.
        //
        McBSP_setRxSignExtension(slaveBase, MCBSP_RIGHT_JUSTIFY_FILL_ZERO);
    
        //
        // Enable clock stop mode.
        //
        McBSP_setClockStopMode(slaveBase, MCBSP_CLOCK_SPI_MODE_NO_DELAY);
    
        //
        // Set Rx & Tx delay to 0.
        //
        McBSP_setRxDataDelayBits(slaveBase, MCBSP_DATA_DELAY_BIT_0);
        McBSP_setTxDataDelayBits(slaveBase, MCBSP_DATA_DELAY_BIT_0);
    
        //
        // Set CLKX & FSX as inputs
        //
        McBSP_setTxClockSource(slaveBase, MCBSP_EXTERNAL_TX_CLOCK_SOURCE);
        McBSP_setTxFrameSyncSource(slaveBase, MCBSP_TX_EXTERNAL_FRAME_SYNC_SOURCE);
    
        //
        // Set Tx and Rx clock and frame-sync polarity.
        //
        McBSP_setTxFrameSyncPolarity(slaveBase, MCBSP_TX_FRAME_SYNC_POLARITY_LOW);
        McBSP_setTxClockPolarity(slaveBase, MCBSP_TX_POLARITY_RISING_EDGE);
        McBSP_setRxClockPolarity(slaveBase, MCBSP_RX_POLARITY_FALLING_EDGE);
    
        //
        // Initialize McBSP data length.
        //
        McBSP_setRxDataSize(slaveBase, MCBSP_PHASE_ONE_FRAME,
                            MCBSP_BITS_PER_WORD_32, 0);
        McBSP_setTxDataSize(slaveBase, MCBSP_PHASE_ONE_FRAME,
                            MCBSP_BITS_PER_WORD_32, 0);
    
        //
        // Set LSPCLK as input source for sample rate generator.
        //
        McBSP_setTxSRGClockSource(slaveBase, MCBSP_SRG_TX_CLOCK_SOURCE_LSPCLK);
    
        //
        // Set Divide down value for CLKG.
        //
        McBSP_setSRGDataClockDivider(slaveBase, 1);
    
        //
        // Set no external clock sync for CLKG.
        //
        McBSP_disableSRGSyncFSR(slaveBase);
    
        //
        // Wait for CPU cycles equivalent to 2 SRG cycles-init delay.
        // Total cycles required = 2*(SYSCLK/LSPCLK). In this example
        // LSPCLK = SYSCLK/4.
        //
        MCBSP_CYCLE_NOP(8);
    
        //
        // Enable Sample rate generator and wait for at least 2 CLKG clock cycles.
        //
        McBSP_enableSampleRateGenerator(slaveBase);
        McBSP_enableFrameSyncLogic(slaveBase);
    
        //
        // Wait for CPU cycles equivalent to 2 CLKG cycles-init delay.
        // Total cycles required = 2*(SYSCLK/(LSPCLK/(1+CLKGDV_VAL))). In this
        // example LSPCLK = SYSCLK/4 and CLKGDV_VAL = 1.
        //
        MCBSP_CYCLE_NOP(16);
    
        //
        // Release Rx, Tx and frame-sync generator from reset.
        //
        McBSP_enableTransmitter(slaveBase);
        McBSP_enableReceiver(slaveBase);
    
        //
        // Wait for CPU cycles equivalent to 2 SRG cycles-init delay.
        // Total cycles required = 2*(SYSCLK/LSPCLK). In this example
        // LSPCLK = SYSCLK/4.
        //
        MCBSP_CYCLE_NOP(8);
    }
    //
    // End of File
    //
    

  • Hello Nicholas,

    1.  Can TI confirm 100% that using MCBSP SPI with DMA works on the TMS320F28377S?  Can we bubble this question up to someone who may know?

    I will bring this up with our design team to see if they can either reproduce this issue or confirm why it's happening.

    2.  If yes to question 1, can TI modify the C2000ware example mcbsp_ex6_spi_ext_loopback.c to use DMA?

    If they find an explanation for this, I will file a fix for this with the software team.

  • Thanks Omer, Any update on when to expect a response on this issue?  

  • Hi Nicholas,

    There has been no update, I've emailed the design team already. I'll try to ping them again to try to get a response.

  • I got a response from the design team, it looks like they have a driverlib test case which is failing so they're currently looking into it. However, they did note that in the below line DRR1 should be DRR2:

    DMA_configAddresses(base_dma_rx,(const void*)(&(rxData[0])), (const void*)(MCBSPA_BASE + MCBSP_O_DRR2));

    I'll follow-up once I got more updates.

  • Thanks, I will try with DRR2.  Based on the C2000Ware_4_00_00_00 mcbsp_ex2_loopback_dma.c I think DRR2 is for 32-bit transfers.  I'll try DRR2 and also try 32-bit transfers.  I have been using 16-bit transfers.

  • Okay, I have confirmed that the driverlib test case seems to be failing according to our validation team, I will be reaching out to the design expert and software expert to see what might be the reason for this.

  • Hi Nicholas,

    I confirmed with the software expert that the issue seemed to be caused by a configuration for DMA as a secondary controller for peripheral frame 2 was missing from the example. This fix has been filed and will update in the next release.

    //#############################################################################
    //
    // FILE:   mcbsp_ex2_loopback_dma.c
    //
    // TITLE:  McBSP loopback with DMA example.
    //
    //! \addtogroup driver_example_list
    //! <h1> McBSP loopback with DMA example. </h1>
    //!
    //! This example demonstrates the McBSP operation using internal loopback and
    //! utilizes the DMA to transfer data from one buffer to the McBSP and then
    //! from McBSP to another buffer.
    //!
    //! Initially, txData[] is filled with values from 0x0000- 0x007F. The DMA moves
    //! the values in txData[] one by one to the DXRx registers of the McBSP. These
    //! values are transmitted and subsequently received by the McBSP. Then, the
    //! the DMA moves each data value to rxData[] as it is received by the McBSP.
    //!
    //! The sent data buffer looks like this: \n
    //!    0000 0001 0002 0003 0004 0005 .... 007F   \n
    //!
    //! Three different serial word sizes can be tested.  Before compiling
    //! this project, select the serial word size of 8, 16 or 32 by using
    //! the \#define statements at the beginning of the code.
    //!
    //! This example uses DMA channel 1 and 2 interrupts. The incoming data is
    //! checked for accuracy.
    //!
    //! \b External \b Connections \n
    //! - None
    //!
    //! \b Watch \b Variables: \n
    //! - \b txData - Sent data buffer
    //! - \b rxData - Received data buffer
    //! - \b errCountGlobal - Error counter
    //
    //#############################################################################
    //
    // 
    // $Copyright:
    // Copyright (C) 2014-2023 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    //#############################################################################
    
    //
    // Included Files
    //
    #include "device.h"
    #include "driverlib.h"
    
    //
    // Defines
    //
    
    //
    // Define to select delay in clock cycles.
    //
    #define MCBSP_CYCLE_NOP0(n)  __asm(" RPT #(" #n ") || NOP")
    #define MCBSP_CYCLE_NOP(n)   MCBSP_CYCLE_NOP0(n)
    
    //
    // Define to select the word-size for McBSP operation to 8, 16 or 32 bit.
    //
    #define WORD_SIZE     8U
    //#define WORD_SIZE     16U
    //#define WORD_SIZE     32U
    
    #pragma DATA_SECTION(txData, "ramgs0")
    #pragma DATA_SECTION(rxData, "ramgs1")
    
    //
    // Globals
    uint16_t txData[128];
    uint16_t rxData[128];
    uint16_t dataSize;
    uint16_t errCountGlobal = 0;
    
    //
    // Function Prototypes
    //
    extern void setupMcBSPAPinmux(void);
    void configDMAChannel1(void);
    void configDMAChannel2(void);
    void configDMA32Channel1(void);
    void configDMA32Channel2(void);
    void initDMA(void);
    void initDMA32(void);
    void initMcBSPLoopback(void);
    void startDMA(void);
    
    //
    // ISR for DMA channel 1 & 2 interrupts.
    //
    __interrupt void localDMAINTCH1ISR(void);
    __interrupt void localDMAINTCH2ISR(void);
    
    //
    // Main
    //
    void main(void)
    {
        uint16_t i;
    
        //
        // Initialize device clock and peripherals.
        //
        Device_init();
    
        //
        // Disable all the interrupts.
        //
        DINT;
    
        //
        // Setup GPIO by disabling pin locks and enabling pullups.
        //
        Device_initGPIO();
    
        //
        // Initialize GPIO.
        //
        setupMcBSPAPinmux();
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Interrupts that are used in this example are re-mapped to
        // ISR functions found within this file.
        //
        Interrupt_register(INT_DMA_CH1, localDMAINTCH1ISR);
        Interrupt_register(INT_DMA_CH2, localDMAINTCH2ISR);
    
        //
        // Configure DMA as secondary master for peripheral frame 2.
        //
        SysCtl_selectSecMaster(SYSCTL_SEC_MASTER_DMA, SYSCTL_SEC_MASTER_DMA);
    
        //
        // User defined code.
        //
        dataSize = WORD_SIZE;
    
        //
        // Initialize data buffers.
        //
        for(i = 0; i<128; i++)
        {
            //
            // Fill txData with values between 0 and 0x007F.
            //
            txData[i] = i;
    
            //
            // Initialize rxData to 0xFFFF.
            //
            rxData[i] = 0xFFFFU;
        }
    
        //
        // Initialize DMA based on desired word size.
        //
        if(dataSize == 32)
        {
            //
            // Initialize DMA for 32-bit transfers.
            //
            initDMA32();
        }
        else
        {
            //
            // Initialize DMA for 16-bit transfers.
            //
            initDMA();
        }
    
        //
        // When using DMA, initialize DMA with peripheral interrupts first and then
        // initialize and release McBSP from reset.
        //
        startDMA();
        initMcBSPLoopback();
    
        //
        // Enable interrupts in PIE block.
        //
        Interrupt_enable(INT_DMA_CH1);
        Interrupt_enable(INT_DMA_CH2);
    
        //
        // Enable group 7 CPU interrupt.
        //
        IER = 0x40;
    
        //
        // Enable global interrupts.
        //
        EINT;
        ERTM;
    
        //
        // Idle loop.
        //
        while(1);
    }
    
    //
    // Configure DMA Channel 1 - This function configures the DMA channel 1 for
    // writing data to transmit buffer for 8 to 16-bit word size.
    //
    void configDMAChannel1()
    {
        //
        // Configure DMA Channel 1 (16 - bit datasize).
        //
        DMA_disableInterrupt(DMA_CH1_BASE);
    
        //
        // Configure 1 word per burst.
        //
        DMA_configBurst(DMA_CH1_BASE, 1U, 0U, 0U);
    
        //
        // Configure 127 bursts per transfer.
        //
        DMA_configTransfer(DMA_CH1_BASE, 128, 1, 0);
    
        //
        // Src start address = buffer & dest start address = MCBSPA DXR
        //
        DMA_configAddresses(DMA_CH1_BASE,(const void*)(MCBSPA_BASE + MCBSP_O_DXR1),
                            (const void*)(&txData[0]));
    
        //
        // Clear peripheral interrupt event flag.
        //
        DMA_clearTriggerFlag(DMA_CH1_BASE);
    
        //
        // Clear sync error flag.
        //
        DMA_clearErrorFlag(DMA_CH1_BASE);
    
        //
        // Configure wrap size to maximum to avoid wrapping.
        //
        DMA_configWrap(DMA_CH1_BASE, 0x10000U, 0, 0x10000U, 0);
    
        //
        // Enable channel interrupt.
        //
        DMA_enableInterrupt(DMA_CH1_BASE);
    
        //
        // Interrupt at end of the transfer.
        //
        DMA_setInterruptMode(DMA_CH1_BASE, DMA_INT_AT_END);
    
        //
        // Enable selected peripheral trigger to start a DMA transfer on DMA
        // channel 1.
        //
        DMA_enableTrigger(DMA_CH1_BASE);
    
        //
        // Configure DMA trigger source as McBSPA Tx EVT.
        //
        DMA_configMode(DMA_CH1_BASE, DMA_TRIGGER_MCBSPAMXEVT, 0);
    
        //
        // Clear any spurious Peripheral interrupts flags.
        //
        DMA_clearTriggerFlag(DMA_CH1_BASE);
    }
    
    //
    // Configure DMA Channel 2 - This function configures the DMA channel 2 for
    // reading from receive buffer for 8 to 16-bit word size.
    //
    void configDMAChannel2()
    {
        //
        // Configure DMA Channel 2 (16 - bit datasize).
        //
        DMA_disableInterrupt(DMA_CH2_BASE);
    
        //
        // Configure 1 word per burst.
        //
        DMA_configBurst(DMA_CH2_BASE, 1U, 0U, 0U);
    
        //
        // Configure 127 bursts per transfer.
        //
        DMA_configTransfer(DMA_CH2_BASE, 128, 0, 1);
    
        //
        // Dest start address = buffer & Src start address = MCBSPA DRR
        //
        DMA_configAddresses(DMA_CH2_BASE,(const void*)(&rxData[0]),
                            (const void*)(MCBSPA_BASE + MCBSP_O_DRR1));
    
        //
        // Clear peripheral interrupt event flag.
        //
        DMA_clearTriggerFlag(DMA_CH2_BASE);
    
        //
        // Clear sync error flag.
        //
        DMA_clearErrorFlag(DMA_CH2_BASE);
    
        //
        // Configure wrap size to maximum to avoid wrapping.
        //
        DMA_configWrap(DMA_CH2_BASE, 0x10000U, 0, 0x10000U, 0);
    
        //
        // Enable channel interrupt.
        //
        DMA_enableInterrupt(DMA_CH2_BASE);
    
        //
        // Interrupt at end of the transfer.
        //
        DMA_setInterruptMode(DMA_CH2_BASE, DMA_INT_AT_END);
    
        //
        // Enable selected peripheral trigger to start a DMA transfer on DMA
        // channel 2.
        //
        DMA_enableTrigger(DMA_CH2_BASE);
    
        //
        // Configure DMA trigger source as McBSPA Tx EVT.
        //
        DMA_configMode(DMA_CH2_BASE, DMA_TRIGGER_MCBSPAMREVT, 0);
    
        //
        // Clear any spurious Peripheral interrupts flags.
        //
        DMA_clearTriggerFlag(DMA_CH2_BASE);
    }
    
    //
    // Configure DMA 32 Channel 1 - This function configures the DMA channel 1 for
    // writing to transmit buffer for 32-bit word size.
    //
    void configDMA32Channel1()
    {
        //
        // Configure DMA Channel 1
        //
        DMA_disableInterrupt(DMA_CH1_BASE);
    
        //
        // Configure 2 word per burst. Increment one 16-bit address between words
        // for src & dest address.
        //
        DMA_configBurst(DMA_CH1_BASE, 2U, 1U, 1U);
    
        //
        // Configure 63 bursts per transfer. For src move to next word in buffer
        // after each word in a burst. For dest go back to DXR2.
        //
        DMA_configTransfer(DMA_CH1_BASE, 64, 1, 0xFFFF);
    
        //
        // Src start address = buffer & dest start address = MCBSPA DXR
        //
        DMA_configAddresses(DMA_CH1_BASE,(const void*)(MCBSPA_BASE + MCBSP_O_DXR2),
                            (const void*)(&txData[0]));
    
        //
        // Clear peripheral interrupt event flag.
        //
        DMA_clearTriggerFlag(DMA_CH1_BASE);
    
        //
        // Clear sync error flag.
        //
        DMA_clearErrorFlag(DMA_CH1_BASE);
    
        //
        // Configure wrap size to maximum to avoid wrapping.
        //
        DMA_configWrap(DMA_CH1_BASE, 0x10000U, 0, 0x10000U, 0);
    
        //
        // Enable channel interrupt.
        //
        DMA_enableInterrupt(DMA_CH1_BASE);
    
        //
        // Interrupt at end of the transfer.
        //
        DMA_setInterruptMode(DMA_CH1_BASE, DMA_INT_AT_END);
    
        //
        // Enable selected peripheral trigger to start a DMA transfer on DMA
        // channel 1.
        //
        DMA_enableTrigger(DMA_CH1_BASE);
    
        //
        // Configure DMA trigger source as McBSPA Tx EVT.
        //
        DMA_configMode(DMA_CH1_BASE, DMA_TRIGGER_MCBSPAMXEVT, 0);
    
        //
        // Clear any spurious Peripheral interrupts flags.
        //
        DMA_clearTriggerFlag(DMA_CH1_BASE);
    }
    
    //
    // Configure DMA Channel 2 - This function configures the DMA channel 2 for
    // reading from receive buffer for 32-bit word-size.
    //
    void configDMA32Channel2()
    {
        //
        // Configure DMA Channel 2 (16 - bit datasize).
        //
        DMA_disableInterrupt(DMA_CH2_BASE);
    
        //
        // Configure 2 word per burst. Increment one 16-bit address between words
        // for src & dest address.
        //
        DMA_configBurst(DMA_CH2_BASE, 2U, 1U, 1U);
    
        //
        // Configure 63 bursts per transfer. For src move to next word in buffer
        // after each word in a burst. For dest go back to DRR2.
        //
        DMA_configTransfer(DMA_CH2_BASE, 64, 0xFFFF, 1);
    
        //
        // Dest start address = buffer & Src start address = MCBSPA DRR
        //
        DMA_configAddresses(DMA_CH2_BASE, (const void*)(&rxData[0]),
                            (const void*)(MCBSPA_BASE + MCBSP_O_DRR2));
    
        //
        // Clear peripheral interrupt event flag.
        //
        DMA_clearTriggerFlag(DMA_CH2_BASE);
    
        //
        // Clear sync error flag.
        //
        DMA_clearErrorFlag(DMA_CH2_BASE);
    
        //
        // Configure wrap size to maximum to avoid wrapping.
        //
        DMA_configWrap(DMA_CH2_BASE, 0x10000U, 0, 0x10000U, 0);
    
        //
        // Enable channel interrupt.
        //
        DMA_enableInterrupt(DMA_CH2_BASE);
    
        //
        // Interrupt at end of the transfer.
        //
        DMA_setInterruptMode(DMA_CH2_BASE, DMA_INT_AT_END);
    
        //
        // Enable selected peripheral trigger to start a DMA transfer on DMA
        // channel 1.
        //
        DMA_enableTrigger(DMA_CH2_BASE);
    
        //
        // Configure DMA trigger source as McBSPA Rx EVT.
        //
        DMA_configMode(DMA_CH2_BASE, DMA_TRIGGER_MCBSPAMREVT, 0);
    
        //
        // Clear any spurious Peripheral interrupts flags.
        //
        DMA_clearTriggerFlag(DMA_CH2_BASE);
    }
    
    //
    // Init DMA - This function initialises the DMA channel 1 & 2 for the 8 or
    // 16-bit transfer.
    //
    void initDMA(void)
    {
        DMA_initController();
        configDMAChannel1();
        configDMAChannel2();
    }
    
    //
    // Init DMA 32 - This function initialises the DMA channel 1 & 2 for the 32-bit
    // transfer.
    //
    void initDMA32(void)
    {
        DMA_initController();
        configDMA32Channel1();
        configDMA32Channel2();
    }
    
    //
    // Init McBSP Loopback - This function initialises McBSP peripheral in digital
    // loopback mode.
    //
    void initMcBSPLoopback()
    {
        //
        // Reset FS generator, sample rate generator, transmitter & receiver.
        //
        McBSP_resetFrameSyncLogic(MCBSPA_BASE);
        McBSP_resetSampleRateGenerator(MCBSPA_BASE);
        McBSP_resetTransmitter(MCBSPA_BASE);
        McBSP_resetReceiver(MCBSPA_BASE);
    
        //
        // Set Rx sign-extension and justification mode.
        //
        McBSP_setRxSignExtension(MCBSPA_BASE, MCBSP_RIGHT_JUSTIFY_FILL_ZERO);
    
        //
        // Enable DLB mode. Comment out for non-DLB mode.
        //
        McBSP_enableLoopback(MCBSPA_BASE);
    
        //
        // Set Rx & Tx delay to 1 cycle.
        //
        McBSP_setRxDataDelayBits(MCBSPA_BASE, MCBSP_DATA_DELAY_BIT_1);
        McBSP_setTxDataDelayBits(MCBSPA_BASE, MCBSP_DATA_DELAY_BIT_1);
    
        //
        // Set CLKX & FSX source as sample rate generator.
        //
        McBSP_setTxClockSource(MCBSPA_BASE, MCBSP_INTERNAL_TX_CLOCK_SOURCE);
        McBSP_setTxFrameSyncSource(MCBSPA_BASE, MCBSP_TX_INTERNAL_FRAME_SYNC_SOURCE);
    
        //
        // Configure McBSP data behaviour.
        //
        if(dataSize == 8)
        {
            McBSP_setRxDataSize(MCBSPA_BASE, MCBSP_PHASE_ONE_FRAME,
                                MCBSP_BITS_PER_WORD_8, 0);
            McBSP_setTxDataSize(MCBSPA_BASE, MCBSP_PHASE_ONE_FRAME,
                                MCBSP_BITS_PER_WORD_8, 0);
        }
        else if(dataSize == 16)
        {
            McBSP_setRxDataSize(MCBSPA_BASE, MCBSP_PHASE_ONE_FRAME,
                                MCBSP_BITS_PER_WORD_16, 0);
            McBSP_setTxDataSize(MCBSPA_BASE, MCBSP_PHASE_ONE_FRAME,
                                MCBSP_BITS_PER_WORD_16, 0);
        }
        else if(dataSize == 32)
        {
            McBSP_setRxDataSize(MCBSPA_BASE, MCBSP_PHASE_ONE_FRAME,
                                MCBSP_BITS_PER_WORD_32, 0);
            McBSP_setTxDataSize(MCBSPA_BASE, MCBSP_PHASE_ONE_FRAME,
                                MCBSP_BITS_PER_WORD_32, 0);
        }
    
        //
        // Set frame-sync pulse period.
        //
        McBSP_setFrameSyncPulsePeriod(MCBSPA_BASE, 31);
    
        //
        // Set frame-sync pulse width.
        //
        McBSP_setFrameSyncPulseWidthDivider(MCBSPA_BASE, 0);
    
        //
        // Set the trigger source for internally generated frame-sync pulse.
        //
        McBSP_setTxInternalFrameSyncSource(MCBSPA_BASE,
                                           MCBSP_TX_INTERNAL_FRAME_SYNC_SRG);
    
        //
        // Set LSPCLK as input source for sample rate generator.
        //
        McBSP_setTxSRGClockSource(MCBSPA_BASE, MCBSP_SRG_TX_CLOCK_SOURCE_LSPCLK);
    
        //
        // Set Divide down value for CLKG. CLKG frequency = LSPCLK/(CLKGDV+1)
        //
        McBSP_setSRGDataClockDivider(MCBSPA_BASE, 0);
    
        //
        // Set no external clock sync for CLKG.
        //
        McBSP_disableSRGSyncFSR(MCBSPA_BASE);
    
        //
        // Wait for CPU cycles equivalent to 2 SRG cycles-init delay.
        // Total cycles required = 2*(SYSCLK/LSPCLK). In this example
        // LSPCLK = SYSCLK/4.
        //
        MCBSP_CYCLE_NOP(8);
    
        //
        // Enable Sample rate generator and wait for atleast 2 CLKG clock cycles.
        //
        McBSP_enableSampleRateGenerator(MCBSPA_BASE);
        McBSP_enableFrameSyncLogic(MCBSPA_BASE);
    
        //
        // Wait for CPU cycles equivalent to 2 CLKG cycles-init delay.
        // Total cycles required = 2*(SYSCLK/(LSPCLK/(1+CLKGDV_VAL))). In this
        // example LSPCLK = SYSCLK/4 and CLKGDV_VAL = 1.
        //
        MCBSP_CYCLE_NOP(16);
    
        //
        // Release Rx, Tx from reset.
        //
        HWREGH(MCBSPA_BASE + MCBSP_O_SPCR2) |= MCBSP_SPCR2_XRST;
        HWREGH(MCBSPA_BASE + MCBSP_O_SPCR1) |= MCBSP_SPCR1_RRST;
    }
    
    //
    // Start DMA - This function starts DMA channel 1 & 2.
    //
    void startDMA(void)
    {
        DMA_startChannel(DMA_CH1_BASE);
        DMA_startChannel(DMA_CH2_BASE);
    }
    
    //
    // Local DMA INT CH1 ISR - ISR for DMA channel 1 interrupt.
    //
    __interrupt void localDMAINTCH1ISR(void)
    {
        DMA_stopChannel(DMA_CH1_BASE);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP7);
        return;
    }
    
    //
    // Local DMA INT CH2 ISR - ISR for DMA channel 2 interrupt.
    //
    __interrupt void localDMAINTCH2ISR(void)
    {
        uint16_t i;
        DMA_stopChannel(DMA_CH2_BASE);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP7);
        for(i = 0; i < 128; i++)
        {
            if(dataSize == 8)
            {
                if((rxData[i] & 0x00FF) != (txData[i] & 0x00FF))
                {
                    errCountGlobal++;
                    Example_Fail = 1;
                    ESTOP0;
                }
    
                Example_PassCount++;
            }
            else
            {
                if(rxData[i] != txData[i])
                {
                    errCountGlobal++;
                    Example_Fail = 1;
                    ESTOP0;
                }
    
                Example_PassCount++;
            }
        }
        return;
    }
    
    //
    // End of File
    //
    

  • Thanks Omer,  That did the trick.  I can now get DMA interrupts using MCBSP SPI as a slave.