K60 SPI Slave issue: extra byte exist

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

K60 SPI Slave issue: extra byte exist

1,680 Views
handy1
Contributor II

I am using K60 as SPI Slave mode. my code push the data frame (0x55,0x55,0x55,0x11,...)to the TXFIFO and wait the SPI Master to read out. But the master will read out the data frame as (0x0,0x55,0x55,0x55,0x11,....). I do not know why there is an extra '0x0' received. I grab the bus wave and found the 0x0 is sent on the MISO .Please refer to the attached pic. I did debug by step-by-step check the FIFO filling action,and no issue occured, no '0x0' was insert into the fifo.

Why the SPI controller will add an 0x0?

screenshot.png

Btw, I found in the K60 RM(50.4.6 Slave Mode Operation Constraints), it said "The transmit data is transferred at second SCK clock edge of the each frame to the shift

register if the SS signal is asserted and any time when transmit data is ready and SS signal is negated."

What is this mean? Does the issue related with this?

Labels (1)
Tags (2)
4 Replies

727 Views
handy1
Contributor II

Well, it turns out that the slave can not response the SPI master ASAP. Seems the slave is too slow.

Even the data has already been pushed into the FIFO, the slave can not put the data to the shift register ASAP, and the underflow issue occured.

I have to add delay between each two bytes transfer at master side.  The acceptable minimal delay is about 32uS if the master inactive the SS between each transfer.

And if SS is not inactive between transfer, the acceptable minimal delay will be much longer.

727 Views
marcelovaranda
Contributor I

I am getting similar issue having an extra byte. The scenario is as following:

I modified the spi_dspi_dma.c file to accept Slave mode. Works fine as long as the number of bytes that the master sends to the slave matches with the number of bytes given to the read functions. in case the master send, lets say, 10 extra bytes then the slave gets the expected "N" bytes (according to the value given to the read) and it is expected to have the next read with 10 bytes at the beginning + whateven the Master sends. However, the result is a bit unexpected: the TX_RX seems to flush the FIFOs and from now and on the slave always gets a single extra byte at the beginning + the correct payload sent by the master (missing the last byte).

Calling fflush() does not do any good even while the CS0 is "1" and clock has already stopped between transfers. The slave gets out of sync "forever".

Is this a known problem?

0 Kudos

727 Views
martynhunt
NXP Employee
NXP Employee

Hi,

Is it possible that the Master device is requesting data before the Slave has pushed data to the FIFO (and transmitting an empty register value 0x00)? Also, what are your SPIx_CTAR_SLAVE[FMSZ], SPIx_CTAR_SLAVE[CPHA] & SPIx_CTAR_SLAVE[CPOL] settings for the Slave device?

Best regards,

Martyn

0 Kudos

727 Views
handy1
Contributor II

Martyn,

No, it is not the case. Because only after the slave push all the data into fifo, it trigger a GPIO as interrupt to the Master, then Master will start the spi transfer.

Part of my init code is as follow:

/* Disable and clear SPI */

  dspi0_ptr->MCR = DSPI_MCR_HALT_MASK | DSPI_MCR_CLR_TXF_MASK | DSPI_MCR_CLR_RXF_MASK;

  dspi0_ptr->MCR &= (~ DSPI_MCR_MDIS_MASK); //leave it '0' in slave mode, since a slave doesn't have control over master transactions.

  /* SPI0 work in Slave mode*/

  dspi0_ptr->MCR &= ~DSPI_MCR_MSTR_MASK;

  /* Receive FIFO overflow disable */

  dspi0_ptr->MCR |= DSPI_MCR_ROOE_MASK;

  /* Set CS0-7 inactive high */

  dspi0_ptr->MCR |= DSPI_MCR_PCSIS(0xFF);

  //set up the spi mode, frame size = 8, CPOL = 0 , CPHA = 1

  dspi0_ptr->CTAR[0] = (DSPI_CTAR_FMSZ(0x7)|DSPI_CTAR_CPHA_MASK);

  dspi_info_ptr ->CTAR_TIMING = dspi0_ptr->CTAR[0];

  /* Disable interrupts */

  dspi0_ptr->RSER = 0;

  /* Clear all flags */

  dspi0_ptr->SR =  DSPI_SR_EOQF_MASK|DSPI_SR_TFUF_MASK|DSPI_SR_TFFF_MASK|DSPI_SR_RFOF_MASK|DSPI_SR_RFDF_MASK;

/* Enable SPI */

  dspi0_ptr->MCR &= (~ DSPI_MCR_HALT_MASK);

0 Kudos