STM32H523VET6 SPI2's RXP flag is never set and times out
- July 9, 2026
- 1 reply
- 50 views
My problem: my SPI2 module doesn’t appear to be clocking in data even if it is configured a full duplex master.
Context:
I am developing the firmware on a board that some other team designed and they picked PB13 (SCK), PB14 (MISO) and PB15 (MOSI) to implement SPI2. I am aware of the fact that those pins are shared with the UCPD dead battery detection feature and that:
- Dead battery detection must be disabled
- Clock rate of SPI is limited to ~3MBd
I am developing my drivers bare-metal (no LL or HAL), but since I couldn’t figure out how to make this work, I decided to try with the HAL code generated by STM32CubeMX.
I created a new project on that software with software package v1.7.0 which appears to be the latest at this time.
I simply configured the clock tree to use HSI (64MHz) → /2 → PLL1 (M=4, N=24, Q=4) = 48MHz. I then use SPI2 prescaler to get 1.5Mbd out of PLL1Q (I tried lower data rate too). The SPI module is configured in full duplex.


Here is the main function code after HAL initialization:
uint8_t txData[4]={0x06};
uint8_t rxData[4];
__enable_irq();
HAL_SPI_TransmitReceive(&hspi2, txData, rxData, 1,10000);
txData[0] = 0x02;
txData[1] = 0x00;
txData[2] = 0xDE;
txData[3] = 0xAD;
HAL_SPI_TransmitReceive(&hspi2, txData, rxData, sizeof(txData),10000);
Obviously I’d like to use ISR/DMA, but I tried to keep it simple for debugging and using polling can’t get any simpler...
Using an oscilloscope, I can see the clock on PB13, the data being clocked out on PB15. The transaction appers to work normally, but the code times out (HAL error code). By setting a breakpoint in HAL code I can see that it fails because the code expects RXP to be set at some point, but it is never set.
Then I tried to use SPI1 which is also implemented on the board using PB3 (SCK), PB4 (MISO), PD7 (MOSI) with the exact same settings (except it uses SPI1). It all works as expected both with HAL code (HAL_OK) and my bare metal driver. So there definitely has something with SPI2 that I must do to make it work.
I tried the following:
- I force injected 3.3V on the MISO signal to see if the I/O pad is getting the signal. Using the debugger I can see that IDR register detects the signal therefore either the SPI module is incorrectly configured or it is the mutiplexer that is not routing the signal to the SPI module.
- GPIO configuration seems correct to me: GPIOB->MODER (0x2 for AF), OSPEEDR (0x1: MEDIUM), OTYPER (0x0), and AFR (0x05 for AF5) are verified correct in debugger.
- I checked that the SPI module configuration looks sound. Sorry for the compact form. The settings match my config above and I’m really configured as Full duplex master (COMM=00’b), so the data should be clocked in at some point.

- No matter the length of the transaction, the module clocks out whatever it has to clock out, but it won’t raise RXP flag even once.
- There are no error flags at all that are set, so it appears the transaction works just fine and TSIZE it accounted for as expected.
- Since UCPD can interfere, I disabled it with HAL_PWREx_DisableUCPDDeadBattery().
- I also tried to turn on the clock of UCPD and clear UCPD_CR_CC1TCDIS and UCPD_CR_CC2TCDIS (in case it would be necessary) before-hand. No dice.
At this point I’m at a loss. I’m pretty sure other people succeeded at configuring this SPI2 module, so there must be something I’m missing. Normally HAL code works, but this one time it doesn’t appear to be, so I must be missing a configuration field on some seemingly unrelated module.
Side note: when debugging I didn’t step the code as reading the rx data register through the SFR window would clear RXP, so I just put a breakpoint at the line where it would return the TIMEOUT error code in the HAL code and I pressed run to reach directly that place. There is a variable that should be decrementing whenever RXP is set, but that variable still holds the initial amount of bytes to read, confirming that RXP never gets set.
I can provide more detail, but other than adding HAL_PWREx_DisableUCPDDeadBattery() and the piece of code above, my HAL code is exactly as is what STM32CubeMX generated. ioc file attached.
Best regards
