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?