mirror of
https://github.com/hathach/tinyusb.git
synced 2026-08-18 11:02:16 +00:00
stm32h5: TRACE_ETM support and stm32h563nucleo reference
H5 hangs its debug AP if trace CoreSight is touched unclocked (recover = power-cycle): the reference's AfterTargetConnect clocks the DBGMCU trace domain but defers IOEN to firmware, or the mid-boot clock switch desyncs the decoder. Stock solder bridges make the CN5 path marginal: validated config is 100 MHz core, width 1, +5 ns (board.h selects the reduced clock for TRACE_ETM builds); width 4 / 250 MHz retest waits on SB removal.
This commit is contained in:
@ -88,7 +88,12 @@ static inline void SystemClock_Config(void) {
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLL1_SOURCE_HSE;
|
||||
RCC_OscInitStruct.PLL.PLLM = 4;
|
||||
#ifdef TRACE_ETM
|
||||
RCC_OscInitStruct.PLL.PLLN = 100; // 100 MHz core: the Nucleo trace path (CN5 via solder bridges)
|
||||
// corrupts the trace stream at higher TRACECLK (= SYSCLK/2)
|
||||
#else
|
||||
RCC_OscInitStruct.PLL.PLLN = 250;
|
||||
#endif
|
||||
RCC_OscInitStruct.PLL.PLLP = 2;
|
||||
RCC_OscInitStruct.PLL.PLLQ = 2;
|
||||
RCC_OscInitStruct.PLL.PLLR = 2;
|
||||
|
||||
113
hw/bsp/stm32h5/boards/stm32h563nucleo/ozone/stm32h563.jdebug
Normal file
113
hw/bsp/stm32h5/boards/stm32h563nucleo/ozone/stm32h563.jdebug
Normal file
@ -0,0 +1,113 @@
|
||||
/*********************************************************************
|
||||
*
|
||||
* OnProjectLoad
|
||||
*
|
||||
* Function description
|
||||
* Project load routine. Required.
|
||||
*
|
||||
* Notes
|
||||
* Nucleo-H563ZI trace: PE2-PE6 reach the MIPI-20 connector (CN5) only
|
||||
* with SB8, SB9, SB64, SB68, SB70, SB71, SB78 removed (MB1404 UM).
|
||||
* Firmware must be built with TRACE_ETM=1 (trace pin + DBGMCU init).
|
||||
*
|
||||
* The trace path through the solder bridges is signal-marginal: reliable
|
||||
* only at 100 MHz core (TRACE_ETM builds select this automatically in
|
||||
* board.h), port width 1 and +5 ns sample timing (validated empirically;
|
||||
* width 4 or 250 MHz core corrupts the stream within ~100 ms).
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
void OnProjectLoad (void) {
|
||||
Project.SetTraceSource ("Trace Pins");
|
||||
Project.SetTracePortWidth (1);
|
||||
Project.SetTraceTiming (5000, 5000, 5000, 5000);
|
||||
Project.SetSWO (0);
|
||||
Edit.SysVar (VAR_TRACE_CORE_CLOCK, 100000000);
|
||||
Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M33F.svd");
|
||||
|
||||
Project.SetDevice ("STM32H563ZI");
|
||||
Project.SetHostIF ("USB", "");
|
||||
Project.SetTargetIF ("SWD");
|
||||
Project.SetTIFSpeed ("4 MHz");
|
||||
|
||||
File.Open ("../../../../../../examples/cmake-build-stm32h563nucleo/device/cdc_msc/cdc_msc.elf");
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* AfterTargetConnect
|
||||
*
|
||||
* Function description
|
||||
* Enable the trace clock domain (DBGMCU_CR: TRACE_IOEN | TRACE_CLKEN |
|
||||
* TRACE_MODE=4-bit) BEFORE Ozone touches the trace CoreSight components.
|
||||
* On STM32H5 an access to unclocked trace components hangs the debug AP
|
||||
* ("Failed to read target status") until the board is power-cycled.
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
void AfterTargetConnect (void) {
|
||||
unsigned int cr;
|
||||
cr = Target.ReadU32(0x44024004); // DBGMCU_CR
|
||||
// clock the domain (CLKEN|MODE=4-bit) but keep the pins OFF (clear IOEN):
|
||||
// the pins must only go live via firmware trace_etm_init() AFTER the system
|
||||
// clock switch, or the mid-trace frequency change desyncs the decoder.
|
||||
Target.WriteU32(0x44024004, (cr & 0xFFFFFFEF) | 0xE0);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* AfterTargetReset
|
||||
*
|
||||
* Function description
|
||||
* Event handler routine.
|
||||
* - Sets the PC register to program reset value.
|
||||
* - Sets the SP register to program reset value on Cortex-M.
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
void AfterTargetReset (void) {
|
||||
unsigned int SP;
|
||||
unsigned int PC;
|
||||
unsigned int VectorTableAddr;
|
||||
|
||||
VectorTableAddr = Elf.GetBaseAddr();
|
||||
|
||||
if (VectorTableAddr == 0xFFFFFFFF) {
|
||||
Util.Log("Project file error: failed to get program base");
|
||||
} else {
|
||||
SP = Target.ReadU32(VectorTableAddr);
|
||||
Target.SetReg("SP", SP);
|
||||
|
||||
PC = Target.ReadU32(VectorTableAddr + 4);
|
||||
Target.SetReg("PC", PC);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* AfterTargetDownload
|
||||
*
|
||||
* Function description
|
||||
* Event handler routine.
|
||||
* - Sets the PC register to program reset value.
|
||||
* - Sets the SP register to program reset value on Cortex-M.
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
void AfterTargetDownload (void) {
|
||||
unsigned int SP;
|
||||
unsigned int PC;
|
||||
unsigned int VectorTableAddr;
|
||||
|
||||
VectorTableAddr = Elf.GetBaseAddr();
|
||||
|
||||
if (VectorTableAddr == 0xFFFFFFFF) {
|
||||
Util.Log("Project file error: failed to get program base");
|
||||
} else {
|
||||
SP = Target.ReadU32(VectorTableAddr);
|
||||
Target.SetReg("SP", SP);
|
||||
|
||||
PC = Target.ReadU32(VectorTableAddr + 4);
|
||||
Target.SetReg("PC", PC);
|
||||
}
|
||||
}
|
||||
@ -99,6 +99,24 @@ static UART_HandleTypeDef UartHandle = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef TRACE_ETM
|
||||
static void trace_etm_init(void) {
|
||||
// H5 trace pins are PE2 to PE6 (Nucleo-144: requires trace solder-bridge config, see board docs)
|
||||
GPIO_InitTypeDef gpio_init;
|
||||
gpio_init.Pin = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6;
|
||||
gpio_init.Mode = GPIO_MODE_AF_PP;
|
||||
gpio_init.Pull = GPIO_PULLUP;
|
||||
gpio_init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
gpio_init.Alternate = GPIO_AF0_TRACE;
|
||||
HAL_GPIO_Init(GPIOE, &gpio_init);
|
||||
|
||||
// Enable trace port + clock, synchronous 4-bit mode
|
||||
DBGMCU->CR |= DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_CLKEN | DBGMCU_CR_TRACE_MODE;
|
||||
}
|
||||
#else
|
||||
#define trace_etm_init()
|
||||
#endif
|
||||
|
||||
void board_init(void) {
|
||||
// Cache UID before ICACHE is enabled (STM32H5 errata: reading UID_BASE with ICACHE causes hard fault)
|
||||
volatile uint32_t* stm32_uuid = (volatile uint32_t*) UID_BASE;
|
||||
@ -127,6 +145,8 @@ void board_init(void) {
|
||||
__HAL_RCC_GPIOI_CLK_ENABLE();
|
||||
#endif
|
||||
|
||||
trace_etm_init();
|
||||
|
||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||
// 1ms tick timer
|
||||
SysTick_Config(SystemCoreClock / 1000);
|
||||
|
||||
Reference in New Issue
Block a user