- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How can one listen to the data send on the ITM channel?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, I never tried the Keil solution as we were not going to be using Keil anyway, so I gave up.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.