cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Slave mode using DMA and soft NSS

wh
Associate III

0693W00000JOrukQAD.jpgI'm trying to transmit some data using DMA as a slave SPI device. I'm sending 8 byte but the peripheral always gives me 9 byte on the MISO line (first byte twice). The Master NSS is connected to a GPIO input (SPI_ENABLE) using external interrupt Mode with Rising/Falling edge trigger detection. Within the GPIO interrupt routine I set or clear the SPI_CR1_SSI bit as follows.

   if (0 == pUSBPD->spi_nss.Get())

    {

       hspi->Instance->CR1 &= ~SPI_CR1_SSI;

       flag_USBPD_SPI_Active = true;

    }

    else

    {

       hspi->Instance->CR1 |= SPI_CR1_SSI;

       flag_USBPD_SPI_Active = false;

    }

the data transmitted using DMA is:

uint8_t txBuf[8] = { 0x81, 0x01, 0x80, 0xFF, 0x55, 0xAA, 0xAA, 0xAA };

The attachment shows the result. I have no idea why the first byte is send twice. Does anyone have any idea

Thanks in advance.

5 REPLIES 5
TDK
Guru

> I have no idea why the first byte is send twice. Does anyone have any idea

Possibly the data is already in the buffer and is waiting to be sent. The new data gets shifted out on TXE events, which don't occur immediately if data is present.

Your code has other issues since the clock is toggling before CS goes low.

If you feel a post has answered your question, please click "Accept as Solution".
S.Ma
Principal

Use hw spi nss in slave mode to hiz the outputs to be future proof. Use EXTI for NSS and use the rising edge to prepare the next transfer using DMA in cyclic mode to avoid any latency challenges. Once NSS goes high, process the received message, reset the spi by SYSCFG/RCC and reinit the SPI. The spi tx fifo or DR can't be flushed as SCK is not toggling when NSS goes up.

wh
Associate III

I notice that the first byte is no always a copy. It can be spurious data. Note that I get the same result in DMA mode as well as Interrupt mode.

The issue concerning the clock is out of my control. This is what the master device does when I make the TX_ENABLE line high indicating that there is some data to sent from slave to master. The master device is a STUSB1602 controller. I am forced to use this device since the previously used device STUSB4500 is no longer available.

wh
Associate III

Note sure what SYSCFG/RCC is. I'm using the STM32L476 MCU. Right now the HW NSS line for the used SPI is already taken. It's a existing design that needs to be modified since the STUSB4500 is no longer available.  

Petr Sladecek
ST Employee

Hello WH,

I’ve checked briefly the timing diagram attached and have following comments:

·       It is not a slave but SPI master which controls number of data transacted on the bus, slave is forced to transmit even invalid data at case no data is ready for transmission at slave side if master continues at transaction (no matter of the slave configuration - slave faces data underrun condition in fact at such a case)

·       From the snapshot it seems that master includes 10 data session while slave misses start of the session. SPI enable comes too late at slave at time when master handles the first data frame transaction already (~ at about mid of it).

·       Slave must be ALWAYS selected and ready with EACH data frame loaded into data register prior the master starts its transaction on the bus. No matter if hw or sw control is applied for SS, it must be set active before the session starts. The same condition is required for SPI enable which has to be managed while SCK is still at idle to capture well the next transaction start. This is not a case here evidently what make a big mess at data reception at master side (data received are shifted by few bits).

You need either very fast reaction upon interrupt announcing start of the master communication else it is better to keep SPI always ready and enabled to capture correct transaction start and be well synchronized with expected data flow. Note SPI is synchronous interface, slave cannot start its transaction at libitum.

Best regards,

Petr