KL81 clock hang after enabling USB Bootloader

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

KL81 clock hang after enabling USB Bootloader

944 Views
SynapticLathe
Contributor I

In trying to use the ROM Bootloader on the KL81 over USB, we're running into the chip failing to transition to PEE clock mode.  This results in the post-bootloader initialization code sometimes becoming permanently stuck in an infinite loop.  Performing a hardware reset of the chip restarts everything, sometimes causing the same issue to reproduce.  The problem reproduces ~60% of the time.

An almost identical issue has been described in errata ERR009879 "ROM Bootloader: User code may fail to transition to FEE clock mode after booting from ROM" which is listed in KINETIS_L_0N51R.pdf.  It listed 3 potential workarounds.  However, while the 1st work-around is the ideal option, it does not fix the issue in this case.  The other 2 workarounds are "don't use USB in the bootloader" and "don't transition the clock to FEE mode" which are less than ideal.
 
The 1st workaround says that instead of configuring FOPT[BOOTSRC_SEL] to binary 11 to instead use 10 (or use 00 but that disables the bootloader entirely).  FOPT is located in internal FLASH at address 0x40d and the BOOTSRC_SEL field is bits 7 and 6.
 
Details:
 
FOPT byte value at address 0x40D is currently set to 0xBF (thus, bits 7 and 6 are set to binary 10).
 
BCA (Bootloader Configuration Area) at address 0x3C0 is set to the following values:
    .tag                        = 0x6766636BU, /* Magic Number */
    .crcStartAddress            = 0xFFFFFFFFU, /* Disable CRC check */
    .crcByteCount               = 0xFFFFFFFFU, /* Disable CRC check */
    .crcExpectedValue           = 0xFFFFFFFFU, /* Disable CRC check */
    .enabledPeripherals         = 0x10,        /* Enable only USB peripheral */
    .i2cSlaveAddress            = 0xFF,        /* Use default I2C address */
    .peripheralDetectionTimeoutMs = 3000U,     /* Use 3.0s timeout */
    .usbVid                     = 0xFFFFU,     /* Use default USB Vendor ID */
    .usbPid                     = 0xFFFFU,     /* Use default USB Product ID */
    .usbStringsPointer          = 0xFFFFFFFFU, /* Use default USB Strings */
    .clockFlags                 = 0x01,        /* Enable High speed mode */
    .clockDivider               = 0xFF,        /* Use clock divider 1 */
    .bootFlags                  = 0x01,        /* Enable communication with host */
    .keyBlobPointer             = 0xFFFFFFFFU, /* No keyblob data */
    .qspiConfigBlockPtr         = 0xFFFFFFFFU  /* No QSPI configuration */
    /* All reserved fields initialized to 0 */
 
After the bootloader times out, main() starts executing and calls BOARD_BootClockRUN() after initializing the board's pins.  BOARD_BootClockRUN() calls multiple functions but the call stack where it hangs is that it calls CLOCK_BootToPeeMode(), which in turn calls CLOCK_SetPbeMode().  This last function sets some MCG registers and sometimes waits forever for the clock status register bit, MCG_S[IREFST], to change to 0 (so source of FLL is external) but it remains stuck at 1.
 

For the 1st work-around, are other steps necessary to get it to work?

Labels (2)
Tags (3)
0 Kudos
Reply
3 Replies

854 Views
SynapticLathe
Contributor I

Regarding the other work-arounds:

  • Work-around #2 (i.e., don't use USB for the ROM Bootloader) does fix the problem.
  • Work-around #3 (i.e., don't transition to FEE mode) was only partially investigated.  Unclear whether would fix the problem or whether it might break something else.

We're using an external clock.

No modifications have been made to BOARD_BootClockRUN() or CLOCK_BootToPeeMode() functions nor to their related variables.  For reference, the config code is provided below.

We could try using CLOCK_SetPeeMode(), but should point out that this would be making code changes to CLOCK_BootToPeeMode() that is in fsl_clock.c whose implementation comes from the FRDM-KL82Z SDK.  The SDK version of CLOCK_BootToPeeMode() calls CLOCK_SetToPbeMode().  Would doing such an edit of an SDK file cause other unintended consequences for the clocks?

There is an update and a correction on this issue, so hopefully this does not cause any confusion.  This issue is occurring with the KL82, not the KL81.  Essentially, there are 2 pieces of hardware being used:

  • Issue reproduces on the FRDM-KL82Z dev kit board that uses the KL82.
    • Jumpers are set to their from-the-factory settings.  It is connected to another piece of hardware via jumpers wires that is unlikely to be related to the issue.
    • Using one of the sample apps (qspi_polling_transfer).  It uses BOARD_BootClockRUN() and CLOCK_BootToPeeMode() unmodified from the sample.
    • Enabling the ROM Bootloader and activating USB using work-around #1 still cause the original issue above.
  • Issue does not reproduce on a custom board that uses the KL81
    • The clock uses a 12MHz oscillator connected only to EXTAL0.  This is different than the dev kit that uses a 12MHZ crystal connected to EXTAL0, XTAL0, and a few passives.
    • It uses the same clock initialization code from the above sample.
    • Enabling the ROM Bootloader and activating USB using work-around #1 does not cause issues and works as expected.

