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.

C6727 Master SPI to Slave SPI 4-pin SCS connection Polarity=1 shifts 1 or 2 bits Slave received data with SPI slave boot mode configuration: Phase = 0, Polarity = 1 and wordlength = 16bits.

Hi,

I have two C6727B DSPs: Master and Slave in the system. I have to use SPI 0 Slave boot mode load from the Master DSP for the Slave DSP. SPI has to be set 4-pin (0x0E01), Phase = 0, Polarity = 1 and wordlength = 16bits.
So first I created two simple Master and Slave DSP projects for testing SPI 0 communication. In the SPI test the Master DSP/SPI sends/reads back data to/from the Slave DSP and the Slave DSP/SPI receives/sends back data from/to the Master DSP. I used TI’s csl_C672x\dsp\examples\c6727\spi project as base for creating the tests.
In the SPI test I found that the Slave DSP received from the Master DSP 1 or 2 bits shifted data: 0x7878 instead of expected 0xF0F0 with SPI configured: Phase = 0, Polarity = 1 (CSL_SPI_POLARITY_INACTIVEHI) and wordlength = 16bits. But the SPI test ran fine with Polarity = 0 (CSL_SPI_POLARITY_INACTIVELO).
Internal Master SPI loopback in fine with Polarity = 1 or 0;

What could be the problem? ... DSP?

I have the following set up:
CCS v 4.2.0;
CSL 3.00.09;
Two DSP Weuffen C6727 EVM with SPI 0 connected;


I put below my Master/Slave SPI test project source code so that you can reproduce my problem:

Spi_example.h and  Spi_example.c files.


Spi_example.h file:

#ifndef _SPI_EXAMPLE_H_
#define _SPI_EXAMPLE_H_

#ifdef __cplusplus
extern "C"
{
#endif

#include <csl_pllc.h>
#include <csl_spi.h>
#include <string.h>
#include <stdio.h>

/*
 * For every error the error count variable is increased. So count will be
 * zero when there is no error.
 */
#define SPI_TEST_PASSED             0

/*
 * The data to be transmitted through SPI
 */
#define SPI_TX_DATA                    0xF0F0

#define SPI_CHK_RX_MASK                0x80
#define SPI_RX_FLG_SET                0x80

#define SPI_DATA_FMT_CHARLEN_16BIT    0x10

#define SPI_PINCTRL_SPIFUNC_4PIN    0x0E01

#define SPI_PLLC_DIV_RATIO            0x001u

/*
 * =============================================================================
 *  @func   spi_csl_example_test
 *
 *  @desc
 *     This is the test routine which transmit and verify data in loop back mode
 *
 *  @arg
 *      NONE
 * 
 *  @return
 *      NONE
 * =============================================================================
*/
extern void spi_csl_example_test (
    void
);

/*
 * =============================================================================
 *  @func   spi_error_exit
 *
 *  @desc
 *     This calls the module close function in case of error
 *
 *  @arg
 *      NONE
 * 
 *  @return
 *      NONE
 * =============================================================================
 */
extern void spi_error_exit (
    void
);

#ifdef __cplusplus
}
#endif


#endif        /* _SPI_EXAMPLE_H_ */

 

Spi_example.c file:

 

#define USE_DSP_WEUFFEN_EVM

#include "Spi_example.h"
#ifdef USE_DSP_WEUFFEN_EVM
#include "sysbasetypes.h"
#include "c6727dsk.h"
#endif


#define DSP_NUM  (1)    // DSP 1 is Master DSP 2 is Slave


/* Handle for the SPI instance */
CSL_SpiHandle            hSpi;

/* SPI data declarations */
CSL_SpiCptData           RxData;

CSL_SpiHwSetup           SpihwSetup;
//Sets up the a formatting for an outgoing word
//This object is used to set up or get the setup of the format registers in Spi
CSL_SpiHwSetupPriFmt     priFmt0, priFmt1, priFmt2, priFmt3;                 

