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

SWO signal inversion bug

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

Parents Reply Children
  • Edvin,

    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)
    {
        uint32_t                     err_code;
        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
    #else
            .baud_rate    = NRF_UARTE_BAUDRATE_115200
    #endif
        };
    
        APP_UART_FIFO_INIT(&comm_params,
                           UART_RX_BUF_SIZE,
                           UART_TX_BUF_SIZE,
                           uart_event_handle,
                           APP_IRQ_PRIORITY_LOWEST,
                           err_code);
        APP_ERROR_CHECK(err_code);
    }

    I tested this and it throws a framing error in the UART event handler. Remember to comment out this:

            case APP_UART_COMMUNICATION_ERROR:
                //APP_ERROR_HANDLER(p_event->data.error_communication);
                break;

    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

    Best regards,

    Edvin

Related