summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/bsp/imxrt/boards/metro_m7_1011/ozone/metro_m7_1011.jdebug3
-rw-r--r--hw/bsp/imxrt/boards/mimxrt1170_evkb/board.h5
-rw-r--r--hw/bsp/imxrt/boards/mimxrt1170_evkb/ozone/mimxrt1176.jdebug69
-rw-r--r--hw/bsp/imxrt/boards/mimxrt1170_evkb/ozone/mimxrt1176_trace.JLinkScript11
-rw-r--r--hw/bsp/imxrt/family.c73
-rw-r--r--hw/bsp/lpc18/boards/lpcxpresso18s37/board.h6
-rw-r--r--hw/bsp/lpc18/boards/mcb1800/board.h27
-rw-r--r--hw/bsp/lpc18/boards/mcb1800/ozone/lpc1857.jdebug6
-rw-r--r--hw/bsp/lpc18/family.c1
-rw-r--r--hw/bsp/lpc40/boards/ea4088_quickstart/ozone/ea4088_quickstart.jdebug2
-rw-r--r--hw/bsp/lpc43/boards/ea4357/board.h16
-rw-r--r--hw/bsp/lpc43/boards/lpcxpresso43s67/board.h6
-rw-r--r--hw/bsp/lpc43/family.c6
-rw-r--r--hw/bsp/nrf/boards/nrf52840dk/ozone/nrf52840.jdebug2
-rw-r--r--hw/bsp/nrf/boards/nrf5340dk/ozone/nrf5340.jdebug6
-rw-r--r--hw/bsp/nrf/family.c6
-rw-r--r--hw/bsp/ra/boards/ra6m5_ek/ozone/ra6m5.jdebug2
-rw-r--r--hw/bsp/ra/boards/ra8m1_ek/ozone/ra8m1.jdebug17
-rw-r--r--hw/bsp/ra/boards/ra8m1_ek/ozone/ra8m1_trace.JLinkScript20
-rw-r--r--hw/bsp/ra/family.c29
-rw-r--r--hw/bsp/rp2040/boards/raspberry_pi_pico2/board.cmake14
-rw-r--r--hw/bsp/rp2040/boards/raspberry_pi_pico2/ozone/rp2350.jdebug70
-rw-r--r--hw/bsp/rp2040/family.c27
-rw-r--r--hw/bsp/samd5x_e5x/boards/same54_xplained/ozone/same54.jdebug89
-rw-r--r--hw/bsp/samd5x_e5x/family.c27
-rw-r--r--hw/bsp/same7x/boards/same70_xplained/board.h4
-rw-r--r--hw/bsp/same7x/boards/same70_xplained/ozone/same70.jdebug115
-rw-r--r--hw/bsp/same7x/family.c32
-rw-r--r--hw/bsp/stm32h5/boards/stm32h563nucleo/board.h5
-rw-r--r--hw/bsp/stm32h5/boards/stm32h563nucleo/ozone/stm32h563.jdebug113
-rw-r--r--hw/bsp/stm32h5/family.c20
-rw-r--r--hw/bsp/stm32h7/boards/stm32h743eval/ozone/stm32h743.jdebug3
-rw-r--r--hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/board.h6
-rw-r--r--hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/ozone/stm32h7s3.jdebug94
-rw-r--r--hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/ozone/stm32h7s3_trace.JLinkScript11
-rw-r--r--hw/bsp/stm32h7rs/family.c19
-rw-r--r--hw/bsp/stm32n6/boards/stm32n657nucleo/board.h6
-rw-r--r--hw/bsp/stm32n6/boards/stm32n657nucleo/ozone/stm32n657.jdebug94
-rw-r--r--hw/bsp/stm32n6/family.c22
39 files changed, 1045 insertions, 39 deletions
diff --git a/hw/bsp/imxrt/boards/metro_m7_1011/ozone/metro_m7_1011.jdebug b/hw/bsp/imxrt/boards/metro_m7_1011/ozone/metro_m7_1011.jdebug
index 90f9b77e5..80489b61c 100644
--- a/hw/bsp/imxrt/boards/metro_m7_1011/ozone/metro_m7_1011.jdebug
+++ b/hw/bsp/imxrt/boards/metro_m7_1011/ozone/metro_m7_1011.jdebug
@@ -10,6 +10,7 @@
*/
void OnProjectLoad (void) {
Project.SetTraceSource ("Trace Pins");
+ Project.SetTracePortWidth (4);
Project.SetTraceTiming (50, 50, 50, 50);
Project.SetDevice ("MIMXRT1011xxx4A");
Project.SetHostIF ("USB", "");
@@ -22,7 +23,7 @@ void OnProjectLoad (void) {
// timing delay for trace pins in pico seconds, default is 2 nano seconds
- File.Open ("../../../../../../examples/cmake-build-metro-m7-1011-sd/device/cdc_msc/cdc_msc.elf");
+ File.Open ("../../../../../../examples/cmake-build-metro_m7_1011/device/cdc_msc/cdc_msc.elf");
}
/*********************************************************************
diff --git a/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.h b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.h
index a6332d896..c041fd47b 100644
--- a/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.h
+++ b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.h
@@ -35,6 +35,11 @@
// required since iMXRT MCUX-SDK include this file for board size
#define BOARD_FLASH_SIZE (0x1000000U)
+// TRACE_ETM: this board wires the 100M PHY reset (ENET_RST_B) to
+// GPIO_LPSR_04; the family trace init holds it in reset (RMII lines share
+// the trace pads)
+#define TRACE_ETM_QUIET_ENET_PHY 1
+
// LED: IOMUXC_GPIO_AD_04_GPIO9_IO03
#define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL
#define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL
diff --git a/hw/bsp/imxrt/boards/mimxrt1170_evkb/ozone/mimxrt1176.jdebug b/hw/bsp/imxrt/boards/mimxrt1170_evkb/ozone/mimxrt1176.jdebug
new file mode 100644
index 000000000..6931b9cd1
--- /dev/null
+++ b/hw/bsp/imxrt/boards/mimxrt1170_evkb/ozone/mimxrt1176.jdebug
@@ -0,0 +1,69 @@
+/*********************************************************************
+*
+* OnProjectLoad
+*
+* Function description
+* Project load routine. Required.
+*
+* Notes
+* MIMXRT1170-EVKB trace requires board rework: the TRACE pads
+* (GPIO_DISP_B2_02..06) are factory-wired to the ENET_1G PHY - populate
+* 0-ohm R1881-R1886 to route them to the Cortex Debug+ETM connector J58
+* (EVKB Hardware User Guide 3.2).
+* Firmware must be built with TRACE_ETM=1 (trace pad mux + CSTRACE clock
+* + JTAG_nTRST/DMIC_DATA1 pad fix in board_init).
+*
+* Validated: port width 1, 0 ns sample timing, 50 MHz CSTRACE root
+* (25 MHz TRACE_CLK pin, set by trace_etm_init - the rework path corrupts
+* at the stock 132 MHz root) while the CM7 runs 996 MHz. A startup-burst
+* trace overflow is expected and benign; width 4 fails at any timing.
+*
+**********************************************************************
+*/
+void OnProjectLoad (void) {
+ // declares the CSSYS TPIU/funnel (system APB-AP, not in the CM7 ROM table)
+ Project.SetJLinkScript ("./mimxrt1176_trace.JLinkScript");
+ Project.SetTraceSource ("Trace Pins");
+ Project.SetTracePortWidth (1);
+ Project.SetTraceTiming (0, 0, 0, 0);
+ Project.SetSWO (0);
+ Edit.SysVar (VAR_TRACE_CORE_CLOCK, 996000000);
+ Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M7F.svd");
+
+ Project.SetDevice ("MIMXRT1176xxxA_M7");
+ Project.SetHostIF ("USB", "");
+ Project.SetTargetIF ("SWD");
+ Project.SetTIFSpeed ("4 MHz");
+
+ File.Open ("../../../../../../examples/cmake-build-mimxrt1170_evkb/device/cdc_msc/cdc_msc.elf");
+}
+
+/*********************************************************************
+*
+* AfterTargetReset
+*
+* Function description
+* JTAG_nTRST shares its pad with DMIC_DATA1, which drives it low by
+* default and kills ETM trace - mux the pad to GPIO before the app runs
+* (EVKB Hardware User Guide 3.2). No SP/PC init here: the app boots from
+* FlexSPI NOR, so the ROM bootloader must perform it (SEGGER wiki
+* "i.MXRT1176" / NXP community solution for ERR050708 boards).
+*
+**********************************************************************
+*/
+void AfterTargetReset (void) {
+ Target.WriteU32 (0x40C08028, 0xA); // IOMUXC GPIO_LPSR_10 -> GPIO12_IO10
+}
+
+/*********************************************************************
+*
+* AfterTargetDownload
+*
+* Function description
+* Intentionally empty: SP/PC init from the vector table would bypass the
+* ROM bootloader's FlexSPI setup (see AfterTargetReset note).
+*
+**********************************************************************
+*/
+void AfterTargetDownload (void) {
+}
diff --git a/hw/bsp/imxrt/boards/mimxrt1170_evkb/ozone/mimxrt1176_trace.JLinkScript b/hw/bsp/imxrt/boards/mimxrt1170_evkb/ozone/mimxrt1176_trace.JLinkScript
new file mode 100644
index 000000000..ef39235d8
--- /dev/null
+++ b/hw/bsp/imxrt/boards/mimxrt1170_evkb/ozone/mimxrt1176_trace.JLinkScript
@@ -0,0 +1,11 @@
+/* RT1176 pin trace: the CSSYS TPIU and ATB funnel live on the system APB-AP
+ * (AP2) and are not discoverable from the CM7 ROM table - declare them, or
+ * J-Link aborts with "Required trace components for pin trace not found!"
+ * (addresses per i.MX RT1170 RM memory map: CSSYS TPIU E004_6000, CSSYS ATB
+ * Funnel E004_5000; same values as SEGGER's RT1176 trace example script).
+ */
+int ConfigTargetSettings(void) {
+ JLINK_ExecCommand("CORESIGHT_SetTPIUBaseAddr = 0xE0046000 ForceUnlock = 1 APIndex = 2");
+ JLINK_ExecCommand("CORESIGHT_SetCSTFBaseAddr = 0xE0045000 ForceUnlock = 1 APIndex = 2");
+ return 0;
+}
diff --git a/hw/bsp/imxrt/family.c b/hw/bsp/imxrt/family.c
index 9f3297e9a..4bd7993f0 100644
--- a/hw/bsp/imxrt/family.c
+++ b/hw/bsp/imxrt/family.c
@@ -106,6 +106,74 @@ static void init_usb_phy(uint8_t usb_id) {
usb_phy->TX = phytx;
}
+#ifdef TRACE_ETM
+static void trace_etm_init(void) {
+#if defined(CPU_MIMXRT1011DAE5A)
+ // Metro M7 rev A "ETM Trace" rework: 4-bit TRACE + TRACE_CLK on the added
+ // 2x10 header; the RT1011 has a single mux option per trace signal
+ IOMUXC_SetPinMux(IOMUXC_GPIO_AD_00_ARM_TRACE0, 0U);
+ IOMUXC_SetPinMux(IOMUXC_GPIO_13_ARM_TRACE1, 0U);
+ IOMUXC_SetPinMux(IOMUXC_GPIO_12_ARM_TRACE2, 0U);
+ IOMUXC_SetPinMux(IOMUXC_GPIO_11_ARM_TRACE3, 0U);
+ IOMUXC_SetPinMux(IOMUXC_GPIO_AD_02_ARM_TRACE_CLK, 0U);
+ // fast slew, max speed, high drive
+ IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_00_ARM_TRACE0, 0x00F1U);
+ IOMUXC_SetPinConfig(IOMUXC_GPIO_13_ARM_TRACE1, 0x00F1U);
+ IOMUXC_SetPinConfig(IOMUXC_GPIO_12_ARM_TRACE2, 0x00F1U);
+ IOMUXC_SetPinConfig(IOMUXC_GPIO_11_ARM_TRACE3, 0x00F1U);
+ IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_02_ARM_TRACE_CLK, 0x00F1U);
+
+ // TRACE_CLK_ROOT already runs 132 MHz (PLL2/4) from BOARD_BootClockRUN,
+ // which leaves it gated - just ungate
+ CLOCK_EnableClock(kCLOCK_Trace);
+#elif defined(CPU_MIMXRT1176DVMAA_cm7)
+ // JTAG_nTRST pad is shared with DMIC_DATA1 which drives it low by default and
+ // breaks ETM trace - switch the pad to GPIO (MIMXRT1170-EVKB HUG 3.2)
+ IOMUXC_SetPinMux(IOMUXC_GPIO_LPSR_10_GPIO12_IO10, 0U);
+
+#ifdef TRACE_ETM_QUIET_ENET_PHY
+ // Hold the 100M Ethernet PHY (RTL8201) in reset: its RMII lines are
+ // hardwired to the trace pads and drive against the stream at speed. The
+ // reset net is a BOARD property (mimxrt1170_evkb: ENET_RST_B =
+ // GPIO_LPSR_04), hence the board.h gate.
+ IOMUXC_SetPinMux(IOMUXC_GPIO_LPSR_04_GPIO12_IO04, 0U);
+ GPIO12->GDIR |= (1U << 4);
+ GPIO12->DR &= ~(1U << 4);
+#endif
+
+ // TRACE0-3 + TRACE_CLK on GPIO_DISP_B2_02..06, fast slew + high drive
+ IOMUXC_SetPinMux(IOMUXC_GPIO_DISP_B2_02_ARM_TRACE00, 0U);
+ IOMUXC_SetPinMux(IOMUXC_GPIO_DISP_B2_03_ARM_TRACE01, 0U);
+ IOMUXC_SetPinMux(IOMUXC_GPIO_DISP_B2_04_ARM_TRACE02, 0U);
+ IOMUXC_SetPinMux(IOMUXC_GPIO_DISP_B2_05_ARM_TRACE03, 0U);
+ IOMUXC_SetPinMux(IOMUXC_GPIO_DISP_B2_06_ARM_TRACE_CLK, 0U);
+ IOMUXC_SetPinConfig(IOMUXC_GPIO_DISP_B2_02_ARM_TRACE00, IOMUXC_SW_PAD_CTL_PAD_DSE_MASK);
+ IOMUXC_SetPinConfig(IOMUXC_GPIO_DISP_B2_03_ARM_TRACE01, IOMUXC_SW_PAD_CTL_PAD_DSE_MASK);
+ IOMUXC_SetPinConfig(IOMUXC_GPIO_DISP_B2_04_ARM_TRACE02, IOMUXC_SW_PAD_CTL_PAD_DSE_MASK);
+ IOMUXC_SetPinConfig(IOMUXC_GPIO_DISP_B2_05_ARM_TRACE03, IOMUXC_SW_PAD_CTL_PAD_DSE_MASK);
+ IOMUXC_SetPinConfig(IOMUXC_GPIO_DISP_B2_06_ARM_TRACE_CLK, IOMUXC_SW_PAD_CTL_PAD_DSE_MASK);
+
+ // 100 MHz CSTRACE root (OscRc400M/4) -> 50 MHz TRACE_CLK pin (= root/2).
+ // With the PHY held in reset the CLK line is clean here; 133 MHz root
+ // (66 MHz pin) is marginal on this board, stock 132 MHz corrupts.
+ CLOCK_SetRootClockMux(kCLOCK_Root_Cstrace, kCLOCK_CSTRACE_ClockRoot_MuxOscRc400M);
+ CLOCK_SetRootClockDiv(kCLOCK_Root_Cstrace, 4);
+ CLOCK_EnableClock(kCLOCK_Cstrace);
+
+ // Enable the CM7 slave port on the platform trace funnel (E004_3000): the
+ // debugger only programs the CSSYS funnel/TPIU it was told about, and this
+ // in-between funnel resets with all ports disabled, silently eating the ETM
+ // stream. Core-side CoreSight accesses honor the lock, hence the LAR unlock.
+ *(volatile uint32_t *) 0xE0043FB0 = 0xC5ACCE55;
+ *(volatile uint32_t *) 0xE0043000 |= 1U;
+#else
+ #error "TRACE_ETM: no trace pin setup for this MCU variant"
+#endif
+}
+#else
+ #define trace_etm_init()
+#endif
+
void board_init(void) {
// make sure the dcache is on.
#if defined(__DCACHE_PRESENT) && __DCACHE_PRESENT
@@ -119,10 +187,7 @@ void board_init(void) {
SystemCoreClockUpdate();
BOARD_ConfigMPU(); // defined in board.h
-
-#ifdef TRACE_ETM
- //CLOCK_EnableClock(kCLOCK_Trace);
-#endif
+ trace_etm_init();
#if CFG_TUSB_OS == OPT_OS_NONE
// 1ms tick timer
diff --git a/hw/bsp/lpc18/boards/lpcxpresso18s37/board.h b/hw/bsp/lpc18/boards/lpcxpresso18s37/board.h
index 2cf4dbdf8..1be07c49e 100644
--- a/hw/bsp/lpc18/boards/lpcxpresso18s37/board.h
+++ b/hw/bsp/lpc18/boards/lpcxpresso18s37/board.h
@@ -76,6 +76,12 @@ static inline void board_lpc18_pinmux(void)
Chip_SCU_SetPinMuxing(pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T));
}
+
+// TRACE_ETM builds: no trace header is wired out on the LPCXpresso18S37 -
+// provide the no-op the family init expects (see mcb1800/ea4357 for a
+// board that routes the trace pins)
+static inline void board_trace_pinmux(void) {}
+
#ifdef __cplusplus
}
#endif
diff --git a/hw/bsp/lpc18/boards/mcb1800/board.h b/hw/bsp/lpc18/boards/mcb1800/board.h
index dba7a62a3..ec7f1fa95 100644
--- a/hw/bsp/lpc18/boards/mcb1800/board.h
+++ b/hw/bsp/lpc18/boards/mcb1800/board.h
@@ -48,15 +48,6 @@
static inline void board_lpc18_pinmux(void) {
const PINMUX_GRP_T pinmuxing[] = {
- // ETM Trace
- #ifdef TRACE_ETM
- { 0xF, 4, SCU_MODE_FUNC2 | SCU_MODE_HIGHSPEEDSLEW_EN },
- { 0xF, 5, SCU_MODE_FUNC3 | SCU_MODE_HIGHSPEEDSLEW_EN },
- { 0xF, 6, SCU_MODE_FUNC3 | SCU_MODE_HIGHSPEEDSLEW_EN },
- { 0xF, 7, SCU_MODE_FUNC3 | SCU_MODE_HIGHSPEEDSLEW_EN },
- { 0xF, 8, SCU_MODE_FUNC3 | SCU_MODE_HIGHSPEEDSLEW_EN },
- #endif
-
// LEDs
{ 0xD, 10, (SCU_MODE_INBUFF_EN | SCU_MODE_INACT | SCU_MODE_FUNC4) },
{ 0xD, 11, (SCU_MODE_INBUFF_EN | SCU_MODE_INACT | SCU_MODE_FUNC4 | SCU_MODE_PULLDOWN) },
@@ -96,6 +87,24 @@ static inline void board_lpc18_pinmux(void) {
}
}
+#ifdef TRACE_ETM
+// Must run AFTER Chip_SetupCoreClock: muxing the trace pins earlier starts
+// TRACECLK at the boot clock and the mid-init frequency switch desyncs the
+// trace decoder ("Unknown trace data packet").
+static inline void board_trace_pinmux(void) {
+ // SCU_MODE_INACT: disable the pull-up on the 60 MHz trace lines - leaving it
+ // enabled degrades the edges enough for intermittent decode corruption.
+ const PINMUX_GRP_T trace_pinmux[] = {
+ { 0xF, 4, SCU_MODE_INACT | SCU_MODE_FUNC2 | SCU_MODE_HIGHSPEEDSLEW_EN },
+ { 0xF, 5, SCU_MODE_INACT | SCU_MODE_FUNC3 | SCU_MODE_HIGHSPEEDSLEW_EN },
+ { 0xF, 6, SCU_MODE_INACT | SCU_MODE_FUNC3 | SCU_MODE_HIGHSPEEDSLEW_EN },
+ { 0xF, 7, SCU_MODE_INACT | SCU_MODE_FUNC3 | SCU_MODE_HIGHSPEEDSLEW_EN },
+ { 0xF, 8, SCU_MODE_INACT | SCU_MODE_FUNC3 | SCU_MODE_HIGHSPEEDSLEW_EN },
+ };
+ Chip_SCU_SetPinMuxing(trace_pinmux, sizeof(trace_pinmux) / sizeof(PINMUX_GRP_T));
+}
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/hw/bsp/lpc18/boards/mcb1800/ozone/lpc1857.jdebug b/hw/bsp/lpc18/boards/mcb1800/ozone/lpc1857.jdebug
index f94960f09..a6dcef0eb 100644
--- a/hw/bsp/lpc18/boards/mcb1800/ozone/lpc1857.jdebug
+++ b/hw/bsp/lpc18/boards/mcb1800/ozone/lpc1857.jdebug
@@ -10,7 +10,7 @@
*/
void OnProjectLoad (void) {
Project.AddSvdFile ("Cortex-M3.svd");
- Project.AddSvdFile ("../../../../../../../cmsis-svd/data/NXP/LPC18xx.svd");
+ //Project.AddSvdFile ("../../../../../../../cmsis-svd/data/NXP/LPC18xx.svd");
Project.SetDevice ("LPC1857");
Project.SetHostIF ("USB", "");
@@ -20,8 +20,8 @@ void OnProjectLoad (void) {
Project.SetTraceSource ("Trace Pins");
Project.SetTracePortWidth (4);
- //File.Open ("../../../../../../examples/cmake-build-mcb1800/device/cdc_msc/cdc_msc.elf");
- File.Open ("../../../../../../examples/cmake-build-mcb1800/host/cdc_msc_hid/cdc_msc_hid.elf");
+ File.Open ("../../../../../../examples/cmake-build-mcb1800/device/cdc_msc/cdc_msc.elf");
+ //File.Open ("../../../../../../examples/cmake-build-mcb1800/host/cdc_msc_hid/cdc_msc_hid.elf");
}
/*********************************************************************
*
diff --git a/hw/bsp/lpc18/family.c b/hw/bsp/lpc18/family.c
index 8a612d9d8..58c2193fc 100644
--- a/hw/bsp/lpc18/family.c
+++ b/hw/bsp/lpc18/family.c
@@ -69,6 +69,7 @@ void SystemInit(void) {
#ifdef TRACE_ETM
// Trace clock is limited to 60MHz, limit CPU clock to 120MHz
Chip_SetupCoreClock(CLKIN_CRYSTAL, 120000000UL, true);
+ board_trace_pinmux(); // after clock setup so TRACECLK starts at its final frequency
#else
// CPU clock max to 180 Mhz
Chip_SetupCoreClock(CLKIN_CRYSTAL, MAX_CLOCK_FREQ, true);
diff --git a/hw/bsp/lpc40/boards/ea4088_quickstart/ozone/ea4088_quickstart.jdebug b/hw/bsp/lpc40/boards/ea4088_quickstart/ozone/ea4088_quickstart.jdebug
index 6aaf1076d..20de1e915 100644
--- a/hw/bsp/lpc40/boards/ea4088_quickstart/ozone/ea4088_quickstart.jdebug
+++ b/hw/bsp/lpc40/boards/ea4088_quickstart/ozone/ea4088_quickstart.jdebug
@@ -21,7 +21,7 @@ void OnProjectLoad (void) {
Project.SetTracePortWidth (4);
// User settings
- File.Open ("../../../../../../examples/device/cdc_msc/cmake-build-ea4088-quickstart/cdc_msc.elf");
+ File.Open ("../../../../../../examples/cmake-build-ea4088_quickstart/device/cdc_msc/cdc_msc.elf");
}
/*********************************************************************
diff --git a/hw/bsp/lpc43/boards/ea4357/board.h b/hw/bsp/lpc43/boards/ea4357/board.h
index fca617361..0152825f5 100644
--- a/hw/bsp/lpc43/boards/ea4357/board.h
+++ b/hw/bsp/lpc43/boards/ea4357/board.h
@@ -83,6 +83,22 @@ static const PINMUX_GRP_T pinmuxing[] = {
// { 0, 3, SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_FUNC0 },
//};
+#ifdef TRACE_ETM
+// Must run AFTER Chip_SetupCoreClock: muxing the trace pins earlier starts
+// TRACECLK at the boot clock and the mid-init frequency switch desyncs the
+// trace decoder. SCU_MODE_INACT keeps pull-ups off the 60 MHz lines.
+static inline void board_trace_pinmux(void) {
+ const PINMUX_GRP_T trace_pinmux[] = {
+ { 0xF, 4, SCU_MODE_INACT | SCU_MODE_FUNC2 | SCU_MODE_HIGHSPEEDSLEW_EN },
+ { 0xF, 5, SCU_MODE_INACT | SCU_MODE_FUNC3 | SCU_MODE_HIGHSPEEDSLEW_EN },
+ { 0xF, 6, SCU_MODE_INACT | SCU_MODE_FUNC3 | SCU_MODE_HIGHSPEEDSLEW_EN },
+ { 0xF, 7, SCU_MODE_INACT | SCU_MODE_FUNC3 | SCU_MODE_HIGHSPEEDSLEW_EN },
+ { 0xF, 8, SCU_MODE_INACT | SCU_MODE_FUNC3 | SCU_MODE_HIGHSPEEDSLEW_EN },
+ };
+ Chip_SCU_SetPinMuxing(trace_pinmux, sizeof(trace_pinmux) / sizeof(PINMUX_GRP_T));
+}
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/hw/bsp/lpc43/boards/lpcxpresso43s67/board.h b/hw/bsp/lpc43/boards/lpcxpresso43s67/board.h
index 4427905e8..6a317b5dc 100644
--- a/hw/bsp/lpc43/boards/lpcxpresso43s67/board.h
+++ b/hw/bsp/lpc43/boards/lpcxpresso43s67/board.h
@@ -71,6 +71,12 @@ static const PINMUX_GRP_T pinmuxing[] = {
{0x2, 5, SCU_MODE_INBUFF_EN | SCU_MODE_PULLUP | SCU_MODE_FUNC4 },
};
+
+// TRACE_ETM builds: no trace header is wired out on the LPCXpresso43S67 -
+// provide the no-op the family init expects (see mcb1800/ea4357 for a
+// board that routes the trace pins)
+static inline void board_trace_pinmux(void) {}
+
#ifdef __cplusplus
}
#endif
diff --git a/hw/bsp/lpc43/family.c b/hw/bsp/lpc43/family.c
index 5aff49704..411ea7d58 100644
--- a/hw/bsp/lpc43/family.c
+++ b/hw/bsp/lpc43/family.c
@@ -89,7 +89,13 @@ void SystemInit(void)
// Chip_SCU_ClockPinMuxSet(pinclockmuxing[i].pinnum, pinclockmuxing[i].modefunc);
// }
+#ifdef TRACE_ETM
+ // Trace clock is limited to 60MHz, limit CPU clock to 120MHz
+ Chip_SetupCoreClock(CLKIN_CRYSTAL, 120000000UL, true);
+ board_trace_pinmux(); // after clock setup so TRACECLK starts at its final frequency
+#else
Chip_SetupXtalClocking();
+#endif
}
void board_init(void)
diff --git a/hw/bsp/nrf/boards/nrf52840dk/ozone/nrf52840.jdebug b/hw/bsp/nrf/boards/nrf52840dk/ozone/nrf52840.jdebug
index fa7ab9e23..40f28baa9 100644
--- a/hw/bsp/nrf/boards/nrf52840dk/ozone/nrf52840.jdebug
+++ b/hw/bsp/nrf/boards/nrf52840dk/ozone/nrf52840.jdebug
@@ -21,7 +21,7 @@ void OnProjectLoad (void) {
Project.SetTracePortWidth (4);
// User settings
- File.Open ("../../../../../../examples/device/cdc_msc/cmake-build-pca10056/cdc_msc.elf");
+ File.Open ("../../../../../../examples/cmake-build-nrf52840dk/device/cdc_msc/cdc_msc.elf");
}
/*********************************************************************
diff --git a/hw/bsp/nrf/boards/nrf5340dk/ozone/nrf5340.jdebug b/hw/bsp/nrf/boards/nrf5340dk/ozone/nrf5340.jdebug
index 4ad0376a4..34b1841b0 100644
--- a/hw/bsp/nrf/boards/nrf5340dk/ozone/nrf5340.jdebug
+++ b/hw/bsp/nrf/boards/nrf5340dk/ozone/nrf5340.jdebug
@@ -29,9 +29,13 @@ void OnProjectLoad (void) {
Project.SetTraceSource ("Trace Pins");
Project.SetTracePortWidth (4);
+ // +3 ns sample point: the DK's analog-switch/SWO stubs make TD=0 marginal
+ // (Ozone sends TraceSampleAdjust TD=0 when no timing is set); solid across
+ // the +2..+4 ns band with SB27/SB28 cut, SB57 (SWO) left intact
+ Project.SetTraceTiming (3000, 3000, 3000, 3000);
// User settings
- File.Open ("../../../../../../examples/device/cdc_msc/cmake-build-pca10095/cdc_msc.elf");
+ File.Open ("../../../../../../examples/cmake-build-nrf5340dk/device/cdc_msc/cdc_msc.elf");
}
/*********************************************************************
diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c
index 31a6bac9e..3cef4dac3 100644
--- a/hw/bsp/nrf/family.c
+++ b/hw/bsp/nrf/family.c
@@ -165,6 +165,12 @@ static nrfx_gpiote_t _gpiote = NRFX_GPIOTE_INSTANCE(0);
//
//--------------------------------------------------------------------+
void board_init(void) {
+#if defined(TRACE_ETM) && defined(NRF5340_XXAA)
+ // SystemInit (ENABLE_TRACE) sets the TAD trace port to 64 MHz, which is
+ // marginal through the DK's switch stubs - 16 MHz streams reliably (matches the validated nrf52840dk) and is
+ // ample bandwidth for the 64 MHz core
+ NRF_TAD_S->TRACEPORTSPEED = TAD_TRACEPORTSPEED_TRACEPORTSPEED_16MHz;
+#endif
#if !defined(NRF54H20_XXAA) && !defined(NRF54LM20A_ENGA_XXAA)
// stop LF clock just in case we jump from application without reset
NRF_CLOCK->TASKS_LFCLKSTOP = 1UL;
diff --git a/hw/bsp/ra/boards/ra6m5_ek/ozone/ra6m5.jdebug b/hw/bsp/ra/boards/ra6m5_ek/ozone/ra6m5.jdebug
index ca18fed7c..466658f39 100644
--- a/hw/bsp/ra/boards/ra6m5_ek/ozone/ra6m5.jdebug
+++ b/hw/bsp/ra/boards/ra6m5_ek/ozone/ra6m5.jdebug
@@ -15,7 +15,7 @@ void OnProjectLoad (void) {
Project.SetDevice ("R7FA6M5BH");
Project.SetHostIF ("USB", "");
Project.SetTargetIF ("SWD");
- Project.SetTIFSpeed ("50 MHz");
+ Project.SetTIFSpeed ("4 MHz"); // 50 MHz SWD gave intermittent "Failed to initialize DAP"
Project.SetTraceSource ("Trace Pins");
Project.SetTracePortWidth (4);
diff --git a/hw/bsp/ra/boards/ra8m1_ek/ozone/ra8m1.jdebug b/hw/bsp/ra/boards/ra8m1_ek/ozone/ra8m1.jdebug
index 242a15db9..02d568240 100644
--- a/hw/bsp/ra/boards/ra8m1_ek/ozone/ra8m1.jdebug
+++ b/hw/bsp/ra/boards/ra8m1_ek/ozone/ra8m1.jdebug
@@ -10,10 +10,11 @@
*/
void OnProjectLoad (void) {
Project.SetTraceSource ("Trace Pins");
+ Project.SetTracePortWidth (4);
Project.SetDevice ("R7FA8M1AH");
Project.SetHostIF ("USB", "");
Project.SetTargetIF ("SWD");
- Project.SetTIFSpeed ("50 MHz");
+ Project.SetTIFSpeed ("4 MHz"); // 50 MHz SWD gave intermittent "Failed to initialize DAP"
Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M85F.svd");
Project.AddSvdFile ("../../../../../../../cmsis-svd-data/data/Renesas/R7FA6M5BH.svd");
@@ -32,7 +33,7 @@ void OnProjectLoad (void) {
void BeforeTargetConnect (void) {
// Trace pin init is done by J-Link script file as J-Link script files are IDE independent
//Project.SetJLinkScript("../../../debug.jlinkscript");
- Project.SetJLinkScript ("$(ProjectDir)/Renesas_RA8_TracePins.pex");
+ Project.SetJLinkScript ("./ra8m1_trace.JLinkScript");
}
/*********************************************************************
@@ -40,12 +41,14 @@ void BeforeTargetConnect (void) {
* AfterTargetConnect
*
* Function description
-* Event handler routine. Optional.
+* Cache the boot-ROM range for the trace decoder on --attach sessions
+* too (the download hook that normally does this is skipped on attach).
*
**********************************************************************
*/
-//void AfterTargetConnect (void) {
-//}
+void AfterTargetConnect (void) {
+ Exec.Command("ReadIntoTraceCache 0x0 0x10000");
+}
/*********************************************************************
*
@@ -83,8 +86,12 @@ void BeforeTargetConnect (void) {
*/
void AfterTargetDownload (void) {
_SetupTarget();
+ // RA8 executes chip-ROM code at runtime (seen at ~0x3B20); without this the
+ // trace decoder dies there ("not covered by trace cache" -> unknown packet)
+ Exec.Command("ReadIntoTraceCache 0x0 0x10000");
}
+
/*********************************************************************
*
* BeforeTargetDisconnect
diff --git a/hw/bsp/ra/boards/ra8m1_ek/ozone/ra8m1_trace.JLinkScript b/hw/bsp/ra/boards/ra8m1_ek/ozone/ra8m1_trace.JLinkScript
new file mode 100644
index 000000000..3869c1eb7
--- /dev/null
+++ b/hw/bsp/ra/boards/ra8m1_ek/ozone/ra8m1_trace.JLinkScript
@@ -0,0 +1,20 @@
+/* RA8M1 pin trace: CSTF funnel and TMC are off the core ROM table (AP1) -
+ * declare them or trace init cannot route the M85 ETM stream (addresses per
+ * SEGGER's RA8 trace example script). Pins + TRCKCR belong to firmware
+ * (trace_etm_init): the SEGGER pex also muxed them at trace start, and its
+ * clock choice fought the firmware's mid-run = decoder desync.
+ */
+int ConfigTargetSettings(void) {
+ JLINK_ExecCommand("CORESIGHT_SetCSTFBaseAddr = 0x80013000 ForceUnlock = 1 APIndex = 1");
+ JLINK_ExecCommand("CORESIGHT_SetTMCBaseAddr = 0x80014000 ForceUnlock = 1 APIndex = 1");
+ return 0;
+}
+
+/* Replace J-Link's built-in RA8 trace start, which enables the trace clock
+ * from reset - bsp_clock_init's MOCO -> 480 MHz PLL switch would then step
+ * TRCLK mid-stream and desync the decoder. The firmware's trace_etm_init
+ * enables TRCKCR at the final clock instead.
+ */
+int OnTraceStart(void) {
+ return 0;
+}
diff --git a/hw/bsp/ra/family.c b/hw/bsp/ra/family.c
index c8a4d33d9..307644972 100644
--- a/hw/bsp/ra/family.c
+++ b/hw/bsp/ra/family.c
@@ -99,13 +99,32 @@ void board_init(void) {
R_IOPORT_Open(&IOPORT_CFG_CTRL, &IOPORT_CFG_NAME);
#ifdef TRACE_ETM
- // TRCKCR is protected by PRCR bit0 register
- R_SYSTEM->PRCR = (uint16_t) (BSP_PRV_PRCR_KEY | 0x01);
+ // TRCKCR is only writable while a debugger is connected (RA HUM) - a
+ // standalone boot must skip trace init or the write wedges the chip into
+ // an un-attachable crash loop (recover: power-cycle + immediate erase)
+ if (DCB->DHCSR & DCB_DHCSR_C_DEBUGEN_Msk) {
+ // TRCKCR is protected by PRCR bit0 register
+ R_SYSTEM->PRCR = (uint16_t) (BSP_PRV_PRCR_KEY | 0x01);
- // Enable trace clock (max 100Mhz). Since PLL/CPU is 200Mhz, clock div = 2
- R_SYSTEM->TRCKCR = R_SYSTEM_TRCKCR_TRCKEN_Msk | 0x01;
+ // TCLK pin = TRCLK/2; set the divider with TRCKEN=0 first (HUM procedure).
+ // Values are the empirical per-board ceilings.
+#if defined(BSP_MCU_GROUP_RA8M1)
+ // 480 MHz CPU: /4 -> 120 MHz TRCLK, 60 MHz pin - chip max, clean on
+ // EK-RA8M1 with the committed empty-OnTraceStart JLinkScript (which
+ // defers the trace clock to firmware; without it the FSP MOCO->PLL
+ // switch steps the clock mid-stream and any divider fails)
+ R_SYSTEM->TRCKCR = 0x02;
+ R_SYSTEM->TRCKCR = R_SYSTEM_TRCKCR_TRCKEN_Msk | 0x02;
+#else
+ // RA6M5 200 MHz CPU: /4 -> 50 MHz TRCLK, 25 MHz pin. /2 (50 MHz pin) is
+ // silent on the EK-RA6M5 in every combination - board path ceiling,
+ // reconfirmed with J9 closed and the OnTraceStart override
+ R_SYSTEM->TRCKCR = 0x02;
+ R_SYSTEM->TRCKCR = R_SYSTEM_TRCKCR_TRCKEN_Msk | 0x02;
+#endif
- R_SYSTEM->PRCR = (uint16_t) BSP_PRV_PRCR_KEY;
+ R_SYSTEM->PRCR = (uint16_t) BSP_PRV_PRCR_KEY;
+ }
#endif
#if CFG_TUSB_OS == OPT_OS_FREERTOS
diff --git a/hw/bsp/rp2040/boards/raspberry_pi_pico2/board.cmake b/hw/bsp/rp2040/boards/raspberry_pi_pico2/board.cmake
index 0a7dd4d23..08384b0cd 100644
--- a/hw/bsp/rp2040/boards/raspberry_pi_pico2/board.cmake
+++ b/hw/bsp/rp2040/boards/raspberry_pi_pico2/board.cmake
@@ -1,3 +1,17 @@
set(PICO_PLATFORM rp2350-arm-s)
set(PICO_BOARD pico2)
#set(OPENOCD_SERIAL E6614103E77C5A24)
+
+if (TRACE_ETM STREQUAL "1")
+ # TRACECLK is clk_sys/2 and must stay constant once trace is armed (a step
+ # desyncs the decoder), so the trace clock is pinned from crt0 onwards.
+ # 48 MHz (24 MHz TRACECLK) holds full-width trace on a typical fly-wire
+ # seating; a fresh, tight seating supports up to 72-80 MHz (re-qualify per
+ # the etm-trace skill), and >80 MHz needs a V3 probe + real trace board.
+ add_compile_definitions(
+ SYS_CLK_KHZ=48000
+ PLL_SYS_VCO_FREQ_HZ=1440000000
+ PLL_SYS_POSTDIV1=6
+ PLL_SYS_POSTDIV2=5
+ )
+endif ()
diff --git a/hw/bsp/rp2040/boards/raspberry_pi_pico2/ozone/rp2350.jdebug b/hw/bsp/rp2040/boards/raspberry_pi_pico2/ozone/rp2350.jdebug
new file mode 100644
index 000000000..ff48eb673
--- /dev/null
+++ b/hw/bsp/rp2040/boards/raspberry_pi_pico2/ozone/rp2350.jdebug
@@ -0,0 +1,70 @@
+/*********************************************************************
+*
+* OnProjectLoad
+*
+* Function description
+* Project load routine. Required.
+*
+* Notes
+* Pico 2 has no trace connector - fly-wire GPIO1-5 to the MIPI20:
+* TRACECLK=GPIO1->12, D0=GPIO2->14, D1=GPIO3->16, D2=GPIO4->18,
+* D3=GPIO5->20 (SEGGER validates this board the same way). Firmware must
+* be built with TRACE_ETM=1: it pins clk_sys to 48 MHz (board.cmake) so
+* the 4-bit port never saturates and the clock never steps mid-stream,
+* and keeps the us-timer free of TIMER DBGPAUSE (family.c). The whole
+* chip-side trace path (ETM/funnel/TPIU/pin mux) is armed by J-Link's
+* built-in RP2350 script at every resume - do NOT set a custom
+* JLinkScript here: it would replace that script and J-Link then fails
+* with "Required trace components for pin trace not found".
+* GPIO1 is the default UART0 RX: console TX still works, RX is lost.
+*
+**********************************************************************
+*/
+void OnProjectLoad (void) {
+ Project.SetTraceSource ("Trace Pins");
+ Project.SetTracePortWidth (4);
+ Project.SetSWO (0);
+ Edit.SysVar (VAR_TRACE_CORE_CLOCK, 48000000);
+ Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M33F.svd");
+
+ Project.SetDevice ("RP2350_M33_0");
+ Project.SetHostIF ("USB", "");
+ Project.SetTargetIF ("SWD");
+ Project.SetTIFSpeed ("25 MHz");
+
+ File.Open ("../../../../../../examples/cmake-build-raspberry_pi_pico2/device/cdc_msc/cdc_msc.elf");
+}
+
+/*********************************************************************
+*
+* 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) {
+ // intentionally empty: the RP2350 bootrom must run to validate the
+ // IMAGE_DEF and hand over to the app - setting SP/PC from the vector
+ // table bypasses it and the pico-sdk runtime never comes up
+}
+
+/*********************************************************************
+*
+* 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) {
+ // intentionally empty: the RP2350 bootrom must run to validate the
+ // IMAGE_DEF and hand over to the app - setting SP/PC from the vector
+ // table bypasses it and the pico-sdk runtime never comes up
+}
diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c
index 15f179656..e12f51b14 100644
--- a/hw/bsp/rp2040/family.c
+++ b/hw/bsp/rp2040/family.c
@@ -161,11 +161,28 @@ static void stdio_rtt_init(void) {
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
+#if defined(TRACE_ETM) && defined(PICO_RP2350) && PICO_RP2350 == 1
+// J-Link's built-in RP2350 device script re-arms the whole chip-side trace
+// path (ETM/funnel/TPIU/pins) via OnTraceStart at every resume, so firmware
+// must NOT touch it - it only keeps the us-timer running while cores sit
+// debug-halted (default TIMER DBGPAUSE freezes it, and sleep_ms() then spins
+// forever after any debugger session).
+static void trace_etm_init(void) {
+ *(volatile uint32_t*) 0x400B002Cu = 0; // TIMER0 DBGPAUSE
+ *(volatile uint32_t*) 0x400B802Cu = 0; // TIMER1 DBGPAUSE
+}
+#else
+ #define trace_etm_init()
+#endif
+
void board_init(void)
{
#if (CFG_TUH_ENABLED && CFG_TUH_RPI_PIO_USB) || (CFG_TUD_ENABLED && CFG_TUD_RPI_PIO_USB)
// Set the system clock to a multiple of 12mhz for bit-banging USB with pico-usb
#if defined(PICO_RP2350) && PICO_RP2350 == 1
+ #ifdef TRACE_ETM
+ #error "TRACE_ETM pins clk_sys to 48 MHz (board.cmake) - too slow for PIO-USB, and a runtime clock switch desyncs the trace stream"
+ #endif
set_sys_clock_khz(156000, true); // rp2350 default is 150Mhz
#else
set_sys_clock_khz(120000, true); // rp2040 default is 125Mhz
@@ -199,10 +216,18 @@ void board_init(void)
#endif
#ifdef UART_DEV
- bi_decl(bi_2pins_with_func(UART_TX_PIN, UART_RX_PIN, GPIO_FUNC_UART));
uart_inst = uart_get_instance(UART_DEV);
+#if defined(TRACE_ETM) && defined(PICO_RP2350) && PICO_RP2350 == 1
+ // GPIO1 (default UART RX) is TRACECLK: TX-only console, and never touch
+ // GPIO1 - even a brief re-mux gaps the trace clock and desyncs the probe
+ bi_decl(bi_1pin_with_name(UART_TX_PIN, "UART TX"));
+ stdio_uart_init_full(uart_inst, CFG_BOARD_UART_BAUDRATE, UART_TX_PIN, -1);
+#else
+ bi_decl(bi_2pins_with_func(UART_TX_PIN, UART_RX_PIN, GPIO_FUNC_UART));
stdio_uart_init_full(uart_inst, CFG_BOARD_UART_BAUDRATE, UART_TX_PIN, UART_RX_PIN);
#endif
+#endif
+ trace_etm_init();
#if defined(LOGGER_RTT)
stdio_rtt_init();
diff --git a/hw/bsp/samd5x_e5x/boards/same54_xplained/ozone/same54.jdebug b/hw/bsp/samd5x_e5x/boards/same54_xplained/ozone/same54.jdebug
new file mode 100644
index 000000000..a0f8d5c3d
--- /dev/null
+++ b/hw/bsp/samd5x_e5x/boards/same54_xplained/ozone/same54.jdebug
@@ -0,0 +1,89 @@
+/*********************************************************************
+*
+* OnProjectLoad
+*
+* Function description
+* Project load routine. Required.
+*
+* Notes
+* SAM E54 Xplained Pro carries a populated 20-pin Cortex Debug+ETM
+* connector (Table 5-11): TRACECLK=PC27, D0=PC28, D1=PC26, D2=PC25,
+* D3=PC24 - no rework needed. Firmware must be built with TRACE_ETM=1
+* (mux function H on those pins in board_init); TPIU/ETM are
+* ROM-table-discoverable so no J-Link script is required.
+* Trace clock is CPU/2 = 60 MHz at the stock 120 MHz core.
+*
+**********************************************************************
+*/
+void OnProjectLoad (void) {
+ Project.SetTraceSource ("Trace Pins");
+ Project.SetTracePortWidth (4);
+ Project.SetSWO (0);
+ Edit.SysVar (VAR_TRACE_CORE_CLOCK, 120000000);
+ Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M4F.svd");
+
+ Project.SetDevice ("ATSAME54P20");
+ Project.SetHostIF ("USB", "");
+ Project.SetTargetIF ("SWD");
+ Project.SetTIFSpeed ("4 MHz");
+
+ File.Open ("../../../../../../examples/cmake-build-same54_xplained/device/cdc_msc/cdc_msc.elf");
+}
+
+/*********************************************************************
+*
+* 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);
+ }
+}
diff --git a/hw/bsp/samd5x_e5x/family.c b/hw/bsp/samd5x_e5x/family.c
index 71ef2d6ce..a2c3b70de 100644
--- a/hw/bsp/samd5x_e5x/family.c
+++ b/hw/bsp/samd5x_e5x/family.c
@@ -87,6 +87,31 @@ void USB_3_Handler(void) { USB_Any_Handler(); }
static void max3421_init(void);
#endif
+#if defined(TRACE_ETM)
+// same54_xplained routes 4-bit trace to its 20-pin Cortex Debug+ETM header:
+// TRACECLK=PC27, D0=PC28, D1=PC26, D2=PC25, D3=PC24 - all peripheral
+// function H (CM4 trace). TPIU/ETM are ROM-table-discoverable; the debugger
+// arms them, firmware only muxes the pins.
+static void trace_etm_init(void) {
+ // the CM4 trace unit runs from its own GCLK channel (47): feed it GCLK0
+ // (CPU clock) - without this the pins mux fine but the port stays silent
+ GCLK->PCHCTRL[47].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN;
+ while (!(GCLK->PCHCTRL[47].reg & GCLK_PCHCTRL_CHEN)) {}
+
+ const uint8_t pin[] = {24, 25, 26, 27, 28};
+ for (unsigned i = 0; i < 5; i++) {
+ PORT->Group[2].PINCFG[pin[i]].reg = PORT_PINCFG_PMUXEN | PORT_PINCFG_DRVSTR;
+ if (pin[i] & 1) {
+ PORT->Group[2].PMUX[pin[i] >> 1].bit.PMUXO = 7; // function H
+ } else {
+ PORT->Group[2].PMUX[pin[i] >> 1].bit.PMUXE = 7;
+ }
+ }
+}
+#else
+ #define trace_etm_init()
+#endif
+
void board_init(void) {
// Clock init ( follow hpl_init.c )
hri_nvmctrl_set_CTRLA_RWS_bf(NVMCTRL, 0);
@@ -104,6 +129,8 @@ void board_init(void) {
// Init 1ms tick timer (samd SystemCoreClock may not correct)
SystemCoreClock = CONF_CPU_FREQUENCY;
+ trace_etm_init();
+
#if CFG_TUSB_OS == OPT_OS_NONE
SysTick_Config(CONF_CPU_FREQUENCY / 1000);
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
diff --git a/hw/bsp/same7x/boards/same70_xplained/board.h b/hw/bsp/same7x/boards/same70_xplained/board.h
index 85e23deb8..86edf606f 100644
--- a/hw/bsp/same7x/boards/same70_xplained/board.h
+++ b/hw/bsp/same7x/boards/same70_xplained/board.h
@@ -52,6 +52,10 @@ extern "C" {
#define UART_PORT_CLOCK ID_USART1
#define BOARD_USART USART1
+// TRACE_ETM: this board wires the KSZ8081 PHY reset to PC10; the family
+// trace init holds it in reset (RMII rx lines share the trace pads)
+#define TRACE_ETM_QUIET_ENET_PHY 1
+
static inline void board_vbus_set(uint8_t rhport, bool state) {
(void) rhport;
(void) state;
diff --git a/hw/bsp/same7x/boards/same70_xplained/ozone/same70.jdebug b/hw/bsp/same7x/boards/same70_xplained/ozone/same70.jdebug
new file mode 100644
index 000000000..f024f0ceb
--- /dev/null
+++ b/hw/bsp/same7x/boards/same70_xplained/ozone/same70.jdebug
@@ -0,0 +1,115 @@
+/*********************************************************************
+*
+* OnProjectLoad
+*
+* Function description
+* Project load routine. Required.
+*
+* Notes
+* SAM E70 Xplained: solder a 20-pin 50-mil header on the J403 ETM footprint
+* (bottom side). TRACECLK=PD8 (peripheral D), TRACED0-3=PD4-7 (peripheral C),
+* shared with the Ethernet PHY - no Ethernet while tracing. TRACE_ETM=1
+* builds mux the pins and clock the TPIU from PCK3=MCK; TPIU/ETM are
+* ROM-table-discoverable so no J-Link script is required.
+* Trace clock pin is PCK3/2 = 75 MHz at the stock 300 MHz core (MCK 150).
+*
+**********************************************************************
+*/
+void OnProjectLoad (void) {
+ Project.SetTraceSource ("Trace Pins");
+ Project.SetTracePortWidth (4);
+ Project.SetSWO (0);
+ Edit.SysVar (VAR_TRACE_CORE_CLOCK, 300000000);
+ Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M7F.svd");
+
+ Project.SetDevice ("ATSAME70Q21B");
+ Project.SetHostIF ("USB", "");
+ Project.SetTargetIF ("SWD");
+ Project.SetTIFSpeed ("4 MHz");
+
+ File.Open ("../../../../../../examples/cmake-build-same70_xplained/device/cdc_msc/cdc_msc.elf");
+}
+
+/*********************************************************************
+*
+* 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);
+ }
+
+ // TPIU trace clock = PCK3; it must run BEFORE Ozone arms the trace
+ // components (TPIU programming while PCK3 is stopped is lost and the port
+ // emits unformatted garbage). A target reset wipes the PMC, so this runs
+ // in the post-reset/post-download hooks, not AfterTargetConnect.
+ Target.WriteU32 (0x400E064C, 0x00000014); // PMC_PCK3: CSS=MCK, PRESS=/2
+ Target.WriteU32 (0x400E0600, 0x00000800); // PMC_SCER: PCK3 on
+ // wait for PCKRDY3 (bounded) before Ozone arms the trace components
+ int i;
+ i = 0;
+ while (((Target.ReadU32 (0x400E0668) & 0x00000800) == 0) && (i < 100)) {
+ i = i + 1;
+ }
+}
+
+/*********************************************************************
+*
+* 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);
+ }
+
+ // TPIU trace clock = PCK3; it must run BEFORE Ozone arms the trace
+ // components (TPIU programming while PCK3 is stopped is lost and the port
+ // emits unformatted garbage). A target reset wipes the PMC, so this runs
+ // in the post-reset/post-download hooks, not AfterTargetConnect.
+ Target.WriteU32 (0x400E064C, 0x00000014); // PMC_PCK3: CSS=MCK, PRESS=/2
+ Target.WriteU32 (0x400E0600, 0x00000800); // PMC_SCER: PCK3 on
+ // wait for PCKRDY3 (bounded) before Ozone arms the trace components
+ int i;
+ i = 0;
+ while (((Target.ReadU32 (0x400E0668) & 0x00000800) == 0) && (i < 100)) {
+ i = i + 1;
+ }
+}
diff --git a/hw/bsp/same7x/family.c b/hw/bsp/same7x/family.c
index d02e6c5f1..8ec6a708b 100644
--- a/hw/bsp/same7x/family.c
+++ b/hw/bsp/same7x/family.c
@@ -62,6 +62,38 @@ void board_init(void) {
/* Disable Watchdog */
hri_wdt_set_MR_WDDIS_bit(WDT);
+#if defined(TRACE_ETM)
+ // same70_xplained J403 (Cortex Debug+ETM footprint, bottom side) carries
+ // 4-bit trace: TRACECLK=PD8 (peripheral D), TRACED0-3=PD4-7 (peripheral C).
+#ifdef TRACE_ETM_QUIET_ENET_PHY
+ // The trace pins double as the Ethernet PHY's RMII receive lines
+ // (PD4=CRS_DV, PD5/6=RXD0/1, PD7=RXER - PHY OUTPUTS): hold the KSZ8081 in
+ // reset or it drives against the trace stream. The reset net is a BOARD
+ // property (same70_xplained: PHY_RESET=PC10), hence the board.h gate.
+ _pmc_enable_periph_clock(ID_PIOC);
+ gpio_set_pin_level(GPIO(GPIO_PORTC, 10), false);
+ gpio_set_pin_direction(GPIO(GPIO_PORTC, 10), GPIO_DIRECTION_OUT);
+ gpio_set_pin_function(GPIO(GPIO_PORTC, 10), GPIO_PIN_FUNCTION_OFF);
+#endif
+
+ // The TPIU is clocked from PCK3 (datasheet 16.7.4) - run it from MCK.
+ // skip if the debugger already started PCK3 (reprogramming glitches the
+ // clock mid-stream and desyncs the decoder)
+ uint32_t const pck3 = PMC_PCK_CSS_MCK | PMC_PCK_PRES(1); // MCK/2 = 75 MHz -> 37.5 MHz pin
+ if (PMC->PMC_PCK[3] != pck3 || !(PMC->PMC_SR & PMC_SR_PCKRDY3)) {
+ PMC->PMC_PCK[3] = pck3;
+ PMC->PMC_SCER = PMC_SCER_PCK3;
+ while (!(PMC->PMC_SR & PMC_SR_PCKRDY3)) {}
+ }
+ _pmc_enable_periph_clock(ID_PIOD);
+ uint32_t const clk_pin = PIO_PD8D_TPIU_TRACECLK;
+ uint32_t const dat_pin = PIO_PD4C_TPIU_TRACED0 | PIO_PD5C_TPIU_TRACED1 |
+ PIO_PD6C_TPIU_TRACED2 | PIO_PD7C_TPIU_TRACED3;
+ PIOD->PIO_ABCDSR[0] = (PIOD->PIO_ABCDSR[0] | clk_pin) & ~dat_pin; // D=11, C=01
+ PIOD->PIO_ABCDSR[1] |= clk_pin | dat_pin;
+ PIOD->PIO_PDR = clk_pin | dat_pin; // hand the pins to the peripheral
+#endif
+
#ifdef LED_PIN
_pmc_enable_periph_clock(LED_PORT_CLOCK);
gpio_set_pin_level(LED_PIN, LED_STATE_OFF);
diff --git a/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h b/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h
index 18c13017a..959dc4828 100644
--- a/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h
+++ b/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h
@@ -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;
diff --git a/hw/bsp/stm32h5/boards/stm32h563nucleo/ozone/stm32h563.jdebug b/hw/bsp/stm32h5/boards/stm32h563nucleo/ozone/stm32h563.jdebug
new file mode 100644
index 000000000..04f4e4582
--- /dev/null
+++ b/hw/bsp/stm32h5/boards/stm32h563nucleo/ozone/stm32h563.jdebug
@@ -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);
+ }
+}
diff --git a/hw/bsp/stm32h5/family.c b/hw/bsp/stm32h5/family.c
index 867171734..36a95ac8c 100644
--- a/hw/bsp/stm32h5/family.c
+++ b/hw/bsp/stm32h5/family.c
@@ -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);
diff --git a/hw/bsp/stm32h7/boards/stm32h743eval/ozone/stm32h743.jdebug b/hw/bsp/stm32h7/boards/stm32h743eval/ozone/stm32h743.jdebug
index 32a8155c1..f9780147d 100644
--- a/hw/bsp/stm32h7/boards/stm32h743eval/ozone/stm32h743.jdebug
+++ b/hw/bsp/stm32h7/boards/stm32h743eval/ozone/stm32h743.jdebug
@@ -10,6 +10,7 @@
*/
void OnProjectLoad (void) {
Project.SetTraceSource ("Trace Pins");
+ Project.SetTracePortWidth (4);
Project.SetTraceTiming (100, 100, 100, 100);
Project.SetSWO (0);
Edit.SysVar (VAR_TRACE_CORE_CLOCK, 200000000);
@@ -22,7 +23,7 @@ void OnProjectLoad (void) {
Project.SetTargetIF ("SWD");
Project.SetTIFSpeed ("50 MHz");
- File.Open ("../../../../../../examples/device/cdc_msc/cmake-build-stm32h743eval/cdc_msc.elf");
+ File.Open ("../../../../../../examples/cmake-build-stm32h743eval/device/cdc_msc/cdc_msc.elf");
// File.Open ("../../../../../../examples/cmake-build-stm32h743eval_host1/host/cdc_msc_hid/cdc_msc_hid.elf");
}
diff --git a/hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/board.h b/hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/board.h
index 996eb1515..098fc0bed 100644
--- a/hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/board.h
+++ b/hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/board.h
@@ -123,7 +123,13 @@ static inline void SystemClock_Config(void)
RCC_OscInitStruct.PLL1.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL1.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL1.PLLM = 12;
+#ifdef TRACE_ETM
+ // 300 MHz core -> 50 MHz trace clock: at 600 MHz the stream survives idle
+ // but dies (unknown trace packet) during IRQ-heavy bursts, e.g. USB traffic
+ RCC_OscInitStruct.PLL1.PLLN = 150;
+#else
RCC_OscInitStruct.PLL1.PLLN = 300;
+#endif
RCC_OscInitStruct.PLL1.PLLP = 1;
RCC_OscInitStruct.PLL1.PLLQ = 2;
RCC_OscInitStruct.PLL1.PLLR = 2;
diff --git a/hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/ozone/stm32h7s3.jdebug b/hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/ozone/stm32h7s3.jdebug
new file mode 100644
index 000000000..f6658d2d7
--- /dev/null
+++ b/hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/ozone/stm32h7s3.jdebug
@@ -0,0 +1,94 @@
+/*********************************************************************
+*
+* OnProjectLoad
+*
+* Function description
+* Project load routine. Required.
+*
+* Notes
+* Nucleo-H7S3L8 wires 4-bit trace to the CN1 MIPI20 natively (no rework):
+* TRACE_CLK/D0 = PE2/PE3, TRACE_D1/D2/D3 = PG14/PD2/PC12 (MB1737 Table 7).
+* Firmware must be built with TRACE_ETM=1 (trace pin mux + DBGMCU
+* DBGCKEN/TRACECLKEN in board_init).
+*
+* TRACE_ETM builds run a 300 MHz core (board.h) -> 50 MHz trace clock
+* (cpu/3/2). Width 2 on the stub-free D0/D1 lines: SB11/SB12 (default ON)
+* stub D2/D3 onto Zio CN8 and the 4-bit stream dies under IRQ-heavy USB
+* traffic (idle is clean) - remove SB11/SB12 to try width 4 / 600 MHz.
+*
+**********************************************************************
+*/
+void OnProjectLoad (void) {
+ // declares the off-ROM-table CSTF/TMC/TPIU (see the script header)
+ Project.SetJLinkScript ("./stm32h7s3_trace.JLinkScript");
+ Project.SetTraceSource ("Trace Pins");
+ Project.SetTracePortWidth (2);
+ Project.SetSWO (0);
+ Edit.SysVar (VAR_TRACE_CORE_CLOCK, 300000000);
+ Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M7F.svd");
+
+ Project.SetDevice ("STM32H7S3L8");
+ Project.SetHostIF ("USB", "");
+ Project.SetTargetIF ("SWD");
+ Project.SetTIFSpeed ("4 MHz");
+
+ File.Open ("../../../../../../examples/cmake-build-stm32h7s3nucleo/device/cdc_msc/cdc_msc.elf");
+}
+
+/*********************************************************************
+*
+* 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);
+ }
+}
diff --git a/hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/ozone/stm32h7s3_trace.JLinkScript b/hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/ozone/stm32h7s3_trace.JLinkScript
new file mode 100644
index 000000000..5ef4f164d
--- /dev/null
+++ b/hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/ozone/stm32h7s3_trace.JLinkScript
@@ -0,0 +1,11 @@
+/* STM32H7RS pin trace: the CSTF funnel, TMC (ETF) and TPIU are not in the
+ * core ROM table - declare them or J-Link aborts trace init with "Required
+ * trace components for pin trace not found!" (addresses per SEGGER's
+ * NUCLEO-H7S3L8 trace example script; AP0).
+ */
+int ConfigTargetSettings(void) {
+ JLINK_ExecCommand("CORESIGHT_SetCSTFBaseAddr = 0x5C013000 ForceUnlock = 1 APIndex = 0");
+ JLINK_ExecCommand("CORESIGHT_SetTMCBaseAddr = 0x5C014000 ForceUnlock = 1 APIndex = 0");
+ JLINK_ExecCommand("CORESIGHT_SetTPIUBaseAddr = 0x5C015000 ForceUnlock = 1 APIndex = 0");
+ return 0;
+}
diff --git a/hw/bsp/stm32h7rs/family.c b/hw/bsp/stm32h7rs/family.c
index b0841c947..385b3c929 100644
--- a/hw/bsp/stm32h7rs/family.c
+++ b/hw/bsp/stm32h7rs/family.c
@@ -98,17 +98,24 @@ void OTG_HS_IRQHandler(void) {
#ifdef TRACE_ETM
void trace_etm_init(void) {
- // H7 trace pin is PE2 to PE6
- GPIO_InitTypeDef gpio_init;
- gpio_init.Pin = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6;
+ // Nucleo-H7S3L8 routes 4-bit trace to the CN1 MIPI20: TRACE_CLK/D0 on
+ // PE2/PE3, TRACE_D1/D2/D3 on the PG14/PD2/PC12 alternates (MB1737 Table 7).
+ // No pull: pull-ups degrade the edges at the 100 MHz trace clock (= cpu/3/2)
+ GPIO_InitTypeDef gpio_init;
gpio_init.Mode = GPIO_MODE_AF_PP;
- gpio_init.Pull = GPIO_PULLUP;
+ gpio_init.Pull = GPIO_NOPULL;
gpio_init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
gpio_init.Alternate = GPIO_AF0_TRACE;
+ gpio_init.Pin = GPIO_PIN_2 | GPIO_PIN_3;
HAL_GPIO_Init(GPIOE, &gpio_init);
+ gpio_init.Pin = GPIO_PIN_14;
+ HAL_GPIO_Init(GPIOG, &gpio_init);
+ gpio_init.Pin = GPIO_PIN_2;
+ HAL_GPIO_Init(GPIOD, &gpio_init);
+ gpio_init.Pin = GPIO_PIN_12;
+ HAL_GPIO_Init(GPIOC, &gpio_init);
- // Enable trace clk, also in D1 and D3 domain
- DBGMCU->CR |= DBGMCU_CR_DBG_TRACECKEN | DBGMCU_CR_DBG_CKD1EN | DBGMCU_CR_DBG_CKD3EN;
+ DBGMCU->CR |= DBGMCU_CR_DBGCKEN | DBGMCU_CR_TRACECLKEN;
}
#else
#define trace_etm_init()
diff --git a/hw/bsp/stm32n6/boards/stm32n657nucleo/board.h b/hw/bsp/stm32n6/boards/stm32n657nucleo/board.h
index be9ea7a31..873c004d9 100644
--- a/hw/bsp/stm32n6/boards/stm32n657nucleo/board.h
+++ b/hw/bsp/stm32n6/boards/stm32n657nucleo/board.h
@@ -152,7 +152,13 @@ static void SystemClock_Config(void) {
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_PCLK4 | RCC_CLOCKTYPE_PCLK5);
RCC_ClkInitStruct.CPUCLKSource = RCC_CPUCLKSOURCE_IC1;
RCC_ClkInitStruct.IC1Selection.ClockSelection = RCC_ICCLKSOURCE_PLL1;
+#ifdef TRACE_ETM
+ // 300 MHz CPU -> 37.5 MHz TPIU clock (fixed cpu/8): at 600 MHz the trace
+ // stream dies with unknown-packet decode errors in the startup burst
+ RCC_ClkInitStruct.IC1Selection.ClockDivider = 4;
+#else
RCC_ClkInitStruct.IC1Selection.ClockDivider = 2;
+#endif
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_IC2_IC6_IC11;
RCC_ClkInitStruct.IC2Selection.ClockSelection = RCC_ICCLKSOURCE_PLL1;
RCC_ClkInitStruct.IC2Selection.ClockDivider = 3;
diff --git a/hw/bsp/stm32n6/boards/stm32n657nucleo/ozone/stm32n657.jdebug b/hw/bsp/stm32n6/boards/stm32n657nucleo/ozone/stm32n657.jdebug
new file mode 100644
index 000000000..16eead280
--- /dev/null
+++ b/hw/bsp/stm32n6/boards/stm32n657nucleo/ozone/stm32n657.jdebug
@@ -0,0 +1,94 @@
+/*********************************************************************
+*
+* OnProjectLoad
+*
+* Function description
+* Project load routine. Required.
+*
+* Notes
+* Nucleo-N657X0-Q wires 4-bit trace to the CN1 MIPI20 natively (SB36/38/
+* 39/40/41 fitted by default): TRACE_CLK = PB3, D0/D1/D2/D3 =
+* PE3/PB0/PB6/PB7 (MB1940 Table 5). No J-Link script needed - the N6
+* trace components sit behind a ROM table J-Link discovers natively.
+*
+* BOOT1 (JP2) must select Development boot (BOOT1 = 1): the N657 is
+* flashless, the app is a RAM image (AXISRAM2) loaded by the debugger,
+* and in flash boot the bootROM parks the chip un-attachable.
+* Firmware must be built with TRACE_ETM=1 (pin mux + DBGMCU
+* DBGCLKEN/TRACECLKEN). Trace clock = cpu/8. TRACE_ETM builds run a 300 MHz core (board.h) ->
+* 37.5 MHz TPIU clock: 600 MHz kills the stream in the startup burst.
+*
+**********************************************************************
+*/
+void OnProjectLoad (void) {
+ Project.SetTraceSource ("Trace Pins");
+ Project.SetTracePortWidth (4);
+ Project.SetSWO (0);
+ Edit.SysVar (VAR_TRACE_CORE_CLOCK, 300000000);
+ Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M55F.svd");
+
+ Project.SetDevice ("STM32N657X0");
+ Project.SetHostIF ("USB", "");
+ Project.SetTargetIF ("SWD");
+ Project.SetTIFSpeed ("4 MHz");
+
+ File.Open ("../../../../../../examples/cmake-build-stm32n657nucleo/device/cdc_msc/cdc_msc.elf");
+}
+
+/*********************************************************************
+*
+* 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);
+ }
+}
diff --git a/hw/bsp/stm32n6/family.c b/hw/bsp/stm32n6/family.c
index 80de20c6a..9d3faa1f2 100644
--- a/hw/bsp/stm32n6/family.c
+++ b/hw/bsp/stm32n6/family.c
@@ -110,6 +110,27 @@ void USB1_OTG_HS_IRQHandler(void) {
tusb_int_handler(0, true);
}
+#ifdef TRACE_ETM
+static void trace_etm_init(void) {
+ // Nucleo-N657X0-Q routes 4-bit trace to the CN1 MIPI20 natively:
+ // TRACE_CLK = PB3, D0 = PE3, D1 = PB0, D2 = PB6, D3 = PB7 (MB1940 Table 5)
+ GPIO_InitTypeDef gpio_init;
+ gpio_init.Mode = GPIO_MODE_AF_PP;
+ gpio_init.Pull = GPIO_NOPULL;
+ gpio_init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ gpio_init.Alternate = GPIO_AF0_TRACE;
+ gpio_init.Pin = GPIO_PIN_0 | GPIO_PIN_3 | GPIO_PIN_6 | GPIO_PIN_7;
+ HAL_GPIO_Init(GPIOB, &gpio_init);
+ gpio_init.Pin = GPIO_PIN_3;
+ HAL_GPIO_Init(GPIOE, &gpio_init);
+
+ // trace clock (ck_cpu_tpiu) is a fixed cpu/8 - just enable it
+ DBGMCU->CR |= DBGMCU_CR_DBGCLKEN | DBGMCU_CR_TRACECLKEN;
+}
+#else
+ #define trace_etm_init()
+#endif
+
void board_init(void) {
/* Enable BusFault and SecureFault handlers (HardFault is default) */
SCB->SHCSR |= (SCB_SHCSR_BUSFAULTENA_Msk | SCB_SHCSR_SECUREFAULTENA_Msk);
@@ -148,6 +169,7 @@ void board_init(void) {
for (uint8_t i = 0; i < TU_ARRAY_SIZE(board_pindef); i++) {
HAL_GPIO_Init(board_pindef[i].port, &board_pindef[i].pin_init);
}
+ trace_etm_init();
NVIC_SetPriority(UCPD1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
NVIC_EnableIRQ(UCPD1_IRQn);