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.

TMS570LC4357: MibSPI Issue when configured as slave

Part Number: TMS570LC4357

Hi Team,

 In our application we are using MibSPI interface for communication between TMS570LC4357 and FPGA, where the FPGA is configured as master mode and the TMS570LC4357  as SLAVE.

The communication established is in 4-pin mode (i.e. SOMI, MISO, CS, CLK). where the master clock (FPGA) is 10MHZ . We have configured TMS570LC4357  system clock to 180 MHZ and peripheral clock to 30MHZ as shown below:

 and used below code to configure mibSPI ( used MibSPI2) as slave ( Halcogne generated code):

void mibspiInit(void)
{
uint32 i ;

/* USER CODE BEGIN (2) */
/* USER CODE END */


/** @b initialize @b MIBSPI2 */

/** bring MIBSPI out of reset */
mibspiREG2->GCR0 = 0U;
mibspiREG2->GCR0 = 1U;

/** enable MIBSPI2 multibuffered mode and enable buffer RAM */
mibspiREG2->MIBSPIE = (mibspiREG2->MIBSPIE & 0xFFFFFFFEU) | 1U;

/** MIBSPI2 master mode and clock configuration */
mibspiREG2->GCR1 = (mibspiREG2->GCR1 & 0xFFFFFFFCU) | ((uint32)((uint32)0U << 1U) /* CLOKMOD */
| 0U); /* MASTER */

/** MIBSPI2 enable pin configuration */
mibspiREG2->INT0 = (mibspiREG2->INT0 & 0xFEFFFFFFU) | (uint32)((uint32)0U << 24U); /* ENABLE HIGHZ */

/** - Delays */
mibspiREG2->DELAY = (uint32)((uint32)0U << 24U) /* C2TDELAY */
| (uint32)((uint32)0U << 16U) /* T2CDELAY */
| (uint32)((uint32)0U << 8U) /* T2EDELAY */
| (uint32)((uint32)0U << 0U); /* C2EDELAY */

/** - Data Format 0 */
mibspiREG2->FMT0 = (uint32)((uint32)0U << 24U) /* wdelay */
| (uint32)((uint32)0U << 23U) /* parity Polarity */
| (uint32)((uint32)0U << 22U) /* parity enable */
| (uint32)((uint32)0U << 21U) /* wait on enable */
| (uint32)((uint32)0U << 20U) /* shift direction */
| (uint32)((uint32)0U << 17U) /* clock polarity */
| (uint32)((uint32)0U << 16U) /* clock phase */
| (uint32)((uint32)2U << 8U) /* baudrate prescale */
| (uint32)((uint32)16U << 0U); /* data word length */

/** - Data Format 1 */
mibspiREG2->FMT1 = (uint32)((uint32)0U << 24U) /* wdelay */
| (uint32)((uint32)0U << 23U) /* parity Polarity */
| (uint32)((uint32)0U << 22U) /* parity enable */
| (uint32)((uint32)0U << 21U) /* wait on enable */
| (uint32)((uint32)0U << 20U) /* shift direction */
| (uint32)((uint32)0U << 17U) /* clock polarity */
| (uint32)((uint32)0U << 16U) /* clock phase */
| (uint32)((uint32)29U << 8U) /* baudrate prescale */
| (uint32)((uint32)16U << 0U); /* data word length */

/** - Data Format 2 */
mibspiREG2->FMT2 = (uint32)((uint32)0U << 24U) /* wdelay */
| (uint32)((uint32)0U << 23U) /* parity Polarity */
| (uint32)((uint32)0U << 22U) /* parity enable */
| (uint32)((uint32)0U << 21U) /* wait on enable */
| (uint32)((uint32)0U << 20U) /* shift direction */
| (uint32)((uint32)0U << 17U) /* clock polarity */
| (uint32)((uint32)0U << 16U) /* clock phase */
| (uint32)((uint32)29U << 8U) /* baudrate prescale */
| (uint32)((uint32)16U << 0U); /* data word length */

/** - Data Format 3 */
mibspiREG2->FMT3 = (uint32)((uint32)0U << 24U) /* wdelay */
| (uint32)((uint32)0U << 23U) /* parity Polarity */
| (uint32)((uint32)0U << 22U) /* parity enable */
| (uint32)((uint32)0U << 21U) /* wait on enable */
| (uint32)((uint32)0U << 20U) /* shift direction */
| (uint32)((uint32)0U << 17U) /* clock polarity */
| (uint32)((uint32)0U << 16U) /* clock phase */
| (uint32)((uint32)29U << 8U) /* baudrate prescale */
| (uint32)((uint32)16U << 0U); /* data word length */

/** - Default Chip Select */
mibspiREG2->DEF = (uint32)(0xFFU);

/** - wait for buffer initialization complete before accessing MibSPI registers */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
while ((mibspiREG2->FLG & 0x01000000U) != 0U)
{
} /* Wait */

/** enable MIBSPI RAM Parity */
mibspiREG2->PAR_ECC_CTRL = (mibspiREG2->PAR_ECC_CTRL & 0xFFFFFFF0U) | (0x00000005U);

/** - initialize transfer groups */
mibspiREG2->TGCTRL[0U] = (uint32)((uint32)1U << 30U) /* oneshot */
| (uint32)((uint32)0U << 29U) /* pcurrent reset */
| (uint32)((uint32)TRG_ALWAYS << 20U) /* trigger event */
| (uint32)((uint32)TRG_DISABLED << 16U) /* trigger source */
| (uint32)((uint32)0U << 8U); /* start buffer */

mibspiREG2->TGCTRL[1U] = (uint32)((uint32)1U << 30U) /* oneshot */
| (uint32)((uint32)0U << 29U) /* pcurrent reset */
| (uint32)((uint32)TRG_ALWAYS << 20U) /* trigger event */
| (uint32)((uint32)TRG_DISABLED << 16U) /* trigger source */
| (uint32)((uint32)8U << 8U); /* start buffer */

mibspiREG2->TGCTRL[2U] = (uint32)((uint32)1U << 30U) /* oneshot */
| (uint32)((uint32)0U << 29U) /* pcurrent reset */
| (uint32)((uint32)TRG_ALWAYS << 20U) /* trigger event */
| (uint32)((uint32)TRG_DISABLED << 16U) /* trigger source */
| (uint32)((uint32)(8U+0U) << 8U); /* start buffer */

mibspiREG2->TGCTRL[3U] = (uint32)((uint32)1U << 30U) /* oneshot */
| (uint32)((uint32)0U << 29U) /* pcurrent reset */
| (uint32)((uint32)TRG_ALWAYS << 20U) /* trigger event */
| (uint32)((uint32)TRG_DISABLED << 16U) /* trigger source */
| (uint32)((uint32)(8U+0U+0U) << 8U); /* start buffer */

mibspiREG2->TGCTRL[4U] = (uint32)((uint32)1U << 30U) /* oneshot */
| (uint32)((uint32)0U << 29U) /* pcurrent reset */
| (uint32)((uint32)TRG_ALWAYS << 20U) /* trigger event */
| (uint32)((uint32)TRG_DISABLED << 16U) /* trigger source */
| (uint32)((uint32)(8U+0U+0U+0U) << 8U); /* start buffer */

mibspiREG2->TGCTRL[5U] = (uint32)((uint32)1U << 30U) /* oneshot */
| (uint32)((uint32)0U << 29U) /* pcurrent reset */
| (uint32)((uint32)TRG_ALWAYS << 20U) /* trigger event */
| (uint32)((uint32)TRG_DISABLED << 16U) /* trigger source */
| (uint32)((uint32)(8U+0U+0U+0U+0U) << 8U); /* start buffer */

mibspiREG2->TGCTRL[6U] = (uint32)((uint32)1U << 30U) /* oneshot */
| (uint32)((uint32)0U << 29U) /* pcurrent reset */
| (uint32)((uint32)TRG_ALWAYS << 20U) /* trigger event */
| (uint32)((uint32)TRG_DISABLED << 16U) /* trigger source */
| (uint32)((uint32)(8U+0U+0U+0U+0U+0U) << 8U); /* start buffer */

mibspiREG2->TGCTRL[7U] = (uint32)((uint32)1U << 30U) /* oneshot */
| (uint32)((uint32)0U << 29U) /* pcurrent reset */
| (uint32)((uint32)TRG_ALWAYS << 20U) /* trigger event */
| (uint32)((uint32)TRG_DISABLED << 16U) /* trigger source */
| (uint32)((uint32)(8U+0U+0U+0U+0U+0U+0U) << 8U); /* start buffer */


mibspiREG2->TGCTRL[8U] = (uint32)(8U+0U+0U+0U+0U+0U+0U+0U) << 8U;

mibspiREG2->LTGPEND = (mibspiREG2->LTGPEND & 0xFFFF00FFU) | (uint32)(((uint32)(8U+0U+0U+0U+0U+0U+0U+0U)-1U) << 8U);

 /* Didn't copy the code which configure RAM Group */

/** - MIBSPI2 Port output values */
mibspiREG2->PC3 = (uint32)((uint32)1U << 0U) /* SCS[0] */
| (uint32)((uint32)1U << 1U) /* SCS[1] */
| (uint32)((uint32)0U << 8U) /* ENA */
| (uint32)((uint32)0U << 9U) /* CLK */
| (uint32)((uint32)0U << 10U) /* SIMO */
| (uint32)((uint32)0U << 11U); /* SOMI */

/** - MIBSPI2 Port direction */
mibspiREG2->PC1 = (uint32)((uint32)0U << 0U) /* SCS[0] */
| (uint32)((uint32)1U << 1U) /* SCS[1] */
| (uint32)((uint32)0U << 8U) /* ENA */
| (uint32)((uint32)1U << 9U) /* CLK */
| (uint32)((uint32)1U << 10U) /* SIMO */
| (uint32)((uint32)0U << 11U); /* SOMI */

/** - MIBSPI2 Port open drain enable */
mibspiREG2->PC6 = (uint32)((uint32)0U << 0U) /* SCS[0] */
| (uint32)((uint32)0U << 1U) /* SCS[1] */
| (uint32)((uint32)0U << 8U) /* ENA */
| (uint32)((uint32)0U << 9U) /* CLK */
| (uint32)((uint32)0U << 10U) /* SIMO */
| (uint32)((uint32)0U << 11U); /* SOMI */


/** - MIBSPI2 Port pullup / pulldown selection */
mibspiREG2->PC8 = (uint32)((uint32)1U << 0U) /* SCS[0] */
| (uint32)((uint32)1U << 1U) /* SCS[1] */
| (uint32)((uint32)1U << 8U) /* ENA */
| (uint32)((uint32)1U << 9U) /* CLK */
| (uint32)((uint32)1U << 10U) /* SIMO */
| (uint32)((uint32)1U << 11U); /* SOMI */


/** - MIBSPI2 Port pullup / pulldown enable*/
mibspiREG2->PC7 = (uint32)((uint32)0U << 0U) /* SCS[0] */
| (uint32)((uint32)0U << 1U) /* SCS[1] */
| (uint32)((uint32)0U << 8U) /* ENA */
| (uint32)((uint32)0U << 9U) /* CLK */
| (uint32)((uint32)0U << 10U) /* SIMO */
| (uint32)((uint32)0U << 11U); /* SOMI */


/* MIBSPI2 set all pins to functional */
mibspiREG2->PC0 = (uint32)((uint32)1U << 0U) /* SCS[0] */
| (uint32)((uint32)0U << 1U) /* SCS[1] */
| (uint32)((uint32)1U << 8U) /* ENA */
| (uint32)((uint32)1U << 9U) /* CLK */
| (uint32)((uint32)1U << 10U) /* SIMO */
| (uint32)((uint32)1U << 11U); /* SOMI */

/** - Finally start MIBSPI2 */
mibspiREG2->GCR1 = (mibspiREG2->GCR1 & 0xFEFFFFFFU) | 0x01000000U;

}

