Skip to main content
Geoffrey1
Associate III
August 13, 2026
Question

tearing down spi connection before stop1 breaks flash write on stm32u375

  • August 13, 2026
  • 7 replies
  • 53 views

That pretty much says it all.   Any attempt to tear down the connection (disable spi, disable dma, etc) before (long before) stop1 causes flash write after (many instructions after) the wfi to fail with PGSERR error.   Not tearing down the connection, flash write works, but standby doesn’t without additional work.   To be concrete

 

dma3ChannelFreeI(spip->dmatx);

 if (spip->state == SPI_READY) {

/* Just in case this has been called uncleanly.*/
(void) spi_lld_stop_abort(spip);

spip->spi->CFG1 &= ~(SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN);
spip->spi->CR1 &= ~SPI_CR1_SPE;

/* Releasing DMA channels.*/
dma3ChannelFreeI(spip->dmarx);
dma3ChannelFreeI(spip->dmatx);

 

Those two lines -- spip->spi→… are what break flash write.  Clearly there is an undocumented interaction between peripherals and the clock and data transfer system, but the documentation for the part is shockingly incomplete on important details such as this.

Leaving those lines out means standby doesn’t work unless I hit spi with a reset hammer.  Stop2 doesn’t work at all.

 

 

7 replies

waclawek.jan
Super User
August 14, 2026

Prepare a minimal but complete compilable example exhibiting the problem, and post.

JW

Geoffrey1
Geoffrey1Author
Associate III
August 14, 2026

You've got to be kidding.  ST has well documented issues (by users) with low power modes for which it has provided childishly incomplete documentation.  Provide documentation of the state machine handling these modes, don't ask users to develop test cases for buggy black boxes 

 

waclawek.jan
Super User
August 14, 2026

I’m not ST.

SPI and FLASH sounds to be detached enough so that any connection between them is likely to be through your code.

JW

ST Technical Moderator
August 14, 2026

Hi ​@Geoffrey1 

Thank you for reporting this. We need to reproduce the issue and isolate the root cause. This is HAL based example using SPI DMA transfer across STOP1, first you can add flash programming sequence after wake up from STOP1 to confirm the reference behavior and the second test would be to cleanly disable SPI and DMA before STOP1 to reproduce the issue. We need to check whether it’s incomplete SPI/DMA shutdown or STOP1 exit/wakeup timing issue or something else.

To give better visibility on the answered topics, please click on "Best answer" on the reply which solved your issue or answered your question.Best regards,FBL
Geoffrey1
Geoffrey1Author
Associate III
August 14, 2026

ok, this was super difficult to resolve and in the end I wrote a stand alone program to run on my board that did:

  1. Enable second alarm
  2. Do a spi dma operation
  3. (optionally) clear spi registers -- this is to test the incomplete clear
  4. enter stop mode (0, 1, or 2) waiting for second alarm
  5. attempt to write internal flash

Here’s what I found

 -- without fully clearing the spi registers (doing a complete shutdown), while the WFI worked, the core wasn’t actually in the low power state, and writing flash worked

-- with fully clearing the spi registers, the core entered the appropriate low power state and writing flash failed.

So, the spi issue, while not exactly a red herring, was causal only in that it blocked the low power state (btw, the documentation needs to address clearly what is required to enter a low power state).

In the end I had to explicitly restart the power mode and do some cleanup on flash (code follows).  This is, at best, under-documented in the reference manual.

Note: none of this diagnosis would have been possible without my Joulescope.  No amount of simply running code or staring at give the insight from actually measuring power levels and correlating them with specific I/O events

 

#define STM32_PWR_VOSR                      PWR_VOSR_RANGE1



static void idlePowerRecoverAfterStop(void)
{
uint32_t vos_ready = 0U;
const uint32_t flash_acr =
(STM32_FLASH_ACR & ~FLASH_ACR_LATENCY_Msk) | STM32_FLASHBITS;

#if STM32_BOOSTER_ENABLED == TRUE
MODIFY_REG(RCC->CFGR4, RCC_CFGR4_BOOSTSEL | RCC_CFGR4_BOOSTDIV,
STM32_BOOSTSEL | STM32_BOOSTDIV);
WRITE_REG(PWR->VOSR, STM32_PWR_VOSR | PWR_VOSR_BOOSTEN);
#else
WRITE_REG(PWR->VOSR, STM32_PWR_VOSR);
#endif

if ((STM32_PWR_VOSR & PWR_VOSR_R1EN) != 0U)
{
vos_ready |= PWR_VOSR_R1RDY;
}
if ((STM32_PWR_VOSR & PWR_VOSR_R2EN) != 0U)
{
vos_ready |= PWR_VOSR_R2RDY;
}
#if STM32_BOOSTER_ENABLED == TRUE
vos_ready |= PWR_VOSR_BOOSTRDY;
#endif

for (uint32_t timeout = IDLE_STOP_WAIT_LIMIT;
(timeout > 0U) && ((PWR->VOSR & vos_ready) != vos_ready);
timeout--)
{
__NOP();
}

#if TAG_IDLE_STOP_DIAGNOSTICS
if ((vos_ready != 0U) && ((PWR->VOSR & vos_ready) != vos_ready))
{
palSetLine(LINE_LED1);
}
#endif

CLEAR_BIT(FLASH->ACR, IDLE_FLASH_STOP_BITS);
WRITE_REG(FLASH->ACR, flash_acr & ~IDLE_FLASH_STOP_BITS);

for (uint32_t timeout = IDLE_STOP_WAIT_LIMIT;
(timeout > 0U) &&
((FLASH->SR & IDLE_FLASH_POWERDOWN_FLAGS) != 0U);
timeout--)
{
__NOP();
}

#if TAG_IDLE_STOP_DIAGNOSTICS
if ((FLASH->SR & IDLE_FLASH_POWERDOWN_FLAGS) != 0U)
{
palSetLine(LINE_LED1);
}
#endif

SET_BIT(FLASH->SR, IDLE_FLASH_CLEAR_FLAGS);
}

 

TDK
August 14, 2026

There is plenty of documentation saying how to enter low power modes and why it may not be working right. There are also examples for entering these states. Hard to say if this note in particular was the relevant one, seems likely. There’s also a few notes in the low-power section that seem relevant. It’s easy to just blame documentation but it’s more productive to enter these situations with the idea that maybe the answer is there and you’re the one missing it. The RM is 2870 pages. It’s reasonable and expected to miss stuff.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Geoffrey1
Geoffrey1Author
Associate III
August 14, 2026

I'm pretty sure that specific problems,  that stop1 does not restore range 1, and the flash is not writable without added work after stop 1 are not documented.   I've read everything that the reference manual has to say about stop modes.  Id be surprised if the total is more than 1000 words.  So yes, I blame the documentation,  and the verbose, but at the same trivial examples in the hal.

I've written processor specifications, designed processors and, early in life, worked as an application engineer.  So I have a pretty clear idea what is involved.   Enumerating the bits, but not the behavior and error modes is insufficient.