cancel
Showing results for 
Search instead for 
Did you mean: 

[STM32F469] Using HAL_SPI_TransmitReceive not writing on the receive buffer.

Riccardo Franceschetto
Associate III

Hello,

I implemented a simple spi transmission on a STM32F469 based board.

The problem i'm facing is that the spi function I'm not getting any value in the receive buffer.

Trough the oscilloscope i can see the byte being send and the one transmitted back from slave device, i'm using a gpio as chip select because notoriusly the hardware NSS by hal does not work properly.

What could be the problem?

Here's my code., the function names might differ because of internal implementation, but are HAL based.

Init Function:

void SIN_SPI6_Init(SPI_HandleTypeDef* spiP)
{
 
 
  spiP ->Instance = SPI6;
  spiP ->Init.Mode = SPI_MODE_MASTER;
  spiP ->Init.Direction = SPI_DIRECTION_2LINES;
  spiP ->Init.DataSize = SPI_DATASIZE_8BIT;
  spiP ->Init.CLKPolarity = SPI_POLARITY_LOW;
  spiP ->Init.CLKPhase = SPI_PHASE_1EDGE;
  spiP ->Init.NSS = SPI_NSS_SOFT;
  spiP ->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
  spiP ->Init.FirstBit = SPI_FIRSTBIT_MSB;
  spiP ->Init.TIMode = SPI_TIMODE_DISABLE;
  spiP ->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  spiP ->Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(spiP) != HAL_OK)
  {
        Error_Handler(2);
  }
 
}

MSP function:

void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
   if(hspi->Instance==SPI2)
  {
    /* Peripheral clock enable */
    __HAL_RCC_SPI2_CLK_ENABLE();
 
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    /**SPI2 GPIO Configuration
    PB13     ------> SPI2_SCK
    PC3     ------> SPI2_MOSI
    PC2     ------> SPI2_MISO
    */
    GPIO_InitStruct.Pin = GPIO_PIN_13;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
  }
 
   else if(hspi->Instance==SPI6)
  {
  /* USER CODE BEGIN SPI6_MspInit 0 */
 
  /* USER CODE END SPI6_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_SPI6_CLK_ENABLE();
 
    __HAL_RCC_GPIOG_CLK_ENABLE();
    /**SPI6 GPIO Configuration
    PG14     ------> SPI6_MOSI
    PG13     ------> SPI6_SCK
    PG12     ------> SPI6_MISO
    */
    GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_13|GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI6;
    HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
 
    }
}

The code to the transmission:

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET);  //SPI6_NSS  low
  
            uint8_t readStatusRegister = 0b00000101;
            uint8_t  readback = 0;
            
                
            if (HAL_SPI_TransmitReceive (&hspi6, &readStatusRegister,&readback,2, 10) != HAL_OK)
            {
                  Error_Handler(6);    
            }
 
            HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET);    //SPI6_NSS  high

14 REPLIES 14

Basically SPI master always sends and receives the specified number of data frames. It cannot receive anything without sending. You send N frames/bytes and you receive exactly N frames/bytes.

The Function discards the volatile specifier when compiling

Solved the problem, making the variables global saved the day, also the amount of data is the number of bytes to transmit plus receive. So the master sends n bytes and reads after sending the total - n bytes sent.

As gbm already said, if a local variable is referenced, the compiler puts it in a stack memory. Of course, the stack can be put in a memory not accessible by DMA, but other than that a local/global and volatile are language concepts and hardware (DMA or other) has nothing to do with those. And the topic author's code doesn't use DMA anyway...

> Function discards the volatile

First, the function (code) cannot discard a code because that is just an illogical nonsense... Second, a compiler is not allowed to do it by the language specification.

Doing a random Voodoo dances is not an engineering...

No, you are wrong on all counts. Other posts from me and gbm explain why... Also, if the if the variable needs a static storage, it doesn't have to be made global - making it a local static variable is enough. And for SPI the reception happens simultaneously with transmission, not after it.

You have to understand that something appearing to work doesn't prove it actually works correctly.