How to use SWO on Kinetis?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to use SWO on Kinetis?

Jump to solution
5,810 Views
frank26080115
Contributor II

I would like to use Cortex M's SWO for debugging on a MK10 and MK20, I own a J-Link and I love using the SWO viewer for debugging.

I usually use STM32 microcontrollers, and I already know how to do the same thing on them, basically setup CoreDebug and ITM, but they also have a ST specific DBGMCU pheripheral that needs to be configured.

DBGMCU only exist on ST chips. What is the equivalent on Kinetis? I do not see any in the KQRUG document. Does that mean I can just write to ITM and see the output? Does the pin automatically default to being a SWO pin instead of GPIO?

Thanks

Labels (1)
1 Solution
3,073 Views
frank26080115
Contributor II

got my code working, apparently the answer is that there is Kinetis specific setup required, but the standard Cortex setup for ITM, CoreDebug, and DWT are required.

void swo_init()
{
     uint32_t SWOSpeed = 6000000; //6000kbps, default for JLinkSWOViewer
     uint32_t SWOPrescaler = (F_CPU / SWOSpeed) - 1; // SWOSpeed in Hz, note that F_CPU is expected to be 96000000 in this case
     CoreDebug->DEMCR = CoreDebug_DEMCR_TRCENA_Msk;
     *((volatile unsigned *)(ITM_BASE + 0x400F0)) = 0x00000002; // "Selected PIN Protocol Register": Select which protocol to use for trace output (2: SWO)
     *((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 = 0x00000001; // 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
}

// may not be needed
void swo_deinit()
{
     volatile uint32_t i = 0xFFF;
     while (ITM->PORT[0].u32 == 0 && i--); // wait for any pending transmission
     CoreDebug->DEMCR = 0;
     *((volatile unsigned *)(ITM_BASE + 0x00FB0)) = 0xC5ACCE55; // ITM Lock Access Register, C5ACCE55 enables more write access to Control Register 0xE00 :: 0xFFC
     ITM->TCR = 0;
     ITM->TPR = 0;
     ITM->TER = 0;
}

// function mostly copied from ITM_SendChar
void swo_sendchar(char x)
{
     if (
          (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) &&    // if debugger is attached (does it really work?)
          (CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk)  &&      // Trace enabled
          (ITM->TCR & ITM_TCR_ITMENA_Msk)                  &&      // ITM enabled
          (ITM->TER & (1UL << 0))                                  // ITM Port #0 enabled
     )
     {
          volatile uint32_t i = 0xFFF; // implement a timeout
          while (ITM->PORT[0].u32 == 0 && i--); // wait for next
          if (ITM->PORT[0].u32 != 0 && i != 0) {
               ITM->PORT[0].u8 = (uint8_t) x; // send
          }
     }
}

View solution in original post

5 Replies
3,074 Views
frank26080115
Contributor II

got my code working, apparently the answer is that there is Kinetis specific setup required, but the standard Cortex setup for ITM, CoreDebug, and DWT are required.

void swo_init()
{
     uint32_t SWOSpeed = 6000000; //6000kbps, default for JLinkSWOViewer
     uint32_t SWOPrescaler = (F_CPU / SWOSpeed) - 1; // SWOSpeed in Hz, note that F_CPU is expected to be 96000000 in this case
     CoreDebug->DEMCR = CoreDebug_DEMCR_TRCENA_Msk;
     *((volatile unsigned *)(ITM_BASE + 0x400F0)) = 0x00000002; // "Selected PIN Protocol Register": Select which protocol to use for trace output (2: SWO)
     *((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 = 0x00000001; // 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
}

// may not be needed
void swo_deinit()
{
     volatile uint32_t i = 0xFFF;
     while (ITM->PORT[0].u32 == 0 && i--); // wait for any pending transmission
     CoreDebug->DEMCR = 0;
     *((volatile unsigned *)(ITM_BASE + 0x00FB0)) = 0xC5ACCE55; // ITM Lock Access Register, C5ACCE55 enables more write access to Control Register 0xE00 :: 0xFFC
     ITM->TCR = 0;
     ITM->TPR = 0;
     ITM->TER = 0;
}

// function mostly copied from ITM_SendChar
void swo_sendchar(char x)
{
     if (
          (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) &&    // if debugger is attached (does it really work?)
          (CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk)  &&      // Trace enabled
          (ITM->TCR & ITM_TCR_ITMENA_Msk)                  &&      // ITM enabled
          (ITM->TER & (1UL << 0))                                  // ITM Port #0 enabled
     )
     {
          volatile uint32_t i = 0xFFF; // implement a timeout
          while (ITM->PORT[0].u32 == 0 && i--); // wait for next
          if (ITM->PORT[0].u32 != 0 && i != 0) {
               ITM->PORT[0].u8 = (uint8_t) x; // send
          }
     }
}
3,073 Views
tsvetanmudrov
Contributor III

Hello. I'm also "coming" from STM32, and there, under eclipse and SWV tool from Segger - all is fine with SWO debug messages. But this is not the case for me with Kinetis and Code Warrior.

I'm configuring the ITM in similar way like you. Seems it works, because I see an output data frame on SWO output. But I don't have any data in SWO Viewer (Segger's tool). I'm asking me, is it possible that CodeWarrior debug plugin takes the control over the J-link probe and blocks the channel to external SWO tool?

Frank, what kind of IDE you are using with success of SWO view?

0 Kudos
3,073 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Frank,

I check IAR ARM Workbench support J-Link SWO debug/Trace.

I do a test with IAR software and record my setting with below pictures.

Wish it could be helpful.

with regards,

Ma Hui

Setting with IAR project option:

SWO trace0.jpg

SWO trace1.jpg

Debug panel setting:

SWO trace2.jpg

SWO trace3.jpg

SWO trace4.jpg

SWO trace5.jpg

0 Kudos
3,073 Views
frank26080115
Contributor II

Hi Hui Ma

Thanks but you did not answer my question at all.

DBGMCU only exist on ST chips. What is the equivalent on Kinetis? I do not see any in the KQRUG document. Does that mean I can just write to ITM and see the output? Does the pin automatically default to being a SWO pin instead of GPIO?

I am not using IAR, I am not using any auto-configuration tool of any kind. When you show me how to click those buttons, I need to know what is happening behind the scenes.

0 Kudos
3,073 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Frank,

I will check this thread. I will let you know when there with any updated info.

Thank you for the patience.

B.R.

Ma Hui

0 Kudos