cancel
Showing results for 
Search instead for 
Did you mean: 

Why I cannot read SPI via HAL but can directly through registers?

MPlet.1
Associate

I am using stmf413xx to talk to M25P16 via SPI. I have working code that can send and receive data to flash via SPI but when I transition to HAL (I want get to interrupts eventually) it no longer works.

The code that works is

while ((SPI3->SR & SPI_FLAG_TXE) == 0) {}
  
  volatile uint32_t tmp;
  tmp = SPI3->DR; // to clear RXNE
  (void)tmp;
  
  SPI3->DR = byte;
  while ((SPI3->SR & SPI_FLAG_RXNE) == 0) {}
  
  return SPI3->DR;

The code that does not work is

if(HAL_SPI_Transmit(spi_handle, &byte, 1, 1000) != HAL_OK)
  {
    log("failed 72");
  }
  if(HAL_SPI_Receive(spi_handle, &byte, 1, 1000))
  {
    log("failed 76");
  }

Both HAL_SPI_Transmit and HAL_SPI_Receive are successfull.

My SPI config is

SPI_HandleTypeDef hal_handle =
{
  .Instance = SPI3,
  .Init =
  {
    .Mode = SPI_MODE_MASTER,
    .Direction = SPI_DIRECTION_2LINES,
    .DataSize = SPI_DATASIZE_8BIT,
    .CLKPolarity = SPI_POLARITY_HIGH,
    .CLKPhase = SPI_PHASE_2EDGE,
    .NSS = SPI_NSS_HARD_OUTPUT,
    .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2,
    .FirstBit = SPI_FIRSTBIT_MSB,
    .TIMode = SPI_TIMODE_DISABLE,
    .CRCCalculation = SPI_CRCCALCULATION_DISABLE,
    .CRCPolynomial = 10
  }
};
 
SPI_HandleTypeDef * spi_handle = &hal_handle;

SPI_HandleTypeDef * spi_handle = &hal_handle; 

3 REPLIES 3
KnarfB
Principal III

The SPI HAL code by Nima Askari worked for me: https://github.com/nimaltd/w25qxx

A couple of thoughts.

Hardware NSS needs a pull up resistor to work properly.

Using dot notation initializers has the side effect of zeroing all non-specified fields. Perhaps something that you aren't setting is getting a value that you're not expecting.

TDK
Guru

Your "code that works" and "code that does not work" do different things. The first sends one byte and receives one byte. The second sends two bytes, and reads only the second byte. I think you want a single HAL_SPI_TransmitReceive call with a data length of one byte.

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