Tool/software:
Hi TI,
I have a custom board, where GTC is clocked with 62.5 MHz by MAIN_PLL3_HSDIV1_CLKOUT. I am running the following code on R5 in main domain (MCU2_1) in debug mode:
const uint32_t arrayElems = 16; uint32_t counterValueSet[arrayElems] = {0xF0000000, 0xE0000000, 0xD0000000, 0xC0000000, 0xB0000000, 0xA0000000, 0x90000000, 0x80000000, 0x70000000, 0x60000000, 0x50000000, 0x40000000, 0x30000000, 0x20000000, 0x10000000, 0x00000000}; uint32_t counterValueGet[arrayElems]; for(uint32_t i = 0; i < arrayElems; i++) { HW_WR_REG32(CSL_GTC0_GTC_CFG1_BASE + CSL_GTC_CFG1_CNTCR, 0x0); HW_WR_REG32(CSL_GTC0_GTC_CFG1_BASE + CSL_GTC_CFG1_CNTCV_LO, counterValueSet[i]); HW_WR_REG32(CSL_GTC0_GTC_CFG1_BASE + CSL_GTC_CFG1_CNTCR, 0x1); counterValueGet[i] = HW_RD_REG32(CSL_GTC0_GTC_CFG2_BASE); }
The values I get for counterValueGet are (2 runs):
0xF0000017 (hex) 0xF000005C (hex) 0xF00000A2 (hex) 0xC0000017 (hex) 0xB0000017 (hex) 0xA0000017 (hex) 0x90000017 (hex) 0x90000067 (hex) 0x70000017 (hex) 0x60000017 (hex) 0x50000018 (hex) 0x40000017 (hex) 0x30000017 (hex) 0x20000017 (hex) 0x10000017 (hex) 0x10000068 (hex)
0xB2E19CE6 (hex) 0xB2E19D2B (hex) 0xB2E19D71 (hex) 0xC0000017 (hex) 0xB0000018 (hex) 0xA0000017 (hex) 0x90000017 (hex) 0x90000067 (hex) 0x70000017 (hex) 0x60000017 (hex) 0x50000017 (hex) 0x50000067 (hex) 0x30000017 (hex) 0x20000017 (hex) 0x10000017 (hex) 0x00000017 (hex)
So sometimes the desired value is captured, sometimes not. Setting the GTC value in the way I am doing it seems to be unreliable therefore.
Adding additional delays like here:
const uint32_t arrayElems = 16; uint32_t counterValueSet[arrayElems] = {0xF0000000, 0xE0000000, 0xD0000000, 0xC0000000, 0xB0000000, 0xA0000000, 0x90000000, 0x80000000, 0x70000000, 0x60000000, 0x50000000, 0x40000000, 0x30000000, 0x20000000, 0x10000000, 0x00000000}; uint32_t counterValueGet[arrayElems]; for(uint32_t i = 0; i < arrayElems; i++) { HW_WR_REG32(CSL_GTC0_GTC_CFG1_BASE + CSL_GTC_CFG1_CNTCR, 0x0); for(uint32_t j = 0; j < 32; j++) { asm("nop"); } HW_WR_REG32(CSL_GTC0_GTC_CFG1_BASE + CSL_GTC_CFG1_CNTCV_LO, counterValueSet[i]); for(uint32_t j = 0; j < 32; j++) { asm("nop"); } HW_WR_REG32(CSL_GTC0_GTC_CFG1_BASE + CSL_GTC_CFG1_CNTCR, 0x1); for(uint32_t j = 0; j < 32; j++) { asm("nop"); } counterValueGet[i] = HW_RD_REG32(CSL_GTC0_GTC_CFG2_BASE); }
also does not improve the reliability. The results are the following:
0xE03EA32F (hex) 0xE03EA394 (hex) 0xD0000036 (hex) 0xD000009B (hex) 0xB0000036 (hex) 0xB00000A4 (hex) 0x90000036 (hex) 0x80000036 (hex) 0x800000A5 (hex) 0x80000113 (hex) 0x80000181 (hex) 0x800001F2 (hex) 0x30000037 (hex) 0x20000036 (hex) 0x10000036 (hex) 0x00000036 (hex)
Are you able to reproduce the problem on your side? Do you have any idea on what is wrong in setting the GTC value the way I am doing it? HW_WR_REG32 includes an additional HW_SYNC_BARRIER (dsb instruction) which does the following (excerpt from Crtex R5 TRM:
"This instruction forces the processor to wait for all pending explicit data accesses to complete before any additional instructions stages can be executed. There is no effect on pre-fetching of instructions."
So in my understanding, HW_WR_REG32 should only return when the value is actually written.
Thanks and best regards,
Felix