//Sets up the parameters that are needed by multi-buffer as well as compatibility modes
//This objetc is used to set up or get the setup of parameters that are needed by multi-buffer as
//well as compatibility modes
CSL_SpiHwSetupGen        spiGen = CSL_SPI_HWSETUP_GEN_DEFAULTS;
//Sets up the parameters to be setup in priority mode
//This object is used to setup or get the setup of the parameters to be setup in priority mode
CSL_SpiHwSetupPri        spiPri = CSL_SPI_HWSETUP_PRI_DEFAULTS;
//Sets up the Spi for compatibility mode
//This structure is used to setup or get the setup of Spi in comaptibility mode
CSL_SpiHwSetupCpt        spiCpt = CSL_SPI_HWSETUP_CPT_DEFAULTS;
//Sets up the properties if the pins of Spi
//This object is used to setup or get the setup of the pins in Spi
//CSL_SpiHwSetupPins       spiPins = CSL_SPI_HWSETUP_PINS_DEFAULTS;
CSL_SpiHwSetupPins       spiPins;

/* Variable to count the test failure */
Uint32                   spiTestFail = SPI_TEST_PASSED;
Uint32                   nBlocks = 50;

/*
 * =============================================================================
 *  @func   main
 *
 *  @desc
 *     This is the test main
 *
 *  @arg
 *      NONE
 * 
 *  @return
 *      NONE
 * =============================================================================
*/
void
main (
    void
)
{
    CSL_PllcHandle           hPllc;
    CSL_Status               status;
    CSL_PllcObj              pllcObj;
    CSL_PllcHwSetup          hwSetup;
    int i;
    int nRuns = 1;
   
    #ifdef USE_DSP_WEUFFEN_EVM
    /* Set HPI to multiplexed 16Bit (C6713 compatible) */
    InitHPI();

    /* Init the GPIO pins for controling the address lines of the GAL and the FLASH */
    InitGPIO();

    /* Init the external memory interface */
    InitEmif();
   
    CPLD_SetLEDs(CPLD_ALL_LEDS);
    #endif
   
    /* Enable use of CSL */
    CSL_sysInit();
   
    #if 0
    /* Intialize PLLC module */
    status = CSL_pllcInit (NULL);

    /* Intialize the PLLC obj structure to zero */
    memset (&pllcObj, 0, sizeof (CSL_PllcObj));

    /* Get handle for PLLC Module */
    hPllc = CSL_pllcOpen (&pllcObj, CSL_PLLC, NULL, &status);
    if ((status != CSL_SOK) || (hPllc == NULL)) {
        spiTestFail++;
        printf ("SPI: Opening PLLC instance... Failed.\n");
        return;
    }
    else {
        printf ("SPI: Opening PLLC instance... Passed.\n");
    }

    /*
     * Put PLLC in By pass Mode
     * Enable divider 2
     * divider 2 ratio set to divide by 2
     */
    hwSetup.pllcMode = CSL_PLLC_BYPASS;
    hwSetup.div2Enable.divEnable = CSL_PLLC_PLLDIV_ENABLE;
    hwSetup.div2Enable.pllDivRatio = SPI_PLLC_DIV_RATIO;

    /* pllc setup */
    status = CSL_pllcHwSetup (hPllc, &hwSetup);
    if (status != CSL_SOK) {
        spiTestFail++;
        printf ("SPI: PLLC Hardware setup ... Failed.\n");
        return;
    }
    else {
        printf ("SPI: PLLC Hardware setup ... Passed.\n");
    }

    /* Close PLLC module */
    status = CSL_pllcClose (hPllc);
    if (status != CSL_SOK) {
        spiTestFail++;
        printf ("SPI: PLLC Close instance ... Failed.\n");
        return;
    }
    else {
        printf ("SPI: PLLC Close instance ... Passed.\n");
    }
    #endif

    /* Perform the SPI Loop Back Test */
    for (i=0; i<nRuns; i++)
    {
        spi_csl_example_test ();

        /* Check for errors */
        if (spiTestFail == SPI_TEST_PASSED) {
            printf ("\nCSL SPI example Test %d PASSED \n",i);
        }
        else {
            printf ("\nCSL SPI example Test %d FAILED \n",i);
        }
    }
    return;
}

