2025-06-01 6:39 PM - edited 2025-06-01 6:51 PM
All,
I have somehow concocted a CubeMX configuration (attached) that causes the CPU to latch up when the LTDC clock is enabled during HAL initialization. Here's what I'm seeing/doing:
Here's the "before":
Before the crash
And here's the "after":
After the crash
My question is... why is this happening? It does this on both the U5G9 DK2 board and our custom board. I have a valid(?) 32.4 MHz clock going to the LTDC. It's sourced from PLL2R, which in turn is sourced from HSE (16 MHz). I created a quickie test project which just initializes the clocks and the UARTs, and I can get correct UART output from our board while running the CPU and peripheral buses on an HSE-derived PLLCLK (PLL1R), which should be proof that our 16 MHz crystal is good. I see the same behavior if I switch to using HSI (16 MHz) instead of HSE for PLL1 and PLL2.
A peripheral causing an internal fault when being accessed is, in my experience, an indicator of the peripheral not being clocked. But the peripheral registers are already readable until __HAL_RCC_LTDC_CLK_ENABLE() is called, at which point the CPU and debugger both die.
Now, here's the important bit... if you close the Variables view, such that the debugger is not accessing the LTDC peripheral memory, and you step over __HAL_RCC_LTDC_CLK_ENABLE(), the program continues to function. I am able to step over (F6) the rest of HAL_LTDC_MspInit() and return to HAL_LTDC_Init(). But once that function starts to access the LTDC registers to configure the peripheral, it dies. Again, here's the before:
Before program crash
And here's the after, trying to step over line 277:
After program crash
So it still dies even if you don't have the debugger Variables view open; it's the act of trying to read LTDC peripheral registers (after __HAL_RCC_LTDC_CLK_ENABLE() has been called) that kills the processor and debugger. I used the attached IOC file to generate a new STM32 CubeMX project, and the generated project exhibits this failure, so you should be able to use this IOC file to try to reproduce my failure. I'm running the latest IDE (v1.18.1, Windows) with the latest CubeMX packages.
Any idea what I'm doing wrong?
Dana M.
2025-06-01 8:36 PM - edited 2025-06-01 8:45 PM
FWIW, I created a new project where I'm going to start with nothing but the bare minimum to allow me to initialize the LTDC without complaints:
For giggles, I also enabled USART1 on PA9/10 and added code just before the main loop:
/* Need to #include <string.h> up top. */
const char *str = "Hi mom.\r\n";
HAL_UART_Transmit_IT(&huart1, (const uint8_t*) str, strlen(str));
And with this configuration, it works. Tracing through, I find... wait, what the heck? Here's the MSP init code from this minimal example I just created:
Clock init code generated
See all that clock initialization code there with PLL divisors and such? Here's the MSP init code from the "broken" IOC in my original post:
Clock init code not generated
There's no clock initialization code being generated there. Why? That's got to be the issue. What is it about my original IOC file that causes no PLL2R clock initialization code to be generated in HAL_LTDC_MspInit()?
EDIT: If I graft the clock initialization code from the minimal example into my original project (using the user code begin/end block), LTDC initializes correctly, and the system runs. So... the issue seems to be the omission of the clock init code. If you can find out why it's doing that using the IOC file in my original post, I think that solves the issue.
Dana M.