PSOC6 Serial Wire Viewer

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
user_2738496
Level 1
Level 1
First like received

Hi, I am searching for information on how to get printf working over the SWD port.

I have a miniprog3 connected and I would like a terminal on my computer where I can see debug messages.

Does anyone have some code to set this up? (I guess more is needed than selecting "SWD+SWV" in Programming/Debugging)

Also what is the best way to watch the output? Is it getting a J-link, looking in the Output tab of PSOC Creator, or something else?

So far I have borrowed this together off the internet,

best regards

Anders

/*********************************************************************

*

*       Defines for Cortex-M debug unit

*/

#define ITM_STIM_U32 (*(volatile unsigned int*)0xE0000000)    // Stimulus Port Register word access

#define ITM_STIM_U8  (*(volatile         char*)0xE0000000)    // Stimulus Port Register byte access

#define ITM_ENA      (*(volatile unsigned int*)0xE0000E00)    // Trace Enable Ports Register

#define ITM_TCR      (*(volatile unsigned int*)0xE0000E80)    // Trace control register

/*********************************************************************

*

*       SWO_PrintChar()

*

* Function description

*   Checks if SWO is set up. If it is not, return,

*    to avoid program hangs if no debugger is connected.

*   If it is set up, print a character to the ITM_STIM register

*    in order to provide data for SWO.

* Parameters

*   c:    The Chacracter to be printed.

* Notes

*   Additional checks for device specific registers can be added.

*/

void SWO_PrintChar(char c) {

  //

  // Check if ITM_TCR.ITMENA is set

  //

  if ((ITM_TCR & 1) == 0) {

    return;

  }

  //

  // Check if stimulus port is enabled

  //

  if ((ITM_ENA & 1) == 0) {

    return;

  }

  //

  // Wait until STIMx is ready,

  // then send data

  //

  while ((ITM_STIM_U8 & 1) == 0);

  ITM_STIM_U8 = c;

}

int _write(int file, char *ptr, int len)

{

    int i;

    for (i = 0; i < len; i++)

    {

        SWO_PrintChar(*ptr++);

    }

    return len;

}

0 Likes
1 Solution
SrikanthD_56
Employee
Employee
25 sign-ins First question asked First comment on blog

To read the debug printf messages through SWV pin, I did the following:

1. Changed the Debug Select to SWD+SWV in one of the PSoC 6 MCU project and built it.

2. Exported the project to Keil uVision 5 by following the steps provided in Creating µVision Projects for PSoC 6 of the PSoC Creator Help document.

3. Redirected the STDERR, STDIN, STDOUT to ITM in Keil uVision IDE's is Run-time Environment (steps are available in the uVision's User Guide).

4. Connected the ULINKpro debugger to J11 header CY8CKIT-062-BLE board. Rebuilt the project in uVision and started the debug session.

I was successfully able to see the message steam in Debug (printf) Viewer window of the uVision IDE.

Although I haven't used the MiniProg3 here, thought of sharing this info, if you are interested to try.

View solution in original post

9 Replies
RodolfoGL
Employee
Employee
250 solutions authored 250 sign-ins 5 comments on KBA

You can always use an UART component in your firmware to sent out debugging messages. PSoC 6 kit has an embedded USB to UART, so you can use PC Terminal to visualize debug messages sent by your firmware.

0 Likes

Yes, I know, but I think the debug port is generally the most elegant way to do it, and in the long run I want the code to run on boards lacking the kitprog2

0 Likes
user_2738496
Level 1
Level 1
First like received

I found and added some initiation code also, but it get what seems to be a bus fault when accessing the TPI unit,
anyone know why?

CoreDebug->DEMCR |= (1 << 24);

ITM->LAR  = 0xC5ACCE55;

ITM->TER  = 0x0;

ITM->TCR  = 0x0;

TPI->SPPR = 2;

TPI->ACPR = 24;

ITM->TPR  = 0x0;

DWT->CTRL = 0x400003FE;

ITM->TCR  = 0x0001000D;

TPI->FFCR = 0x00000100;

ITM->TER  = 0x1;

0 Likes

If you check core_cm4.h file, there are three system call functions:

- ITM_SendChar

- ITM_ReceiveChar

- ITM_CheckChar

They use the ITM channel to send/receive messages.

0 Likes

How can one listen to the data send on the ITM channel?

0 Likes

Thanks, I checked, and the ITM_SendChar i virtually identical to the SWO_Printchar function.

I tried running:

GitHub - kyoung2112/csharp-miniprog3-swv: C# Express SWV Printf viewer for Miniprog3

And also J-link + SWO-viewer.

Checking using a logic analyzer I see that nothing happens on the SWO pin.

If this is at all possible something more is needed.

0 Likes

Did you manage to use the SWO pin? A have the same issue with a Psoc6. No activity on SWO pin.

I configure and enable the ITM using the code below

// Debug Exception Monitor and Control register

#define DEMCR   (*((unsigned long *) 0xe000edfc))

#define TRCENA  0x01000000  // enable trace

// Stimulus Port registers

#define ITM_STIM0 (*((unsigned long *) 0xe0000000))

#define ITM_STIM1 (*((unsigned long *) 0xe0000004))

#define ITM_STIM2 (*((unsigned long *) 0xe0000008))

#define ITM_STIM3 (*((unsigned long *) 0xe000000c))

// Trace enable registers

#define ITM_TER   (*((unsigned long *) 0xe0000e00))

// Privilege register: registers that can be accessed by unprivileged code

#define ITM_TPR   (*((unsigned long *) 0xe0000e40))

// Trace Control register

#define ITM_TCR   (*((unsigned long *) 0xe0000e80))

// Lock Access register

#define ITM_LAR   (*((unsigned long *) 0xe0000fb0))

// unlock value

#define ITM_LAR_ACCESS  0xc5acce55

void ITM_init(void)

{

    ITM_LAR = ITM_LAR_ACCESS; // unlock

    ITM_TCR = 0x1;            // global enable for ITM

    ITM_TPR = 0x1;            // first 8 stim registers have unpriv access

    ITM_TER = 0xf;            // enable 4 stim ports

    DEMCR = TRCENA;           // global enable DWT and ITM

}

and the implimation of fputc()

int32_t ITM_SendChar (int32_t ch) {

  if ((ITM_TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */

      (ITM_TER & (1UL << 0)        )) { /* ITM Port #0 enabled */

    while (ITM_PORT0_U32 == 0);

    ITM_PORT0_U8 = (uint8_t)ch;

  }

  return (ch);

}

The ITM_PORT0_U32 is always 0 so never return from the while (ITM_PORT0_U32 == 0);

0 Likes

No, I never tried the Keil solution as we were not going to be using Keil anyway, so I gave up.

SrikanthD_56
Employee
Employee
25 sign-ins First question asked First comment on blog

To read the debug printf messages through SWV pin, I did the following:

1. Changed the Debug Select to SWD+SWV in one of the PSoC 6 MCU project and built it.

2. Exported the project to Keil uVision 5 by following the steps provided in Creating µVision Projects for PSoC 6 of the PSoC Creator Help document.

3. Redirected the STDERR, STDIN, STDOUT to ITM in Keil uVision IDE's is Run-time Environment (steps are available in the uVision's User Guide).

4. Connected the ULINKpro debugger to J11 header CY8CKIT-062-BLE board. Rebuilt the project in uVision and started the debug session.

I was successfully able to see the message steam in Debug (printf) Viewer window of the uVision IDE.

Although I haven't used the MiniProg3 here, thought of sharing this info, if you are interested to try.