In this Configuration, while sending the data through MIBSPI we are seeing the data in the MIBSPI-RAM is written properly but FPGA was the data with MSB bit set to one.

Example: if we are transmitting 0x01, 0x02, 0x03, FPGA was receiving 0xC001, 0xC002, 0xC003...

Not sure the actual root cause which is causing this issue.We also tried the Configuring the MIBSPI-RAM to different MPU configurations like Strongly Ordered, Device shareable and write-through , but did not work.

 While debugging we observed that the SPI-INTFLAGs are getting set for the bit error and data length error after transmission ( value as INTFLAGs  = 0x0251)and the RxBUF/Emu is being written as 0x81000000.

But when we increase the VCLK1 Clock from 30MHZ to 90MHz (shown in fig.i), then we are not seeing this issue and no error flag is being set in INTFLAGs(shown in fig. ii). Also, RxBUF/Emu is read as 0x8000FFFF and the data is being properly receievd on the FPGA .

fig.i: -

 

 

 

fig. ii :-

 

We did also try VCLK1 with 60MHZ, but we saw bit error being set in the INTFLAGS as shown below:

Please let us know if we are missing any configuration here.

 

 

  • Hello,

    The maximum input frequency on the SPICLK pin when in slave mode is VCLK frequency /2. If the Slave is configured in either 3-pin or 4-pin (without SPIENA) modes, then, between end of last SPICLK and the start of SPICLK for next buffer, there should be at least 6 VCLK cycles of delay.

  • hi Wang,

    Thank you for your reply. Have a few more queries about your reply.

    1. The maximum input frequency on the SPICLK pin when in slave mode is VCLK frequency /2. 

        If we configure VCLK to 30MHZ or 60 MHZ which will be 15MHZ or 30MHZ respectively for the max clock on SPICLCK pin on the slave, but still we were seeing issues on the data transferred along with bit-error & data length errors being set.

       Surprisingly, If we configure VCLK to 90MHZ, data transmission works well with no error bits set. Not sure why increasing the frequency resolves the issue.

    2. If the Slave is configured in either 3-pin or 4-pin (without SPIENA) modes, then, between the end of the last SPICLK and the start of SPICLK for the next buffer, there should be at least 6 VCLK cycles of delay.

      If a minimum of 6 VCLK cycles of delay is required, then we were wondering how it works for a 90MHZ clock? and not for 30 or 60MHZ.

    Also, please do share with us the related documentation which explains the SPICLK pin behavior in slave mode with different clock configurations.

    Regards,

    Srhari

  • Hello Srhari,

    I will setup my board to do similar test, then come back to you. Sorry for my delayed response.

  • Hello Srhari,

    I did a test with VCLK=37.5MHz, and SPICLK=1MHz. In my test SPI1 is master, and SPI3 is slave. 

    I run the loop for around 9000 time, no error.

  • My test is based on standard SPI mode: SPI1 and SPI3. I will try Multi-buffered mode

  • Hi Wang,

    Thank you for testing the SPI.

    we were looking for the below configuration to work for MibSPI.

    We also had one observation, if we configure the clock as below, MibSPi works but we observed frequent DAP reset issues.

    Regards,

    Srihari

  • Hello,

    Can you please increase the C2TDELAY? I saw the issue the received data on master side is not correct. Below is the waveform I captured. The channel 1 is nCS, channel 3 is SIMO, and channel 4 is SOMI signal. The data on SOMI and SIMO should be 0x5A5A. But the SOMI data is right-shifted by 1 bit. This means that the slave output the signal starting at the 2nd clock edge.

    MibSPI3 is slave in my test. As stated in TRM, the master should wait for 6 VCLK cycles before sending clock to begin the transaction if SPIENA is not used. After I increased the C2TDELAY, the slave outputs correct data. I know you use different slave which may have different setup time requirement.  

  • Hello Srihari,

    Does insertion of C2TDELAY help your situation?

  • Hi Wang,

    We tried inserting C2TDEALY, but it didn't help.

  • Thanks for your try, I will investigate this issue further.