I am trying to re-invoke the USB ISP bootloader using the IAP method on the LPCXpresso5411x.
As stated in LPC51U68-Reinvoke-ISP-in-USB-Mode-is-not-working the IAP_ReinvokeISP() method is broken in two ways:
Apparently there are some prerequisites for the USB bootloader to operate property, but I cannot find any documentation on this:
So when using a clock setup with 48MHz FRO as main and manually calling the IAP entry point, the USB bootloader indeed works as expected.
However, setting up a higher clock rate for my main application and switching back to 48MHz before making the IAP call doesn't work for me. The USB device is not responsive from the perspective of the OS.
[[noreturn]] int main() {
BOARD_InitBootPins();
BOARD_BootClock98MHz(); // <- this line breaks the USB bootloader
BOARD_BootClock48MHz();
fixed_IAP_Reinvoke_ISP_USB();
The BOARD_BootClockX methods are created using the IDE clock tool:
void BOARD_BootClock98MHz(void)
{
#ifndef SDK_SECONDARY_CORE
/*!< Set up the clock sources */
/*!< Set up FRO */
POWER_DisablePD(kPDRUNCFG_PD_FRO_EN); /*!< Ensure FRO is on */
CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */
CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change voltage without accidentally
being below the voltage for current speed */
POWER_SetVoltageForFreq(96000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */
CLOCK_SetFLASHAccessCyclesForFreq(96000000U); /*!< Set FLASH wait states for core */
CLOCK_SetupFROClocking(96000000U); /*!< Set up high frequency FRO output to selected frequency */
/*!< Set up dividers */
CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */
/*!< Set up clock selectors - Attach clocks to the peripheries */
CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */
/*< Set SystemCoreClock variable. */
SystemCoreClock = BOARD_BOOTCLOCK98MHZ_CORE_CLOCK;
#endif
}
So the question is, are there any other particular system states that must be enabled/disabled/reset for the USB bootloader to operate properly?
Hello Pwuertz,
The USB clock input must be 48Mhz regardless of the mode you would be using. You can see on the Clocks Config Tool that you would get an error if the USB clock is different to 48Mhz. This because the USB module has its own internal PLLS that generates the 480Mhz required for USB from this 24Mhz input. (You may use the FRO96 Mhz an apply a divider).
From the BootClock98Mhz initialization I’m assuming you are using a different system clock at 98Mhz. You can maintain the rest of your configuration and setup the USB lock from the FRO at 48 or 96Mhz and add a divider as required to achieve the 48Mhz.
My apologies for the inconvenience.
Regards,
Gustavo
Please note that I'm not talking about USB applications in a user program. These are working perfectly for me and in the other linked post. Yes, I'm aware that the USB peripheral needs 48 MHz, which is what my USB application init-code does, taking the current FRO setting into account (exactly like all the SDK examples).
What we (other post and I) observed is that calling the USB ISP Bootloader from a running application results in a dysfunctional device. My understanding is that the bootloader must have some kind of initialization code to configure USB from power-up-defaults, and apparently it cannot cope with some system states you might see in an already running application.
What has been identified is that irq-disable and running the FRO / Main at 96 MHz will break the USB Bootloader. My question was: What are the prerequisites for running the USB ISP successfully?
For me, switching FRO / Main from 96 MHz back to 48 MHz does not work, I need my application to run at 48 MHz from the start or the bootloader won't work. Maybe the switch to 96 MHz isn't the sole reason? maybe the 48 MHz setting just hides some race condition?