cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H755ZI SPI / Proper way to receive data

DSchl.1
Associate III

Hi everyone

I'm currently working with the STM32H755ZI SPI1 peripheral. I'm using low level driver to read 2 bytes of data. I'm transmitting 2 dummy data bytes (0xFF) in order to get some response from the SPI slaves. Most of the time, the receive works well, but from time to time, I'm receiving 0x00, even though the RxFIFOPackingLevel is > 0 and the signals on the oscilloscope look fine at that time... I used a conditional breakpoint to stop when one of the data bytes is 0x00 and checked the SPI1 registers, and everything looked fine (the RxFIFO packing level / RXPLVL showed 0 at the time, but I assume it gets cleared after reading the rx data register).

I've also tried to lower the SPI1 clock, but this didn't help...

What's the proper way to receive data bytes from the SPI peripheral? Is waiting for RxFIFOPackingLevel > 0 correct?

edit: I've also tried to check RXP flag, but this doesn't change anything.

This question is related to the previous question I had, however I'm posting it as a new topic. Previous question https://community.st.com/s/question/0D53W000002h0qFSAQ/stm32h755zi-spi-behaviour-of-mosi-after-disabling-peripheral.

I'm sorry for the redundancy in my posts, but I thought that these are two totally different questions.

Parameters are as shown below:

Baudrate = LL_SPI_BAUDRATEPRESCALER_DIV256 (clock is 180MHz)

BitOrder = LL_SPI_MSB_FIRST

CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE

CRCPoly = CRCPOLY 0x00

ClockPhase = LL_SPI_PHASE_1EDGE

ClockPolarity = LL_SPI_POLARITY_LOW

DataWidth = LL_SPI_DATAWIDTH_8BIT

Mode = LL_SPI_MODE_MASTER

NSS = LL_SPI_NSS_HARD_OUTPUT

TransferDirection = LL_SPI_FULL_DUPLEX

I'm also setting the following parameters:

  • LL_SPI_PROTOCOL_MOTOROLA
  • LL_SPI_NSS_POLARITY_HIGH
  • Enable NSS Pulse Management
  • Enable GPIO Control

After initialization, I'm trying to read 2 bytes of data. I'm using the following procedure:

  • Start the transfer size (with requested number of bytes + 1, so this is set to 3)
  • Enable the SPI peripheral and start master transfer
  • Wait for TXP, send first dummy data byte (0xFF)
  • Wait for TXP, send second dummy data byte (0xFF) and read first data byte if FIFO packing level is > 0
  • Read second data byte if FIFO packing level is > 0
  • Wait until EOT
  • Clear EOT and TXTF flags
  • Suspend master transfer and disable SPI peripheral

Any explanation would be greatly appreciated.

Regards

Daniel.

EDIT: To give some more information, here's my routine for sending and receiving the SPI data:

EDIT2: Updated due to comments below. This shows now the actual implementation.

// The following simplified function gets called with a zero-initialized buffer of 2 bytes and size = 2.
 
void reveive_buffer(uint8_t* buffer, uint32_t size)
{
    LL_SPI_SetTransferSize(SPI1, size);
    LL_SPI_Enable(SPI1);
    LL_SPI_StartMasterTransfer(SPI1);
 
    for (uint32_t i = 0; i < size; ++i)
    {
        while (LL_SPI_IsActiveFlag_TXP(SPI1) == 0);
        LL_SPI_TransmitData8(SPI1, 0xFF);
    }
 
    for (uint32_t i = 0; i < size; ++i)
    {
        while (LL_SPI_GetRxFIFOPackingLevel(SPI1) == 0);
        buffer[i] = LL_SPI_ReceiveData8(SPI1);
    }
 
    while (LL_SPI_IsActiveFlag_EOT(SPI1) == 0); 
    LL_SPI_ClearFlag_EOT(SPI1);
    LL_SPI_ClearFlag_TXTF(SPI1);
    LL_SPI_SuspendMasterTransfer(SPI1);
    LL_SPI_Disable(SPI1);
}

11 REPLIES 11
TDK
Guru

> uint32_t totalSize = size + 1;

> LL_SPI_SetTransferSize(SPI1, totalSize);

Seems like if you're sending/receiving X bytes, then the second line should pass X, and not X+1.

If you feel a post has answered your question, please click "Accept as Solution".
DSchl.1
Associate III

That's correct. That's why I have refactored the function, see my answer from March 23, 2020 at 3:29 AM. Im having a size of 2.