Wrong ID for downloading on the FRDM K-64 MCU from NXP?

Comments

18 comments

  • Avatar
    Markus

    Hello Bård,

     

    this is a known Bug in the Kinetis Controller described in the errata e7534.

    I’ve extended the Target-Detection Scrip to work around this Bug and fixed also a Bug with the Kinetis K0x Controller.

    It seems like Rowley has no interest in fixing this Bugs as I’ve sent them my Bugfixes already half a year ago.

     

    As it is not possible to attach a File here, I’ll try to post my code in the next reply. Use it to replace the File

    C:\Users\<XXX>\AppData\Local\Rowley Associates Limited\CrossWorks for ARM\v4\packages\targets\Kinetis\Kinetis_Target.js

     

    Regards

    0
    Comment actions Permalink
  • Avatar
    Markus

    /******************************************************************************
      Target Script for Freescale Kinetis

      Copyright (c) 2010-2014 Rowley Associates Limited.

      This file may be distributed under the terms of the License Agreement
      provided with this software.

      THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE
      WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     ******************************************************************************/

    function Connect()
    {
      TargetInterface.setMaximumJTAGFrequency(8000000);
      if (TargetInterface.implementation() != "j-link")
        TargetInterface.setDebugInterfaceProperty("max_ap_num", 3);
    }

    function EnableTrace(TraceInterfaceType)
    {
      if (TraceInterfaceType == "ETB")
        {
          TargetInterface.pokeWord(0xE0080014, 0x00000030); // MCM_ETB_CNT_CTRL - disable TPIU
          var CSTF_Ctrl_Reg = ((0x908<<16)|0);
          v = TargetInterface.getICEBreakerRegister(CSTF_Ctrl_Reg);
          TargetInterface.setICEBreakerRegister(CSTF_Ctrl_Reg, v | 0x00000003); // EnS0 | EnS1  
        }
      else if (TraceInterfaceType == "TracePort")
        {
          TargetInterface.pokeWord(0xE0080014, 0x00000000); // MCM_ETB_CNT_CTRL - enable TPIU
          // When the TracePort is on PortA
          TargetInterface.pokeWord(0x40048038, TargetInterface.peekWord(0x40048038)|(1<<9));  
          TargetInterface.pokeWord(0x40048004, 0x00001000);   // TRACECLKSEL
          TargetInterface.pokeWord(0x40049018, 0x00000700);   // TraceClock, low drive strength
          TargetInterface.pokeWord(0x4004901C, 0x00000740);   // Trace data, High drive strength
          TargetInterface.pokeWord(0x40049020, 0x00000740);
          TargetInterface.pokeWord(0x40049024, 0x00000740);
          TargetInterface.pokeWord(0x40049028, 0x00000740);
        }
      else if (TraceInterfaceType == "SWO")
        TargetInterface.pokeWord(0xE0080014, 0x00000000); // MCM_ETB_CNT_CTRL - enable TPIU
    }

    function Reset()
    {
      if (TargetInterface.implementation() == "crossworks_simulator")
        {
          TargetInterface.stop(1);
          return;
        }
      if (TargetInterface.implementation() == "j-link")
        {
          TargetInterface.resetAndStop(100);
          return;
        }
      if (TargetInterface.implementation() == "P&E")
        TargetInterface.stop();
      TargetInterface.setDebugRegister(0x01000004, 0x8); // set System Reset Request,
      TargetInterface.delay(1);
      TargetInterface.setDebugRegister(0x01000004, 0x10); // clear System Reset Request and set Core Hold Reset
      TargetInterface.pokeWord(0xE000EDFC, 0x1); // Reset vector catch
      TargetInterface.setDebugRegister(0x01000004, 0x0); // clear Core Hold Reset
      TargetInterface.waitForDebugState(1000);
    }

    function SRAMReset()
    {
      Reset();
    }

    function FLASHReset()
    {
      Reset();
    }

    function CheckSystemSecurity()
    {
      var status = TargetInterface.getDebugRegister(0x01000000);    
      if (status & (1<<2))
        {
          if (CWSys == undef || (CWSys.popup && CWSys.popup("System Security Enabled - MassErase to unlock?\nNote that the nSRST must be connected to the debug port\n")))
            MassEraseUnderNSRST();
          else
            TargetInterface.error("System Security Enabled\n");
        }  
      status = TargetInterface.getDebugRegister(0x01000000);  
      if ((status & (1<<3))==0)
        {
          TargetInterface.setDebugRegister(0x01000004, 0x10);
          TargetInterface.delay(1000);      
        }    
    }

    function GetPartName()
    {
      CheckSystemSecurity();
      TargetInterface.pokeWord(0xE000EDFC, (1<<24));
      var PartName;
      var PartName2;
      var PartName3;
      var ForD;
      var SubPartName="";
      var CPUID = TargetInterface.peekWord(0xE000ED00);
      if (((CPUID>>4)&0xf)==0) // Cortex-M0
        {      
          var SIM_SDID = TargetInterface.peekWord(0x40048024);
          var SIM_FCFG2 = TargetInterface.peekWord(0x40048050);
          var Length;
          switch ((SIM_SDID>>20)&0xf)
            {
              case 0:
              case 1:
                if (((SIM_SDID>>24)&0xff) < 10)
                  PartName = "MKL0"+((SIM_SDID>>24)&0xff).toString(16)+"Z";
                else if (((SIM_SDID>>28)&0xf) == 9)
                  PartName = "MKL"+(((SIM_SDID>>24)&0xff)-0x10).toString(16)+"Z";
                else
                  PartName = "MKL"+((SIM_SDID>>24)&0xff).toString(16)+"Z";
                Length = ((SIM_FCFG2>>24) & 0x3f)<<3;
                Length += ((SIM_FCFG2>>16) & 0x3f)<<3;
                break;
              case 2:
                if (((SIM_SDID>>24)&0xff) < 10)
                  PartName = "MKE0"+((SIM_SDID>>24)&0xff).toString(16)+"Z";
                else
                  PartName = "MKE"+((SIM_SDID>>24)&0xff).toString(16)+"Z";
                Length = ((SIM_FCFG2>>24) & 0x3f)<<3;
                break;
              case 5:
                if (((SIM_SDID>>24)&0xff) < 10)
                  PartName = "MKW0"+((SIM_SDID>>24)&0xff).toString(16)+"Z";
                else
                  PartName = "MKW"+((SIM_SDID>>24)&0xff).toString(16)+"Z";
                Length = ((SIM_FCFG2>>24) & 0x3f)<<3;
                Length += ((SIM_FCFG2>>16) & 0x3f)<<3;
                break;
              case 6:
                if (((SIM_SDID>>24)&0xff) < 10)
                  PartName = "MKV0"+((SIM_SDID>>24)&0xff).toString(16)+"Z";
                else
                  PartName = "MKV"+((SIM_SDID>>24)&0xff).toString(16)+"Z";
                Length = ((SIM_FCFG2>>24) & 0x3f)<<3;
                Length += ((SIM_FCFG2>>16) & 0x3f)<<3;
                break;
            }            
          PartName += Length.toString();
        }
      else
        {
          var SIM_SDID = TargetInterface.peekWord(0x40048024);
          if (((SIM_SDID)>>24) & 0xff)    // Check valid content in Family-ID and Subfamily-ID (at least one of them must not be zero)
            {
              switch ((SIM_SDID>>20) & 0xf)
                {
                  case 0:
                    PartName = "MK";
                    break;
                  case 1:
                    PartName = "MKL";
                    break;
                  case 2:
                    PartName = "MKE";
                    break;
                  case 5:
                    PartName = "MKW";
                    break;
                  case 6:
                    PartName = "MKV";
                    break;
                  case 7:
                    PartName = "MKS";
                    break;
                }
              PartName += ((SIM_SDID>>28)&0xf).toString(16);    // Write the Family-ID
              PartName += ((SIM_SDID>>24)&0xf).toString(16);    // Write the Sub-Family-ID
              if (TargetInterface.peekWord(0xE000EF40))
                ForD = "F";
              else
                ForD = "D";

              // check for "e7534: SUBFAMID reads back incorrect sub-family of the Kinetis device"
              var SIM_SOPT1 = TargetInterface.peekWord(0x4047000);
              var RamSize = (SIM_SOPT1 >> 12) &0xF;
              switch (PartName)
              {
                case "MK62":
                  // There is no K62 in the Kinetis Family --> errata e7534 found
                  PartName = "MK64"
                  TargetInterface.message("e7534 found: MK62 --> MK64")
                  break;
                case "MK61":
                  if (RamSize == 0xB)    // RAM-Size is 256 KByte.
                  {
                    // There is no K61 with 256 KByte in the Kinetis Family --> errata e7534 found
                    PartName = "MK63"
                    TargetInterface.message("e7534 found: MK61 --> MK63")
                  }
                  break;
                case "MK22":
                  if (RamSize == 0xB)    // RAM-Size is 256 KByte.
                  {
                    // There is no K22 with 256 KByte in the Kinetis Family --> errata e7534 found
                    PartName = "MK24"
                    TargetInterface.message("e7534 found: MK22 --> MK24")
                  }
                  break;
              }
            }
          else
            {          
              switch ((SIM_SDID>>4) & 0x7)
                {
                  case 0: // K10/K12
                    PartName = "MK10";
                    PartName2 = "MK12";
                    break;
                  case 1: // K20/K22
                    PartName = "MK20";
                    PartName2 = "MK22";
                    break;
                  case 2: // K30/K11/K61
                    PartName = "MK30";
                    PartName2 = "MK11";
                    PartName3 = "MK61";
                    break;
                  case 3: // K40/K21
                    PartName = "MK40";
                    PartName2 = "MK21";
                    break;
                  case 4: // K60/K62
                    PartName = "MK60";
                    PartName2 = "MK62";
                    break;
                  case 5: // K70
                    PartName = "MK70";
                    break;
                  case 6: // K50/K52
                    PartName = "MK50";
                    PartName2 = "MK52";
                    PartName3 = "MKW24";
                    break;
                  case 7: // K51/K53
                    PartName = "MK51";
                    PartName2 = "MK53";
                    break;
                }        
              if (((SIM_SDID>>7) & 0x7)==3)
                ForD = "F";
              else
                ForD = "D";

              TargetInterface.message("GetPartName - Second: ");
              TargetInterface.message(PartName);
            }
          var SIM_FCFG2 = TargetInterface.peekWord(0x40048050);
          if (SIM_FCFG2 & (1<<23))
            {
              if (PartName.substring(0,3) != "MKV")
                SubPartName += "N";
              Length = ((SIM_FCFG2>>24) & 0x7f)<<3;
              Length += ((SIM_FCFG2>>16) & 0x7f)<<3;
              switch ((SIM_SDID>>7) & 0x7)
                {
                  case 3:
                  case 7:
                    Length *= 2;
                    break;
                }
              if (Length == 1024)
                SubPartName += "1M0";
              else if (Length == 2048)
                SubPartName += "2M0";
              else
                SubPartName += Length.toString();
            }
          else
            {
              if (PartName.substring(0,3) != "MKE")
                SubPartName += "X";
              Length = ((SIM_FCFG2>>24) & 0x7f)<<3;
              if (((SIM_SDID>>7) & 0x7)==3)
                Length *= 2;
              SubPartName += Length.toString();
            }
          PartName += ForD+SubPartName;
          if (PartName2)
            PartName += "/"+PartName2+ForD+SubPartName;
          if (PartName3)
            PartName += "/"+PartName3+ForD+SubPartName;
        }
      return PartName;
    }

    function MatchPartName(name)
    {  
      var partName = GetPartName();
      if (partName.length >= 8)
        {
          if (partName.substring(0,4) == "MK10" && name.substring(0,4) == "MK12")
            return name.substring(4,4) == partName.substring(4,4);
          else if (partName.substring(0,4) == "MK20" && name.substring(0,4) == "MK22")
            return name.substring(4,4) == partName.substring(4,4);
          else if (partName.substring(0,4) == "MK30" && (name.substring(0,4) == "MK11" || name.substring(0,4) == "MK61"))
            return name.substring(4,4) == partName.substring(4,4);
          else if (partName.substring(0,4) == "MK40" && (name.substring(0,4) == "MK21") || (name.substring(0,4) == "MKW2"))
            return name.substring(4,4) == partName.substring(4,4);
          else if (partName.substring(0,4) == "MK60" && name.substring(0,4) == "MK22")
            return name.substring(4,4) == partName.substring(4,4);
          else if (partName.substring(0,4) == "MK50" && (name.substring(0,4) == "MK52") || (name.substring(0,4) == "MKW2"))
            return name.substring(4,4) == partName.substring(4,4);
          else if (partName.substring(0,4) == "MK51" && name.substring(0,4) == "MK53")
            return name.substring(4,4) == partName.substring(4,4);
          else
            return name.substring(0, 8) == partName.substring(0, 8);
        }
      else (partName.length >= 6)
        return name.substring(0, 6) == partName.substring(0, 6);
      return false;
    }

    // MKM devices have the SIM module at a different address
    function GetPartName2()
    {
      TargetInterface.setMaximumJTAGFrequency(2000000);
      CheckSystemSecurity();
      TargetInterface.pokeWord(0xE000EDFC, (1<<24));
      var PartName;
      var SIM_SDID = TargetInterface.peekWord(0x4003F024);
      var SIM_FCFG2 = TargetInterface.peekWord(0x4003F050);
      switch (SIM_SDID >> 20)
        {
          case 0x123:
          case 0x133:
          case 0x143:
          case 0x323:
          case 0x333:
          case 0x343:
            PartName = "MKM"+((SIM_SDID>>28)&0xf).toString()+((SIM_SDID>>24)&0xf).toString()+"Z"+(((SIM_FCFG2>>24) & 0x3f)<<3).toString();
            break;
        }
      return PartName;
    }

    function MatchPartName2(name)
    {  
      var partName = GetPartName2();  
      return name.substring(0, 8) == partName.substring(0, 8);
    }

    // MKE devices have different id scheme
    function GetPartName3()
    {
      CheckSystemSecurity();
      TargetInterface.pokeWord(0xE000EDFC, (1<<24));
      var PartName;
      var SIM_SRSID = TargetInterface.peekWord(0x40048000);
      switch (SIM_SRSID >> 24)
        {
          case 2: // KE02
            PartName = "MKE02Z/SKEAZN64/MWPR15";
            break;
          case 4: // KE04
            PartName = "MKE04Z/SKEAZN8";
            break;
          case 6: // KE06
            PartName = "MKE06Z/SKEAZ128";
            break;
        }
      return PartName;
    }

    function MatchPartName3(name)
    {  
      var SIM_SRSID = TargetInterface.peekWord(0x40048000);
      switch (SIM_SRSID >> 24)
        {
          case 2: // KE02
            return name == "MKE02Z" || name.substring(0,8) == "SKEAZN64" || name == "MWPR1516";
          case 4: // KE04
            return name == "MKE04Z" || name.substring(0,7) == "SKEAZN8";
          case 6: // KE06
            return name == "MKE06Z" || name.substring(0,8) == "SKEAZ128";
            break;
        }
      return 0;
    }

    // MKL28 devices have the SIM module at a different address
    function GetPartName4()
    {  
      CheckSystemSecurity();
      TargetInterface.pokeWord(0xE000EDFC, (1<<24));
      var PartName;
      var SIM_SDID = TargetInterface.peekWord(0x40075024);
      var SIM_FCFG2 = TargetInterface.peekWord(0x40075050);
      if (((SIM_SDID>>24)&0xff) < 10)
        PartName = "MKL0"+((SIM_SDID>>24)&0xff).toString(16)+"Z";
      else
        PartName = "MKL"+((SIM_SDID>>24)&0xff).toString(16)+"Z";
      Length = ((SIM_FCFG2>>24) & 0x3f)<<3;
      Length += ((SIM_FCFG2>>16) & 0x3f)<<3;
      PartName += Length.toString();  
      return PartName;
    }

    function MatchPartName4(name)
    {  
      var partName = GetPartName4();  
      return name.substring(0, 8) == partName.substring(0, 8);
    }

    function MDMStatus()
    {
      var status = TargetInterface.getDebugRegister(0x01000000);  
      if (status & (1<<0))
        WScript.Echo("Flash Mass Erase Acknowledge\n");
      if (status & (1<<1))
        WScript.Echo("Flash Ready\n");
      if (status & (1<<2))
        WScript.Echo("System Security\n");
      if ((status & (1<<3))==0)
        WScript.Echo("System Is In Reset\n");
      if (status & (1<<5))
        WScript.Echo("Mass Erase Enable\n");
      if (status & (1<<6))
        WScript.Echo("Backdoor Access Key Enable\n");
      if (status & (1<<7))
        WScript.Echo("LP Enabled\n");
      if (status & (1<<8))
        WScript.Echo("Very Low Power Mode\n");
      if (status & (1<<9))
        WScript.Echo("LLS Mode Exit\n");
      if (status & (1<<10))
        WScript.Echo("VLLSx Modes Exit\n");
      if (status & (1<<16))
        WScript.Echo("Core Halted\n");
      if (status & (1<<17))
        WScript.Echo("Core SLEEPDEEP\n");
      if (status & (1<<18))
        WScript.Echo("Core SLEEPING\n");
    }

    function MDMControl()
    {
      var status = TargetInterface.getDebugRegister(0x01000004);
      if (status & (1<<0))
        WScript.Echo("Flash Mass Erase in Progress\n");
      if (status & (1<<1))
        WScript.Echo("Debug Disable\n");
      if (status & (1<<2))
        WScript.Echo("Debug Request\n");
      if (status & (1<<3))
        WScript.Echo("System Reset Request\n");
      if (status & (1<<4))
        WScript.Echo("Core Hold Reset\n");
      if (status & (1<<5))
        WScript.Echo("VLLSx Debug Request\n");
      if (status & (1<<6))
        WScript.Echo("VLLSx Debug Acknowledge\n");
      if (status & (1<<7))
        WScript.Echo("LLS, VLLSx Status Acknowledge\n");
    }

    function MassEraseUnderNSRST()
    {
      TargetInterface.setNSRST(0);
      TargetInterface.setDebugRegister(0x01000004, 0x1);
      TargetInterface.delay(1000);  
      if (TargetInterface.getDebugRegister(0x01000004) & 1)    
        TargetInterface.message("MassErase failed");
      TargetInterface.setNSRST(1);
    }

    0
    Comment actions Permalink
  • Avatar
    babjerke

    Hello Markus

    Thanks for the info - I have asked Rowley several times but the will not fix this problem. However, they fixed the short keyboard command (on Mac) to hide the application with the standard cmd-h, its now a even greater pleasure to use Crossworks!

    Bård

    0
    Comment actions Permalink
  • Avatar
    Martin Honeywill

    Hi 

    I've hit exactly the same problem, when using a FRDM-K64 board from NXP. I've downloaded bothe the CMSIS-DAP and JLINK jtag firmware for this board and both respond that the incorrect Chip has been detected. See below for CMSIS-DAP response

    See here for JLINK response

    I've tried the modified "Kinetis_Target.js" mentioned in this post. It seems to work for CMSIS-DAP but not for JLINK. With Jlink you get the following message

    I expect I can turn of processor target detection in Rowley but this is quite a useful feature

    I know this is not a Rowley bug as such but, is it something that Rowley can fix PLEASE as it would be really helpful to have the  "Kinetis_Target.js" supplied by Rowley correctly handle this situation.

    Cheers

    Martin

    0
    Comment actions Permalink
  • Avatar
    rosdi ablatiff

    Personal private web systems identity

    0
    Comment actions Permalink
  • Avatar
    Markus

    Hey Martin,

     

    my FRDM-K64 is also working with the Segger-JLINK JTAG firmware and I have no Problems to detect the Controller with my modified Kinetis_Target.js script. It is working perfectly fine with my board.

    Do you have flashed the newest Version of the JTAG Firmware, and the Board-Specific ones? The recent one is from 2018-06-28: https://www.segger.com/downloads/jlink/OpenSDA_FRDM-K64F

    Which Version of the J-Link Software do you use? If you install a newer Version, don’t forget, that you have to update the path to the JLinkARM.dll in the CrossStudio-Properties

     

    Hope that helps.

     

    Regards

    0
    Comment actions Permalink
  • Avatar
    Martin Honeywill

    Hi Markus,

     

    Thanks for your feedback, see below for the details of the connected Segger Jlink, all seems to make sense to me. Its just when I try and connect to debug code I get the error reading from memory error.

    Exactly the same project loads and debugs fine when connected via CMSIS-DAP, I don't know if this is a Segger issue or a Rowley issue. If I use the original "Kinetis_Target.js" I get a target mismatch error which I just click through and accept.

    I'm just trying to get to the bottom of this to help others too.

    Regards

    0
    Comment actions Permalink
  • Avatar
    Michael Johnson

    There are a couple of issues here

    1) When using the Built-in Flash Loader for J-Link CrossWorks doesn't run the GetPartName() target script function, but it does run the MatchPartName(). This can be disabled with

    2) The previously mentioned errata e7534 affects the GetPartName() - not sure I understand/trust the workaround.

    0
    Comment actions Permalink
  • Avatar
    Martin Honeywill

    Thanks Michael,

    I presume in your screenshot you meant disabling the "Check Project And Target Compatibility" option, and yes this does work. But I was trying to get to a better result. If you are not happy with the suggested edits to "Kinetis_Target.js" does Rowley have any suggested fixes to this issue. Seems a shame to turn off processor detection just to get this working, as it could be useful on other projects.

    Regards

    Martin

    0
    Comment actions Permalink
  • Avatar
    Markus

    Hello Michael,

     

    thanks for the official Reply.

    In Reply to your issues:

    1) MatchPartName() is calling GetPartName() in the Kinetis_Target.js script. So, there should be no differences in running the workaround.

     

    2) The workaround is quite simple. The Controller is identified by Family and Subfamily in the SIM_SDID Register. Some device-types do a masquerade here and give false values

    K64 shows upas K62; K63 as K61; K24 as K22

    Therefore, NXP recommends to use the RAM size as an additional criteria to identify the type correctly. That is what I’ve done in the Patch:

    3) OK you had no number tree, but I would like to add the Bugfix for K0x family This is not NXPs fault but a little bug in the script. The K0x family is not identified correctly. The Value 0 of the FAMILYID is used as an indication for invalid. But for the K0x-Family it is a valid setting. We’ve already discussed this topic in the Request #11500.

    Regards

    0
    Comment actions Permalink
  • Avatar
    Martin Honeywill

    Thanks, to both Markus and Michael, for responding to this ticket.

    I hope that we'll end up with a solution that works for everyone.

    Still Getting the Error reading from Memory Error, Michael can you break point the js code?

     

    0
    Comment actions Permalink
  • Avatar
    Markus

    Hey Martin,

    you can do printf-debugging via
    TargetInterface.message (“Hello world”)

    Regards

    0
    Comment actions Permalink
  • Avatar
    Michael Johnson

    HI Martin,

    I can't reproduce the problem - is your jlink.dll up to date?

    Regards

    Michael

    0
    Comment actions Permalink
  • Avatar
    Martin Honeywill

    Hi Michael,

    I thought my Jlink was up to date but went online to Segger and realised that 6.32g had been upgraded to 6.32h in the last few days, since I satrted playing with this last week. So I upgraded to 6.32h and it now seems to work :-).

    I'm using Markus's modified Kinetis_Target.js, are you happy at using this. Is this something that Rowley will incorporate? Otherwise I guess it will be changed whenever you upgrade the Kinetis target files.

    Regards

    Martin

     

    0
    Comment actions Permalink
  • Avatar
    Martin Honeywill

    For anyone reading this post this seems to have been fixed by Rowley in the V3.9 release of the Kinetis support package see https://www.rowleydownload.co.uk/arm/packages/Kinetis_V3.htm thanks Markus looks like your script changes have been adopted :-). The system works.

    0
    Comment actions Permalink
  • Avatar
    Markus

    Yay, finally it is in the package an it is looking good 😊

    0
    Comment actions Permalink
  • Avatar
    Martin Honeywill

    Thanks for providing the initial Fix Markus

    0
    Comment actions Permalink
  • Avatar
    babjerke

    Fantastic, after 5 months this problem has been fixed! I only updated the Kinetis support package to V3.9 and it works. Thanks to everybody who helped to solve this issue!

    0
    Comment actions Permalink

Please sign in to leave a comment.