cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F412 SPI not sending

cdjackson
Associate II

I'm using the STM32F412 with an SPI LCD on a custom board and am having problems with the SPI communications. It seems that the TXE flag is always high, and therefore the code locks on the  -:

while (!__HAL_SPI_GET_FLAG(&spiHal, SPI_FLAG_TXE))
:- check used after loading the first character into the FIFO.
 
I'm using the Arduino TFT_eSPI library and this was previously tested using an STM32F410 Nucleo board. We used the F412 for the production system as we need more memory and may require USB later, but I would have expected this to work much the same on the two processors.
 
I could guess that I've not got something configured correctly somewhere - possibly with the clocks (since I'm a little suspicious that my clock config isn't being updated correctly), but I'd welcome any pointers as to why the SPI might show busy. There is little else done before this other than to configure the alternative pin functions and configure some debug serial and LED...
 
Thanks.
7 REPLIES 7
TDK
Guru

> It seems that the TXE flag is always high

High or low? The code you posted will wait until it's high, which is the default state of TXE. No problem there, code won't hang if TXE is high.

 

Assuming you meant low: Is it initialized and enabled? TXE staying low would indicate it's not active, or misconfigured. Show the contents of the SPI registers at the time of the error.

 

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

Thanks for the response. You're correct - the check is negative, but the issue is the same as the code locks on the line I mentioned above because the TXE flag is always showing not empty which is the base of the issue.

I'm using a library that worked fine with the 32F410 - of course the problem with using someone elses library is without digging through the code to find what it does, it's impossible to say if it enables everything (or anything!) but I expected it to work similarly to the F410.  I added some code to explicitly enable the SPI2 - the code was autogenerated by the Cube IDE so I assume this is correct. This doesn't help and it still locks on the same line with the TXE flag low and BUSY is low (not busy).

I ported some code across to the CubeIDE using the HAL SPI calls, and it works there, so the hardware is fine. My guess is that there's a low level configuration issue - as above - I've taken the autogenerated code from CubeIDE that configures the clocks and SPI and put that into the PlatformIO code, and it seems to run, but the HAL SPI Transmit still times out...  I think this points to a low level config issue so I'll keep digging there...

 

TDK
Guru

All STM32F4 chips have the same SPI peripheral. That's not the issue.

> it's impossible to say if it enables everything

Why? Can't you look at it?

Sounds like the peripheral isn't enabled, or is in slave mode.

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

@TDK wrote:

All STM32F4 chips have the same SPI peripheral. That's not the issue.

> it's impossible to say if it enables everything

Why? Can't you look at it?

Sounds like the peripheral isn't enabled, or is in slave mode.

I can look through the source, of course - that was my point above immediately prior to the part you quoted -:

without digging through the code to find what it does, it's impossible to say if it enables everything

If you're suggesting doing something to read back the status, I'd appreciate it if you can state specifically what you suggest I "look at". As I said, I have enabled the SPI using the code generated by the IDE and that works fine when run in the STM IDE, but not when run under PlatformIO.

The code that I'm using to enable this is -:

  hspi2.Instance = SPI2;
  hspi2.Init.Mode = SPI_MODE_MASTER;
  hspi2.Init.Direction = SPI_DIRECTION_2LINES;
  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi2.Init.NSS = SPI_NSS_SOFT;
  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi2.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi2) != HAL_OK)
  {
    Error_Handler();
  }

 


@TDK wrote:

Sounds like the peripheral isn't enabled, or is in slave mode.


Again, this code does work when running under the STM IDE - the same code runs fine in PlatformIO, but the SPI doesn't work. If you can advise what I should check, that would be appreciated.

 

Thanks.

> If you're suggesting doing something to read back the status, I'd appreciate it if you can state specifically what you suggest I "look at".

Here's what I suggested in the first post:

> Show the contents of the SPI registers at the time of the error.

What this would do is show the state of the peripheral, including configuration and current status. Since the peripheral runs based solely on the state of the registers, this provides complete information, at least in determining if/how the peripheral is configured.

Showing the HAL initialization code is okay, but clearly there's something else amiss and examining the registers directly will shed light as to what that is. Since the HAL code works in STM32CubeIDE, there are unlikely to be issues with it.

Once that's determined, you can use that information to look for the part of the code that isn't doing the thing it's supposed to be doing.

In STM32CubeIDE this (examining peripheral register values) can be done via the SFRs window (Window -> Show View ->SFRs).

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

Thanks. I have tried to read out the registers, with (for example) 

READ_REG(hspi2.Instance->CR1). This always returns 0 on all registers. I'm not sure if this is the correct way to read the registers - it seems so from other code I've looked at, but maybe not...
 

@TDK wrote:

In STM32CubeIDE this (examining peripheral register values) can be done via the SFRs window (Window -> Show View ->SFRs).


Note that the problem is not manifesting within STM32CubeIDE - my SPI test works fine there and as mentioned previously, I can communicate with the LCD. I'm trying to get the SPI working under PlatformIO - as above - the code worked fine with the F410, but doesn't work with the F412.
TDK
Guru

> This always returns 0 on all registers.

Then likely the SPI clock is not enabled. This should be done before configuring it or accessing any of its registers.

 

__HAL_RCC_SPIx_CLK_ENABLE();

 

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