Mike Menci
/
SIEMENS_FEEDER_LOOP
Siemens Dual Lane Feeder
Diff: IAP_LPC11U.cpp
- Revision:
- 1:4d3738338cf1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/IAP_LPC11U.cpp Sat Feb 04 01:27:29 2017 +0000 @@ -0,0 +1,266 @@ +#if defined(TARGET_LPC11UXX) | defined(TARGET_LPC11U6X) + +#include "IAP_LPC11U.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; + +#if defined(TARGET_LPC11U6X) + //Set the vector table offset to address 0 + SCB->VTOR = 0; +#endif + + //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 +} + +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; +} + +#endif \ No newline at end of file