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