How to Enable Kinetis Trace

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

How to Enable Kinetis Trace

Jump to solution
4,361 Views
future_boston
Contributor II

 

TRACE pins on the K20 power up to MUX function 5.  How is the part and signals set to allow trace?

 

Is there a compile option in MQX to initialize these pins to MUX setting 7, or is up to the application to set them?  Some other boot option?

These are the power up states, and MQX does not initialized them to the TRACE function, which is MUX setting = 7 (JTAG/TRACE)

On the K20DN512, 144 pin, these are:

* Pin 58, PTA6, TRACE-CLKOUT --- documentation says default is "disabled", MUX setting 5 is undefined

* Pin 59, PTA7, TRACE-D3 ---- default is ADC0_SE10, MUX setting 5 is undefined

* Pin 60, PTA8, TRACE-D2 ---- default is ADC0_SE11, MUX setting 5 is undefined

* Pin 61, PTA9, TRACE-D1 ---- default is "disabled", MUX setting 5 is undefined

* Pin 62, PTA10, TRACE-D0 ---- default is "disabled", MUX setting 5 is undefined

Labels (1)
1 Solution
2,445 Views
future_boston
Contributor II

 

Both Segger and Keil said that enabling the trace pins is a low level function of the debugger/IDE.

Keil says that a debug script is added to the project and their U-link-Pro cable supports the parallel trace pins. The scripts are provided by Keil. The one described to me was named "Trace_port..." or something similar.

Segger calls the trace enabling commands a Macro. It is placed at the DLL level. The Macro is executed when the debugger connects to the target. Segger said their J-Trace-Cortex 8.13.00 supports the parallel trace pins and works with either Keil or IAR tools.

View solution in original post

0 Kudos
4 Replies
2,446 Views
future_boston
Contributor II

 

Both Segger and Keil said that enabling the trace pins is a low level function of the debugger/IDE.

Keil says that a debug script is added to the project and their U-link-Pro cable supports the parallel trace pins. The scripts are provided by Keil. The one described to me was named "Trace_port..." or something similar.

Segger calls the trace enabling commands a Macro. It is placed at the DLL level. The Macro is executed when the debugger connects to the target. Segger said their J-Trace-Cortex 8.13.00 supports the parallel trace pins and works with either Keil or IAR tools.

0 Kudos
2,447 Views
egoodii
Senior Contributor III

We use the IAR toolchain here (IDE, J-Trace) and use this Kinetis_trace.mac file to command the Trace pins prior to debugger attempts to access:

 

execUserReset() {

__var __reset;

__reset = __readMemory32(4,"Memory");

#PC = __reset;

__reset = __readMemory32(0,"Memory");

#SP = __reset;

 

__message "---- Enabling internal clock to Port A ----" ;

__writeMemory32(0xFFFF,0x40048038, "Memory");

__message "---- Enabling Trace Clock ----" ;

__writeMemory32(0x00001000,0x40048004, "Memory");

__message "---- Enabling Trace Pin Function ----" ;

__writeMemory32(0x00000740,0x40049018, "Memory"); // TraceClock, low drive strength

__writeMemory32(0x00000740,0x4004901C, "Memory"); // Trace data, High drive strength

__writeMemory32(0x00000740,0x40049020, "Memory");

__writeMemory32(0x00000740,0x40049024, "Memory");

__writeMemory32(0x00000740,0x40049028, "Memory");

__message "---- Enable trace funtion ----" ;

__writeMemory32(0x01000000,0xE000EDFC, "Memory");

__message "---- Unlock ETM ----" ;

__writeMemory32(0xC5ACCE55,0xE0041FB0, "Memory");

__message "---- Set sync port size as 4 ----" ;

__writeMemory32(0x00000008,0xE0040004, "Memory");

__writeMemory32(0x00000000,0xE00400F0, "Memory");

__writeMemory32(0x00FFFF00,0xE0001004, "Memory"); // DWT_CYCCNT_REG = 0x00FFFF00;

__writeMemory32(0x00000000,0xE0001000, "Memory"); // DWT_CTRL_REG = 0x00000401;

// __writeMemory32(0x00000401,0xE0001000, "Memory"); // DWT_CTRL_REG = 0x00000401;

// __writeMemory32(0x00000001,0xE0000E80, "Memory"); // ITM Trace control. Bit 0: Global enable

// __writeMemory32(0x00000005,0xE0000E80, "Memory"); // ITM Trace control. Bit 2: SYNCENA, Bit 0: Global enable

// __writeMemory32(0x0000000D,0xE0000E80, "Memory"); // ITM Trace control. Bit 2: SYNCENA, Bit 0: Global enable

// __writeMemory32(0x00000400,0xE0000E90, "Memory"); // ITM Trace cycle count

}

