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;
}
Solved! Go to Solution.
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.
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.
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
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;
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.
How can one listen to the data send on the ITM channel?
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.
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);
No, I never tried the Keil solution as we were not going to be using Keil anyway, so I gave up.
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.