/*
 * =============================================================================
 *  @func   spi_csl_example_test
 *
 *  @desc
 *     This is the test routine which transmit and verify data in loop back mode
 *
 *  @arg
 *      NONE
 * 
 *  @return
 *      NONE
 * =============================================================================
*/
void
spi_csl_example_test (
    void
)
{
    CSL_SpiObj               spiObj;
    CSL_Status               status;
    Uint16                   TxData = SPI_TX_DATA;
    Uint8                    flagStatus = 0;
    int                      i;  
   
    /* Clear local data structures */
    memset (&spiObj, 0, sizeof (CSL_SpiObj));
    memset (&SpihwSetup, 0, sizeof (SpihwSetup));
    memset (&spiPins, 0, sizeof (spiPins));
    memset (&priFmt0, 0, sizeof (priFmt0));
    memset (&priFmt1, 0, sizeof (priFmt1));
    memset (&priFmt2, 0, sizeof (priFmt2));  
    memset (&priFmt3, 0, sizeof (priFmt3));    
   
    /* Initialize SPI module */
    status = CSL_spiInit (NULL);
    if (status != CSL_SOK) {
        spiTestFail++;
        printf ("SPI: Initialization... Failed.\n");
        printf ("\tReason: CSL_spiInit failed. [status = 0x%x].\n", status);
        return;
    }
    else {
        printf ("SPI: Initialization... Passed.\n");
    }

    hSpi = CSL_spiOpen (&spiObj, CSL_SPI_0, NULL, &status);
    if ((status != CSL_SOK) || (hSpi == NULL)) {
        spiTestFail++;
        printf ("SPI: Opening instance... Failed.\n");
        printf
            ("\tReason: Error opening the instance. [status = 0x%x, hSpi = 0x%x]\n",
            status, hSpi);
        return;
    }
    else {
        printf ("SPI: Opening instance... Passed.\n");
    }

    /* Reset SPI */
    status = CSL_spiHwControl (hSpi, CSL_SPI_CMD_PRI_RESET, NULL);
    if (status != CSL_SOK) {
        spiTestFail++;
        printf ("SPI: CSL_spiHwControl - CSL_SPI_CMD_RESET... Failed.\n");
        printf ("\tReason: Error while resetting SPI. [status = 0x%x]\n",
            status);
        spi_error_exit ();
        return;
    }
    else {
        printf ("SPI: CSL_spiHwControl - CSL_SPI_CMD_RESET... Passed.\n");
    }

    /* Set SIMO & SOMI to Functional Pins */
    spiPins.func = SPI_PINCTRL_SPIFUNC_4PIN;
    /* Intialize the SPI hardware setpu structure */
    spiPri.fmt[0] = &priFmt0;
    spiPri.fmt[1] = &priFmt1;
    spiPri.fmt[2] = &priFmt2;
    spiPri.fmt[3] = &priFmt3;
    SpihwSetup.genPtr = &spiGen;
    SpihwSetup.priPtr = &spiPri;
    SpihwSetup.cptPtr = &spiCpt;
    SpihwSetup.pinsPtr = &spiPins;

    /* Set SPI to Master mode */
    #if DSP_NUM == 2
    SpihwSetup.genPtr->opMode = CSL_SPI_OPMOD_SLAVE;
    #else
    SpihwSetup.genPtr->opMode = CSL_SPI_OPMOD_MASTER;
    #endif

    /* set char lenth to 16 bit */
    priFmt0.charLen = priFmt1.charLen = priFmt2.charLen = priFmt3.charLen = SPI_DATA_FMT_CHARLEN_16BIT;

    /* set shift direction to LSB first */
    //priFmt0.shiftDir = priFmt1.shiftDir = priFmt2.shiftDir = priFmt3.shiftDir = CSL_SPI_SHDIR_LSBFIRST;
    priFmt0.shiftDir = priFmt1.shiftDir = priFmt2.shiftDir = priFmt3.shiftDir = CSL_SPI_SHDIR_MSBFIRST;

    //priFmt0.preScale = 7;
    priFmt0.preScale = priFmt1.preScale = priFmt2.preScale = priFmt3.preScale = 30;
   
    //priFmt0.polarity = priFmt1.polarity = priFmt2.polarity = priFmt3.polarity = CSL_SPI_POLARITY_INACTIVELO;
    priFmt0.polarity = priFmt1.polarity = priFmt2.polarity = priFmt3.polarity = CSL_SPI_POLARITY_INACTIVEHI;
    priFmt0.phase = priFmt1.phase = priFmt2.phase = priFmt3.phase = CSL_SPI_PHASE_IN;
   
    // Set Chip-select-active-to-transmit-start-delay
    SpihwSetup.genPtr->c2tDelay = 31;   //priFmt3.preScale;
    // Set Transmit-end-to-chip-select-inactive-delay
    SpihwSetup.genPtr->t2cDelay = 31;   //priFmt3.preScale;   
   
    SpihwSetup.genPtr->enaHiZ = CSL_SPI_ENAHIZ_YES;
 
    status = CSL_spiHwSetup (hSpi, &SpihwSetup);
     if (status != CSL_SOK) {
        spiTestFail++;
        printf ("SPI: HW Setup... Failed.\n");
        printf ("\tReason: Error while SPI Hw Setup. [status = 0x%x]\n",
            status);
        spi_error_exit ();
        return;
    }
    else {
        printf ("SPI: HW Setup... Passed.\n");
    }

    /* set SPI to loopback mode */
    //CSL_FINST (hSpi->regs->SPIGCR1, SPI_SPIGCR1_LOOPBACK, ENABLE);

    /* Data Word 0 Selected */
    CSL_spiHwControl (hSpi, CSL_SPI_CMD_CPT_WRITE1, 0);

    /* Reset SPI */
    status = CSL_spiHwControl (hSpi, CSL_SPI_CMD_PRI_RESET, NULL);
    if (status != CSL_SOK) {
        spiTestFail++;
        printf ("SPI: CSL_spiHwControl - CSL_SPI_CMD_RESET... Failed.\n");
        printf ("\tReason: Error while resetting SPI. [status = 0x%x]\n",
            status);
        spi_error_exit ();
        return;
    }
    else {
        printf ("SPI: Reset... Passed.\n");
    }

    /* enable SPI for Data transfer */
    status = CSL_spiHwControl (hSpi, CSL_SPI_CMD_XFER_ENABLE, NULL);
    if (status != CSL_SOK) {
        spiTestFail++;
        printf ("SPI: CSL_spiHwControl - CSL_SPI_CMD_XFER_ENABLE... Failed.\n");
        spi_error_exit ();
        return;
    }
    else {
        printf ("SPI: Transfer enable ... Passed.\n");
    }

    #if DSP_NUM == 2
    while (1)
    {
        /* Write trasmit data to DATA0 register */
        status = CSL_spiHwControl (hSpi, CSL_SPI_CMD_CPT_WRITE0, &TxData);
        if (status != CSL_SOK) {
            spiTestFail++;
            printf ("SPI: CSL_spiHwControl - CSL_SPI_CMD_CPT_WRITE0... Failed.\n");
            spi_error_exit ();
            return;
        }
        else {
            //printf ("SPI: Transfering data ... Passed.\n");
        }
      
       do {
            CSL_spiGetHwStatus (hSpi, CSL_SPI_QUERY_EVT_STATUS,&flagStatus);
        } while ((flagStatus & SPI_CHK_RX_MASK) != SPI_RX_FLG_SET);   
       
        status = CSL_spiHwControl (hSpi, CSL_SPI_CMD_CPT_READ, &RxData);
        if (status != CSL_SOK) {
            spiTestFail++;
            printf ("SPI: CSL_spiHwControl - CSL_SPI_CMD_CPT_READ... Failed.\n");
            spi_error_exit ();
            return;
        }
        else {
            //printf ("SPI: Reading received data ... Passed.\n");
        }
       
        TxData = RxData.data;
        printf ("DSP2 Txd %d Rxd %d\n",TxData,RxData.data);
    } 
    #else
    //for (i=0; i<nBlocks; i++)
    while (1)
    {
        //TxData ++;
        /* Write trasmit data to DATA0 register */
        status = CSL_spiHwControl (hSpi, CSL_SPI_CMD_CPT_WRITE0, &TxData);
        if (status != CSL_SOK) {
            spiTestFail++;
            printf ("SPI: CSL_spiHwControl - CSL_SPI_CMD_CPT_WRITE0... Failed.\n");
            spi_error_exit ();
            return;
        }
        else {
            //printf ("SPI: Transfering data ... Passed.\n");
        }
   
        do {
            CSL_spiGetHwStatus (hSpi, CSL_SPI_QUERY_EVT_STATUS,&flagStatus);
        } while ((flagStatus & SPI_CHK_RX_MASK) != SPI_RX_FLG_SET);
       
        status = CSL_spiHwControl (hSpi, CSL_SPI_CMD_CPT_READ, &RxData);
        if (status != CSL_SOK) {
            spiTestFail++;
            printf ("SPI: CSL_spiHwControl - CSL_SPI_CMD_CPT_READ... Failed.\n");
            spi_error_exit ();
            return;
        }
        else {
            //printf ("SPI: Reading received data ... Passed.\n");
        }
   
        if (TxData == (RxData.data+1)) {
            printf ("SPI: Loopback Test... Passed.\n");
        }
        else {
            spiTestFail++;
            //printf ("SPI: Loopback Test... Failed. %d Del %d\n",spiTestFail,TxData - RxData.data);
            printf ("DSP1 Txd %d Rxd %d\n",TxData,RxData.data);
        }
    }
    #endif       

    /* Close the SPI Module */
    status = CSL_spiClose (hSpi);
    if (status != CSL_SOK) {
        spiTestFail++;
        printf ("SPI: Close the instance ... Failed\n");
    }
    else {
        //printf ("SPI: Close valid instance... Passed.\n");
    }

    return;
}