2,444 Views
williamely
Contributor IV

Your mac file helped me get going with my new I-Jet Trace on a K64 100 pin part. Here's my modified version.

execUserReset() {

__var __reset;

__reset = __readMemory32(4,"Memory");

#PC = __reset;

__reset = __readMemory32(0,"Memory");

#SP = __reset;

__message "---- Enabling internal clock to Port E ----" ;

__writeMemory32(0xFFFF,0x40048038, "Memory");

__message "---- Enabling Trace Clock ----" ;

__writeMemory32(0x00001000,0x40048004, "Memory");

__message "---- Enabling Trace Pin Function ----" ;

__writeMemory32(0x00000540,0x4004D000, "Memory"); // TraceClock, low drive strength

__writeMemory32(0x00000540,0x4004D004, "Memory"); // Trace data, High drive strength

__writeMemory32(0x00000540,0x4004D008, "Memory");

__writeMemory32(0x00000540,0x4004D00C, "Memory");

__writeMemory32(0x00000540,0x4004D010, "Memory");

__message "---- Enable trace function ----" ;

__writeMemory32(0x01000000,0xE000EDFC, "Memory");

__message "---- Unlock ETM ----" ;

__writeMemory32(0xC5ACCE55,0xE0041FB0, "Memory");

__message "---- Set sync port size as 4 ----" ;

__writeMemory32(0x00000008,0xE0040004, "Memory");

__writeMemory32(0x00000000,0xE00400F0, "Memory");

__writeMemory32(0x00FFFF00,0xE0001004, "Memory"); // DWT_CYCCNT_REG = 0x00FFFF00;

__writeMemory32(0x00000000,0xE0001000, "Memory"); // DWT_CTRL_REG = 0x00000401;

// __writeMemory32(0x00000401,0xE0001000, "Memory"); // DWT_CTRL_REG = 0x00000401;

// __writeMemory32(0x00000001,0xE0000E80, "Memory"); // ITM Trace control. Bit 0: Global enable

// __writeMemory32(0x00000005,0xE0000E80, "Memory"); // ITM Trace control. Bit 2: SYNCENA, Bit 0: Global enable

// __writeMemory32(0x0000000D,0xE0000E80, "Memory"); // ITM Trace control. Bit 2: SYNCENA, Bit 0: Global enable

// __writeMemory32(0x00000400,0xE0000E90, "Memory"); // ITM Trace cycle count

}

0 Kudos
2,444 Views
DaveTonyCook
Contributor IV

Hi

I thought I would add to this thread as I have just had over 4 days faff with the I-Jet Trace probe on the K64 and K24 Tower boards using IAR's Embedded Workbench 7.40.3.

This is what I've found:-

1. K64 code examples from both IAR and Freescale assign the wrong port in sysinit.c PTA6,alt7 instead of PTE0,alt5

2. The schematics showing port assignment for TRACECLOCKOUT are correct whilst the Tower user manual for the K64 is incorrect

3. The Kxx.dmac macro file supplied by IAR is has bugs for the K24 and K64 and most likely others

This info below describes problem/solution for common debugger gotchas

PROBLEM - 1

Warning - Skipping flash loading pass because there is no data in the

designated range: 0x10000000-0x13FFFFFF.

Two flash ranges, 0-0x0FFF FFFF and 0x10000000-0x13FFFFFF

If nothing is placed in one of the ranges then there is a warning that despite being enabled the flash loader was not used.

SOLUTION - 1

In Project -> Options -> Debugger -> Download -> Check "Override default .board file" -> delete the line for the surplus

flash range to eliminate the problem, or just ignore this message.

PROBLEM - 2

ETB trace and SWO cannot co-exist

ETM trace and SWO cannot co-exist.

If ETM or ETB trace is enabled then any SWO data (such as interrupt logging) is sent using the same data channel. IF the board actually allows ETM trace you will with some luck find the correct data being transferred after stopping, but the trace memory is limited, a few million bytes and logging on average one byte per instruction executed, so it fills in seconds.

SOLUTION - 2

So if you wish to use any SWO features set trace (Project -> Options ->Debugger -> I-jet -> Trace) to SWO

For Trace and SWO to work the latest unreleased Kxx.dmac file is required. This will be released in the next release of EWB (see attached)

The following settings get the SWO working on the TWR-K64F120M board:

