I'm having issues with an LPC11C14 IAP command 57. When run, the code makes its way to memory location 0x1fff0e4a, where it has an unconditional branch back to 0x1fff0e4a. It never returns (expected), but it never resets the micro to run the bootloader. I have stepped through the entire
I'm using the library from AN10995, and have tried all of the variations of adjusting the stack pointer around. I can successfully read the Chip ID, so the ROM and IAP call is working, but IAP57 is not operating correctly.
I have pin 0_3 grounded, so it should enter the CAN Bootloader, but it doesn't. If I reset the microcontroller and hold Pin 0_1 low, it enters the CAN Bootloader, and I can read the part ID by sending 0x40, 0x18, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00 with Data Length 8 to ID 0x67D. After executing IAP57, the CAN peripheral doesn't acknowledge, so it hasn't reached the bootloader.
Am I missing something?
Source Code for AN10995 excerpted below (copied directly from my project). Again, ReadPartID works, ReinvokeISP does not.
#include "IAP.h"
#include <LPC11xx.h>
/* IAP Command Definitions */
#define IAP_CMD_PREPARE_SECTORS 50
#define IAP_CMD_COPY_RAM_TO_FLASH 51
#define IAP_CMD_ERASE_SECTORS 52
#define IAP_CMD_BLANK_CHECK_SECTORS 53
#define IAP_CMD_READ_PART_ID 54
#define IAP_CMD_READ_BOOT_ROM_VERSION 55
#define IAP_CMD_COMPARE 56
#define IAP_CMD_REINVOKE_ISP 57
/* IAP boot ROM location and access function */
#define IAP_ROM_LOCATION 0x1FFF1FF1UL
#define IAP_EXECUTE_CMD(a, b) ((void (*)())(IAP_ROM_LOCATION))(a, b)
/*****************************************************************************
** Function name: u32IAP_ReadPartID
**
** Description: Read the part identification number.
**
** Parameters: pu32PartID - Pointer to storage for part ID number.
*
** Returned value: Status code returned by IAP ROM function.
**
******************************************************************************/
uint32_t u32IAP_ReadPartID(uint32_t *pu32PartID)
{
uint32_t au32Result[3];
uint32_t au32Command[5];
au32Command[0] = IAP_CMD_READ_PART_ID;
IAP_EXECUTE_CMD(au32Command, au32Result);
*pu32PartID = au32Result[1];
return au32Result[0];
}
/*****************************************************************************
** Function name: vIAP_ReinvokeISP
**
** Description: Invoke the bootloader in ISP mode.
**
** Parameters: None.
*
** Returned value: None.
**
******************************************************************************/
void vIAP_ReinvokeISP(void)
{
uint32_t au32Result[3];
uint32_t au32Command[5];
au32Command[0] = IAP_CMD_REINVOKE_ISP;
IAP_EXECUTE_CMD(au32Command, au32Result);
}
To enter ReinvokeISP, this is the setup:
LPC_GPIO_T *GPIO = LPC_GPIO_PORT0_BASE;
LPC_IOCON_T *IOCON = LPC_IOCON_BASE;
//Write Pin 0_1 Low here as another attempt at debugging.
Chip_IOCON_PinMuxSet(IOCON, IOCON_PIO0_1, IOCON_FUNC0 | MD_PDN | IOCON_DIGMODE_EN);//MPOS
Chip_GPIO_SetPinDIROutput(GPIO, 0, 1);
Chip_GPIO_SetPinOutLow(LPC_GPIO_PORT0_BASE, 0, 1);
//ReadPartID works. Can read partID if a breakpoint is hit.
uint32_t partID;
uint32_t Result = u32IAP_ReadPartID(&partID);
//Enters, never returns, never enters bootloader.
vIAP_ReinvokeISP();
an10995
lpc11c14 lpc11cxxlpc11c24
iap57
reinvokeISP
Hello Pierce,
I would reccommend that you use the following application note as reference, it illustrates how to update the user application code using the CAN bus interface. The secondary bootloader uses IAP ROM APIs to update the firmware in the flash:
https://www.nxp.com/docs/en/application-note/AN11772.zip
Hope it helps!
Best Regards,
Carlos Mendoza
Technical Support Engineer
Hey Carlos,
The IAP.c and .h files are exactly the same as I used as a base for my code... I don't have enough space for the secondary bootloader, and the reason we selected this processor is that it already had a bootloader built in... So why does it seem like it is hard to access the boot loader when this should be as simple as calling a function?