Our understanding is that the below code should be correct for the FRDM-KL82Z since it is from a sample app from its SDK.  Also, we assume it is acceptable to use this for the custom board even though it uses an oscillator rather than a crystal.

Here is the implementation if BOARD_BootClockRUN(), up to the call to CLOCK_BootToPeeMode():

void BOARD_BootClockRUN(void)
{

    CLOCK_SetSimSafeDivs();
    CLOCK_InitOsc0(&oscConfig_BOARD_BootClockRUN);
    CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockRUN.freq);
    CLOCK_CONFIG_SetFllExtRefDiv(mcgConfig_BOARD_BootClockRUN.frdiv);
    CLOCK_BootToPeeMode(mcgConfig_BOARD_BootClockRUN.oscsel,
        kMCG_PllClkSelPll0,
        &mcgConfig_BOARD_BootClockRUN.pll0Config);
    ...

Here are the config structures for the clocks:

const mcg_config_t mcgConfig_BOARD_BootClockRUN =
{
    .mcgMode = kMCG_ModePEE,/* PEE - PLL Engaged External */
    .irclkEnableMode = kMCG_IrclkEnable,/* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */

    .ircs = kMCG_IrcSlow,/* Slow internal reference clock selected */
    .fcrdiv = 0x0U, /* Fast IRC divider: divided by 1 */
    .frdiv = 0x0U,/* FLL reference clock divider: divided by 32 */

    .drs = kMCG_DrsLow, /* Low frequency range */
    .dmx32 = kMCG_Dmx32Default,/* DCO has a default range of 25% */

    .oscsel = kMCG_OscselOsc,/* Selects System Oscillator (OSCCLK) */
    .pll0Config =
    {
       .enableMode = MCG_PLL_DISABLE,/* MCGPLLCLK disabled */
       .prdiv = 0x0U,/* PLL Reference divider: divided by 1 */
       .vdiv = 0x8U, /* VCO divider: multiplied by 24 */
    },
};

const osc_config_t oscConfig_BOARD_BootClockRUN =
{
    .freq = 12000000U,/* Oscillator frequency: 12000000Hz */
    .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */
    .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */
    .oscerConfig =
    {
       .enableMode = kOSC_ErClkEnable,/* Enable external reference clock, disable external reference clock in STOP mode */

       .erclkDiv = 0,/* Divider for OSCERCLK: divided by 1 */
    }
};

 

0 Kudos
Reply

813 Views
RaRo
NXP TechSupport
NXP TechSupport

Hello @SynapticLathe,

Relating the use of CLOCK_SetPeeMode(), please continue to use CLOCK_SetPbeMode() as it is necessary for CLOCK_BootToPeeMode() to work.

Also, could you please change the following values of the BCA?

  •  .peripheralDetectionTimeoutMs = FFFFU (5s)
  • .clockFlags = 0x00 (Clear the clockFlags bit for HighSpeed)

What other differences do you have between the custom board and FDRM-KL82? In the FDRM-KL82 could you please try with another example that is not QSPI related? Could be a led_blinky example.

Finally, regarding your bootloader, could you please share us how are you exiting the bootloader and jumping to the application? Are you using MCU Boot?

Best regards, Raul.

0 Kudos
Reply

866 Views
RaRo
NXP TechSupport
NXP TechSupport

Hello @SynapticLathe,

First of all, let us apologize for the late reponse.

Just for double check, could you please check if by using the other workarounds the stuck issue is solved?

You are mentioning that the program got stuck in MCG_S[IREFST], could you please tell us if you are using an external or an internal reference clock?

Also, have you done some modification to BOARD_BootClockRUN() or CLOCK_BootToPeeMode() functions or variables related to them? Which PLL output clock are you selecting and CLOCK_BootToPeeMode() configuration do you have?

Finally, you are mentioning that you want to use PEE mode, could you please use CLOCK_SetPeeMode() instead of CLOCK_SetPbeMode() and configure it as mentioned in KL81 Sub-Family Reference Manual. Chapter 29.5.1.1. MCG modes of operation?

RaulRomero_0-1690221454848.png

[KL81 Sub-Family RM. Table 29-4. MCG modes of operation]

Best regards, Raul.

0 Kudos
Reply