Changes from the default:

1. In Library config: Set library low level interface implementation, stdout/sterr to "via SWO"

2. Set debug driver to I-jet (under download enable Verify download)

3. In I-jet category, set Trace -> 'Trace Data collection' to serial (SWO), disable "Enable ETB"

Now I can see datalog, interrupt and others. I do not want to choke the thin data bus so I do not enable SWO trace.

Note1:

1. Trace is not supported in hardware on K24 twr, and maybe some others

2. ETM and SWO can not be used at the same time

3. Only SWO will collect data for the timeline display

4. When using any live update feature it is best practice to limit the number of data eg dont have int and data loging on at the same time as there is a limited bandwidth

Note2:

Make sure the settings are correct,

1.Library config: Semihosting, via SWO

2.Set debugdriver to I-jet (under download I always enable Verify download)

3.In I-jet category, set Trace Data collection to SWO, disable "Enable ETB"

Now SWO data features work fine.

PROBLEM -3

Trace does not work.

The K64 supports trace in hardware however TRACECLOCKOUT is routed on chip to PTE0,alt5 but the tower user manual is incorrect as it specifies PTA6, alt7

This is further complicated as all the example code provided by both Freescale and IAR specify PTA6,alt7 in the code examples.  This error has also propargated into the Kxx.dmac macro file

SOLUTION

1. Get new Kxx.dmac file from IAR

2. Recode sysinit() in sysinit.c to use PTE0,alt5

3. Make sure settings are correct. see above.

Lastly, the notes are for the IAR toolchain and probe however I think the same issues are likely to be found in other vendors kit