/*
 * =============================================================================
 *  @func   spi_error_exit
 *
 *  @desc
 *     This calls the module close function in case of error
 *
 *  @arg
 *      NONE
 * 
 *  @return
 *      NONE
 * =============================================================================
 */
void
spi_error_exit (
    void
)
{
    CSL_Status               status;

    /* Check closing the module */
    status = CSL_spiClose (hSpi);
    if (status != CSL_SOK) {
        spiTestFail++;
        printf ("SPI: Close Spi instance... Failed\n");
    }
    else {
        printf ("SPI: Close Spi instance... Passed\n");
    }
}

Thanks for your time,
Vlad

  • Vlad,

    CSL might not have been tested on this EVM (Weuffen C6727 EVM ).  Are there some Board Support package or example code that came with the EVM? These example might include SPI driver which is tested on this EVM and can be used as the base code for your application.

    Regards,
    Gaurav

  • Unfortunately DSP Weuffen C6727 EVM Board Support does not have SPI communication example.

    Can you try my example in your set up ?

  • Hi,

    Sorry, my report is wrong. The SPI test runs fine with Polarity = 1 (CSL_SPI_POLARITY_INACTIVEHI), but shows shifted data with Polarity = 0 (CSL_SPI_POLARITY_INACTIVELO). So SPI slave bootload configuration works fine in my SPI 0 communication test project and I can continue with SPI0 slave bootload.

    But now I am having one more problem. I am trying to bootload C6727 Slave DSP from C6727 Master DSP by using SPI0. The Slave/Master SPI have the following configuration: 4-pin (0x0E01), Phase = 0, Polarity = 1 and wordlength = 16bits. The Master DSP sends SWS 0x5853 to the Slave DSP, but always receives all zeros bits from the Slave. I check SCS, CLK, SIMO and SOMI signals with logical analyzer – all signals and SWS bits are fine, but SOMI is always zero. See the picture below.

    What could be my problem and how can I debug this problem?

    Thanks,
    Vlad

    0830.LISTING.TIF

  • Vlad,

    Are you sending an additional 16-bits from the master to the slave? When you send the startword (0x5853) the slave will receive it and will prepare to respond by placing it's response in the send buffer.  But that response won't be sent out until the master drives the clock for 16 more cycles.  The only way to do that is to send some something to the slave (such as 0x0000), and then examine the bits received.  They should be the correct response.

    Please let us know if that works or not.

    Regards, Daniel

  • Daniel

    I found my problem with the Master SPI always receives all zeros bits from the Slave. It was related to the DSP Weuffen board that has switcher for routing SPI either to internal codec or to external header (to Master SPI). The switcher routed Slave SPI to the internal codec by default. I changed the default switcher status to connect to external header and now the Master DSP performs successfully Start-Word Synchronization and Ping Op-code Synchronization with Slave, but fails in Op-code Synchronization. The Master DSP fails on checking first AIS command because it is 0x00005853. The second command is 0x5853590B – fine. I checked my AIS file generated by genAis utility – the first and second commands are the same.
    My AIS file has the following:
        0x41504954
        0x00005853
        0x5853590B
        0x0000000A
        0x00000001
        0x00000002
        0x00000003
        0x00000004
        0x00000005
        0x00000006
        0x00000007
        0x00000008
        0x00000009
        0x0000000A
        0x58535903
        0x58535901

    I ran genAis utility with the following options:
    genAis –I Dsp2Boot.out -o Dsp2Boot.ais -bootmode spislave -otype ascii -cfgtype ais
    What could be my problem?

    Thanks, Vlad

  • Hi,

    I think the first 15 words in AIS file can be ignored, as they are for Ping Op-code Synchronization.
    So I modified the Master DSP SW to send AIS file starting from the 16th word. After this modification Master DSP sends successfully all SET command to the Slave, but it fails on first SECTION LOAD command. The Master DSP sends successfully the SECTION LOAD command value, section address, but after sending first 16bit of the section size, the CSL_spiGetHwStatus function set flagStatus = 0x15 instead of 0x80.

    CSL_spiGetHwStatus (hSpi, CSL_SPI_QUERY_EVT_STATUS,&flagStatus);

    The flagStatus = 0x15 = 10101b means:

    Bit 0 TIMEOUTFLG - Timeout due to non-activation of SPIx_ENA signal.
    Bit 2 DESYNCFLG - Desynchronization of slave SPIx_ENA signal.
    Bit 4 Reserved

    But the SPIs use 4-Pin with SCS signal configuration (0x0E01) without SPIx_ENA.


    Is my interpretation on  Flag Status right?

    Thanks, Vlad

  • Hi,

    Normal 0 false false false EN-CA X-NONE X-NONE MicrosoftInternetExplorer4

    I found my problem: the CSL_spiGetHwStatus function sets errors Flag Status. In my code the CSL_SpiObj  spiObj was corrupted because it was allocated in stack instead being static.

    Thanks, Vlad

  • Glad to hear that you got past that hurtle.

    Regards, Daniel

  • Hi,

    Now Master DSP sometimes receives half word shifted SWS. Tried to swap half word, but the Ping Op-code Synchronization failed. It requires further work. But my boss decided to use Host port bootload and I was driven to another work. So no more reports from me.

    Thanks, Vlad