STM32 gotchas

This is a collection of more or less unexpected or surprising behaviour of STM32 microcontrollers, whether documented or not. What constitutes a gotcha is subjective, and some of the items here are not gotchas at all, just poiting out a feature or idiosyncracy, which may be surprising for some. Also, some of the items are not STM32-specific at all, but apply more broadly to ARM Cortex-M-based mcus, or are related to C or programming generally.

This collection will grow, check back or subscribe to the RSS if you want to follow. Oh yes, no social media, learn how to use real information sources.

Many items are a result of discussion at STM32 forum at community.st.com. I'll try to give relevant links to forum threads where applicable, but they have changed in the past and may do so in the future too, and I won't be able to go and fix all of them. ST assisted me to migrate most of the links lost during migration of forum in 2023.

There's no particular ordering or sorting, it would be hard to find out something half-sane, so just browse through and enjoy.

NEW! First 200 gotchas now also in a single pdf.

Legalese: STMicroelectronics registered STM32 as a trademark in various countries, although I don't exactly know what are the ramifications of this, I am not a lawyer. I am not affiliated with ST. In what I write here I may be completely wrong, use below information at your own risk.

Comments are welcome, email them to stm32 at efton dot sk.

  1. Peripheral clock must be enabled in RCC (else registers cannot be written and read as 0)
  2. Timers' clock is 2x APB clock, if APB divider > 1
  3. Advanced timers (TIM1, TIM8, ...), to enable output, need to set TIMx_BDTR.MOE
  4. Debugging is intrusive (e.g. UART/SPI Rx may not work when debugging)
  5. 'F4/'F2 CCM RAM is not good for DMA nor for bit-banding, nor for code
  6. RTC seemingly does not run if only time is read
  7. Interrupt called without reason (late interrupt source clear)
  8. Timer does not work if ARR=0
  9. TIMx->SR &= ~TIM_SR_flag results in lost interrupts (don't RMW or bit-band on status registers)
  10. Strange behaviour after increasing system clock frequency (FLASH latency has to follow system clock)
  11. DAC output does not go rail-to-rail and the output buffer makes it worse
  12. UART parity bit missing as it counts up to data bits
  13. Delay is 1ms longer than required (SW/library, not STM32-specific)
  14. GPIO is not toggling at a rate promised by datasheet
  15. Timer appears to run slower than is set (unrealistically high interrupt rate)
  16. Interrupt does not fire - some troubleshooting hints
  17. Program freezes after enabling an interrupt
  18. ADC readings not as expected because of high signal impedance
  19. Debugger keeps jumping into interrupt when single stepping on 'F746
  20. NDTR problematic when DMA used as Rx FIFO
  21. SPI master NSS unusable
  22. Writing one byte to SPI transmits two bytes (because of data packing)
  23. STM32 hangs in UART interrupt if Rx overrun is not handled
  24. UART Rx stops working (Rx overrun revisited)
  25. STM32 are not microcontrollers, but SoC causing various timing-related issues
  26. Don't use printf() in interrupt or any other lengthy operation
  27. In 'F4, after enabling backup domain access in PWR, wait before accessing RCC_BDCR or BKPSRAM
  28. SPI master does not work as NSS switches it to slave
  29. Processor (and debugger) hangs while debugging OTG USB Host
  30. Only DMA2 can be used to transfer to/from GPIO in 'F4 and 'F2/'F7
  31. Timer - if compare is enabled, setting CCRx > ARR still causes interrupts and DMA and TRGO
  32. SPI generates too many clocks while Rx in Bidir more, and in Rx-only mode
  33. Smaller packages require port remapping for certain functions namely the USB pins PA11 PA12 on 'F042 in TSSOP20
  34. ADC in 'L47x/48x has an extra switch in GPIOx_ASCR
  35. 'F1 don't have the GPIO AF matrix unlike all other STM32 families
  36. Peripherals don't have unique AF number in GPIO matrix they do in 'L1 and mostly do in 'F2/'F4/'F7
  37. GPIO pin input state can still be read, if it's set to Out or AF and EXTI works, too
  38. Analog switch voltage booster (for ADC and other) to be switched on at lower VDD on certain STM32
  39. Software or watchdog reset does not work if NRST is pulled-up hard externally
  40. First TIM period is too short, prescaler does not work - PSC is preloaded; and so is RCR
  41. One TIM period is too long/one PWM pulse is shorter/longer than expected - use preload when needed
  42. First TIM Update ("PeriodElapsed") interrupt fires immediately after configuration when using Cube/SPL
  43. No bit-banding in Cortex-M0/M0+ but not in Cortex-M7 either
  44. Some STM32 models after first programming don't run and need power-on reset (AN2606 pattern6)
  45. Not only frequency but also VOS setting implies FLASH waitstates
  46. Some pins on my Disco/Nucleo/EVAL board don't work as expected
  47. TIMx_CHxN is not inverted if TIMx_CHx is not enabled
  48. TIMx_CHxN cannot be used as input to timer
  49. F3 CCM RAM can't be used for DMA but it can be used for code
  50. In 'F4 CRC, data are ignored if written too soon after reset
  51. Not all TIM_CHx are created equal
  52. TIM - in Encoder mode, prescaler must be 0 (otherwise the counted value is nonsense)
  53. TIM does not run if ARR was changed from 0 to nonzero due to ARR preload
  54. In 'F1, RDP also sets write protection on first sectors
  55. 'F2/'F4/'F7/'H7 unreliable at higher frequencies due to incorrect VCAP capacitor
  56. Internal temperature sensor on ADC indicates surprisingly high temperature but it's most probably correct
  57. 'H7 lifetime may be surprisingly short at elevated working temperatures
  58. Changing clock frequency requires careful readjustment of peripherals
  59. PF4 on 'F303 does not work because it's missing on 'F303RD/E
  60. TIM DMA burst (DMAR/DCR) does not work properly if TIMx_DMAR observed in debugger
  61. In 'F42x/43x, erase sector does not work due to confusing sector numbering
  62. Backup domain is not reset by setting RCC_BDCR.BDRST unless PWR_CR.DBP is set, too
  63. Compatibility within the Value Line (0-ending) models
  64. Standard C library function does not work not STM32-specific
  65. Standard C library function (e.g. printf()) fails in interrupt or RTOS not STM32-specific
  66. SPI master Tx outputs 16 clocks, even if its Data Size set to 8 bit keyword: data packing
  67. Where are GPIO AF numbers given for individual pins? And where are the NVIC registers described?
  68. SPI_SR.BSY is unusable
  69. In 'F746/756, ADC triggering from TIM does not work properly but for some cases this can be fixed by switching on DAC
  70. Pins don't work even if set in GPIO due to nonzero default values in 'L0/'L4/'Gx/'H7 GPIOx_MODER
  71. RTC does not work because of RCC_APBxENR.RTCAPBEN bit in some models
  72. No DMA to/from GPIO in 'L0/'G0 i.e. where the Cortex-M0+ core is used
  73. Always read the Errata and not only those directly given for your STM32 model
  74. Write Protection (WRP) granularity may be non-uniform in large-FLASH 'F1/'F0/'F3
  75. Unexpected ETH interrupts after longer uptime due to MAC management counters interrupts being enabled by default
  76. RTC digital calibration does not apply to wakeup period with a specific wakeup source selection
  77. ETH does not work with certain APB2 clock settings due to internal delays between modules
  78. Using TIM input channel filter may produce confusing results if fed with periodic signal
  79. If TIM is set to downcounter, 0% PWM is not possible
  80. When processor stopped in debugger, peripherals and DMA if used by those peripherals keep running
  81. Crash due to stack content getting corrupted DMA writes to buffer improperly allocated on stack
  82. On the RTC readout lock mechanism and its deficiencies
  83. Cannot access BKPSRAM in CubeProgrammer unless register values are manipulated
  84. GPIO pin does not output enough current if set to low GPIO_OSPEEDR setting
  85. Not all GPIO pins are created equal e.g. PA10/PB12 pullup/down in 'F2/'F4/'F7 is only 10kΩ
  86. 'G0/'G4 USB-C Dead Battery conundrum pin influenced by other pin, unexpected pulldowns
  87. UART Tx is not driven immediately after enabling UART and UART_BRR has to be set properly
  88. The Y2k38 bug not STM32-specific
  89. How to set TRGO in TIM16/TIM17? Also, TIM channel needs output enabled if controls another module, e.g. ADC.
  90. Some time after peripheral (TIM, SPI, etc.) function finished, pin state changes resulting in unwanted clock/transition
  91. Some interrupts cannot be disabled, and attempts to do so may lead to HardFault e.g. SysTick
  92. Peripheral connected to other than a single pin in GPIO AF matrix #GPIO_is_poorly_documented
  93. Timers don't support DIR/STEP encoders except in 'G4/'U5 - but a trick may exist
  94. 'G4 lifetime may be surprisingly short at elevated working temperatures
  95. How to achieve consistent RTC readout?
  96. TCM don't support highest clock frequencies in 'H723/725
  97. 5V-tolerant pins don't always tolerate 5V especially if mcu is powered down
  98. FLASH is not erased to 0xFF in 'L0 and 'L1 but to 0x00
  99. FLASH is 0xFF but cannot be written if there's ECC and granule has been already written
  100. In lower-end 'F0xx, GPIOC/GPIOD don't have AFR[2] registers
  101. VDDA is pulled high when ADC is enabled if VDDA<2.4V and booster not enabled
  102. STLink-V3 8MHz MCO output is not derived from crystal partial workaround available
  103. After being cleared in NVIC outside an ISR, interrupt reappears if pending flag in NVIC is cleared too soon after removing the interrupt source
  104. USB packet buffer memory in 'F042 is not bytewise writable
  105. Clicked ETH/USB in CubeIDE/CubeMX, and it does not work
  106. Bit-banding cannot be used with DMA
  107. No atomic access through bit-banding to GPIO registers' bits except in 'F1
  108. Toggling GPIO in 'H7 is slow due to complex bus structure
  109. PF0/PF1/PC14/PC15 don't work GPIO overriden by oscillator enabled in RCC
  110. Using interrupt or DMA, only first few data are transmitted correctly due to local variable as buffer - not ST-specific
  111. Some interrupts invoke incorrect ISR if VTOR is not properly aligned
  112. After setting GPIOA things stop to work due to overwriting SWD pins settings
  113. Used this Cube/SPL function and it works weird uninitialized struct as parameter
  114. Some TIM register fields are not continuous in newer STM32 families
  115. Incorrect values from internal temperature sensor due to errorneous values in 'G4 datasheet
  116. RTC loses half a second per powerup/reset Cube bug, fixed
  117. Current consumption in sleep modes unexpectedly high during debugging due to debugging in sleep enabled by DBGMCU_CR bits
  118. DWT_CYCCNT does not work in some sleep modes
  119. ETH IPv4 checksum offload does not work if checksum fields in the packet submitted to ETH/MAC are not zero
  120. Unique ID (UID) is not available in some STM32 families
  121. 96-bit Unique ID cannot be shortened and still considered unique
  122. Unique ID is not at continuous addresses in memory in some STM32 families
  123. INITS flag may not be the best indicator of RTC having been already initialized if date has not been set
  124. Calibration values (UniqueID, temperature, internal VREF) are not at the same address not even within the same family
  125. USB/DFU bootloader in 'F4/'F7 may start unreliably with higher frequency crystals
  126. Not all STM32F730 are created equal and some don't have the built-in HS USB PHY
  127. Built-in USB HS PHY in 'F723/'F730 requires certain crystal frequencies
  128. In 'F2, subseconds don't work in RTC nor smooth calibration (and same is for 'L1 Cat.1)
  129. In 'F1, PA15/PB3/PB4 don't work they are assigned to JTAG by default
  130. In 'F1, PA15/PB3/PB4 stop working after remapping unrelated peripherals AFIO_MAPR.SWJ_CFG bits are write-only
  131. Undefined AF in GPIO may turn pin to output
  132. DMA vs. DMAMUX numbering discrepancy
  133. PA2 unexpectedly outputs a 32kHz signal? RTC behaves strangely? Maybe consequence of VBAT brownout
  134. Internal VREFBUF reference not available in lower-pin-count packages where VREF+ is bonded to VDDA
  135. Using the internal VREFBUF reference requires a specific value capacitor connected to VREF+ pin
  136. Cannot reprogram FLASH after inadvertent write access to FLASH area, and if Cube/HAL is used
  137. Communication errors in prototype on breadboard/with flying leads - on importance of signal integrity and proper ground/return (not STM32-specific)
  138. Built-in bootloader works unreliably or not at all if there is activity on other bootloader-related pins
  139. BOOT0 pin pulled up, but bootloader does not start in 'F1/'L1/'F2/'F4 you need to pull down BOOT1, too
  140. Not all TIM2/TIM5 are created equal in some STM32 they are not 32-bit
  141. On UART IDLE frame insertion upon UART_CR1.TE being set
  142. Not all TIMx_RCR are created equal some are 8-bit, some 16-bit
  143. VREFINT and temperature calibration values not available in 'F1 and 'F2
  144. Timer trigger interrupt/DMA does not work until TIMx_SMCR.SMS is set to nonzero
  145. Not all TIM input polarity selection created equal in non-XL 'F1 there's no both-edges selection
  146. Only one EXTI per pin number, this means routing which is different in 'F1 and 'G0/'C0/'L5/'U5
  147. Slow input signal slew rate may cause multiple interrupts especially with EXTI, which is asynchronous
  148. Touchscreen flipped or does not work on 32F429IDISCOVERY
  149. Incorrect ADC readout due to missing calibration
  150. Incorrect ADC readout in some families due to the "wrong result after 1ms delay" erratum
  151. Missing ADC codes in 'H7 due to missing calibration
  152. Internal temperature sensor returned unexpected value so here's some troubleshooting guide
  153. Internal temperature sensor, VREFINT and VBAT can't be part of a fast ADC sequence in families where ADC has a common sampling-length register
  154. In 'L07x, some TIM3_CHx pins don't work unless remapped in TIM3_OR
  155. After programming/reset/power cycle, program does not work and debugging ends up at 0x1FFFxxxx addresses
  156. USB and PG2..PG15 don't work on some STM32 they have a dedicated power pin and an isolation switch
  157. In 'U5, ADC calibration hangs if VDDA isolation is not removed
  158. STM32F407 runs at cca 20x lower frequency than set a RCC/HSE/PLL puzzle
  159. PLLI2S/PLLSAI outputs unexpected frequency due to prescaler shared amongst PLLs
  160. LSI in 'U5 does not work unless Backup Domain access is enabled before enabling LSI
  161. No connectivity from ETH and OTG-HS to FLASH in 'F407 and 'F446 so ETH/USB won't transmit const data
  162. LPUART Rx clocked from LSE corrupts bytes at 9600 Baud unless LPUART_CR3.UCESM is set
  163. UART Rx corruption if glich occurs during 2nd half of stopbit
  164. Strange characters received in terminal in PC parity or baudrate mismatch, or RS232 converter was used for UART
  165. UART/USART conundrum
  166. FMC/FSMC conundrum
  167. 'H7 longevity revisited
  168. Inconsistent numbering considered harmful especially mixing 0-based and 1-based numbering
  169. Inconsistent naming considered harmful especially between RM and CMSIS-mandated device headers
  170. Programming 'G0/'C0 from built in bootloader has to be well-planned as default bootloader entry depends on empty FLASH
  171. 'G0/'G4 bricked after programming RDP1 if BOOT_LOCK is set
  172. UART receives zeros? Using pullup with UART_Rx may be a good idea not STM32-specific
  173. Some remarks on UART used in halfduplex mode
  174. Anecdotes about missing VDDx
  175. Data register reads zero in 'H7 SPI/I2S if read width is narrower than data width set for SPI/I2S
  176. SPI/I2S set to PCM runs twice the expected sample rate PCM is MONO, I2S is STEREO
  177. I2SxExt allows not only fullduplex SPI, but also dual-Tx/dual-Rx
  178. I2SxExt_SD and SPIx_MISO are different AF in 'F4, but the same AF in 'F3
  179. I2S clock numbering is confusing in 'F446 and 'F413
  180. In TIM, TRGI signal is generated only if TIMx_SMCR.SMS is nonzero
  181. On the Commutation event (COM) in some timers
  182. TIM channel can't be enabled in TIMx_CCER if TIMx_CR2.CCPC is set by mistake
  183. After enabling clock in RCC, delay may be needed before accessing some peripherals
  184. DMAMUX clock how to enable
  185. What's all this kernel clock stuff, anyhow?
  186. Some kernel clocks are not selected/enabled in RCC
  187. Where's that clock enable? It's tied to some other peripheral.
  188. ... and then there's also no clock enable at all...
  189. ... or the clock is enabled by default...
  190. ... or the clock enable bit is just named confusingly
  191. Datecode in chip marking is not unique as year is single digit
  192. What's up with these -P and -Q suffixed STM32? They have different pinout than the non-suffixed ones.
  193. My STM32 board does not work. Are all these pins properly connected?
  194. PLL does not output expected frequency or does not work at all physical ratio not identical to value in registers
  195. PLL output does not work if its enable bit is not set
  196. Not all RTC are created equal
  197. Problems with day rollover in 'F1 RTC if SPL/Cube are used
  198. RTC at midnight does not roll over, but goes to 24:00:00 and counts up
  199. RTC clock source can be set only once
  200. LSI is not a good clock to keep real time in RTC
  201. STM32 with SMPS+LDO may be hard to recover, if inadvertently set to SMPS upon startup
  202. HRTIM cannot output duty cycles below 3 ticks
  203. FPU must be enabled before main() else fault may occur in main() prologue
  204. 'L4P5 and 'L4R5 are very similar but different resulting in binary compatibility broken in subtle but possibly significant ways
  205. In 'L4P5, TAMPER clears SRAM2 leading to surprising crashes if data or stack are located in SRAM2
  206. In 'G0Bx, erratum makes both FLASH banks barely usable for code
  207. Neo-Chrom graphic processor (GPU2D) is undocumented
  208. Strange ADC readings on some ('L4+) Disco boards due to VREF+ not powered in anticipation of using internal VREFBUF
  209. ADC/DAC readings don't correspond to VREFBUF setting due to VREF+ being connected to external voltage source
  210. ADC at low sampling rate needs LFTRIG bit set in 'G0/'C0/'U0/'U5
  211. Unexpected ADC readings when using interrupt and ISR execution is too slow
  212. ADC at maximum speed may be difficult to read even with DMA
  213. ADC with DMA stops working
  214. ADC in polling/interrupt mode stops working due to ADC_DR being observed in debugger
  215. Using asynchronous clock in ADC increases chances for repeated/"false" interrupts due to late interrupt flag clear
  216. ADC sampling causes "dip" in the input signal and this may cause problems if this signal has other purposes, too
  217. Incorrect ADC readout because VREF+ impedance matters