This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

PC Sample output via SWO pin in nrf52832

Hi, well the question says it all - I am trying to get the Program Counter samples sent out of the SWO pin on the nrf52832.

Use Case: I am trying to measure the power consumption of our custom board utilizing nrf52832 and synchronize it with the PC samples (code that is executing at that point in time and the power consumed). I know this approach is not highly accurate - well something is better than nothing.

What I already tried I configured the SWO pin for output - I can see the output from SWO (the printf style using ITM_SendChar)

Now I tried enabling the PC sample output on the DWT->CTRL register and its not giving any output.

DWT->CTRL = 0x400113FF;

Do I need to do anything more to get it working? Any pointers would be greatly appreciated.

  • Unfortunately no and I am still stuck on this one.

    In the meantime, I am just measuring the power consumption by modifying the software to just do 1 functionality at a time - which is proving to be too time consuming and also will take me only so far. The dynamic behavior when all the functionalities comes together is something I would need in the near future - for which I either need to figure out how to get the PC samples through SWO or move to the costlier option of trace probes (Jtrace, utrace etc..) and I hope it will not come to that.

  • My understanding is that you want to monitor the activity of the CPU ? You may need to use TRACE interface, which also needs the j-trace debugger

    There is a trick to check when the CPU is active is to toggle a pin, you can toggle a pin inside the main loop so that when the CPU is sleeping, the pin is not toggle. You can then monitor the pin to know if the CPU is off or on. 

  • I am sure we don't need a trace probe for getting PC samples out of the CPU at a predefined interval, as supported by DWT/TPIU. As per the ARM Cortex-M4 Technical Reference manual if the core implements the full DWT (containing 4 Comparators - which I know for sure nRF52832 is implementing as per the default value of the DWT register upon power-on) then it should be able to send a sub-sampled PC values to the debugger.

    Also my idea is to figure out what code is being executed (not just whether the CPU is on or sleeping) and along withe periodic power measurement data I can get code correlation. Also note that I am not trying to achieve the accuracy of ETM here.

    By the way, I succeeded in getting the PC samples out of the nRF52832 using Keil (Windows) with OB JLink (No trace support) present on the nRF52-DK. I also tried the same with my custom nRF52832 borad using a JLink Base (not the trace version) and was able to get the PC sample output on the Instruction Trace Window.

    I know I must have done something wrong with the register configuration in my code (note: my env is GCC on Ubuntu). Now I need to figure out how to receive this PC samples in my dev env (Ubuntu). Basically what it means is having the right register values and then I would need a SWOViewer to receive, parse and log the PC sample data into a file.

    At this moment I am not sure if Keil software is doing the decoding of the PC samples or is it the debugger that is doing the decoding of PC samples. I am also not sure if  SWOViewer provided by segger could already decode the PC samples in addition to displaying the SWO printf messages. These are something I will try in the near future and I will write/blog about it more as I figure things out.

  • IDK if you are still running into this issue, but I was able to get it working on nrf52833-DK with following code:

    // setup speed for SWO
    NRF_CLOCK->TRACECONFIG = (NRF_CLOCK->TRACECONFIG & ~CLOCK_TRACECONFIG_TRACEPORTSPEED_Msk) |
        (CLOCK_TRACECONFIG_TRACEPORTSPEED_4MHz << CLOCK_TRACECONFIG_TRACEPORTSPEED_Pos);
    
    
    // permissions and enabling ITM
    ITM->LAR = 0xc5acce55;
    ITM->TCR |= 9;
    ITM->TPR |= 1;
    ITM->TER |= 1;
    
    // enable PC sampling
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
    DWT->CTRL |= 0x103FF;

    Also, note that you need to add the `-DENABLE_SWO` flag to your flags

Related