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.

TMS320F28069: McBSP SPI Mode DMA

Part Number: TMS320F28069
Other Parts Discussed in Thread: C2000WARE, LAUNCHXL-F28069M

Hello,

We have got the DMA working with the SPI module using the examples provided by TI. How do we maximize the data transfer speed? What parameters do we need to modify in the code? The SPI clock is about 1-2 Mhz in the examples provided by TI but we need much faster data transfer rate. Highly appreciate the urgent response.

Thanks 

  • George,

    C2000Ware McBSP (SPI) mode use LSPCLK (@20MHz) as input clock and SRGR1.CLKGDV = 0xF. You need to either bump-up the LSPCLK using LOSPCP register (or) reduce SRGR1.CLKGDV to increase the SPICLK frequency.

    Regards,

    Manoj

  • Hi Manoj,

    #define CPU_SPD              80E6

    #define MCBSP_SRG_FREQ       CPU_SPD/2

    #define CLKGDV_VAL           1

    SysCtrlRegs.LOSPCP.all = 0x0002;

    SysCtrlRegs.XCLK.bit.XCLKOUTDIV=2;
    Changing the values above ( except for LOSPCP) did not have any impact on the clock frequency. For example, we tried different values for CLKGDV_VAL   and noticed no change. Decressing LOsPCP from 2 to 1 doubled the clock frequency from 1.2 Mhz to 2.5 Mhz. Any other suggestions? Thanks a lot.

  • George,

    I'm not aware of these macro definitions. Which example code are you running. I was suggesting you to try below example project in C2000Ware.

    <C2000Ware>\device_support\f2806x\examples\c28\mcbsp_spi_loopback

    Regards,

    Manoj

  • Manoj,

    Running same code as you mentioned. Please check " F2806x_McBSP.c " file.

  • George,

    You need to make the changes in init_mcbsp_spi function available in Example_2806xMcBSP_SPI_DLB.c file.

    The macro definitions shown below in F2806x_McBSP.c file are not used by the example project

    #define CPU_SPD              80E6

    //
    // SRG input is LSPCLK (SYSCLKOUT/2) for examples
    //
    #define MCBSP_SRG_FREQ       CPU_SPD/2

    #define CLKGDV_VAL           1

    //
    // # of CPU cycles in 2 SRG cycles-init delay
    //
    #define MCBSP_INIT_DELAY     2*(CPU_SPD/MCBSP_SRG_FREQ)

    //
    // # of CPU cycles in 2 CLKG cycles-init delay
    //
    #define MCBSP_CLKG_DELAY     2*(CPU_SPD/(MCBSP_SRG_FREQ/(1+CLKGDV_VAL)))

    Regards,

    Manoj

  • Were you able to get McBSP working at higher frequency using above suggestion?

    -Manoj

  • Unfortunately not. Changing SRGR1.CLKGDV has no effect.

  • I'm currently held up with an important project for next 3 days. I shall look into this by this friday and provide a response.

    Regards,

    Manoj

  • George,

    Just wanted to let you know that I will be looking into this today. I shall post an update by today evening.

    Regards,

    Manoj

  • George,

    Made the following changes in the code and got SPI clock = 18 MHz. Please check below

    1) Modified the below InitMcbspaGpio function in F2806x_McBSP.c

    void InitMcbspaGpio(void)

    {

    EALLOW;

    //Master

    //Configuring GPIOs as McBSP signals

    GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 2; // GPIO22 is MCLKXA pin (SPICLK)

    GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 2; // GPIO23 is MFSXA pin (SPISTE)

    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 2; // GPIO20 is MDXA pin (MOSI)

    //Configuring GPIOs as ASYNC

    GpioCtrlRegs.GPAQSEL2.bit.GPIO22 = 3; // Asynch input GPIO22 (MCLKXA) - (SPICLK)

    GpioCtrlRegs.GPAQSEL2.bit.GPIO23 = 3; // Asynch input GPIO23 (MFSXA) - (SPISTE)

    GpioCtrlRegs.GPAQSEL2.bit.GPIO20 = 3; // Asynch input GPIO29 (MDXA) - (MOSI)

    //Slave

    //Configuring GPIOs as McBSP signals

    GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 1; // GPIO58 is MCLKRA pin (SPICLK)

    GpioCtrlRegs.GPBMUX1.bit.GPIO44 = 1; // GPIO44 is MFSRA pin (SPISTE)

    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 2; // GPIO21 is MDRA pin (SOMI)

    //Configuring GPIOs as ASYNC

    GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3; // Asynch input GPIO58 (MCLKRA) - (SPICLK)

    GpioCtrlRegs.GPBQSEL1.bit.GPIO44 = 3; // Asynch input GPIO44 (MFSRA) - (SPISTE)

    GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 3; // Asynch input GPIO21 (MDRA) - (SOMI)

    EDIS;

    }

    2) Configured SYSCLK = LSPCLK = 90 MHz (Modified LOSPCP = 0 (SYSCLK / 1)) in InitPeripheralClocks function in

    Example_2806xMcBSP_SPI_DLB.c file.

    3) CLKG = LSPCLK / (CLKGDV + 1) = 90 MHz / (4+ 1) = 18 MHz.

        (Modified McbspaRegs.SRGR1.bit.CLKGDV = 4;) in init_mcbsp_spi function in Example_2806xMcBSP_SPI_DLB.c file.

    Regards,

    Manoj

  • Hi Manoj,

    Thanks. Can you please check our code below to see if you find any issues? Basically, we are trying to implement DMA on SPI using McBSP. 

    //###########################################################################

    //
    // FILE:   main.c
    //
    // TITLE:  McBSP Loopback with DMA Example
    //
    //! \addtogroup f2806x_example_list
    //! <h1>McBSP Loopback with DMA (mcbsp_loopback_dma)</h1>
    //!
    //!  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.
    //!
    //!  The sent data buffer will alternate between: \n
    //!     0000 0001 0002 0003 0004 0005 .... 007F   \n
    //!  and\n
    //!     FFFF FFFE FFFD FFFC FFFB FFFA ....        \n
    //!
    //!  Three different McBSP 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.  If an error is
    //!  found the error() function is called and execution stops.
    //!
    //!  By default for the McBSP examples, the McBSP sample rate generator
    //!  (SRG) input clock frequency is LSPCLK (80E6/4)
    //!  assuming SYSCLKOUT = 80 MHz.
    //!
    //!  This example will execute until terminated by the user.
    //!
    //!  \b Watch \b Variables: \n
    //!  - sdata  - Sent data buffer
    //!  - rdata  - Received data buffer
    //
    //###########################################################################
    // $TI Release: F2806x Support Library v2.03.00.00 $
    // $Release Date: Sun Mar 25 13:24:47 CDT 2018 $
    // $Copyright:
    // Copyright (C) 2009-2018 Texas Instruments Incorporated - <a href="www.ti.com/.../a>
    //
    // 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.
    // $
    //###########################################################################
    #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
    __interrupt void local_D_INTCH1_ISR(void);
    __interrupt void local_D_INTCH2_ISR(void);
    void mcbsp_init_dlb(void);
    void init_dma(void);
    void init_dma_32(void);
    void start_dma(void);
    void error(void);
    void delay_loopp(void);
    //
    // Place sdata and rdata buffers in DMA-accessible RAM (L5 for this example)
    //
    #pragma DATA_SECTION(sdata, "DMARAML5")
    #pragma DATA_SECTION(rdata, "DMARAML5")
    Uint16 sdata[128];    // Sent Data
    Uint16 rdata[128];    // Received Data
    Uint16 data_size;     // Word Length variable
    void
    delay_loopp()
    {
        double j;
        for (j = 0; j < 4000000; j++)
        {
        }
    }
    void init_mcbsp_spi(void)
    {
        //
        // McBSP-A register settings
        //
        //
        // Reset FS generator, sample rate generator & transmitter
        //
        McbspaRegs.SPCR2.all=0x0000;
        //
        // Reset Receiver, Right justify word, Digital loopback dis.
        //
        McbspaRegs.SPCR1.all=0x0000;
        McbspaRegs.PCR.all=0x0F08;       // (CLKXM=CLKRM=FSXM=FSRM= 1, FSXP = 1)
       McbspaRegs.SPCR1.bit.DLB = 1;
        //
        // Together with CLKXP/CLKRP determines clocking scheme
        //
        McbspaRegs.SPCR1.bit.CLKSTP = 2;
        McbspaRegs.PCR.bit.CLKXP = 0;   // CPOL = 0, CPHA = 0 rising edge no delay
        McbspaRegs.PCR.bit.CLKRP = 0;
        //
        // FSX setup time 1 in master mode. 0 for slave mode (Receive)
        //
        McbspaRegs.RCR2.bit.RDATDLY=01;
        //
        // FSX setup time 1 in master mode. 0 for slave mode (Transmit)
        //
        McbspaRegs.XCR2.bit.XDATDLY=01;
        McbspaRegs.RCR1.bit.RWDLEN1=0;   // 32-bit word
        McbspaRegs.XCR1.bit.XWDLEN1=0;   // 32-bit word
        McbspaRegs.SRGR2.all=0x2000;     // CLKSM=1, FPER = 1 CLKG periods
        McbspaRegs.SRGR1.all= 0x000F;    // Frame Width = 1 CLKG period, CLKGDV=16
        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
    }
    //
    // Step 7. Insert all local Interrupt Service Routines (ISRs) and functions
    // here:
    //
    void error(void)
    {
        __asm("     ESTOP0"); // Test failed!! Stop!
        for (;;);
    }
    void mcbsp_init_dlb()
    {
        //
        // Reset FS generator, sample rate generator & transmitter
        //
        McbspaRegs.SPCR2.all=0x0000;
        McbspaRegs.SPCR1.all=0x0000;        // Reset Receiver, Right justify word
        //
        // Enable DLB mode. Comment out for non-DLB mode.
        //
       McbspaRegs.SPCR1.bit.DLB = 1;
        McbspaRegs.MFFINT.all=0x0;          // Disable all interrupts
        //
        // Single-phase frame, 1 word/frame, No companding  (Receive)
        //
        McbspaRegs.RCR2.all=0x0;
        McbspaRegs.RCR1.all=0x0;
        //
        // Single-phase frame, 1 word/frame, No companding  (Transmit)
        //
        McbspaRegs.XCR2.all=0x0;
        McbspaRegs.XCR1.all=0x0;
        //
        // CLKSM=1 (If SCLKME=0, i/p clock to SRG is LSPCLK)
        //
        McbspaRegs.SRGR2.bit.CLKSM = 1;
        McbspaRegs.SRGR2.bit.FPER = 31;     // FPER = 32 CLKG periods
        McbspaRegs.SRGR1.bit.FWID = 0;      // Frame Width = 1 CLKG period
        McbspaRegs.SRGR1.bit.CLKGDV = 0;    // CLKG frequency = LSPCLK/(CLKGDV+1)
        //
        // FSX generated internally, FSR derived from an external source
        //
        McbspaRegs.PCR.bit.FSXM = 1;
        //
        // CLKX generated internally, CLKR derived from an external source
        //
        McbspaRegs.PCR.bit.CLKXM = 1;
        //
        // Initialize McBSP Data Length
        //
        if(data_size == 8)             // Run a loopback test in 8-bit mode
        {
            InitMcbspa8bit();
        }
        if(data_size == 16)            // Run a loopback test in 16-bit mode
        {
            InitMcbspa16bit();
        }
        if(data_size == 32)            // Run a loopback test in 32-bit mode
        {
            InitMcbspa32bit();
        }
        //
        // 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
    void init_dma()
    {
        EALLOW;
        DmaRegs.DMACTRL.bit.HARDRESET = 1;
        __asm(" NOP");                         // Only 1 NOP needed per Design
        DmaRegs.CH1.MODE.bit.CHINTE = 0;
        //
        // Channel 1, McBSPA transmit
        //
        DmaRegs.CH1.BURST_SIZE.all = 0;     // 1 word/burst
        DmaRegs.CH1.SRC_BURST_STEP = 0;     // no effect when using 1 word/burst
        DmaRegs.CH1.DST_BURST_STEP = 0;     // no effect when using 1 word/burst
        //
        // Interrupt every frame (127 bursts/transfer)
        //
        DmaRegs.CH1.TRANSFER_SIZE = 127;
        //
        // Move to next word in buffer after each word in a burst
        //
        DmaRegs.CH1.SRC_TRANSFER_STEP = 1;
        //
        // Don't move destination address
        //
        DmaRegs.CH1.DST_TRANSFER_STEP = 0;
        //
        // Start address = buffer
        //
        DmaRegs.CH1.SRC_ADDR_SHADOW = (Uint32) &sdata[0];
        //
        // Not needed unless using wrap function
        //
        DmaRegs.CH1.SRC_BEG_ADDR_SHADOW = (Uint32) &sdata[0];
        //
        // Start address = McBSPA DXR
        //
        DmaRegs.CH1.DST_ADDR_SHADOW = (Uint32) &McbspaRegs.DXR1.all;
        //
        // Not needed unless using wrap function
        //
        DmaRegs.CH1.DST_BEG_ADDR_SHADOW = (Uint32) &McbspaRegs.DXR1.all;
        //
        // Clear peripheral interrupt event flag
        //
        DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1;
        DmaRegs.CH1.CONTROL.bit.ERRCLR = 1;     // Clear sync error flag
        //
        // Put to maximum - don't want destination wrap
        //
        DmaRegs.CH1.DST_WRAP_SIZE = 0xFFFF;
        //
        // Put to maximum - don't want source wrap
        //
        DmaRegs.CH1.SRC_WRAP_SIZE = 0xFFFF;
        //
        // Enable channel interrupt
        //
        DmaRegs.CH1.MODE.bit.CHINTE = 1;
        //
        // Interrupt at end of transfer
        //
        DmaRegs.CH1.MODE.bit.CHINTMODE = 1;
        //
        // Enable peripheral interrupt event
        //
        DmaRegs.CH1.MODE.bit.PERINTE = 1;
        //
        // Peripheral interrupt select = McBSP MXSYNCA
        //
        DmaRegs.CH1.MODE.bit.PERINTSEL = DMA_MXEVTA;
        //
        // Clear any spurious interrupt flags
        //
        DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1;
        //
        // Channel 2, McBSPA Receive
        //
        DmaRegs.CH2.MODE.bit.CHINTE = 0;
        DmaRegs.CH2.BURST_SIZE.all = 0;     // 1 word/burst
        DmaRegs.CH2.SRC_BURST_STEP = 0;     // no effect when using 1 word/burst
        DmaRegs.CH2.DST_BURST_STEP = 0;     // no effect when using 1 word/burst
        DmaRegs.CH2.TRANSFER_SIZE = 127;    // Interrupt every 127 bursts/transfer
        DmaRegs.CH2.SRC_TRANSFER_STEP = 0;  // Don't move source address
        //
        // Move to next word in buffer after each word in a burst
        //
        DmaRegs.CH2.DST_TRANSFER_STEP = 1;
        //
        // Start address = McBSPA DRR
        //
        DmaRegs.CH2.SRC_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR1.all;
        //
        // Not needed unless using wrap function
        //
        DmaRegs.CH2.SRC_BEG_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR1.all;
        //
        // Start address = Receive buffer (for McBSP-A)
        //
        DmaRegs.CH2.DST_ADDR_SHADOW = (Uint32) &rdata[0];
        //
        // Not needed unless using wrap function
        //
        DmaRegs.CH2.DST_BEG_ADDR_SHADOW = (Uint32) &rdata[0];
        //
        // Clear peripheral interrupt event flag
        //
        DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1;
        DmaRegs.CH2.CONTROL.bit.ERRCLR = 1;     // Clear sync error flag
        //
        // Put to maximum - don't want destination wrap
        //
        DmaRegs.CH2.DST_WRAP_SIZE = 0xFFFF;
        //
        // Put to maximum - don't want source wrap
        //
        DmaRegs.CH2.SRC_WRAP_SIZE = 0xFFFF;
        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
        //
        // Peripheral interrupt select = McBSP MRSYNCA
        //
        DmaRegs.CH2.MODE.bit.PERINTSEL = DMA_MREVTA;
        //
        // Clear any spurious interrupt flags
        //
        DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1;
        EDIS;
    }
    //
    // init_dma_32 - 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 1, McBSPA transmit
        //
        DmaRegs.CH1.BURST_SIZE.all = 1;     // 2 word/burst
        DmaRegs.CH1.SRC_BURST_STEP = 1;     // increment 1 16-bit addr. btwn words
        DmaRegs.CH1.DST_BURST_STEP = 1;     // increment 1 16-bit addr. btwn words
        DmaRegs.CH1.TRANSFER_SIZE = 63;     // Interrupt every 63 bursts/transfer
        //
        // Move to next word in buffer after each word in a burst
        //
        DmaRegs.CH1.SRC_TRANSFER_STEP = 1;
        DmaRegs.CH1.DST_TRANSFER_STEP = 0xFFFF;     // Go back to DXR2
        DmaRegs.CH1.SRC_ADDR_SHADOW = (Uint32) &sdata[0]; // Start address = buffer
        //
        // Not needed unless using wrap function
        //
        DmaRegs.CH1.SRC_BEG_ADDR_SHADOW = (Uint32) &sdata[0];
        //
        // Start address = McBSPA DXR2
        //
        DmaRegs.CH1.DST_ADDR_SHADOW = (Uint32) &McbspaRegs.DXR2.all;
        //
        // Not needed unless using wrap function
        //
        DmaRegs.CH1.DST_BEG_ADDR_SHADOW = (Uint32) &McbspaRegs.DXR2.all;
        DmaRegs.CH1.CONTROL.bit.ERRCLR = 1;     // Clear sync error flag
        //
        // Put to maximum - don't want destination wrap
        //
        DmaRegs.CH1.DST_WRAP_SIZE = 0xFFFF;
        //
        // Put to maximum - don't want source wrap
        //
        DmaRegs.CH1.SRC_WRAP_SIZE = 0xFFFF;
        DmaRegs.CH1.MODE.bit.CHINTE = 1;     // Enable channel interrupt
        DmaRegs.CH1.MODE.bit.CHINTMODE = 1;  // Interrupt at end of transfer
        DmaRegs.CH1.MODE.bit.PERINTE = 1;    // Enable peripheral interrupt event
        //
        // Peripheral interrupt select = McBSP MXSYNCA
        //
        DmaRegs.CH1.MODE.bit.PERINTSEL = DMA_MXEVTA;
        //
        // Clear any spurious interrupt flags
        //
        DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1;
        //
        // 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 = 63;     // Interrupt every 63 bursts/transfer
        DmaRegs.CH2.SRC_TRANSFER_STEP = 0xFFFF; // Decrement  back to DRR2
        //
        // Move to next word in buffer after each word in a burst
        //
        DmaRegs.CH2.DST_TRANSFER_STEP = 1;
        //
        // Start address = McBSPA DRR
        //
        DmaRegs.CH2.SRC_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR2.all;
        //
        // Not needed unless using wrap function
        //
        DmaRegs.CH2.SRC_BEG_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR2.all;
        //
        // Start address = Receive buffer (for McBSP-A)
        //
        DmaRegs.CH2.DST_ADDR_SHADOW = (Uint32) &rdata[0];
        //
        // Not needed unless using wrap function
        //
        DmaRegs.CH2.DST_BEG_ADDR_SHADOW = (Uint32) &rdata[0];
        DmaRegs.CH2.CONTROL.bit.ERRCLR = 1;     // Clear sync error flag
        //
        // Put to maximum - don't want destination wrap
        //
        DmaRegs.CH2.DST_WRAP_SIZE = 0xFFFF;
        //
        // Put to maximum - don't want source wrap
        //
        DmaRegs.CH2.SRC_WRAP_SIZE = 0xFFFF;
        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
        //
        // Peripheral interrupt select = McBSP MRSYNCA
        //
        DmaRegs.CH2.MODE.bit.PERINTSEL = DMA_MREVTA;
        //
        // Clear any spurious interrupt flags
        //
        DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1;
        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;
    }
    //
    // local_D_INTCH1_ISR - INT7.1 is DMA Ch1
    //
    __interrupt void local_D_INTCH1_ISR(void)
    {
        EALLOW;     // NEED TO EXECUTE EALLOW INSIDE ISR !!!
        DmaRegs.CH1.CONTROL.bit.HALT = 1;
        //
        // To receive more interrupts from this PIE group, acknowledge this
        // interrupt
        //
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;
        DmaRegs.CH1.CONTROL.bit.RUN = 1; //    ***********************************
       //GpioDataRegs.GPBTOGGLE.bit.GPIO39 = 1;   // Load output latch
       // GpioDataRegs.GPATOGGLE.bit.GPIO26 = 1;   // Load output latch
       //delay_loopp();
       // GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;   // Enable pullup on GPIO8
        EDIS;
        return;
    }
    //
    // local_D_INTCH2_ISR - INT7.2 is DMA Ch2
    //
    __interrupt void local_D_INTCH2_ISR(void)
    {
        Uint16 i;
        EALLOW;         // NEED TO EXECUTE EALLOW INSIDE ISR !!!
        DmaRegs.CH2.CONTROL.bit.HALT = 1;
        //
        // To receive more interrupts from this PIE group, acknowledge this
        // interrupt
        //
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;
        DmaRegs.CH2.CONTROL.bit.RUN = 1;  //  **********************************************
        GpioDataRegs.GPATOGGLE.bit.GPIO26 = 1;   // Load output latch

        for (i=0; i<128; i++)
        {
            if(data_size == 8)
            {
                if( (rdata[i]&0x00FF) !=(sdata[i]&0x00FF))
                {
                    error( ); // Check for correct received data
                }
            }
            else if (data_size == 16)
            {
                if (rdata[i] != sdata[i])
                {
                    error();  // STOP if there is an error !!
                }
            }
            else if (data_size == 32)
            {
                if ((rdata[i])!=(sdata[i]))
                {
                    error ();
                }
            }
        }
        EDIS;
        return;
    }
    void main(void)
    {
        Uint16 i;
        InitSysCtrl();
        InitMcbspaGpio();
        DINT;
        InitPieCtrl();
        IER = 0x0000;
        IFR = 0x0000;
        InitPieVectTable();
        EALLOW;     // Allow access to EALLOW protected registers
        PieVectTable.DINTCH1= &local_D_INTCH1_ISR;
        PieVectTable.DINTCH2= &local_D_INTCH2_ISR;
        EDIS;       // Disable access to EALLOW protected registers

        data_size = WORD_SIZE;

        for (i=0; i< 128; i++)
        {
            sdata[i] = i;      // Fill sdata with values between 0 and 0x007F
            // sdata[i+1] = sdata[i]+0x01;
            rdata[i] = 0;      // Initialize rdata to all 0x0000.
        }
        if (data_size == 32)
        {
            init_dma_32();     // DMA Initialization for 32-bit transfers
        }
        else
        {
            //
            // 1. When using DMA, initialize DMA with peripheral interrupts first
            //
            init_dma();
        }
        start_dma();
        //
        // 2.  Then initialize and release peripheral (McBSP) from Reset
        //
    //    mcbsp_init_dlb();
        init_mcbsp_spi();

        // Enable interrupts required for this example
        //
        PieCtrlRegs.PIECTRL.bit.ENPIE = 1;  // Enable the PIE block
        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=0x40;                            // Enable CPU INT group 7
        EINT;                                // Enable Global Interrupts
        EALLOW;
        GpioCtrlRegs.GPBPUD.bit.GPIO34 = 1;  // Enable pullup on GPIO34
        GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0; // GPIO34 = GPIO34
        GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;  // GPIO34 = input
        GpioCtrlRegs.GPBPUD.bit.GPIO39 = 0;   // Enable pullup on GPIO8
        GpioDataRegs.GPBSET.bit.GPIO39 = 1;   // Load output latch
        GpioCtrlRegs.GPBMUX1.bit.GPIO39 = 0;  // GPIO8 = GPIO8
        GpioCtrlRegs.GPBDIR.bit.GPIO39 = 1;   // GPIO8 = output
        GpioCtrlRegs.GPAPUD.bit.GPIO26 = 1;  // Enable pullup on GPIO34
        GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 0; // GPIO34 = GPIO34
        GpioCtrlRegs.GPADIR.bit.GPIO26 = 1;  // GPIO34 = input

        EDIS;
        //
        for(;;)
        {
            //GpioDataRegs.GPATOGGLE.bit.GPIO26 = 1;   // Load output latch
           //GpioDataRegs.GPBTOGGLE.bit.GPIO39 = 1;   // Load output latch
           //delay_loopp();
            GpioDataRegs.GPBSET.bit.GPIO34 = 1;   // Load output latch
            GpioDataRegs.GPBSET.bit.GPIO39 = 1;   // Load output latch
            delay_loopp();
            GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;   // Load output latch
            GpioDataRegs.GPBCLEAR.bit.GPIO39 = 1;   // Load output latch
            delay_loopp();
            //delay_loopp();
        }
            ;
    }
  • Also can you please upload your complete code? Seems like the code you are using is different than ours!

  • What exactly are you trying to achieve with DMA - SPI interface? Please provide more details on what you want to DMA to do ? It is difficult to read every single line of code to figure what you are trying to do.

    Regards,

    Manoj

  • Hi Manoj,

    1- Can you please send us the code you modified to get 18 MHz on SPI to this email ( georgeandromeda2000@yahoo.com ) ? We are not getting the same results when we make those changes you mentioned to the original SPI code provided by TI. ( Example_2806xMCBSP_SPI_DLB ) . If we can test your code on our set up ( LAUNCHXL-F28069M TI eval board ) successfully, we can confirm that our set up is correct. 

    2-  Regarding your question,  We started from here ( https://e2e.ti.com/support/microcontrollers/c2000/f/171/p/706039/2602073?tisearch=e2e-sitesearch&keymatch=mcbsp_loopback_dma#pi320995filter=all&pi320995scroll=false ) to implement DMA transactions with the SPI module. 

    We simply copied the code from here and replaced the Example_2806xMcBSP_DLB_DMA.c file in the TI example with it. Did not make any other changes to the example code provided by TI. The code seems to be working with some minor issues Can you please review our code to see where we are doing wrong? 

    Appreciate your urgent help on this.

  • George,

    Sorry, for replying late to this thread. I was out of office on Friday.

    As I mentioned in my previous post, you need to explain what is working and what isn't in above sent code for me to look into. Is it right for me to assume your McBSP (SPI) code is working fine and you want DMA to handle the transmit and receive operations? Do you see the McBSP transmit message correctly when using oscilloscope?

    Regards,

    Manoj

  • Hi Manoj,

    Thanks! The only problem we have with the original  McBSP (SPI) code by TI is that the changes you suggested does not change the SPI clock speed. That's why we asked for your modified code to see how that works.

  • George,

    The post I made on Mon, Feb 10 2020 2:34 PM summarized the list of change made to the following files below:-

    These files includes the all the changes I made, you should be able to include this in your mcbsp_spi_loopback project. I was my understanding that you were also able to observe SPI clock of 18 MHz after the changes I suggested in your post.

    //###########################################################################
    //
    // FILE:    1)
    //
    // TITLE:   F2806x Device McBSP Initialization & Support Functions.
    //
    //###########################################################################
    // $TI Release: F2806x Support Library v2.05.00.00 $
    // $Release Date: Mon Dec 23 17:30:00 IST 2019 $
    // $Copyright:
    // Copyright (C) 2009-2019 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 "F2806x_Device.h"     // F2806x Headerfile Include File
    #include "F2806x_Examples.h"   // F2806x Examples Include File
    
    //
    // MCBSP_INIT_DELAY determines the amount of CPU cycles in the 2 sample rate
    // generator (SRG) cycles required for the Mcbsp initialization routine.
    // MCBSP_CLKG_DELAY determines the amount of CPU cycles in the 2 clock
    // generator (CLKG) cycles required for the Mcbsp initialization routine.
    //
    #define CPU_SPD              80E6
    
    //
    // SRG input is LSPCLK (SYSCLKOUT/2) for examples
    //
    #define MCBSP_SRG_FREQ       CPU_SPD/2
    
    #define CLKGDV_VAL           1
    
    //
    // # of CPU cycles in 2 SRG cycles-init delay
    //
    #define MCBSP_INIT_DELAY     2*(CPU_SPD/MCBSP_SRG_FREQ)
    
    //
    // # of CPU cycles in 2 CLKG cycles-init delay
    //
    #define MCBSP_CLKG_DELAY     2*(CPU_SPD/(MCBSP_SRG_FREQ/(1+CLKGDV_VAL)))
    
    
    //
    // InitMcbsp - This function initializes the McBSP to a known state.
    //
    #if DSP28_MCBSPA
    void delay_loop(void);      // Delay function used for SRG initialization
    void clkg_delay_loop(void); // Delay function used for CLKG initialization
    #endif // endif DSP28_MCBSPA
    
    #if DSP28_MCBSPA
    void
    InitMcbsp(void)
    {
        InitMcbspa();
    }
    #endif // endif DSP28_MCBSPA
    
    #if DSP28_MCBSPA
    //
    // InitMcbspa - McBSP-A register settings
    //
    void
    InitMcbspa(void)
    {
        //
        // Reset FS generator, sample rate generator & transmitter
        //    
        McbspaRegs.SPCR2.all=0x0000;
        McbspaRegs.SPCR1.all=0x0000;        // Reset Receiver, Right justify word
        
        //
        // Enable loopback mode for test. Comment out for normal McBSP transfer
        // mode
        //
        McbspaRegs.SPCR1.bit.DLB = 1;
    
        McbspaRegs.MFFINT.all=0x0;          // Disable all interrupts
    
        //
        // Single-phase frame, 1 word/frame, No companding  (Receive)
        //
        McbspaRegs.RCR2.all=0x0;
        
        McbspaRegs.RCR1.all=0x0;
    
        //
        // Single-phase frame, 1 word/frame, No companding  (Transmit)
        //
        McbspaRegs.XCR2.all=0x0;
        
        McbspaRegs.XCR1.all=0x0;
    
        //
        // FSX generated internally, FSR derived from an external source
        //
        McbspaRegs.PCR.bit.FSXM = 1;
        
        //
        // CLKX generated internally, CLKR derived from an external source
        //
        McbspaRegs.PCR.bit.CLKXM = 1;
    
        //
        // CLKSM=1 (If SCLKME=0, i/p clock to SRG is LSPCLK)
        //
        McbspaRegs.SRGR2.bit.CLKSM = 1;
        
        McbspaRegs.SRGR2.bit.FPER = 31;     // FPER = 32 CLKG periods
    
        McbspaRegs.SRGR1.bit.FWID = 0;      // Frame Width = 1 CLKG period
        
        //
        // CLKG frequency = LSPCLK/(CLKGDV+1)
        //
        McbspaRegs.SRGR1.bit.CLKGDV = CLKGDV_VAL;
    
        delay_loop();                // Wait at least 2 SRG clock cycles
    
        McbspaRegs.SPCR2.bit.GRST=1; // Enable the sample rate generator
        clkg_delay_loop();           // Wait at least 2 CLKG 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
    }
    
    //
    // InitMcbspa8bit - McBSP-A Data Lengths
    //
    void
    InitMcbspa8bit(void)
    {
        McbspaRegs.RCR1.bit.RWDLEN1=0;     // 8-bit word
        McbspaRegs.XCR1.bit.XWDLEN1=0;     // 8-bit word
    }
    
    //
    // InitMcbspa12bit - 
    //
    void
    InitMcbspa12bit(void)
    {
        McbspaRegs.RCR1.bit.RWDLEN1=1;     // 12-bit word
        McbspaRegs.XCR1.bit.XWDLEN1=1;     // 12-bit word
    }
    
    //
    // InitMcbspa16bit - 
    //
    void
    InitMcbspa16bit(void)
    {
        McbspaRegs.RCR1.bit.RWDLEN1=2;      // 16-bit word
        McbspaRegs.XCR1.bit.XWDLEN1=2;      // 16-bit word
    }
    
    //
    // InitMcbspa20bit - 
    //
    void
    InitMcbspa20bit(void)
    {
        McbspaRegs.RCR1.bit.RWDLEN1=3;     // 20-bit word
        McbspaRegs.XCR1.bit.XWDLEN1=3;     // 20-bit word
    }
    
    //
    // InitMcbspa24bit -
    //
    void
    InitMcbspa24bit(void)
    {
        McbspaRegs.RCR1.bit.RWDLEN1=4;     // 24-bit word
        McbspaRegs.XCR1.bit.XWDLEN1=4;     // 24-bit word
    }
    
    //
    // InitMcbspa32bit - 
    //
    void
    InitMcbspa32bit(void)
    {
        McbspaRegs.RCR1.bit.RWDLEN1=5;     // 32-bit word
        McbspaRegs.XCR1.bit.XWDLEN1=5;     // 32-bit word
    }
    
    //
    // InitMcbspGpio -
    //
    void
    InitMcbspGpio(void)
    {
        InitMcbspaGpio();
    }
    
    //
    // InitMcbspaGpio - 
    //
    void
    InitMcbspaGpio(void)
    {
        EALLOW;
    
        //Master
        //Configuring GPIOs as McBSP signals
        GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 2;    // GPIO22 is MCLKXA pin (SPICLK)
        GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 2;    // GPIO23 is MFSXA pin  (SPISTE)
        GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 2;    // GPIO20 is MDXA pin   (MOSI)
        //Configuring GPIOs as ASYNC
        GpioCtrlRegs.GPAQSEL2.bit.GPIO22 = 3;   // Asynch input GPIO22 (MCLKXA) - (SPICLK)
        GpioCtrlRegs.GPAQSEL2.bit.GPIO23 = 3;   // Asynch input GPIO23 (MFSXA)  - (SPISTE)
        GpioCtrlRegs.GPAQSEL2.bit.GPIO20 = 3;   // Asynch input GPIO29 (MDXA)   - (MOSI)
    
        //Slave
        //Configuring GPIOs as McBSP signals
        GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 1;    // GPIO58 is MCLKRA pin (SPICLK)
        GpioCtrlRegs.GPBMUX1.bit.GPIO44 = 1;    // GPIO44 is MFSRA pin  (SPISTE)
        GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 2;    // GPIO21 is MDRA pin   (SOMI)
        //Configuring GPIOs as ASYNC
        GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3;   // Asynch input GPIO58 (MCLKRA) - (SPICLK)
        GpioCtrlRegs.GPBQSEL1.bit.GPIO44 = 3;   // Asynch input GPIO44 (MFSRA)  - (SPISTE)
        GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 3;   // Asynch input GPIO21 (MDRA)   - (SOMI)
    
        EDIS;
    }
    
    //
    // delay_loop - 
    //
    void
    delay_loop(void)
    {
        long      i;
        
        //
        // delay in McBsp init. must be at least 2 SRG cycles
        //
        for (i = 0; i < MCBSP_INIT_DELAY; i++)
        {
            
        }
    }
    
    //
    // clkg_delay_loop - 
    //
    void
    clkg_delay_loop(void)
    {
        long      i;
        
        //
        // delay in McBsp init. must be at least 2 SRG cycles
        //
        for (i = 0; i < MCBSP_CLKG_DELAY; i++)
        {
            
        }
    }
    #endif // endif DSP28_MCBSPA
    
    //
    // End of File
    //
    
    

    //###########################################################################
    //
    // FILE:   F2806x_SysCtrl.c
    //
    // TITLE:  F2806x Device System Control Initialization & Support Functions.
    //
    // DESCRIPTION:
    //
    //         Example initialization of system resources.
    //
    //###########################################################################
    // $TI Release: F2806x Support Library v2.05.00.00 $
    // $Release Date: Mon Dec 23 17:30:00 IST 2019 $
    // $Copyright:
    // Copyright (C) 2009-2019 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 "F2806x_Device.h"     // Headerfile Include File
    #include "F2806x_Examples.h"   // Examples Include File
    
    //
    // Functions that will be run from RAM need to be assigned to
    // a different section.  This section will then be mapped to a load and
    // run address using the linker cmd file.
    //
    //  *IMPORTANT*
    //  IF RUNNING FROM FLASH, PLEASE COPY OVER THE SECTION "ramfuncs"  FROM FLASH
    //  TO RAM PRIOR TO CALLING InitSysCtrl(). THIS PREVENTS THE MCU FROM THROWING 
    //  AN EXCEPTION WHEN A CALL TO DELAY_US() IS MADE. 
    //
    #pragma CODE_SECTION(InitFlash, "ramfuncs");
    
    //
    // InitSysCtrl - This function initializes the System Control registers to a 
    // known state.
    // - Disables the watchdog
    // - Set the PLLCR for proper SYSCLKOUT frequency
    // - Set the pre-scaler for the high and low frequency peripheral clocks
    // - Enable the clocks to the peripherals
    //
    void
    InitSysCtrl(void)
    {
        //
        // Disable the watchdog
        //
        DisableDog();
    
        //
        // *IMPORTANT*
        // The Device_cal function, which copies the ADC & oscillator calibration 
        // values from TI reserved OTP into the appropriate trim registers, occurs 
        // automatically in the Boot ROM. If the boot ROM code is bypassed during 
        // the debug process, the following function MUST be called for the ADC and
        // oscillators to function according to specification. The clocks to the 
        // ADC MUST be enabled before calling this function.
        // See the device data manual and/or the ADC Reference
        // Manual for more information.
        //
        EALLOW;
        SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // Enable ADC peripheral clock
        (*Device_cal)();
        SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 0; // Return ADC clock to original state
        EDIS;
    
        //
        // Select Internal Oscillator 1 as Clock Source (default), and turn off all
        // unused clocks to conserve power.
        //
        IntOsc1Sel();
    
        //
        // Initialize the PLL control: PLLCR and CLKINDIV
        // DSP28_PLLCR and DSP28_CLKINDIV are defined in F2806x_Examples.h
        //
        InitPll(DSP28_PLLCR,DSP28_DIVSEL);
    
        //
        // Initialize the peripheral clocks
        //
        InitPeripheralClocks();
    }
    
    //
    // InitFlash - This function initializes the Flash Control registers for 
    // operation at 90MHz.  If you are running slower flash wait states can be 
    // lessened. Refer to the datasheet for propper flash wait state values.
    //                   CAUTION
    // This function MUST be executed out of RAM. Executing it
    // out of OTP/Flash will yield unpredictable results
    //
    void
    InitFlash(void)
    {
        EALLOW;
        
        //
        // Enable Flash Pipeline mode to improve performance of code executed from 
        // Flash.
        //
        FlashRegs.FOPT.bit.ENPIPE = 1;
    
        //                CAUTION
        // Minimum waitstates required for the flash operating
        // at a given CPU rate must be characterized by TI.
        // Refer to the datasheet for the latest information.
        //
        
        //
        // Set the Paged Waitstate for the Flash
        //
        FlashRegs.FBANKWAIT.bit.PAGEWAIT = 3;
    
        //
        // Set the Random Waitstate for the Flash
        //
        FlashRegs.FBANKWAIT.bit.RANDWAIT = 3;
    
        //
        // Set the Waitstate for the OTP
        //
        FlashRegs.FOTPWAIT.bit.OTPWAIT = 5;
    
        //
        // CAUTION -  ONLY THE DEFAULT VALUE FOR THESE 2 REGISTERS SHOULD BE USED
        //
        FlashRegs.FSTDBYWAIT.bit.STDBYWAIT = 0x01FF;
        FlashRegs.FACTIVEWAIT.bit.ACTIVEWAIT = 0x01FF;
        EDIS;
     
        //
        // Force a pipeline flush to ensure that the write to the last register
        // configured occurs before returning.
        //
        __asm(" RPT #7 || NOP");
    }
    
    //
    // ServiceDog - This function resets the watchdog timer. Enable this function 
    // for using ServiceDog in the application
    //
    void
    ServiceDog(void)
    {
        EALLOW;
        SysCtrlRegs.WDKEY = 0x0055;
        SysCtrlRegs.WDKEY = 0x00AA;
        EDIS;
    }
    
    //
    // DisableDog - This function disables the watchdog timer.
    //
    void
    DisableDog(void)
    {
        EALLOW;
        SysCtrlRegs.WDCR= 0x0068;
        EDIS;
    }
    
    //
    // InitPll - This function initializes the PLLCR register.
    //
    void
    InitPll(Uint16 val, Uint16 divsel)
    {
        volatile Uint16 iVol;
    
        // Make sure the PLL is not running in limp mode
        if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
        {
        EALLOW;
        // OSCCLKSRC1 failure detected. PLL running in limp mode.
        // Re-enable missing clock logic.
        SysCtrlRegs.PLLSTS.bit.MCLKCLR = 1;
        EDIS;
        // Replace this line with a call to an appropriate
        // SystemShutdown(); function.
        __asm("        ESTOP0");     // Uncomment for debugging purposes
        }
    
        // DIVSEL MUST be 0 before PLLCR can be changed from
        // 0x0000. It is set to 0 by an external reset XRSn
        // This puts us in 1/4
        if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)
        {
        EALLOW;
        SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;
        EDIS;
        }
    
        //
        // Change the PLLCR
        //
        if (SysCtrlRegs.PLLCR.bit.DIV != val)
        {
            EALLOW;
            
            //
            // Before setting PLLCR turn off missing clock detect logic
            //
            SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;
            SysCtrlRegs.PLLCR.bit.DIV = val;
            EDIS;
            
            //
            // Optional: Wait for PLL to lock.
            // During this time the CPU will switch to OSCCLK/2 until
            // the PLL is stable.  Once the PLL is stable the CPU will
            // switch to the new PLL value.
            //
            // This time-to-lock is monitored by a PLL lock counter.
            //
            // Code is not required to sit and wait for the PLL to lock.
            // However, if the code does anything that is timing critical,
            // and requires the correct clock be locked, then it is best to
            // wait until this switching has completed.
            //
    
            //
            // Wait for the PLL lock bit to be set.
            //
    
            //
            // The watchdog should be disabled before this loop, or fed within
            // the loop via ServiceDog().
            //
            
            //
            // Uncomment to disable the watchdog
            //
            DisableDog();
    
            while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)
            {
                //
                // Uncomment to service the watchdog
                //
                //ServiceDog();
            }
    
            EALLOW;
            SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
            EDIS;
        }
    
        //
        // If switching to 1/2
        //
        if((divsel == 1)||(divsel == 2))
        {
            EALLOW;
            SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;
            EDIS;
        }
    
        //
        // If switching to 1/1
        // * First go to 1/2 and let the power settle
        //   The time required will depend on the system, this is only an example
        // * Then switch to 1/1
        //
        if(divsel == 3)
        {
            EALLOW;
            SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;
            DELAY_US(50L);
            SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;
            EDIS;
        }
    }
    
    //
    // InitPll2 - This function initializes the PLL2 registers.
    //
    void
    InitPll2(Uint16 clksrc, Uint16 pllmult, Uint16 clkdiv)
    {
        EALLOW;
    
        //
        // Check if SYSCLK2DIV2DIS is in /2 mode
        //
        if(DevEmuRegs.DEVICECNF.bit.SYSCLK2DIV2DIS != 0)
        {
            DevEmuRegs.DEVICECNF.bit.SYSCLK2DIV2DIS = 0;
        }
    
        //
        // Enable PLL2
        //
        SysCtrlRegs.PLL2CTL.bit.PLL2EN = 1;
        
        //
        // Select clock source for PLL2
        //
        SysCtrlRegs.PLL2CTL.bit.PLL2CLKSRCSEL = clksrc;
        
        //
        // Set PLL2 Multiplier
        //
        SysCtrlRegs.PLL2MULT.bit.PLL2MULT = pllmult;
        
        //
        // Wait for PLL to lock.
        // Uncomment to disable the watchdog
        //
        DisableDog();
        while(SysCtrlRegs.PLL2STS.bit.PLL2LOCKS!= 1)
        {
            //
            // Uncomment to service the watchdog
            //
            //ServiceDog();
        }
    
        //
        // Set System Clock 2 divider
        //
        DevEmuRegs.DEVICECNF.bit.SYSCLK2DIV2DIS = clkdiv;
        EDIS;
    }
    
    //
    // InitPeripheralClocks - This function initializes the clocks to the 
    // peripheral modules. First the high and low clock prescalers are set
    // Second the clocks are enabled to each peripheral.
    // To reduce power, leave clocks to unused peripherals disabled
    //
    // Note: If a peripherals clock is not enabled then you cannot
    // read or write to the registers for that peripheral
    //
    void
    InitPeripheralClocks(void)
    {
        EALLOW;
    
        //
        // LOSPCP prescale register settings, normally it will be set to default 
        // values
        //
    
        //
        //GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3;  // GPIO18 = XCLKOUT
        //
        SysCtrlRegs.LOSPCP.all = 0x0000;
    
        //
        // XCLKOUT to SYSCLKOUT ratio.  By default XCLKOUT = 1/4 SYSCLKOUT
        //
        SysCtrlRegs.XCLK.bit.XCLKOUTDIV=2;
    
        //
        // Peripheral clock enables set for the selected peripherals.
        // If you are not using a peripheral leave the clock off
        // to save on power.
        //
        // Note: not all peripherals are available on all F2806x derivates.
        // Refer to the datasheet for your particular device.
        //
        // This function is not written to be an example of efficient code.
        //
        SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1;    // ePWM1
        SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1;    // ePWM2
        SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1;    // ePWM3
        SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1;    // ePWM4
        SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1;    // ePWM5
        SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1;    // ePWM6
        SysCtrlRegs.PCLKCR1.bit.EPWM7ENCLK = 1;    // ePWM7
        SysCtrlRegs.PCLKCR1.bit.EPWM8ENCLK = 1;    // ePWM8
    
        SysCtrlRegs.PCLKCR0.bit.HRPWMENCLK = 1;    // HRPWM
        SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;     // Enable TBCLK within the ePWM
    
        SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1;    // eQEP1
        SysCtrlRegs.PCLKCR1.bit.EQEP2ENCLK = 1;    // eQEP2
    
        SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1;    // eCAP1
        SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 1;    // eCAP2
        SysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 1;    // eCAP3
    
        SysCtrlRegs.PCLKCR2.bit.HRCAP1ENCLK = 1;   // HRCAP1
        SysCtrlRegs.PCLKCR2.bit.HRCAP2ENCLK = 1;   // HRCAP2
        SysCtrlRegs.PCLKCR2.bit.HRCAP3ENCLK = 1;   // HRCAP3
        SysCtrlRegs.PCLKCR2.bit.HRCAP4ENCLK = 1;   // HRCAP4
    
        SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;      // ADC
        SysCtrlRegs.PCLKCR3.bit.COMP1ENCLK = 1;    // COMP1
        SysCtrlRegs.PCLKCR3.bit.COMP2ENCLK = 1;    // COMP2
        SysCtrlRegs.PCLKCR3.bit.COMP3ENCLK = 1;    // COMP3
    
        SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0
        SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer 1
        SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; // CPU Timer 2
    
        SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1;      // DMA
    
        SysCtrlRegs.PCLKCR3.bit.CLA1ENCLK = 1;     // CLA1
    
        SysCtrlRegs.PCLKCR3.bit.USB0ENCLK = 1;	   // USB0 
    
        SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1;     // I2C-A
        SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1;     // SPI-A
        SysCtrlRegs.PCLKCR0.bit.SPIBENCLK = 1;     // SPI-B
        SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1;     // SCI-A
        SysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 1;     // SCI-B
        SysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 1;   // McBSP-A
        SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1;      // eCAN-A
    
        SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;     // Enable TBCLK within the ePWM
    
        EDIS;
    }
    
    //
    // CsmUnlock - This function unlocks the CSM. User must replace 0xFFFF's with 
    // current password for the DSP. Returns 1 if unlock is successful.
    //
    #define STATUS_FAIL          0
    #define STATUS_SUCCESS       1
    Uint16
    CsmUnlock()
    {
        volatile Uint16 temp;
    
        //
        // Load the key registers with the current password. The 0xFFFF's are dummy
        // passwords.  User should replace them with the correct password for the 
        // DSP.
        //
        EALLOW;
        CsmRegs.KEY0 = 0xFFFF;
        CsmRegs.KEY1 = 0xFFFF;
        CsmRegs.KEY2 = 0xFFFF;
        CsmRegs.KEY3 = 0xFFFF;
        CsmRegs.KEY4 = 0xFFFF;
        CsmRegs.KEY5 = 0xFFFF;
        CsmRegs.KEY6 = 0xFFFF;
        CsmRegs.KEY7 = 0xFFFF;
        EDIS;
    
        //
        // Perform a dummy read of the password locations if they match the key 
        // values, the CSM will unlock
        //
        temp = CsmPwl.PSWD0;
        temp = CsmPwl.PSWD1;
        temp = CsmPwl.PSWD2;
        temp = CsmPwl.PSWD3;
        temp = CsmPwl.PSWD4;
        temp = CsmPwl.PSWD5;
        temp = CsmPwl.PSWD6;
        temp = CsmPwl.PSWD7;
    
        //
        // If the CSM unlocked, return succes, otherwise return
        // failure.
        //
        if (CsmRegs.CSMSCR.bit.SECURE == 0)
        {
            return STATUS_SUCCESS;
        }
        else
        {
            return STATUS_FAIL;
        }
    }
    
    //
    // IntOsc1Sel - This function switches to Internal Oscillator 1 and turns off 
    // all other clock sources to minimize power consumption
    //
    void
    IntOsc1Sel(void)
    {
        EALLOW;
        SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0;
        SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL=0;  // Clk Src = INTOSC1
        SysCtrlRegs.CLKCTL.bit.XCLKINOFF=1;     // Turn off XCLKIN
        SysCtrlRegs.CLKCTL.bit.XTALOSCOFF=1;    // Turn off XTALOSC
        SysCtrlRegs.CLKCTL.bit.INTOSC2OFF=1;    // Turn off INTOSC2
        EDIS;
    }
    
    //
    // IntOsc2Sel - This function switches to Internal oscillator 2 from External 
    // Oscillator and turns off all other clock sources to minimize 
    // power consumption
    // NOTE: If there is no external clock connection, when switching from
    //       INTOSC1 to INTOSC2, EXTOSC and XLCKIN must be turned OFF prior
    //       to switching to internal oscillator 1
    //
    void
    IntOsc2Sel(void)
    {
        EALLOW;
        
        //
        // Errata Workaround - Toggle XCLKINOFF and XTALOSCOFF bits
        //
        SysCtrlRegs.CLKCTL.all |= 0x6000;
        SysCtrlRegs.CLKCTL.all &= ~0x6000;
        SysCtrlRegs.CLKCTL.all |= 0x6000;
        SysCtrlRegs.CLKCTL.all &= ~0x6000;    
        SysCtrlRegs.CLKCTL.all |= 0x6000;
        
        //
        // Turn on INTOSC2, set as source
        //
        SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 0;     // Turn on INTOSC2
        SysCtrlRegs.CLKCTL.bit.OSCCLKSRC2SEL = 1;  // Select INTOSC2 as source
        
        //
        // Switch to use Internal Oscillator 2
        //
        SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 1;
        
        //
        // Clock Watchdog off of INTOSC1 always
        //
        SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 0;
        
        SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0;     // Leave INTOSC1 on
        EDIS;
    }
    
    //
    // XtalOscSel - This function switches to External CRYSTAL oscillator and turns
    // off all other clock sources to minimize power consumption. This option may 
    // not be available on all device packages
    //
    void
    XtalOscSel(void)
    {
        EALLOW;
        SysCtrlRegs.CLKCTL.bit.XTALOSCOFF = 0;     // Turn on XTALOSC
        
        //
        // Wait for 1ms while XTAL starts up
        //
        DELAY_US(1000);
        
        SysCtrlRegs.CLKCTL.bit.XCLKINOFF = 1;      // Turn off XCLKIN
        SysCtrlRegs.CLKCTL.bit.OSCCLKSRC2SEL = 0;  // Switch to external clock
        
        //
        // Switch from INTOSC1 to INTOSC2/ext clk
        //
        SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 1;   
        
        //
        // Clock Watchdog off of INTOSC1 always
        //
        SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 0;
        
        SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 1;     // Turn off INTOSC2
        SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0;     // Leave INTOSC1 on
        EDIS;
    }
    
    //
    // ExtOscSel - This function switches to External oscillator and turns off all 
    // other clock sources to minimize power consumption.
    //
    void
    ExtOscSel(void)
    {
        EALLOW;
        
        //
        // 1-GPIO19 = XCLKIN, 0-GPIO38 = XCLKIN
        //
        SysCtrlRegs.XCLK.bit.XCLKINSEL = 1;       
        
        SysCtrlRegs.CLKCTL.bit.XTALOSCOFF = 1;    // Turn on XTALOSC
        SysCtrlRegs.CLKCTL.bit.XCLKINOFF = 0;     // Turn on XCLKIN
        SysCtrlRegs.CLKCTL.bit.OSCCLKSRC2SEL = 0; // Switch to external clock
        
        //
        // Switch from INTOSC1 to INTOSC2/ext clk
        //
        SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 1;
        
        //
        // Clock Watchdog off of INTOSC1 always
        //
        SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 0;   
        
        SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 1;    // Turn off INTOSC2
        SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0;    // Leave INTOSC1 on
        EDIS;
    }
    
    //
    // End of File
    //
    
    

    //###########################################################################
    //
    // FILE:   Example_2806xMcBSP_SPI_DLB.c
    //
    // TITLE:  McBSP Loopback using SPI mode Example
    //
    //! \addtogroup f2806x_example_list
    //! <h1>McBSP Loopback using SPI mode (mcbsp_spi_loopback)</h1>
    //!
    //!  This program will execute and transmit words until terminated by the user.
    //!  SPI master mode transfer of 32-bit word size with digital loopback enabled.
    //!
    //!  \b McBSP \b Signals - \b SPI \b equivalent
    //!  - MCLKX - SPICLK  (master)
    //!  - MFSX  - SPISTE  (master)
    //!  - MDX   - SPISIMO
    //!  - MCLKR - SPICLK  (slave - not used for this example)
    //!  - MFSR  - SPISTE  (slave - not used for this example)
    //!  - MDR   - SPISOMI (not used for this example)
    //!
    //!  By default for the McBSP examples, the McBSP sample rate generator (SRG) 
    //!  input clock frequency is LSPCLK 80E6/4.
    //!
    //! \b Watch \b Variables: \n
    //! - sdata1 - Sent data word(1)
    //! - sdata2 - Sent data word(2)
    //! - rdata1 - Received data word(1)
    //! - rdata2 - Received data word(2)
    //
    //
    //###########################################################################
    // $TI Release: F2806x Support Library v2.05.00.00 $
    // $Release Date: Mon Dec 23 17:30:00 IST 2019 $
    // $Copyright:
    // Copyright (C) 2009-2019 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 "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    //
    // Function Prototypes
    //
    void init_mcbsp_spi(void);
    void mcbsp_xmit(int a, int b);
    void error(void);
    
    //
    // Globals
    //
    Uint16 sdata1 = 0x000;    // Sent Data
    Uint16 rdata1 = 0x000;    // Received Data
    
    Uint16 sdata2 = 0x000;    // Sent Data
    Uint16 rdata2 = 0x000;    // Received Data
    
    //
    // Main
    //
    void main(void)
    {
        //
        // Step 1. Initialize System Control:
        // PLL, WatchDog, enable Peripheral Clocks
        // This example function is found in the F2806x_SysCtrl.c file.
        //
        InitSysCtrl();
    
        //
        // Step 2. Initalize GPIO:
        // This example function is found in the F2806x_Gpio.c file and
        // illustrates how to set the GPIO to it's default state.
        //
        
        //
        // Skipped for this example. For this example, only enable the GPIO for 
        // McBSP-A
        //InitGpio();
        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 F2806x_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 DSP281x_DefaultIsr.c.
        // This function is found in F2806x_PieVect.c.
        //
        InitPieVectTable();
    
        //
        // Step 4. Initialize all the Device Peripherals:
        // This function is found in F2806x_InitPeripherals.c
        //
        //InitPeripherals();     // Not required for this example
    
        //
        // Step 5. User specific code
        //
        init_mcbsp_spi();
        sdata1 = 0x55aa;
        sdata2 = 0xaa55;
        
        //
        // Main loop to transfer 32-bit words through MCBSP in SPI mode 
        // periodically
        //
        for(;;)
        {
            mcbsp_xmit(sdata1,sdata2);
            while( McbspaRegs.SPCR1.bit.RRDY == 0 )
            {
                //
                // Master waits until RX data is ready
                //
            }
            rdata2 = McbspaRegs.DRR2.all;     // Read DRR2 first.
            
            //
            // Then read DRR1 to complete receiving of data
            //
            rdata1 = McbspaRegs.DRR1.all;
            
            if((rdata2 != sdata2)&&(rdata1 != sdata1))
            {
                error( );       // Check that correct data is received.
            }
            
            delay_loop();
            sdata1^=0xFFFF;
            sdata2^=0xFFFF;
            __asm("    nop");   // Good place for a breakpoint
        }
    }
    
    //
    // error - Some Useful local functions
    //
    void
    error(void)
    {
        __asm("     ESTOP0");  // test failed!! Stop!
        for (;;);
    }
    
    //
    // init_mcbsp_spi - 
    //
    void
    init_mcbsp_spi()
    {
        //
        // McBSP-A register settings
        //
        
        //
        // Reset FS generator, sample rate generator & transmitter
        //
        McbspaRegs.SPCR2.all=0x0000;
        
        //
        // Reset Receiver, Right justify word, Digital loopback dis.
        //
        McbspaRegs.SPCR1.all=0x0000;
        
        McbspaRegs.PCR.all=0x0F08;       // (CLKXM=CLKRM=FSXM=FSRM= 1, FSXP = 1)
        McbspaRegs.SPCR1.bit.DLB = 1;
        
        //
        // Together with CLKXP/CLKRP determines clocking scheme
        //
        McbspaRegs.SPCR1.bit.CLKSTP = 2;
        
        McbspaRegs.PCR.bit.CLKXP = 0;	// CPOL = 0, CPHA = 0 rising edge no delay
        McbspaRegs.PCR.bit.CLKRP = 0;
        
        //
        // FSX setup time 1 in master mode. 0 for slave mode (Receive)
        //
        McbspaRegs.RCR2.bit.RDATDLY=01;
        
        //
        // FSX setup time 1 in master mode. 0 for slave mode (Transmit)
        //
        McbspaRegs.XCR2.bit.XDATDLY=01;
    
        McbspaRegs.RCR1.bit.RWDLEN1=5;   // 32-bit word
        McbspaRegs.XCR1.bit.XWDLEN1=5;   // 32-bit word
    
        McbspaRegs.SRGR2.all=0x2000; 	 // CLKSM=1, FPER = 1 CLKG periods
        McbspaRegs.SRGR1.all= 0x0004;	 // Frame Width = 1 CLKG period, CLKGDV=16
    
        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
    }
    
    //
    // mcbsp_xmit - 
    //
    void
    mcbsp_xmit(int a, int b)
    {
        McbspaRegs.DXR2.all=b;
        McbspaRegs.DXR1.all=a;
    }
    
    //
    // End of File
    //
    
    

    Regards,

    Manoj