[SOLVED] ATSAME54P20A SWO hangs

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • [SOLVED] ATSAME54P20A SWO hangs

    Hi there,

    I experience some odd issue with SWO with SAME54-Xplained Pro board. It's equipped with ATSAME54P20A (Cortex-M4F) chip.
    What I am trying to attain, is nice high-speed SWO printing. The initialisation procedure is basically the same as I used on LPC1768 (Cortex-M3) except the clock configuration.

    SAME54 runs on 12 MHz.
    • I tried 3,6,12 MHz SWO clock frequency. But none of the are worked for me.
      • No SWO output observed either via telnet client or inside of Eclipse.
      • ITM buffer is ready in very seldom cases. Once per 10 resets or so. And even then no SWO output.
      • JLinkSWOViewer reported once 17 unknown packets. But no actually output.
    • Same result under Windows and Linux.
    • JLink Base and JLink Pro behaves in the same way.
    • Tried gdb and Eclipse - no success.
      • Finally I tried JLinkSWOViewer. And here was another trouble: CPU hangs after SWO clock frequency measurement completed (SWO 12 MHz @ CPU 12 MHz ?!).
        • HW reset while JLink is connected does not help.
        • Only disconnecting JLink and HW reset recovered the state



    1. Is the SWO initialisation is same for Cortex-M3 and Cortex-M4? I couldn't find any differences between those cores.
    2. Is anything special about ATSAME54 in this respect? Why the core hangs?
    3. Is 12 MHz SWO clock frequency automatically detected by JLinkSWOViewer plausible (Cortex-M4 runs @ 12 MHz too)?




    SEGGER J-Link Commander V6.62 (Compiled Jan 24 2020 16:34:54)

    Here is the sample code used to test SWO. It is part of prototype code which is part of minimalist program in order to get the core and USART peripheral up and running.

    C Source Code: SWO_API.c

    1. /*!
    2. * \brief Initialize the SWO trace port for debug message printing
    3. * \param portBits Port bit mask to be configured
    4. * \param cpuCoreFreqHz CPU core clock frequency in Hz
    5. * \param SWOSpeed Baudrate of SWO trace
    6. */
    7. void SWO_Init(uint32_t portBits, uint32_t cpuCoreFreqHz, uint32_t SWOSpeed) {
    8. uint32_t SWOPrescaler = (cpuCoreFreqHz / SWOSpeed) - 1; /* SWOSpeed in Hz, note that cpuCoreFreqHz is expected to be match the CPU core clock */
    9. CoreDebug->DEMCR = CoreDebug_DEMCR_TRCENA_Msk; /* enable trace in core debug */
    10. *((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) */
    11. *((volatile unsigned *) (ITM_BASE + 0x40010)) = SWOPrescaler; /* "Async Clock Prescaler Register". Scale the baud rate of the asynchronous output */
    12. *((volatile unsigned *) (ITM_BASE + 0x00FB0)) = 0xC5ACCE55; /* ITM Lock Access Register, C5ACCE55 enables more write access to Control Register 0xE00 :: 0xFFC */
    13. ITM->TCR = ITM_TCR_TraceBusID_Msk | ITM_TCR_SWOENA_Msk | ITM_TCR_SYNCENA_Msk | ITM_TCR_ITMENA_Msk; /* ITM Trace Control Register */
    14. ITM->TPR = ITM_TPR_PRIVMASK_Msk; /* ITM Trace Privilege Register */
    15. ITM->TER = portBits; /* ITM Trace Enable Register. Enabled tracing on stimulus ports. One bit per stimulus port. */
    16. *((volatile unsigned *) (ITM_BASE + 0x01000)) = 0x400003FE; /* DWT_CTRL */
    17. *((volatile unsigned *) (ITM_BASE + 0x40304)) = 0x00000100; /* Formatter and Flush Control Register */
    18. }
    19. /*!
    20. * \brief Sends a character over the SWO channel. See as well ITM_SendChar() in core_cm4.h
    21. * \param c Character to be sent
    22. * \param portNo SWO channel number, value in the range of 0 to 31
    23. */
    24. void SWO_PrintChar(char c, uint8_t portNo) {
    25. volatile int timeout;
    26. /* Check if Trace Control Register (ITM->TCR at 0xE0000E80) is set */
    27. if ((ITM->TCR & ITM_TCR_ITMENA_Msk) == 0) { /* check Trace Control Register if ITM trace is enabled*/
    28. return; /* not enabled? */
    29. }
    30. /* Check if the requested channel stimulus port (ITM->TER at 0xE0000E00) is enabled */
    31. if ((ITM->TER & (1ul << portNo)) == 0) { /* check Trace Enable Register if requested port is enabled */
    32. return; /* requested port not enabled? */
    33. }
    34. timeout = 5000; /* arbitrary timeout value */
    35. while (ITM->PORT[portNo].u32 == 0) {
    36. /* Wait until STIMx is ready, then send data */
    37. timeout--;
    38. if (timeout == 0) {
    39. return; /* not able to send */
    40. }
    41. }
    42. #if 1 /* different version for Cortex-M3 needed? */
    43. ITM->PORT[portNo].u8 = c;
    44. #elif 0
    45. ITM->PORT[portNo].u16 = 0x08 | (c<<8);
    46. #else
    47. ITM_STIM_U8 = c; /* send data */
    48. #endif
    49. }
    50. /*!
    51. * \brief Sends a string over SWO to the host
    52. * \param s String to send
    53. * \param portNumber Port number, 0-31, use 0 for normal debug strings
    54. */
    55. void SWO_PrintString(const char *s, uint8_t portNumber) {
    56. while (*s != '\0') {
    57. SWO_PrintChar(*s++, portNumber);
    58. }
    59. }
    Display All
  • Hi,
    Thank you for your inquiry.

    Unfortunately this device does not follow the ARM specification, because it has a high CPU speed.
    It is the same problem as with the ATSAM70:
    wiki.segger.com/ATSAME70

    We will implement this natively for the SAM50 devices as well, in the future.

    If you need it before then, you will have to set up your own J-Link Script file.
    Please find further information about this in the J-Link Manual (UM08001).

    Best regards,
    Fabian
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.