OK - so I just started with these chips, and have been asked to find out why SWO debug signal is getting corrupted.
At fairly random intervals the signal passive state inverts from 0 to 1, which corrupts the next few lines of debug output until the passive state inverts back again.
I suspect a silicon bug, or a conflict between something like GPIO and the ITM, but wanted to start by double-checking the hardware configuration settings.
The SWO is configured as follows, but there are quite a few magic numbers in there.
// brief Initialize the SWO trace port for debug message printing
// param portBits Port bit mask to be configured
void SWO_Init(uint32_t portBits)
uint32_t SWOSpeed = 57600; // baud rate
uint32_t SWOPrescaler = (CPU_CORE_FREQUENCY_HZ / SWOSpeed) + 1; // SWOSpeed in Hz, note that CPU_CORE_FREQUENCY_HZ is expected to be match the CPU core clock
CoreDebug->DEMCR = CoreDebug_DEMCR_TRCENA_Msk; // enable trace in core debug */
*((volatile unsigned *)(ITM_BASE + 0x400F0)) = 0x00000002; // "Selected PIN Protocol Register": Select which protocol to use for trace output (2: SWO NRZ, 1: SWO Manchester encoding)
*((volatile unsigned *)(ITM_BASE + 0x40010)) = SWOPrescaler; // "Async Clock Prescaler Register". Scale the baud rate of the asynchronous output
*((volatile unsigned *)(ITM_BASE + 0x00FB0)) = 0xC5ACCE55; // ITM Lock Access Register, C5ACCE55 enables more write access to Control Register 0xE00 :: 0xFFC
ITM->TCR = ITM_TCR_TraceBusID_Msk | ITM_TCR_SWOENA_Msk | ITM_TCR_SYNCENA_Msk | ITM_TCR_ITMENA_Msk; // ITM Trace Control Register
ITM->TPR = ITM_TPR_PRIVMASK_Msk; // ITM Trace Privilege Register
ITM->TER = portBits; // ITM Trace Enable Register. Enabled tracing on stimulus ports. One bit per stimulus port.
*((volatile unsigned *)(ITM_BASE + 0x01000)) = 0x400003FE; // DWT_CTRL
*((volatile unsigned *)(ITM_BASE + 0x40304)) = 0x00000100; // Formatter and Flush Control Register
So first question - anybody know where I can find the register definitions?
I followed this thread about SWO but it took me to the Infocenter, which has been deprecated and I cannot find a reference manual for the 52832
Thanks in advance
I am finding some of the information for the ITM in the ARM infocenter.
the section on the ITM states this..."Other registers are described in the ARM®v7-M Architectural Reference Manual."
And that document is "only available to registered ARM customers"...
Which perhaps explains why I cannot find out what the code is supposed to do. :roll:
NickT said:it is used for runtime logging
In the finished application, or for debugging? Have you considered using the RTT backend for the logger?
Did you try Rick Chung's implementation (step 1-4) in the post that you linked to? Does that behave the same way as your implementation? (flipping the signal?)
The previous engineer added the SWO_init code to the product to get a "uart" data stream available for application monitoring, even when there is no debugger connected.
I don't believe RTT is available without Segger...but I may be wrong
Rick's code seems to assume that SWO can be run at 4MHz, not 57600, but that might be a simple matter of setting the pre-scalar.
NickT said:I don't believe RTT is available without Segger...but I may be wrong
That is correct. It doesn't look like it supports 57600Hz, if you look in the nrf52_bitfields.h on line 1228-1233.
NickT said:The previous engineer added the SWO_init code to the product to get a "uart" data stream available for application monitoring, even when there is no debugger connected.
This should still be possible. You can use the UART to output data even if you only have 1 pin. You can use this as TX and not initialize the RX pin.
If you look at the ble_app_uart example from the SDK, in the uart_init() function, try to comment out the pins that aren't used:
static void uart_init(void)
app_uart_comm_params_t const comm_params =
//.rx_pin_no = RX_PIN_NUMBER,
.tx_pin_no = TX_PIN_NUMBER,
//.rts_pin_no = RTS_PIN_NUMBER,
//.cts_pin_no = CTS_PIN_NUMBER,
.flow_control = APP_UART_FLOW_CONTROL_DISABLED,
.use_parity = false,
#if defined (UART_PRESENT)
.baud_rate = NRF_UART_BAUDRATE_115200
.baud_rate = NRF_UARTE_BAUDRATE_115200
I tested this and it throws a framing error in the UART event handler. Remember to comment out this:
It is just tellling you that you have a framing error on the RX, which is not initialized, so that shouldn't be a concern.
Using the UART, you can also set the baudrate you desire:
.baud_rate = NRF_UART_BAUDRATE_57600