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.

AM5728: SPI transfer loop memory error

Part Number: AM5728
Other Parts Discussed in Thread: TMDSEVM572X

I am using the mcspiLoopbackApp example. I then wrap a loop around the 

SPI_transfer(gSpiHandle, &transaction);

The loop sends a SPI_transfer around 4000-5000 times before the following error occurs.

Exception at 0x0
EFR=0x2 NRP=0x0
Internal exception: IERR=0x1
Instruction fetch exception
ti.sysbios.family.c64p.Exception: line 265: E_exceptionMax: pc = 0x8405b2c8, sp = 0x84056796.
xdc.runtime.Error.raise: terminating execution

This seems like a memory error. I have attached my code so you can reproduce this issue.

MCSPI_Loopback_evmAM572x_c66_SPI_Error.zip

  • Hi Andre,

    Do you use TMDSEVM572X board?

    Do you use AM57x RTOS v6.01, PDK 1.0.16 and CCS v9.1.0?

    Can you also provide a screen shot of the error when this error occur?

    Can you also provide McSPI module register dump at the time this error occur?


    Regards,
    Pavel

  • Hey Pavel,

    Yes this is the TMBSEVM572X: https://www.ti.com/tool/TMDSEVM572X?utm_source=google&utm_medium=cpc&utm_campaign=epd-pro-sit-prodfolderdynamic-cpc-pf-google-wwe&utm_content=prodfolddynamic&ds_k=DYNAMIC+SEARCH+ADS&DCM=yes&gclid=Cj0KCQiA_rfvBRCPARIsANlV66Oz79m_kvWBlrBkB7wjMm14ScotSa-ejCS2COZuPncxVMgpWQus9dgaAj4REALw_wcB&gclsrc=aw.ds

    Versions of software:

    • AM57x RTOS: v6.01.00.08
    • PDK: 1.0.16
    • CCS: 9.1.0.00010

    Screenshot attached at time of error

    McSPI module register dump:

    MCSPI_HL_REV: 4030120B
    MCSPI_HL_HWINFO: 11
    MCSPI_HL_SYSCONFIG: 4
    MCSPI_REVISION: 2B
    MCSPI_SYSCONFIG: 308
    MCSPI_SYSSTATUS: 1
    MCSPI_IRQSTATUS: 0
    MCSPI_IRQENABLE: 0
    MCSPI_WAKEUPENABLE: 0
    MCSPI_SYST: 0
    MCSPI_MODULCTRL: 1
    MCSPI_CH0CONF: 200403FC
    MCSPI_CH1CONF: 60000
    MCSPI_CH2CONF: 60000
    MCSPI_CH3CONF: 60000
    MCSPI_CH0STAT: 0
    MCSPI_CH1STAT: 0
    MCSPI_CH2STAT: 0
    MCSPI_CH3STAT: 0
    MCSPI_CH0CTRL: 200
    MCSPI_CH1CTRL: 0
    MCSPI_CH2CTRL: 0
    MCSPI_CH3CTRL: 0
    MCSPI_TX0: 0
    MCSPI_TX1: 0
    MCSPI_TX2: 0
    MCSPI_TX3: 0
    MCSPI_RX0: 0
    MCSPI_RX1: 0
    MCSPI_RX2: 0
    MCSPI_RX3: 0
    MCSPI_XFERLEVEL: 0
    CTRL_CORE_PAD_SPI1_SCLK: C0000
    CTRL_CORE_PAD_SPI1_D1: C0000
    CTRL_CORE_PAD_SPI1_D0: C0000
    CTRL_CORE_PAD_SPI1_CS0: 60000
    CTRL_CORE_PAD_SPI1_CS1: 60000
    SPI3_SCLK: 90100
    SPI3_D1: 90100
    SPI3_D0: 90100
    SPI3_CS0: 90100
    SPI3_CS1: 5000E
    CM_L4PER_MCSPI1_CLKCTRL: 2
    CM_L4PER_MCSPI2_CLKCTRL: 2
    CM_L4PER_MCSPI3_CLKCTRL: 2
    CM_L4PER_MCSPI4_CLKCTRL: 2MCSPI_HL_REV: 4030120B
    

    Best Regards,

    Andre

  • Andre,

    Can you run this test on Cortex-A15 ARM core? I want to check if this issue is specific for C66x DSP core or not.

    You can also use common approach to debug DSP crash by examine the register dumps, any stack over flow, heap usage issue. There are some info on how to debug RTOS exception here:

    http://software-dl.ti.com/processor-sdk-rtos/esd/docs/latest/rtos/index_how_to_guides.html#exception-handling

    Regards,
    Pavel

  • I don't currently have it setup for the ARM core, but can work on running that. I added the exception-handling to my .cfg file as described:

    var Exception = xdc.useModule('ti.sysbios.family.c64p.Exception');
    Exception.enablePrint = true;

    This is what was printed out to the console:

    [C66xx_DSP1] A0=0x0 A1=0x0
    A2=0x0 A3=0x8
    A4=0x8404d660 A5=0x1000
    A6=0xbd A7=0xbf
    A8=0x84056f45 A9=0x84000fbc
    A10=0x18000a8 A11=0x1800048
    A12=0x1800040 A13=0x84043d88
    A14=0x840012ec A15=0x2
    A16=0x84056f18 A17=0x84056f02
    A18=0x84056eea A19=0x84056dd2
    A20=0x0 A21=0x0
    A22=0x84056d74 A23=0x84056d52
    A24=0x84056d35 A25=0xb1c0e6c0
    A26=0x91d1e6be A27=0x3a0b02c9
    A28=0x3 A29=0x84050660
    A30=0x84057b18 A31=0x0
    B0=0x400 B1=0x0
    B2=0x1 B3=0x840449ac
    B4=0x1f B5=0x0
    B6=0x0 B7=0x40
    B8=0x18000a8 B9=0x1800048
    B10=0x84000000 B11=0x40
    B12=0x84000000 B13=0x40
    B14=0x2 B15=0x8405668f
    B16=0x8405b338 B17=0x840489f0
    B18=0x84001260 B19=0x1e
    B20=0x84056de2 B21=0x1
    B22=0x84053364 B23=0x8405b340
    B24=0x1 B25=0x84039a38
    B26=0x8405b2c8 B27=0x2
    B28=0x84056701 B29=0x58b3533
    B30=0x84056726 B31=0xffef
    NTSR=0x8405b2c8
    ITSR=0x0
    IRP=0x0
    SSR=0xffffffff
    AMR=0xffffffff
    RILC=0x0
    ILC=0xfffffffe
    Exception at 0x0
    EFR=0x2 NRP=0x0
    Internal exception: IERR=0x1
    Instruction fetch exception
    ti.sysbios.family.c64p.Exception: line 265: E_exceptionMax: pc = 0x8405b2c8, sp = 0x84056796.
    xdc.runtime.Error.raise: terminating execution
    

    Does that provide any insight?

  • Are you able to run the code I provided on the DSP without error?

  • FYI: I was able to run the same code on the ARM processor without running into the same error.

  • I was unable to get the code working with the references you provided. Were you able to see the TI code I provided fail when trying to run it on the DSP? I am only taking the TI example directly and looping the SPI transfer multiple times. What would cause this to happen?

  • Hi Andre,

    I experimented with your code on an AM572x IDK. I found the code crashes as you observed on an AM572x EVM (I don't see the mcspiLoopbackApp example for the AM572x EVM is delivered in PRSDK, so I guess you created this on your own). Sometimes I observe the C66 exception, and other times I only see the while() loop stops after 4063 iterations.

    Next I simplified your code a bit by removing all the changes you applied to mcspiLoopbackApp except for those related to the while() loop. This is essentially the same as your example code, and SPI_open(), SPI_transfer() and SPI_close() are repeatedly executed in the while() loop. Even in this simplified case the c66 exception occurs after 4063 iterations.

    I've attached the .c file for the original example provided with PRSDK along with my modified code so you can see the changes I made.

    This seems like a bug to me. I'll discuss this internally with the development team and get back with you.

    Regards,
    Frank

     /*
     *  Copyright (C) 2015-2017 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.
     *
     */
     /**
     *  \file   mcspiLoopbackApp.c
     *
     *  \brief This file contains the application which demonstrates McSPI loopback
     *         which transfers some data pattern from data I/O signal & receives
     *         the data from same data I/O signal.
     *
     */
    
    /* ========================================================================== */
    /*                             Include Files                                  */
    /* ========================================================================== */
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    
    #include "stdint.h"
    #include <stdio.h>
    #include <ti/csl/example/utils/common/inc/app_utils.h>
    #include <ti/csl/soc.h>
    #include <ti/csl/hw_types.h>
    
    #include <ti/board/board.h>
    
    #include <ti/osal/osal.h>
    
    /* UART Header files */
    #include <ti/drv/uart/UART.h>
    
    /* SPI Header files */
    #include <ti/drv/spi/SPI.h>
    #include <ti/csl/csl_mcspi.h>
    #include <ti/drv/spi/soc/SPI_soc.h>
    #if defined SOC_AM335x
    #include "am335x_pinmux.h"
    #endif
    #if defined SOC_AM437x
    #include "am43xx_pinmux.h"
    #endif
    #if defined(SOC_AM335x) || defined(SOC_AM437x)
    #include "chipdb_defs.h"
    #endif
    
    /* ========================================================================== */
    /*                                 Macros                                     */
    /* ========================================================================== */
    
    #define McSPI_DATA_COUNT            50U // Data Count Transaction
    
    #if defined(SOC_AM571x) || defined (SOC_AM572x) || defined (SOC_AM574x)
    #define UART_INSTANCE 2
    #else
    #define UART_INSTANCE 0
    #endif
    
    #define MCSPI_INSTANCE 0
    
    /* ========================================================================== */
    /*                            Global Variables                                */
    /* ========================================================================== */
    uint8_t           gRxBuffer[McSPI_DATA_COUNT];
    uint8_t           gTxBuffer[McSPI_DATA_COUNT];
    
    UART_Handle gUartHandle;
    
    SPI_Handle gSpiHandle;
    
    /* UART parameters structure*/
    const UART_Params gUserParams = {
        UART_MODE_BLOCKING,     /* readMode */
        UART_MODE_BLOCKING,     /* writeMode */
        SemaphoreP_WAIT_FOREVER,/* readTimeout */
        SemaphoreP_WAIT_FOREVER,/* writeTimeout */
        NULL,                  /* readCallback */
        NULL,                 /* writeCallback */
        UART_RETURN_NEWLINE,  /* readReturnMode */
        UART_DATA_TEXT,       /* readDataMode */
        UART_DATA_TEXT,       /* writeDataMode */
        UART_ECHO_ON,         /* readEcho */
        115200,               /* baudRate */
        UART_LEN_8,           /* dataLength */
        UART_STOP_ONE,        /* stopBits */
        UART_PAR_NONE         /* parityType */
    };
    
    /* SPI parameters structure Master mode*/
    SPI_Params gSpiParams = {
        SPI_MODE_BLOCKING,  /* transferMode */
        SemaphoreP_WAIT_FOREVER,/* transferTimeout */
        NULL,               /* transferCallbackFxn */
        SPI_MASTER,         /* mode */
        1000000,            /* bitRate */
        8,                  /* dataSize */
        SPI_POL0_PHA0,      /* frameFormat */
        NULL                /* custom */
    };
    
    /* ========================================================================== */
    /*                          Function Declarations                             */
    /* ========================================================================== */
    static void McSPIInitializeBuffers(void);
    void padConfig_prcmEnable();
    void spi_test(UArg arg0, UArg arg1);
    static int32_t McSPIVerifyData(void);
    
    /* ========================================================================== */
    /*                          Function Definitions                              */
    /* ========================================================================== */
    void padConfig_prcmEnable()
    {
    #if defined (SOC_DRA72x) || (SOC_DRA75x) || defined (SOC_DRA78x)
        Board_initCfg boardCfg;
    
        boardCfg = BOARD_INIT_PINMUX_CONFIG |
            BOARD_INIT_MODULE_CLOCK;
    
        Board_init(boardCfg);
    #endif
        /* Loopback mode is not available for MCSPI. To test Loopback on McSPI,
         * Receive Bit is enabled on both Tx and Rx pins of McSPI
         */
    #if defined(SOC_AM571x) || defined (SOC_AM572x) || defined (SOC_AM574x)
        HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_UART2_CTSN, 0x00050002);
        HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_UART2_RTSN, 0x00010001);
        HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_SPI1_SCLK,0x000C0000);
        HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_SPI1_D1,0x000C0000);
        HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_SPI1_D0,0x000C0000);
        HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_SPI1_CS0,0x00060000);
    #if defined (_TMS320C6X)
        /*
         * AM57x DSP does not have a default Xbar connection for UART
         * interrupts, need to use a reserved IRQ Xbar instance for Xbar
         * interrupt configuration
         */
         /* Use reserved XBAR_INST_DSP1_IRQ_34 */
        CSL_xbarIrqConfigure(CSL_XBAR_IRQ_CPU_ID_DSP1, CSL_XBAR_INST_DSP1_IRQ_34, CSL_XBAR_UART3_IRQ);
    #endif
    #if defined (SOC_AM572x) || defined(SOC_AM574x)
        HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_SPI1_CS1,0x00060000);
    #endif
    #endif
    #if defined (SOC_TDA2XX) || defined(SOC_TDA2PX) || defined (SOC_TDA2EX)
        /*Pad configurations */
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_UART1_RXD,0x00040000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_UART1_TXD,0x00040000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_SPI1_SCLK,0x000C0000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_SPI1_D1,0x000C0000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_SPI1_D0,0x000C0000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_SPI1_CS0,0x00060000);
    #if defined (SOC_TDA2XX) || defined(SOC_TDA2PX)
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_SPI1_CS1,0x00060000);
    #endif
        /* IPU1 Crossbar */
        CSL_xbarIrqConfigure(CSL_XBAR_IRQ_CPU_ID_IPU1, CSL_XBAR_INST_IPU1_IRQ_44, CSL_XBAR_UART1_IRQ);
    #endif
    #if defined(SOC_TDA3XX)
        /*MCSPI1 prcm*/
        HW_WR_REG32(SOC_L4PER_CM_CORE_BASE + CM_L4PER_MCSPI1_CLKCTRL, 0x02);
        while (HW_RD_REG32(SOC_L4PER_CM_CORE_BASE + CM_L4PER_MCSPI1_CLKCTRL) !=
                0x02U)
            {
                ;
            }
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_IO_UART1_RXD,0x00040000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_IO_UART1_TXD,0x00000000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_IO_SPI1_CS0,0x00040000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_IO_SPI1_SCLK,0x00040000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_IO_SPI1_D0,0x00040000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_IO_SPI1_D1,0x00040000);
    
        /* IPU1 crossbar */
    #if defined (__TI_ARM_V7M4__)
        CSL_xbarIrqConfigure(CSL_XBAR_IRQ_CPU_ID_IPU1, CSL_XBAR_INST_IPU1_IRQ_44, CSL_XBAR_UART1_IRQ);
    #elif defined(_TMS320C6X)
        CSL_xbarIrqConfigure(CSL_XBAR_IRQ_CPU_ID_DSP1, CSL_XBAR_INST_DSP1_IRQ_44, CSL_XBAR_UART1_IRQ);
    #endif
    #endif
    #if defined(SOC_AM335x) || defined(SOC_AM437x)
        uint32_t ctrlModBase;
    
        /* UART */
        ctrlModBase = CHIPDBBaseAddress(CHIPDB_MOD_ID_CONTROL_MODULE, UART_INSTANCE);
        HW_WR_REG32(ctrlModBase+PIN_UART0_TXD, PIN_MODE(0));
        HW_WR_REG32(ctrlModBase+PIN_UART0_RXD, PIN_MODE(0) | PIN_RX_ACTIVE);
        /* SPI0 */
        ctrlModBase = CHIPDBBaseAddress(CHIPDB_MOD_ID_CONTROL_MODULE, MCSPI_INSTANCE);
        HW_WR_REG32(ctrlModBase+PIN_SPI0_SCLK, PIN_MODE(0) | PIN_RX_ACTIVE);
        HW_WR_REG32(ctrlModBase+PIN_SPI0_D0, PIN_MODE(0) | PIN_RX_ACTIVE);
        HW_WR_REG32(ctrlModBase+PIN_SPI0_D1, PIN_MODE(0) | PIN_RX_ACTIVE);
        HW_WR_REG32(ctrlModBase+PIN_SPI0_CS0, PIN_MODE(0) | PIN_RX_ACTIVE);
    #endif
    }
    
    void spi_initConfig(void)
    {
        SPI_v1_HWAttrs spi_cfg;
    
        /* Get the default UART init configurations */
        SPI_socGetInitCfg(MCSPI_INSTANCE, &spi_cfg);
    
        /* Modify the default SPI configurations if necessary */
        spi_cfg.chnCfg[spi_cfg.chNum].dataLineCommMode = MCSPI_DATA_LINE_COMM_MODE_4;
    
        /* Set the default UART init configurations */
        SPI_socSetInitCfg(MCSPI_INSTANCE, &spi_cfg);
    }
    
    int main(void)
    {
        Task_Handle task;
        Error_Block eb;
    
        Error_init(&eb);
    
        task = Task_create(spi_test, NULL, &eb);
        if (task == NULL) {
            System_printf("Task_create() failed!\n");
            BIOS_exit(0);
        }
    
        /* Start BIOS */
        BIOS_start();
        return (0);
    }
    
    void spi_test(UArg arg0, UArg arg1)
    {
        UART_Params      params;
        int32_t retVal;
        SPI_Transaction transaction;
    #if defined(SOC_AM335x) || defined(SOC_AM437x) || defined(SOC_AM571x) || defined (SOC_AM572x) || defined (SOC_AM574x)
        Board_initCfg boardCfg;
    #endif
    
        char echoPrompt[] = "\nMcSPI Internal Loopback test app started";
        char echoPrompt1[] = "\nThe Mode of transfer is Interrupt Mode";
        char echoPrompt2[] = "\nMcSPI Data Transmission is successful";
        char echoPrompt3[] = "\nMcSPI Data Transmission is Failed";
    
    #if defined(SOC_AM335x) || defined(SOC_AM437x) || defined(SOC_AM571x) || defined (SOC_AM572x) || defined (SOC_AM574x)
        boardCfg =   BOARD_INIT_MODULE_CLOCK;
        Board_init(boardCfg);
    #endif
    /*Pad configuration and PRCM enable*/
        padConfig_prcmEnable();
    
    #if defined(SOC_TDA3XX)
        AppUtils_defaultInit();
    #endif
        /* Set the UART Parameters */
        UART_init();
        params = gUserParams;
    
        gUartHandle = UART_open(UART_INSTANCE, &params);
        if(gUartHandle == NULL)
        {
            printf("\nError opening UART driver\n");
        }
    
        UART_write(gUartHandle,echoPrompt,sizeof(echoPrompt));
        UART_write(gUartHandle,echoPrompt1,sizeof(echoPrompt1));
    
        /* Modify the default SPI configurations if necessary */
        spi_initConfig();
    
        /* Do the necessary set up configurations for McSPI.*/
        SPI_init();
    
        /* Open MCSPI instance 1 driver */
        gSpiHandle = SPI_open(MCSPI_INSTANCE, &gSpiParams);
        if(gSpiHandle == NULL)
        {
            printf("\nError opening MCSPI driver\n");
        }
    
        McSPIInitializeBuffers();
    
        transaction.count = McSPI_DATA_COUNT;
        transaction.txBuf = gTxBuffer;
        transaction.rxBuf = gRxBuffer;
        SPI_transfer(gSpiHandle, &transaction);
    
        retVal = McSPIVerifyData();
    
        if(retVal != 0)
        {
            UART_write(gUartHandle,echoPrompt3,sizeof(echoPrompt3));
        }
        else
        {
            UART_write(gUartHandle,echoPrompt2,sizeof(echoPrompt2));
        }
    
        SPI_close(gSpiHandle);
    }
    
    static void McSPIInitializeBuffers(void)
    {
        uint32_t index = 0;
    
        for (index = 0; index < McSPI_DATA_COUNT; index++)
        {
            /* Initialize the gTxBuffer McSPI1 with a known pattern of data */
                gTxBuffer[index] = index;
            /* Initialize the gRxBuffer McSPI1 with 0 */
            gRxBuffer[index] = (uint32_t) 0;
        }
    }
    
    static int32_t McSPIVerifyData(void)
    {
        uint32_t index = 0;
        int32_t retVal = 0;
    
        for (index = 0; index < McSPI_DATA_COUNT; index++)
        {
            if(gRxBuffer[index] !=  gTxBuffer[index])
            {
                retVal = -1;
                break;
            }
        }
    
        return retVal;
    }
    /********************************* End Of File ******************************/
    

     /*
     *  Copyright (C) 2015-2017 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.
     *
     */
     /**
     *  \file   mcspiLoopbackApp.c
     *
     *  \brief This file contains the application which demonstrates McSPI loopback
     *         which transfers some data pattern from data I/O signal & receives
     *         the data from same data I/O signal.
     *
     */
    
    /* ========================================================================== */
    /*                             Include Files                                  */
    /* ========================================================================== */
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    
    #include "stdint.h"
    #include <stdio.h>
    #include <ti/csl/example/utils/common/inc/app_utils.h>
    #include <ti/csl/soc.h>
    #include <ti/csl/hw_types.h>
    
    #include <ti/board/board.h>
    
    #include <ti/osal/osal.h>
    
    /* UART Header files */
    #include <ti/drv/uart/UART.h>
    
    /* SPI Header files */
    #include <ti/drv/spi/SPI.h>
    #include <ti/csl/csl_mcspi.h>
    #include <ti/drv/spi/soc/SPI_soc.h>
    #if defined SOC_AM335x
    #include "am335x_pinmux.h"
    #endif
    #if defined SOC_AM437x
    #include "am43xx_pinmux.h"
    #endif
    #if defined(SOC_AM335x) || defined(SOC_AM437x)
    #include "chipdb_defs.h"
    #endif
    
    /* ========================================================================== */
    /*                                 Macros                                     */
    /* ========================================================================== */
    
    #define McSPI_DATA_COUNT            50U // Data Count Transaction
    
    #if defined(SOC_AM571x) || defined (SOC_AM572x) || defined (SOC_AM574x)
    #define UART_INSTANCE 2
    #else
    #define UART_INSTANCE 0
    #endif
    
    #define MCSPI_INSTANCE 0
    
    /* ========================================================================== */
    /*                            Global Variables                                */
    /* ========================================================================== */
    uint8_t           gRxBuffer[McSPI_DATA_COUNT];
    uint8_t           gTxBuffer[McSPI_DATA_COUNT];
    
    UART_Handle gUartHandle;
    
    SPI_Handle gSpiHandle;
    
    /* UART parameters structure*/
    const UART_Params gUserParams = {
        UART_MODE_BLOCKING,     /* readMode */
        UART_MODE_BLOCKING,     /* writeMode */
        SemaphoreP_WAIT_FOREVER,/* readTimeout */
        SemaphoreP_WAIT_FOREVER,/* writeTimeout */
        NULL,                  /* readCallback */
        NULL,                 /* writeCallback */
        UART_RETURN_NEWLINE,  /* readReturnMode */
        UART_DATA_TEXT,       /* readDataMode */
        UART_DATA_TEXT,       /* writeDataMode */
        UART_ECHO_ON,         /* readEcho */
        115200,               /* baudRate */
        UART_LEN_8,           /* dataLength */
        UART_STOP_ONE,        /* stopBits */
        UART_PAR_NONE         /* parityType */
    };
    
    /* SPI parameters structure Master mode*/
    SPI_Params gSpiParams = {
        SPI_MODE_BLOCKING,  /* transferMode */
        SemaphoreP_WAIT_FOREVER,/* transferTimeout */
        NULL,               /* transferCallbackFxn */
        SPI_MASTER,         /* mode */
        1000000,            /* bitRate */
        8,                  /* dataSize */
        SPI_POL0_PHA0,      /* frameFormat */
        NULL                /* custom */
    };
    
    /* ========================================================================== */
    /*                          Function Declarations                             */
    /* ========================================================================== */
    static void McSPIInitializeBuffers(void);
    void padConfig_prcmEnable();
    void spi_test(UArg arg0, UArg arg1);
    static int32_t McSPIVerifyData(void);
    
    // FL: add
    void delay(unsigned int delayValue);
    
    /* ========================================================================== */
    /*                          Function Definitions                              */
    /* ========================================================================== */
    void padConfig_prcmEnable()
    {
    #if defined (SOC_DRA72x) || (SOC_DRA75x) || defined (SOC_DRA78x)
        Board_initCfg boardCfg;
    
        boardCfg = BOARD_INIT_PINMUX_CONFIG |
            BOARD_INIT_MODULE_CLOCK;
    
        Board_init(boardCfg);
    #endif
        /* Loopback mode is not available for MCSPI. To test Loopback on McSPI,
         * Receive Bit is enabled on both Tx and Rx pins of McSPI
         */
    #if defined(SOC_AM571x) || defined (SOC_AM572x) || defined (SOC_AM574x)
        HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_UART2_CTSN, 0x00050002);
        HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_UART2_RTSN, 0x00010001);
        HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_SPI1_SCLK,0x000C0000);
        HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_SPI1_D1,0x000C0000);
        HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_SPI1_D0,0x000C0000);
        HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_SPI1_CS0,0x00060000);
    #if defined (_TMS320C6X)
        /*
         * AM57x DSP does not have a default Xbar connection for UART
         * interrupts, need to use a reserved IRQ Xbar instance for Xbar
         * interrupt configuration
         */
         /* Use reserved XBAR_INST_DSP1_IRQ_34 */
        CSL_xbarIrqConfigure(CSL_XBAR_IRQ_CPU_ID_DSP1, CSL_XBAR_INST_DSP1_IRQ_34, CSL_XBAR_UART3_IRQ);
    #endif
    #if defined (SOC_AM572x) || defined(SOC_AM574x)
        HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_SPI1_CS1,0x00060000);
    #endif
    #endif
    #if defined (SOC_TDA2XX) || defined(SOC_TDA2PX) || defined (SOC_TDA2EX)
        /*Pad configurations */
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_UART1_RXD,0x00040000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_UART1_TXD,0x00040000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_SPI1_SCLK,0x000C0000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_SPI1_D1,0x000C0000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_SPI1_D0,0x000C0000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_SPI1_CS0,0x00060000);
    #if defined (SOC_TDA2XX) || defined(SOC_TDA2PX)
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_SPI1_CS1,0x00060000);
    #endif
        /* IPU1 Crossbar */
        CSL_xbarIrqConfigure(CSL_XBAR_IRQ_CPU_ID_IPU1, CSL_XBAR_INST_IPU1_IRQ_44, CSL_XBAR_UART1_IRQ);
    #endif
    #if defined(SOC_TDA3XX)
        /*MCSPI1 prcm*/
        HW_WR_REG32(SOC_L4PER_CM_CORE_BASE + CM_L4PER_MCSPI1_CLKCTRL, 0x02);
        while (HW_RD_REG32(SOC_L4PER_CM_CORE_BASE + CM_L4PER_MCSPI1_CLKCTRL) !=
                0x02U)
            {
                ;
            }
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_IO_UART1_RXD,0x00040000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_IO_UART1_TXD,0x00000000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_IO_SPI1_CS0,0x00040000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_IO_SPI1_SCLK,0x00040000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_IO_SPI1_D0,0x00040000);
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_IO_SPI1_D1,0x00040000);
    
        /* IPU1 crossbar */
    #if defined (__TI_ARM_V7M4__)
        CSL_xbarIrqConfigure(CSL_XBAR_IRQ_CPU_ID_IPU1, CSL_XBAR_INST_IPU1_IRQ_44, CSL_XBAR_UART1_IRQ);
    #elif defined(_TMS320C6X)
        CSL_xbarIrqConfigure(CSL_XBAR_IRQ_CPU_ID_DSP1, CSL_XBAR_INST_DSP1_IRQ_44, CSL_XBAR_UART1_IRQ);
    #endif
    #endif
    #if defined(SOC_AM335x) || defined(SOC_AM437x)
        uint32_t ctrlModBase;
    
        /* UART */
        ctrlModBase = CHIPDBBaseAddress(CHIPDB_MOD_ID_CONTROL_MODULE, UART_INSTANCE);
        HW_WR_REG32(ctrlModBase+PIN_UART0_TXD, PIN_MODE(0));
        HW_WR_REG32(ctrlModBase+PIN_UART0_RXD, PIN_MODE(0) | PIN_RX_ACTIVE);
        /* SPI0 */
        ctrlModBase = CHIPDBBaseAddress(CHIPDB_MOD_ID_CONTROL_MODULE, MCSPI_INSTANCE);
        HW_WR_REG32(ctrlModBase+PIN_SPI0_SCLK, PIN_MODE(0) | PIN_RX_ACTIVE);
        HW_WR_REG32(ctrlModBase+PIN_SPI0_D0, PIN_MODE(0) | PIN_RX_ACTIVE);
        HW_WR_REG32(ctrlModBase+PIN_SPI0_D1, PIN_MODE(0) | PIN_RX_ACTIVE);
        HW_WR_REG32(ctrlModBase+PIN_SPI0_CS0, PIN_MODE(0) | PIN_RX_ACTIVE);
    #endif
    }
    
    void spi_initConfig(void)
    {
        SPI_v1_HWAttrs spi_cfg;
    
        /* Get the default UART init configurations */
        SPI_socGetInitCfg(MCSPI_INSTANCE, &spi_cfg);
    
        /* Modify the default SPI configurations if necessary */
        spi_cfg.chnCfg[spi_cfg.chNum].dataLineCommMode = MCSPI_DATA_LINE_COMM_MODE_4;
    
        /* Set the default UART init configurations */
        SPI_socSetInitCfg(MCSPI_INSTANCE, &spi_cfg);
    }
    
    uint32_t gSpiXferCnt = 0; // FL: add, formerly 'a'
    
    int main(void)
    {
        Task_Handle task;
        Error_Block eb;
    
        Error_init(&eb);
    
        task = Task_create(spi_test, NULL, &eb);
        if (task == NULL) {
            System_printf("Task_create() failed!\n");
            BIOS_exit(0);
        }
    
        /* Start BIOS */
        BIOS_start();
        return (0);
    }
    
    void spi_test(UArg arg0, UArg arg1)
    {
        UART_Params      params;
        int32_t retVal;
        SPI_Transaction transaction;
    #if defined(SOC_AM335x) || defined(SOC_AM437x) || defined(SOC_AM571x) || defined (SOC_AM572x) || defined (SOC_AM574x)
        Board_initCfg boardCfg;
    #endif
    
        char echoPrompt[] = "\nMcSPI Internal Loopback test app started";
        char echoPrompt1[] = "\nThe Mode of transfer is Interrupt Mode";
        char echoPrompt2[] = "\nMcSPI Data Transmission is successful";
        char echoPrompt3[] = "\nMcSPI Data Transmission is Failed";
    
    #if defined(SOC_AM335x) || defined(SOC_AM437x) || defined(SOC_AM571x) || defined (SOC_AM572x) || defined (SOC_AM574x)
        boardCfg =   BOARD_INIT_MODULE_CLOCK;
        Board_init(boardCfg);
    #endif
    /*Pad configuration and PRCM enable*/
        padConfig_prcmEnable();
    
    #if defined(SOC_TDA3XX)
        AppUtils_defaultInit();
    #endif
        /* Set the UART Parameters */
        UART_init();
        params = gUserParams;
    
        gUartHandle = UART_open(UART_INSTANCE, &params);
        if(gUartHandle == NULL)
        {
            printf("\nError opening UART driver\n");
        }
    
        UART_write(gUartHandle,echoPrompt,sizeof(echoPrompt));
        UART_write(gUartHandle,echoPrompt1,sizeof(echoPrompt1));
    
        /* Modify the default SPI configurations if necessary */
        spi_initConfig();
    
        /* Do the necessary set up configurations for McSPI.*/
        SPI_init();
    
        /**********************************************
         * Begin SPI loop: causes the SPI transfer to fail
         ***********************************************/
        while(1) 
        {
            /* Open MCSPI instance 1 driver */
            gSpiHandle = SPI_open(MCSPI_INSTANCE, &gSpiParams);
            if(gSpiHandle == NULL)
            {
                printf("\nError opening MCSPI driver\n");
            }
    
            McSPIInitializeBuffers();
    
            transaction.count = McSPI_DATA_COUNT;
            transaction.txBuf = gTxBuffer;
            transaction.rxBuf = gRxBuffer;
    
            gSpiXferCnt++;
            SPI_transfer(gSpiHandle, &transaction);
            //delay(100);
    
    
        /******************************************************************
            Verify Data
         ******************************************************************/
        //    retVal = McSPIVerifyData();
        //
        //    if(retVal != 0)
        //    {
        //        UART_write(gUartHandle,echoPrompt3,sizeof(echoPrompt3));
        //    }
        //    else
        //    {
        //        UART_write(gUartHandle,echoPrompt2,sizeof(echoPrompt2));
        //    }
    
            SPI_close(gSpiHandle);
        }
    
        /**********************************************
         * End SPI loop
         ***********************************************/
    }
    
    static void McSPIInitializeBuffers(void)
    {
        uint32_t index = 0;
    
        for (index = 0; index < McSPI_DATA_COUNT; index++)
        {
            /* Initialize the gTxBuffer McSPI1 with a known pattern of data */
                gTxBuffer[index] = index;
            /* Initialize the gRxBuffer McSPI1 with 0 */
            gRxBuffer[index] = (uint32_t) 0;
        }
    }
    
    static int32_t McSPIVerifyData(void)
    {
        uint32_t index = 0;
        int32_t retVal = 0;
    
        for (index = 0; index < McSPI_DATA_COUNT; index++)
        {
            if(gRxBuffer[index] !=  gTxBuffer[index])
            {
                retVal = -1;
                break;
            }
        }
    
        return retVal;
    }
    
    
    
    /*
     *  ======== Delay function ========
     */
    void delay(unsigned int delayValue)
    {
        volatile uint32_t delay1 = delayValue * 1000;
        while (delay1--) ;
    }
    /********************************* End Of File ******************************/
    

  • Thanks for verifying this Frank! I look forward to hearing the development team's response.

  • Andre,

    I've filed a bug with the development team. I'll keep you posted.

    Regards,
    Frank

  • Hi Andre,

    Is this issue a gating item for your development? Is it urgent for this to be resolved?

    Regards,
    Frank

  • Hey Frank,

    Yes, this is a critical need for us and is currently halting our production development.

    Best Regards,

    Andre

  • Hi Andre,

    Thanks for the feedback, I'll inform the development team concerning the urgency.

    Regards,
    Frank

  • Hi Andre,

    Can you please try moving the SPI_init() function from spi_task() to main()?

    Regards,
    Frank