Below are the contents of the Kxx.dmac (I don't know how to upload file so just cut n past and name it Kxx.dmac)

// Trace control macro for KinetisK devices

// It has support for ETB (both ETM and ITM).

// All global variables are 0 when declared.

// All these variables are prefixed with kinetis_ ...

__var kinetis_etbmodeset;       // Set to 1 if 'kinetis_etbmode' is set

__var kinetis_etbmode;          // Currently set Kinetis ETB mode  

__var kinetis_calibrate;        // Currenlty set calibration value

// Low level write to ETB bits

Kinetis_EnableETB(mask)

{

  __var value;

  __var changed;

  __var bits;

 

  bits = 0x3;

  changed = 0;

  value = __readMemory32(0xE0043000, "Memory"); // Funnel

  if ((value & bits) != mask) {                 // Check if we need to change it

    value &= ~bits;

    value |= mask;

    __writeMemory32(value, 0xE0043000, "Memory");

    changed |= bits;

  }

  value = __readMemory32(0xE0080014, "Memory"); // MCM_ETBCC

  if ((value & (bits << 4)) != (mask << 4)) { // Check if we need to change it

    value &= ~(bits << 4);

    value |= (mask << 4);

    __writeMemory32(value, 0xE0080014, "Memory");

    changed |= bits;

  }

  value = value >> 4;

  value &= 0x3;

  if (!kinetis_etbmodeset || value != kinetis_etbmode) {

    // Display message, only when mode changes

    // This function is called before every 'go/step' and we do not want

    // to see it too often.

    kinetis_etbmode = value;

    kinetis_etbmodeset = 1;

    // Display message (so user can see when ETB gets enabled)

    if (value == 0x3) {

      __message "Kinetis: ETB enabled (both ITM and ETM go to ETB)";

    } else

    if (value == 0x1) {

      __message "Kinetis: ETB enabled (only ETM goes to ETB)";

    } else

    if (value == 0x2) {

      __message "Kinetis: ETB enabled (only ITM goes to ETB)";

    } else {

      __message "Kinetis: ETB not enabled";

    }

  }

}

Kinetis_EnableGPIOForETM()

{

  __var value;

  __var enabled;

 

  enabled = 0;

  value = __readMemory32(0x40048038, "Memory");       // ReadRegister( SIM_SCGC5, &value);

  if ((value & (1<<13)) == 0) {

    value |= (1<<13);                                 // Enabling internal clock to Port E

    __writeMemory32(value, 0x40048038, "Memory");     // WriteRegister(SIM_SCGC5, value);

    enabled = 1;

  }

  value = __readMemory32(0x40048004, "Memory");       // ReadRegister( SIM_SOPT2, &value);

  if ((value & (1<<12)) == 0) {

    value |= (1<<12);                                 // Debug trace clock select = Core/system clock

    __writeMemory32(value, 0x40048004, "Memory");     // WriteRegister(SIM_SOPT2, value);

    enabled = 1;

  }

  // ---- Enabling Trace Pin Function ----

  // Trace data and clock pins, high drive strength

  /* TRACE CLK and TRACE D0*/;

  __writeMemory32(0x00000540, 0x4004D000, "Memory");  // WriteRegister(PORTE_PCR0,  0x00000700);

  __writeMemory32(0x00000540, 0x4004D010, "Memory");  // WriteRegister(PORTE_PCR4, 0x00000740);

  if ( __getTracePortSize() >= 2 )

  {

  /* Enable TRACE D1*/;

    __writeMemory32(0x00000540, 0x4004D00C, "Memory");  // WriteRegister(PORTE_PCR3,  0x00000740);

  }

  if ( __getTracePortSize() == 4 )

  {

  /* Enable TRACE D2, D3*/;

  __writeMemory32(0x00000540, 0x4004D008, "Memory");  // WriteRegister(PORTE_PCR2,  0x00000740);

  __writeMemory32(0x00000540, 0x4004D004, "Memory");  // WriteRegister(PORTE_PCR1,  0x00000740);

  }

}

Kinetis_DisableGPIOForETM()

{

  // TODO: Reverse actions above (back to defaults)?

}

// This is common routine to configure trace on Kinetis

// Kinetis has 2 trace sources (ITM/ETM) and 3 export options (ETM/ETB/SWO).

// The following cases are possible:

//      Nothing

//      ETM to TPIU (with ITM)

//      ETM to ETB, ITM to SWO

//      ETM to TPIU, ITM to ETB

//     

KinetisConfigureTrace()

{

  __var modemask;

  __var etbena;

 

  modemask = __getTraceProperty(2);     // Get mask of selected modes

  etbena   = 0;                         // Mask of bits for TPIU

 

  if (modemask & 0x6) {

    // ETB (0x4) or SWO (0x2) are allowed

    if (modemask & 0x2) {

      etbena = 0x1;                     // Only ETM should go to ETB

    } else {

      etbena = 0x1 | 0x2;               // Both ETM and ITM should go to ETB

    }

  } else {

      etbena = 0x0;                     // Both ETM and SWO go to TPIU

  }

 

  /*Check device for ETB*/

  if( __readMemory32(0xE00FF018,"Memory") & 0x1)

  {

  Kinetis_EnableETB(etbena);            // Configure what goes to ETB

  }

 

  if (modemask & 0x10) {                // Is ETM enabled?

    Kinetis_EnableGPIOForETM();         // Yes - enable GPIO for ETM

    if (kinetis_calibrate != 3) {       // Set calibration (only once time)

      kinetis_calibrate = 3;

      if (__probeType("JTAGJet"))

      {

        __probeCmd("trace calibrate 3");        // For Kinetis calibrate 3 works the best

      }

    }

  } else {

    Kinetis_DisableGPIOForETM();        // Enable GPIO for ETM

  }

}

execConfigureTraceETM()

{

  if (!__driverType("ijet")) {

    // Compatible mode (other probes)

    Kinetis_EnableGPIOForETM(); // Enable GPIO for ETM

    return;

  }

 

  // This native (ijet) driver (extended functionality)

  KinetisConfigureTrace();      // Common configuration (for SWO and ETM)

}

execConfigureTraceSWO()

{

  if (!__driverType("ijet")) {

    // Compatible mode (other probes)

    // Nothing (as it was in original DMAC file).

    return;

  }

 

  // This native (ijet) driver (extended functionality)

  KinetisConfigureTrace();      // Common configuration (for SWO and ETM)

}

MassErase()

{

  if (__hasDAPRegs())

  {

    __var mdm_ctrl;

   

    //Select bank 0

    __writeDPReg(0x01000000, 0x8);

    if (__readAPReg(0x0) & 0x20)

    {

      mdm_ctrl = __readAPReg(0x4) | 0x1;

     

      //Do mass erase

      __writeAPReg(mdm_ctrl, 0x4);

      __message "Performing mass erase...";

      //Wait until finished

      do

      { 

        __delay(100);

      } while(__readAPReg(0x4) & 0x1);

   

      __message "Mass erase finished";

    }

    else

    {

      __message "Mass erase is disabled";

    }

  }

  else

  {

    __message "Mass erase cannot be performed";

  }

}

getPersistentQuickLaunchMacros()   // <-- Reserved name, debugger calls it to populate QuickLaunch view.

{

  __message "getPersistentQuickLaunchMacros";

  __var macs;

 

  macs = "MassErase()";

 

  return macs;

}