Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of IAP by
IAP.cpp
00001 /** IAP : internal Flash memory access library 00002 * 00003 * The internal Flash memory access is described in the LPC1768 and LPC11U24 usermanual. 00004 * http://www.nxp.com/documents/user_manual/UM10360.pdf 00005 * http://www.nxp.com/documents/user_manual/UM10462.pdf 00006 * 00007 * LPC1768 -- 00008 * Chapter 2: "LPC17xx Memory map" 00009 * Chapter 32: "LPC17xx Flash memory interface and programming" 00010 * refering Rev. 01 - 4 January 2010 00011 * 00012 * LPC11U24 -- 00013 * Chapter 2: "LPC11Uxx Memory mapping" 00014 * Chapter 20: "LPC11Uxx Flash programming firmware" 00015 * refering Rev. 03 - 16 July 2012 00016 * 00017 * Released under the MIT License: http://mbed.org/license/mit 00018 * 00019 * revision 1.0 09-Mar-2010 1st release 00020 * revision 1.1 12-Mar-2010 chaged: to make possible to reserve flash area for user 00021 * it can be set by USER_FLASH_AREA_START and USER_FLASH_AREA_SIZE in IAP.h 00022 * revision 2.0 26-Nov-2012 LPC11U24 code added 00023 * revision 2.1 26-Nov-2012 EEPROM access code imported from Suga koubou san's (http://mbed.org/users/okini3939/) library 00024 * http://mbed.org/users/okini3939/code/M0_EEPROM_test/ 00025 * revision 3.0 09-Jan-2015 LPC812 and LPC824 support added 00026 * revision 3.1 13-Jan-2015 LPC1114 support added 00027 * revision 3.1.1 16-Jan-2015 Target MCU name changed for better compatibility across the platforms 00028 */ 00029 00030 #include "mbed.h" 00031 #include "IAP.h" 00032 00033 #define USER_FLASH_AREA_START_STR( x ) STR( x ) 00034 #define STR( x ) #x 00035 00036 #if not (defined(TARGET_LPC13XX) || defined(TARGET_LPC15XX)) 00037 unsigned char user_area[ USER_FLASH_AREA_SIZE ] __attribute__((section( ".ARM.__at_" USER_FLASH_AREA_START_STR( USER_FLASH_AREA_START ) ), zero_init)); 00038 #endif 00039 00040 /* 00041 * Reserve of flash area is explained by Igor. Please refer next URL 00042 * http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/?page=1#comment-271 00043 */ 00044 00045 //unsigned char user_area[ size ] __attribute__((section(".ARM.__at_0x78000"), zero_init)); 00046 00047 /* 00048 * IAP command codes 00049 * Table 589. "IAP Command Summary", Chapter 8. "IAP commands", usermanual 00050 */ 00051 00052 enum command_code { 00053 IAPCommand_Prepare_sector_for_write_operation = 50, 00054 IAPCommand_Copy_RAM_to_Flash, 00055 IAPCommand_Erase_sector, 00056 IAPCommand_Blank_check_sector, 00057 IAPCommand_Read_part_ID, 00058 IAPCommand_Read_Boot_Code_version, 00059 IAPCommand_Compare, 00060 IAPCommand_Reinvoke_ISP, 00061 IAPCommand_Read_device_serial_number, 00062 #if defined(TARGET_LPC11UXX) || defined(TARGET_LPC13XX) || defined(TARGET_LPC15XX) 00063 IAPCommand_EEPROM_Write = 61, 00064 IAPCommand_EEPROM_Read, 00065 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X) 00066 IAPCommand_Erase_page = 59, 00067 #endif 00068 }; 00069 00070 int IAP::reinvoke_isp( void ) { 00071 __disable_irq(); 00072 00073 IAP_command[ 0 ] = IAPCommand_Reinvoke_ISP; 00074 00075 iap_entry( IAP_command, IAP_result ); 00076 00077 return ( (int)IAP_result[ 0 ] ); 00078 } 00079 00080 /** Read part identification number 00081 * 00082 * @return device ID 00083 * @see read_serial() 00084 */ 00085 int IAP::read_ID( void ) 00086 { 00087 IAP_command[ 0 ] = IAPCommand_Read_part_ID; 00088 00089 iap_entry( IAP_command, IAP_result ); 00090 00091 // return ( (int)IAP_result[ 0 ] ); 00092 return ( (int)IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS) 00093 } 00094 00095 int *IAP::read_serial( void ) { 00096 IAP_command[ 0 ] = IAPCommand_Read_device_serial_number; 00097 00098 iap_entry( IAP_command, IAP_result ); 00099 00100 // return ( (int)IAP_result[ 0 ] ); 00101 return ( (int *)&IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS) 00102 } 00103 00104 int IAP::blank_check( int start, int end ) 00105 { 00106 IAP_command[ 0 ] = IAPCommand_Blank_check_sector; 00107 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00108 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number) 00109 00110 iap_entry( IAP_command, IAP_result ); 00111 00112 return ( (int)IAP_result[ 0 ] ); 00113 } 00114 00115 int IAP::erase( int start, int end ) 00116 { 00117 IAP_command[ 0 ] = IAPCommand_Erase_sector; 00118 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00119 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number) 00120 IAP_command[ 3 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz 00121 00122 iap_entry( IAP_command, IAP_result ); 00123 00124 return ( (int)IAP_result[ 0 ] ); 00125 } 00126 00127 int IAP::prepare( int start, int end ) 00128 { 00129 IAP_command[ 0 ] = IAPCommand_Prepare_sector_for_write_operation; 00130 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00131 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number). 00132 00133 iap_entry( IAP_command, IAP_result ); 00134 00135 return ( (int)IAP_result[ 0 ] ); 00136 } 00137 00138 int IAP::write( char *source_addr, char *target_addr, int size ) 00139 { 00140 IAP_command[ 0 ] = IAPCommand_Copy_RAM_to_Flash; 00141 IAP_command[ 1 ] = (unsigned int)target_addr; // Destination flash address where data bytes are to be written. This address should be a 256 byte boundary. 00142 IAP_command[ 2 ] = (unsigned int)source_addr; // Source RAM address from which data bytes are to be read. This address should be a word boundary. 00143 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00144 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz. 00145 00146 iap_entry( IAP_command, IAP_result ); 00147 00148 return ( (int)IAP_result[ 0 ] ); 00149 } 00150 00151 int IAP::compare( char *source_addr, char *target_addr, int size ) 00152 { 00153 IAP_command[ 0 ] = IAPCommand_Compare; 00154 IAP_command[ 1 ] = (unsigned int)target_addr; // Starting flash or RAM address of data bytes to be compared. This address should be a word boundary. 00155 IAP_command[ 2 ] = (unsigned int)source_addr; // Starting flash or RAM address of data bytes to be compared. This address should be a word boundary. 00156 IAP_command[ 3 ] = size; // Number of bytes to be compared; should be a multiple of 4. 00157 00158 iap_entry( IAP_command, IAP_result ); 00159 00160 return ( (int)IAP_result[ 0 ] ); 00161 } 00162 00163 int IAP::read_BootVer(void) 00164 { 00165 IAP_command[0] = IAPCommand_Read_Boot_Code_version; 00166 IAP_result[1] = 0; // not sure if in high or low bits. 00167 iap_entry(IAP_command, IAP_result); 00168 return ((int)IAP_result[1]); 00169 } 00170 00171 char * IAP::reserved_flash_area_start( void ) 00172 { 00173 return ( (char *)USER_FLASH_AREA_START ); 00174 } 00175 00176 int IAP::reserved_flash_area_size( void ) 00177 { 00178 return ( USER_FLASH_AREA_SIZE ); 00179 } 00180 00181 #if defined(TARGET_LPC11UXX) || defined(TARGET_LPC13XX) || defined(TARGET_LPC15XX) 00182 00183 void IAP::init_eeprom() 00184 { 00185 #if defined(TARGET_LPC15XX) 00186 __disable_irq(); 00187 LPC_SYSCON->SYSAHBCLKCTRL0 |= 1 << 9; 00188 LPC_SYSCON->PRESETCTRL0 |= 1 << 9; 00189 LPC_SYSCON->PRESETCTRL0 &= ~(1 << 9); 00190 __enable_irq(); 00191 #endif 00192 } 00193 00194 int IAP::write_eeprom( char *source_addr, char *target_addr, int size ) 00195 { 00196 init_eeprom(); 00197 00198 IAP_command[ 0 ] = IAPCommand_EEPROM_Write; 00199 IAP_command[ 1 ] = (unsigned int)target_addr; // Destination EEPROM address where data bytes are to be written. This address should be a 256 byte boundary. 00200 IAP_command[ 2 ] = (unsigned int)source_addr; // Source RAM address from which data bytes are to be read. This address should be a word boundary. 00201 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00202 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz. 00203 00204 iap_entry( IAP_command, IAP_result ); 00205 00206 return ( (int)IAP_result[ 0 ] ); 00207 } 00208 00209 int IAP::read_eeprom( char *source_addr, char *target_addr, int size ) 00210 { 00211 init_eeprom(); 00212 00213 IAP_command[ 0 ] = IAPCommand_EEPROM_Read; 00214 IAP_command[ 1 ] = (unsigned int)source_addr; // Source EEPROM address from which data bytes are to be read. This address should be a word boundary. 00215 IAP_command[ 2 ] = (unsigned int)target_addr; // Destination RAM address where data bytes are to be written. This address should be a 256 byte boundary. 00216 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00217 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz. 00218 00219 iap_entry( IAP_command, IAP_result ); 00220 00221 return ( (int)IAP_result[ 0 ] ); 00222 } 00223 00224 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X) 00225 00226 int IAP::erase_page( int start, int end ) 00227 { 00228 IAP_command[ 0 ] = IAPCommand_Erase_page; 00229 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00230 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number) 00231 IAP_command[ 3 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz 00232 00233 iap_entry( IAP_command, IAP_result ); 00234 00235 return ( (int)IAP_result[ 0 ] ); 00236 } 00237 00238 #endif
Generated on Tue Jul 12 2022 16:18:47 by
1.7.2
