Using STM32H7 ETM without external tool

Hello,

I want to record the execution trace on our STM32H753 (all the time, in circular buffer mode) and, in some particular cases, output this trace to an external peripheral through SPI (no dedicated tool like Lauterbach).

I understood that I can do this thanks to ETM and ETF, however I couldn't find enough details in the various ARM documentation to make it work.

I tried the following code

 volatile uint32_t *ETM_PRGCTRL = (volatile uint32_t *)(0xE0041000 + 4);
        volatile uint32_t *ETM_LAR = (volatile uint32_t *)(0xE0041000 + 0xFB0);
        volatile uint32_t *ETM_STAT = (volatile uint32_t *)(0xE0041000 + 0xC);
        volatile uint32_t *ETM_CONFIG = (volatile uint32_t *)(0xE0041000 + 0x10);
        #define ETF_BASE_ADDR	0x5C014000
        volatile uint32_t *ETF_RRD  = (volatile uint32_t *)(ETF_BASE_ADDR + 0x10);
        volatile uint32_t *ETF_CTL  = (volatile uint32_t *)(ETF_BASE_ADDR + 0x20);
        volatile uint32_t *ETF_FFCR = (volatile uint32_t *)(ETF_BASE_ADDR + 0x304);
        volatile uint32_t *ETF_TRG  = (volatile uint32_t *)(ETF_BASE_ADDR + 0x1C);
        volatile uint32_t *ETF_STS  = (volatile uint32_t *)(ETF_BASE_ADDR + 0x0C);
        volatile uint32_t *ETF_LAR  = (volatile uint32_t *)(ETF_BASE_ADDR + 0xFB0);
        //volatile uint32_t *CTI_LAR = (volatile uint32_t *)(0xE00F1000 + 0xFB0);
        //volatile uint32_t *CTI_CTRL = (volatile uint32_t *)(0xE00F1000);
        //volatile uint32_t *DBGMCU_CR = (volatile uint32_t *)(0xE00E1000 + 0x4);
        #define DWT_BASE_ADDR	0xE0001000
        volatile uint32_t *DWT_CTRL = (volatile uint32_t *)(DWT_BASE_ADDR + 0x0);
        volatile uint32_t *DWT_COMP0 = (volatile uint32_t *)(DWT_BASE_ADDR + 0x20);
        volatile uint32_t *DWT_MASK0 = (volatile uint32_t *)(DWT_BASE_ADDR + 0x24);
        volatile uint32_t *DWT_FUNCT0 = (volatile uint32_t *)(DWT_BASE_ADDR + 0x28);
        volatile uint32_t *DEMCR = (volatile uint32_t *)(0xE000EDFC);

        printf("test etm\r\n");

        // enable DWT in Debug Exception and Monitor Control Register
        *DEMCR |= 1<<24; // trace enable

        // Generates CMPMATCH event: from Archiecture Ref Manual of ARM v7 ->  "the CMPMATCH[N] signals 
        // from the DWT unit are available as control inputs to the ETM unit"
        *DWT_COMP0 = 0x00000000; // adress comparator
        *DWT_MASK0 = 24;
        *DWT_FUNCT0 = 0x00000008; // generate CMPMATCH[0] event


        // setup ETM
        *ETM_LAR  = 0xC5ACCE55;   // unlock periph
        *ETM_CONFIG = (*ETM_CONFIG) | 0x00031F30; // enable all traces
        *ETM_PRGCTRL = 1; // enable ETM

        // setup ETF (by default in circular mode)
        *ETF_LAR  = 0xC5ACCE55; // unlock periph
        *ETF_FFCR = 0x00001123; // ARM recommends to set bits TRIGONTRIGIN FONTRIGEVT STOPONFL ENTI AND ENFT
        *ETF_TRG = 16; // number of 32 words to capture
        *ETF_CTL = 1; // enable trace

        // bullshit processing just to fill the trace
        U4_INDEX = 1000;
        while(U4_INDEX--)
          __asm("nop"); 

        // wait for bit READY
        while ( ((*ETF_STS) & (1<<2)) == 0 );

        // read trace
        printf("*ETF_RRD=0x%x\r\n", *ETF_RRD);
        printf("*ETF_RRD=0x%x\r\n", *ETF_RRD);
        printf("*ETF_RRD=0x%x\r\n", *ETF_RRD);
        printf("*ETF_RRD=0x%x\r\n", *ETF_RRD);

        *ETF_CTL = 0; // disable trace

But the bit ready of ETF_STS never raises.

Would you have resources (specific documentation or even better sample code) to share ?

Best regards

More questions in this forum