cancel
Showing results for 
Search instead for 
Did you mean: 

Zephyr SPI 1 issue after migration from F746zg to F756zg

STM32Fuser
Associate

Hi all
I migrated from a Nucleo F746zg to a F756zg. Code and overlay is the same except that I west build against F756zg. Now SPI 1 is not working properly anymore. On the scope I can see that SPI communication starts (CS goes low, MOSI byte is sent, MISO byte is sent back) but the transfer does not finish. I ran the same but using SPI 3 this worked flawlessly. Don't know maybe an APB or FIFO issue?
Anyone an idea?

Sorry, I forgot to say that I tested this with a Zephyr RTOS firmware (which worked with the F746zg) and as well with a simple straight forward Board-to-Board HAL_SPI_TransmitReceive Ping Pong F756zg (SPI 1 master) <-> F746zg (slave). Besides I want to mention that the same Ping Pong with F756zg (SPI 3 master) <-> F746zg (slave) worked flawlessly.

20 REPLIES 20
TDK
Super User

SPI1 works on both chips, issue is elsewhere.

> but the transfer does not finish

What does this mean?

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

HAL_SPI_TransmitReceive on the master side is entered but never left. I see the outgoing byte on the MOSI line and the same byte with a short delay on the MISO line sent back from the slave. When I check the RXNE register on the master it is set to zero.

This are my settings for F756zg SPI1 master on the:

 
hspi1.Instance = SPI1;

hspi1.Init.Mode = SPI_MODE_MASTER;

hspi1.Init.Direction = SPI_DIRECTION_2LINES;

hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;

hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;

hspi1.Init.NSS = SPI_NSS_SOFT;

hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;

hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi1.Init.CRCPolynomial = 7;

hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;

hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;

 

/**SPI1 GPIO Configuration

PA5 ------> SPI1_SCK

PA6 ------> SPI1_MISO

PB5 ------> SPI1_MOSI

*/

GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6;

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_SPI1;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);



GPIO_InitStruct.Pin = GPIO_PIN_5;

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_SPI1;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);



/* USER CODE BEGIN SPI1_MspInit 1 */

/**SPI1 GPIO Configuration

PA4 ------> SPI1_CS

*/

/*Configure GPIO pin : PA4 */

GPIO_InitStruct.Pin = GPIO_PIN_4;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

//

// /* Set CS high initially (inactive) */

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);


On the slave side I use hardware NSS and the same pins but with a slightly different configuration (due to hardware NSS). 

The same setup F746zg (Master) SPI1 <-> F746zg (Slave) SPI1 worked.

Note that reading DR within the debugger will cause this behavior.

> HAL_SPI_TransmitReceive on the master side is entered but never left.

Run the program, hit pause when it's "stuck". Where is execution at? What is it waiting for?

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

It stucks here in stm32f7xx_hal_spi.c:

/* Wait until RXNE flag is reset */

if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) && (hspi->RxXferCount > 0U))

{


Update:
Sorry, actually I mean in this loop:

while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))

{

 
As far as I can see is the RXNE flag a read only flag. But is there some other flag I must set/reset myself after all is received? And if yes, why did it work with the F746zg without any such measures?

Are you reading the DR register in the debugger? Doing that, or having SCK signal be subpar can cause this issue.

If you feel a post has answered your question, please click "Accept as Solution".
mƎALLEm
ST Employee

Hello @STM32Fuser and welcome to the ST community,

1 - In next time please use </> button to share the code. See this post.

2- I can confidently say that there is no difference between Nucleo F746zg and Nucleo F756zg. Most probably it's a hardware issue and something was modified in the non working board example a resistor a solder bridge or something else. Check the schematic in the SPI pins path.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

No I don't have any Live Expressions, any Watch nor anything intentionally in my code which could periodically access the DR. When I access it, then only manualy during a pause. Besides the scope shows the exact same behaviour when running the code without debugging.

But the SCK is a good hint. The shapes look clean but have quite an overshoot. Maybe reducing the slew rate would help. What do you think? 

Hi
1. Yes sorry, I will keep in mind. I'm new here but it's not an excuse.
2. Yes, R121 must be moved to R122. I did that and checked both lines with a multimeter if everything is correct. I also checked directly at the MCU. I think F746zg share the same schematics with F756zg or did I miss something?


@STM32Fuser wrote:

I think F746zg share the same schematics with F756zg or did I miss something?


Indeed both boards have the same schematic and even the same PCB. That's why I have a doubt about the hardware and something was modified in it ...

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.