/* This function resets some microcontroller peripherals to reset * hardware configuration to ensure that the USB In-System Programming module * will work properly. It is normally called from reset and assumes some reset * configuration settings for the MCU. * Some of the peripheral configurations may be redundant in your specific * project. */ void IAP_ReinvokeISP() { //Make sure USB clock is turned on before calling ISP LPC_SYSCON->SYSAHBCLKCTRL |= 0x04000; //Make sure 32-bit Timer 1 is turned on before calling ISP LPC_SYSCON->SYSAHBCLKCTRL |= 0x00400; //Make sure GPIO clock is turned on before calling ISP LPC_SYSCON->SYSAHBCLKCTRL |= 0x00040; //Make sure IO configuration clock is turned on before calling ISP LPC_SYSCON->SYSAHBCLKCTRL |= 0x10000; //Make sure AHB clock divider is 1:1 LPC_SYSCON->SYSAHBCLKDIV = 1; //Prepare the command array m_Command[0] = 57; //Initialize the storage state machine *((unsigned int *)(0x10000054)) = 0x0; //Set stack pointer to ROM value (reset default) //This must be the last piece of code executed before calling ISP, //because most C expressions and function returns will fail after the stack pointer is changed. __set_MSP(*((unsigned int *)0x00000000)); //Invoke IAP call... IAP_Entry(m_Command, m_Result); //Shouldn't return while(1); } |
#include "mbed.h" #include "IAP_LPC11UXX.h" DigitalOut led1(LED1, 1); int main() { led1 = !led1; wait(0.5); led1 = !led1; wait(0.5); led1 = !led1; wait(0.5); IAP_ReinvokeISP(); } |
#ifndef IAP_LPC11UXX_H #define IAP_LPC11UXX_H #include "mbed.h" //128-bit unique ID struct typedef struct UID { unsigned int word0; /**< Word 0 of 128-bit UID (bits 31 to 0) */ unsigned int word1; /**< Word 1 of 128-bit UID (bits 63 to 32) */ unsigned int word2; /**< Word 2 of 128-bit UID (bits 95 to 64) */ unsigned int word3; /**< Word 3 of 128-bit UID (bits 127 to 96) */ }; //IAP return code enumeration enum IapReturnCode { IAP_CMD_SUCCESS = 0, IAP_INVALID_COMMAND, IAP_SRC_ADDR_ERROR, IAP_DST_ADDR_ERROR, IAP_SRC_ADDR_NOT_MAPPED, IAP_DST_ADDR_NOT_MAPPED, IAP_COUNT_ERROR, IAP_INVALID_SECTOR, IAP_SECTOR_NOT_BLANK, IAP_SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION, IAP_COMPARE_ERROR, IAP_BUSY }; //Function prototypes IapReturnCode IAP_PrepareSectors(unsigned int sector_start, unsigned int sector_end); IapReturnCode IAP_CopyRAMToFlash(void* ram_address, void* flash_address, unsigned int length); IapReturnCode IAP_EraseSectors(unsigned int sector_start, unsigned int sector_end); IapReturnCode IAP_BlankCheckSectors(unsigned int sector_start, unsigned int sector_end); unsigned int IAP_ReadPartID(); unsigned short IAP_ReadBootCodeVersion(); IapReturnCode IAP_Compare(void* address1, void* address2, unsigned int bytes); void IAP_ReinvokeISP(); UID IAP_ReadUID(); IapReturnCode IAP_ErasePage(unsigned int page_start, unsigned int page_end); IapReturnCode IAP_WriteEEPROM(unsigned int ee_address, char* buffer, unsigned int length); IapReturnCode IAP_ReadEEPROM(unsigned int ee_address, char* buffer, unsigned int length); #endif |
#include "IAP_LPC11UXX.h" namespace { //This data must be global so it is not read from the stack unsigned int m_Command[5], m_Result[5]; typedef void (*IAP)(unsigned int [], unsigned int []); const IAP IAP_Entry = (IAP)0x1FFF1FF1; } static inline void _iap_CriticalEntry() { //Disable interrupts __disable_irq(); //Safely perform IAP entry IAP_Entry(m_Command, m_Result); //Enable interrupts __enable_irq(); } IapReturnCode IAP_PrepareSectors(unsigned int sector_start, unsigned int sector_end) { //Prepare the command array m_Command[0] = 50; m_Command[1] = sector_start; //The start of the sector to be prepared m_Command[2] = sector_end; //The end of the sector to be prepared //Invoke critical IAP call... _iap_CriticalEntry(); //Extract the result code IapReturnCode ret = (IapReturnCode)m_Result[0]; //Return the result code return ret; } IapReturnCode IAP_CopyRAMToFlash(void* ram_address, void* flash_address, unsigned int length) { //Prepare the command array m_Command[0] = 51; m_Command[1] = (unsigned int)flash_address; //Flash address where the contents are to be copied (it should be within 256bytes boundary) m_Command[2] = (unsigned int)ram_address; //RAM address to be copied (it should be in word boundary) m_Command[3] = length; //Number of data to be copied in bytes: 256, 512, 1024, or 4096 m_Command[4] = SystemCoreClock / 1000; //Invoke critical IAP call... _iap_CriticalEntry(); //Extract the result code IapReturnCode ret = (IapReturnCode)m_Result[0]; //Return the result code return ret; } IapReturnCode IAP_EraseSectors(unsigned int sector_start, unsigned int sector_end) { //Prepare the command array m_Command[0] = 52; m_Command[1] = sector_start; //The start of the sector to be erased m_Command[2] = sector_end; //The end of the sector to be erased m_Command[3] = SystemCoreClock / 1000; //System Clock Frequency (CCLK) in kHz //Invoke critical IAP call... _iap_CriticalEntry(); //Extract the result code IapReturnCode ret = (IapReturnCode)m_Result[0]; //Return the result code return ret; } IapReturnCode IAP_BlankCheckSectors(unsigned int sector_start, unsigned int sector_end) { //Prepare the command array m_Command[0] = 53; m_Command[1] = sector_start; //The start of the sector to be checked m_Command[2] = sector_end; //The end of the sector to be checked //Invoke critical IAP call... _iap_CriticalEntry(); //Extract the result code IapReturnCode ret = (IapReturnCode)m_Result[0]; //Return the result code return ret; } unsigned int IAP_ReadPartID() { //Prepare the command array m_Command[0] = 54; //Invoke critical IAP call... _iap_CriticalEntry(); //Extract the part ID unsigned int ret = m_Result[1]; //Return the part ID return ret; } unsigned short IAP_ReadBootCodeVersion() { //Prepare the command array m_Command[0] = 55; //Invoke critical IAP call... _iap_CriticalEntry(); //Extract the boot code version unsigned int ret = (unsigned short)m_Result[1]; //Return the boot code version return ret; } IapReturnCode IAP_Compare(void* address1, void* address2, unsigned int bytes) { //Prepare the command array m_Command[0] = 56; m_Command[1] = (unsigned int)address1; //Starting flash or RAM address of data bytes to be compared. This address should be a word boundary. m_Command[2] = (unsigned int)address2; //Starting flash or RAM address of data bytes to be compared. This address should be a word boundary. m_Command[3] = bytes; //Number of bytes to be compared; should be a multiple of 4. //Invoke critical IAP call... _iap_CriticalEntry(); //Extract the result code IapReturnCode ret = (IapReturnCode)m_Result[0]; //Return the result code return ret; } /* This function resets some microcontroller peripherals to reset * hardware configuration to ensure that the USB In-System Programming module * will work properly. It is normally called from reset and assumes some reset * configuration settings for the MCU. * Some of the peripheral configurations may be redundant in your specific * project. */ void IAP_ReinvokeISP() { //Make sure USB clock is turned on before calling ISP LPC_SYSCON->SYSAHBCLKCTRL |= 0x04000; //Make sure 32-bit Timer 1 is turned on before calling ISP LPC_SYSCON->SYSAHBCLKCTRL |= 0x00400; //Make sure GPIO clock is turned on before calling ISP LPC_SYSCON->SYSAHBCLKCTRL |= 0x00040; //Make sure IO configuration clock is turned on before calling ISP LPC_SYSCON->SYSAHBCLKCTRL |= 0x10000; //Make sure AHB clock divider is 1:1 LPC_SYSCON->SYSAHBCLKDIV = 1; //Prepare the command array m_Command[0] = 57; //Initialize the storage state machine *((unsigned int*)(0x10000054)) = 0x0; //Set stack pointer to ROM value (reset default) //This must be the last piece of code executed before calling ISP, //because most C expressions and function returns will fail after the stack pointer is changed. __set_MSP(*((unsigned int*)0x00000000)); //Invoke IAP call... IAP_Entry(m_Command, m_Result); } UID IAP_ReadUID() { //Prepare the command array m_Command[0] = 58; //Invoke critical IAP call... _iap_CriticalEntry(); //Extract the UID UID ret = { m_Result[1], m_Result[2], m_Result[3], m_Result[4] }; //Return the UID return ret; } IapReturnCode IAP_ErasePage(unsigned int page_start, unsigned int page_end) { //Prepare the command array m_Command[0] = 59; m_Command[1] = page_start; //The start of the page to be erased m_Command[2] = page_end; //The end of the page to be erased m_Command[3] = SystemCoreClock / 1000; //System Clock Frequency (CCLK) in kHz //Invoke critical IAP call... _iap_CriticalEntry(); //Extract the result code IapReturnCode ret = (IapReturnCode)m_Result[0]; //Return the result code return ret; } IapReturnCode IAP_WriteEEPROM(unsigned int ee_address, char* buffer, unsigned int length) { //Prepare the command array m_Command[0] = 61; m_Command[1] = ee_address; //EEPROM address (byte, half-word or word aligned) m_Command[2] = (unsigned int)buffer; //RAM address (byte, half-word or word aligned) m_Command[3] = length; //Number of bytes to be written (byte, half-word writes are ok) m_Command[4] = SystemCoreClock / 1000; //System Clock Frequency (CCLK) in kHz //Invoke critical IAP call... _iap_CriticalEntry(); //Extract the result code IapReturnCode ret = (IapReturnCode)m_Result[0]; //Return the result code return ret; } IapReturnCode IAP_ReadEEPROM(unsigned int ee_address, char* buffer, unsigned int length) { //Prepare the command array m_Command[0] = 62; m_Command[1] = ee_address; //EEPROM address (byte, half-word or word aligned) m_Command[2] = (unsigned int)buffer; //RAM address (byte, half-word or word aligned) m_Command[3] = length; //Number of bytes to be read (byte, half-word reads are ok) m_Command[4] = SystemCoreClock / 1000; //System Clock Frequency (CCLK) in kHz //Invoke critical IAP call... _iap_CriticalEntry(); //Extract the result code IapReturnCode ret = (IapReturnCode)m_Result[0]; //Return the result code return ret; } |