SPI Slave WriteData Problem

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
Hi,
I have 2 XMC4500. 1 configured as Master, 1 as Slave.
I can receive the words, which are sent by the master in the slave.
But as soon i want to write data back via "SPI003_WriteData", the data, which the slave writes into the buffer will be transmitted completely different and the received bytes from the master will also be different.
And i dont understand why.
Can someone tell me, what i am doing wrong or what i am missing in the Slave implementation?

Using Dave 3.1.10

Used Configuration:
- Standard FullDuplex Mode
- Word length: 16
- Frame Length: 16
- Clock Phase Control: No Delay
- Clock Polarity Control: No Inversion
- Transmit/Receive LSB first
- Transmit and Receive FIFO: Size 2, Trigger Limit 1

Slave:
- Falling Edge trigger ( for triggering DX2T interrupt)
- Enable Slave Select Input Polarity

Master:


void cSpiMaster::WriteMessage(const uint16_t *pSPISendData, const uint16_t& len)
{

uint16_t tmp, i;

uint8_t Status1 = 0;
uint8_t Status2 = 0;
/* Enable start of frame */
EnableStartOfFrame(spi);

/* Start sending len bytes of data from buffer */
for (i=0; i {
SPI001_ClearFlag(&spi,SPI001_RECV_IND_FLAG);
SPI001_ClearFlag(&spi,SPI001_ALT_RECV_IND_FLAG);
SPI001_WriteData(&spi, pSPISendData,SPI001_STANDARD);

do
{
Status1 = SPI001_GetFlagStatus(&spi,SPI001_RECV_IND_FLAG);
Status2 = SPI001_GetFlagStatus(&spi,SPI001_ALT_RECV_IND_FLAG);
}while(!((Status1 == SPI001_SET) || (Status2 == SPI001_SET)));
SPI001_ReadData(&spi,&tmp); // dummy read
pSPISendData++;
}

/* Enable end of frame */
EnableEndOfFrame(spi);
SPI001_ClearFlag(&spi,SPI001_RECV_IND_FLAG);
SPI001_ClearFlag(&spi,SPI001_ALT_RECV_IND_FLAG);

/* Send the last byte
* After sending this data, frame will be finished since we
* enable end of frame
* */
SPI001_WriteData(&spi, pSPISendData,SPI001_STANDARD);

do
{
Status1 = SPI001_GetFlagStatus(&spi,SPI001_RECV_IND_FLAG);
Status2 = SPI001_GetFlagStatus(&spi,SPI001_ALT_RECV_IND_FLAG);
}while(!((Status1 == SPI001_SET) || (Status2 == SPI001_SET)));
SPI001_ReadData(&spi, &tmp); // dummy read

}



Slave: This Function will be called as often according my protocol length

bool cSpiSlave::ReadWord(uint16_t* word)
{
*word = SPI_DUMMY_READ_WORD;
uint16_t tmp = 0;
uint8_t Status1 = 0;
uint8_t Status2 = 0;

do
{
Status1 = SPI003_GetFlagStatus(&spi,SPI003_RECV_IND_FLAG);
Status2 = SPI003_GetFlagStatus(&spi,SPI003_ALT_RECV_IND_FLAG);
}while(!((Status1 == SPI003_SET) || (Status2 == SPI003_SET)));

/* Read data received from flash chip to buffer */
SPI003_ReadData(&spi,&tmp);
*word = tmp;

// Clear flag
SPI003_ClearFlag(&spi,SPI003_RECV_IND_FLAG);
SPI003_ClearFlag(&spi,SPI003_ALT_RECV_IND_FLAG);

// Send read data back
SPI003_WriteData(&spi,&tmp,SPI003_STANDARD);

return true;
}
0 Likes
3 Replies
Not applicable
I could manage it now to do a "WriteData" in the Slave and can still receive the correct data from the Master.
I do the WriteData not after the ReadData anymore. I do it at the FIFO Transmit buffer interrupt.
I am using a FIFO buffer with size 16 now , but somehow the "IN" Registers are never filled, even the code in the SPI003.c file is executed that it writes into the IN register.
Somehow also often the code is executed, where the WriteData method writes into the TBUF register, even it should not be able to execute that code part.
I guess this problem, right now with executing wrong path problably has an code issue from my program right now.
I have to analyse this strange behavior first and will answer in this Thread about my result.
0 Likes
Not applicable
We could fix the problem now.
The problem mainly was about, that the clock had some small "spikes", which let the shift register of the slave shift. So the messages from the Slave was always wrong.
For this problem, there exists a filter in at USIC registers:
hspiUsicRegs.DX0CR|=(USIC_CH_DX0CR_DFEN_Msk|USIC_CH_DX0CR_DSEN_Msk); // turn on input filter for DX0 (MOSI)
hspiUsicRegs.DX1CR|=(USIC_CH_DX1CR_DFEN_Msk|USIC_CH_DX1CR_DSEN_Msk); // turn on input filter for DX1 (SCLK)

We also switched now using the DMA controller and also handle the Chip Select by our own. Also using a frame length of 64bit.
0 Likes
jferreira
Employee
Employee
10 sign-ins 5 sign-ins First like received
Hi,

We strongly advise you to switch to DAVE4.

Regards,
Jesus
0 Likes