cancel
Showing results for 
Search instead for 
Did you mean: 

SPI4 RXNE never raises on STM32G4

amo25
Visitor

Hello, my project is using all 4 SPI interfaces on the STM32G474. SPI1-3 all work flawlessly, but SPI4 never triggers the RXNE flag. All SPI buses are configured identically, with the only differences being the pinouts and APB1 vs 2 bus. I am polling the transactions directly.

Initialization:

if (hspi_.Instance == SPI1)
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);
else if (hspi_.Instance == SPI2)
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);
else if (hspi_.Instance == SPI3)
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI3);
else if (hspi_.Instance == SPI4)
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI4);

LL_SPI_SetMode(hspi_.Instance, LL_SPI_MODE_MASTER);
LL_SPI_SetTransferDirection(hspi_.Instance, LL_SPI_FULL_DUPLEX); 
LL_SPI_SetDataWidth(hspi_.Instance, LL_SPI_DATAWIDTH_8BIT); 
LL_SPI_SetClockPolarity(hspi_.Instance, LL_SPI_POLARITY_LOW); 
LL_SPI_SetClockPhase(hspi_.Instance, LL_SPI_PHASE_1EDGE); 
LL_SPI_SetBaudRatePrescaler(hspi_.Instance, LL_SPI_BAUDRATEPRESCALER_DIV256);
LL_SPI_SetTransferBitOrder(hspi_.Instance, LL_SPI_MSB_FIRST);
LL_SPI_SetStandard(hspi_.Instance, LL_SPI_PROTOCOL_MOTOROLA);
LL_SPI_SetNSSMode(hspi_.Instance, LL_SPI_NSS_SOFT); 
SET_BIT(hspi_.Instance->CR1, SPI_CR1_SSI); 
LL_SPI_SetRxFIFOThreshold(hspi_.Instance, LL_SPI_RX_FIFO_TH_QUARTER); 
LL_SPI_DisableNSSPulseMgt(hspi_.Instance); 
LL_SPI_DisableCRC(hspi_.Instance);
LL_SPI_Enable(hspi_.Instance);

 

Transfer:

 
void write(uint8_t* data, size_t len) {
  for (uint16_t i = 0; i < len; i++)
  {
    while (!LL_SPI_IsActiveFlag_TXE(hspi_.Instance)) {}
    LL_SPI_TransmitData8(hspi_.Instance, data[i]);

    while (!LL_SPI_IsActiveFlag_RXNE(hspi_.Instance)) {}
    (void)LL_SPI_ReceiveData8(hspi_.Instance);
  }
  while (LL_SPI_IsActiveFlag_BSY(hspi_.Instance)) {}
  return;
}

 

For SPI1-3, write works fine. For SPI4, it hangs on the while RXNE wait forever. 

I verified SPI4 is enabled (check RCC_APB2ENR) and not held in reset (check RCC_APB2RSTR):

# RCC_APB2ENR SPI4_EN
(gdb) p/x *0x40021060 >> 15 & 1
$25 = 0x1

# RCC_APB2RSTR SPI4_RST
(gdb) p/x *0x40021040 >> 15 & 1
$20 = 0x0

I can reproduce this across multiple boards and eval boards. Any idea what is wrong?

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Super User

If SCK line isn't toggled, RXNE won't get set. Verify the SCK line is actually active with a scope or logic analyzer.  Barring that, verify the pin can be toggled freely when driven in output mode. Verify pins are set to VERY_HIGH frequency, or whatever is appropriate for the speed you are using.

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

View solution in original post

7 REPLIES 7
TDK
Super User

If SCK line isn't toggled, RXNE won't get set. Verify the SCK line is actually active with a scope or logic analyzer.  Barring that, verify the pin can be toggled freely when driven in output mode. Verify pins are set to VERY_HIGH frequency, or whatever is appropriate for the speed you are using.

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

The pins are AF_PP, NOPULL, and VERY_HIGH speed. I can drive them manually in OUTPUT_PP with no issue. 

SCK is active and toggling, but I notice it is at a way lower voltage level (1.5-2.5V) than expected, though this may be a problem with my board - would this cause issues or is the SCK->RXNE connection internal?  

For what it's worth, I see RXNE fail to respond on the NUCLEO-G474RE eval board as well, which does not have PE2/5/6 exposed. 

 

gbm
Principal

Is SSM bit set?

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
amo25
Visitor

Yes, SSM is set.

(gdb) p hspi_.Instance
$1 = (SPI_TypeDef *) 0x40013c00

(gdb) p/x hspi_.Instance->CR1
$2 = 0x37c
(gdb) p/x hspi_.Instance->CR1 >> 9 & 1
$3 = 0x1


@amo25 wrote:

SCK is active and toggling, but I notice it is at a way lower voltage level (1.5-2.5V) than expected,  


If the level is too low, the STM32 will just see it as a constant low - ie, as no clock.

As already noted, if the STM32 sees no clock, nothing will be clocked-in and RXNE won't get set.

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
waclawek.jan
Super User

> The pins are AF_PP, NOPULL, and VERY_HIGH speed. I can drive them manually in OUTPUT_PP with no issue.

> SCK is active and toggling, but I notice it is at a way lower voltage level (1.5-2.5V) than expected,

Is SCK PE2? And if you toggle it "manually" as GPIO Output, is its amplitude correct, or lower too?

>  would this cause issues or is the SCK->RXNE connection internal?

As others said, yes, this would cause issues, the Rx even in Master uses the input version of the SCK.

> For what it's worth, I see RXNE fail to respond on the NUCLEO-G474RE eval board as well, which does not have PE2/5/6 exposed.

That's irrelevant, there's no PE port on the 64-pin (and 48-pin) 'G474, thus "no" SPI4 - look at the peripherals list/table in the datasheet, for the 48/64-pin variant, there are only 3 SPIs.

JW

amo25
Visitor

Thank you all for the input. The voltage sag was indeed the problem, depopulating the SPI4 bus brings the line back up to 3.3V and RXNE raises as expected.