diff options
Diffstat (limited to 'hw')
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); |
