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 */ 00026 00027 #include "mbed.h" 00028 #include "IAP.h" 00029 00030 #define USER_FLASH_AREA_START_STR( x ) STR( x ) 00031 #define STR( x ) #x 00032 00033 unsigned char user_area[ USER_FLASH_AREA_SIZE ] __attribute__((section( ".ARM.__at_" USER_FLASH_AREA_START_STR( USER_FLASH_AREA_START ) ), zero_init)); 00034 00035 00036 /* 00037 * Reserve of flash area is explained by Igor. Please refer next URL 00038 * http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/?page=1#comment-271 00039 */ 00040 00041 //unsigned char user_area[ size ] __attribute__((section(".ARM.__at_0x78000"), zero_init)); 00042 00043 /* 00044 * IAP command codes 00045 * Table 589. "IAP Command Summary", Chapter 8. "IAP commands", usermanual 00046 */ 00047 00048 enum command_code 00049 { 00050 IAPCommand_Prepare_sector_for_write_operation = 50, 00051 IAPCommand_Copy_RAM_to_Flash, 00052 IAPCommand_Erase_sector, 00053 IAPCommand_Blank_check_sector, 00054 IAPCommand_Read_part_ID, 00055 IAPCommand_Read_Boot_Code_version, 00056 IAPCommand_Compare, 00057 IAPCommand_Reinvoke_ISP, 00058 IAPCommand_Read_device_serial_number, 00059 #if defined(TARGET_LPC11U24) 00060 IAPCommand_EEPROM_Write = 61, 00061 IAPCommand_EEPROM_Read, 00062 #endif 00063 }; 00064 00065 00066 /** Reinvoke ISP 00067 * 00068 * @return error code 00069 */ 00070 00071 int IAP::reinvoke_isp( void ) { 00072 __disable_irq(); 00073 00074 IAP_command[ 0 ] = IAPCommand_Reinvoke_ISP; 00075 00076 iap_entry( IAP_command, IAP_result ); 00077 00078 return ( (int)IAP_result[ 0 ] ); 00079 } 00080 00081 00082 /** Read part identification number 00083 * 00084 * @return device ID 00085 * @see read_serial() 00086 */ 00087 00088 int IAP::read_ID( void ) { 00089 IAP_command[ 0 ] = IAPCommand_Read_part_ID; 00090 00091 iap_entry( IAP_command, IAP_result ); 00092 00093 // return ( (int)IAP_result[ 0 ] ); 00094 return ( (int)IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS) 00095 } 00096 00097 00098 /** Read device serial number 00099 * 00100 * @return device serial number 00101 * @see read_ID() 00102 */ 00103 00104 int IAP::read_serial( void ) { 00105 IAP_command[ 0 ] = IAPCommand_Read_device_serial_number; 00106 00107 iap_entry( IAP_command, IAP_result ); 00108 00109 // return ( (int)IAP_result[ 0 ] ); 00110 return ( (int)IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS) 00111 } 00112 00113 00114 /** Blank check sector(s) 00115 * 00116 * @param start a Start Sector Number 00117 * @param end an End Sector Number (should be greater than or equal to start sector number). 00118 * @return error code: CMD_SUCCESS | BUSY | SECTOR_NOT_BLANK | INVALID_SECTOR 00119 */ 00120 00121 int IAP::blank_check( int start, int end ) { 00122 IAP_command[ 0 ] = IAPCommand_Blank_check_sector; 00123 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00124 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number) 00125 00126 iap_entry( IAP_command, IAP_result ); 00127 00128 return ( (int)IAP_result[ 0 ] ); 00129 } 00130 00131 00132 /** Erase Sector(s) 00133 * 00134 * @param start a Start Sector Number 00135 * @param end an End Sector Number (should be greater than or equal to start sector number). 00136 * @return error code: CMD_SUCCESS | BUSY | SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION | INVALID_SECTOR 00137 */ 00138 00139 int IAP::erase( int start, int end ) { 00140 IAP_command[ 0 ] = IAPCommand_Erase_sector; 00141 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00142 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number) 00143 IAP_command[ 3 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz 00144 00145 iap_entry( IAP_command, IAP_result ); 00146 00147 return ( (int)IAP_result[ 0 ] ); 00148 } 00149 00150 00151 /** Prepare sector(s) for write operation 00152 * 00153 * @param start a Start Sector Number 00154 * @param end an End Sector Number (should be greater than or equal to start sector number). 00155 * @return error code: CMD_SUCCESS | BUSY | INVALID_SECTOR 00156 */ 00157 00158 int IAP::prepare( int start, int end ) { 00159 IAP_command[ 0 ] = IAPCommand_Prepare_sector_for_write_operation; 00160 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00161 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number). 00162 00163 iap_entry( IAP_command, IAP_result ); 00164 00165 return ( (int)IAP_result[ 0 ] ); 00166 } 00167 00168 00169 /** Copy RAM to Flash 00170 * 00171 * @param source_addr Source RAM address from which data bytes are to be read. This address should be a word boundary. 00172 * @param target_addr Destination flash address where data bytes are to be written. This address should be a 256 byte boundary. 00173 * @param size Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00174 * @return error code: CMD_SUCCESS | SRC_ADDR_ERROR (Address not a word boundary) | DST_ADDR_ERROR (Address not on correct boundary) | SRC_ADDR_NOT_MAPPED | DST_ADDR_NOT_MAPPED | COUNT_ERROR (Byte count is not 256 | 512 | 1024 | 4096) | SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION | BUSY 00175 */ 00176 00177 int IAP::write( char *source_addr, char *target_addr, int size ) { 00178 IAP_command[ 0 ] = IAPCommand_Copy_RAM_to_Flash; 00179 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. 00180 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. 00181 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00182 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz. 00183 00184 iap_entry( IAP_command, IAP_result ); 00185 00186 return ( (int)IAP_result[ 0 ] ); 00187 } 00188 00189 00190 /** Compare <address1> <address2> <no of bytes> 00191 * 00192 * @param source_addr Starting flash or RAM address of data bytes to be compared. This address should be a word boundary. 00193 * @param target_addr Starting flash or RAM address of data bytes to be compared. This address should be a word boundary. 00194 * @param size Number of bytes to be compared; should be a multiple of 4. 00195 * @return error code: CMD_SUCCESS | COMPARE_ERROR | COUNT_ERROR (Byte count is not a multiple of 4) | ADDR_ERROR | ADDR_NOT_MAPPED 00196 */ 00197 00198 int IAP::compare( char *source_addr, char *target_addr, int size ) { 00199 IAP_command[ 0 ] = IAPCommand_Compare; 00200 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. 00201 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. 00202 IAP_command[ 3 ] = size; // Number of bytes to be compared; should be a multiple of 4. 00203 00204 iap_entry( IAP_command, IAP_result ); 00205 00206 return ( (int)IAP_result[ 0 ] ); 00207 } 00208 00209 /** Compare <address1> <address2> <no of bytes> 00210 * 00211 * @param source_addr Starting flash or RAM address of data bytes to be compared. This address should be a word boundary. 00212 * @param target_addr Starting flash or RAM address of data bytes to be compared. This address should be a word boundary. 00213 * @param size Number of bytes to be compared; should be a multiple of 4. 00214 * @return error code: CMD_SUCCESS | COMPARE_ERROR | COUNT_ERROR (Byte count is not a multiple of 4) | ADDR_ERROR | ADDR_NOT_MAPPED 00215 */ 00216 00217 int IAP::read_BootVer(void) { 00218 IAP_command[0] = IAPCommand_Read_Boot_Code_version; 00219 IAP_result[1] = 0; // not sure if in high or low bits. 00220 iap_entry(IAP_command, IAP_result); 00221 return ((int)IAP_result[1]); 00222 } 00223 00224 /** Get user reserved flash start address 00225 * 00226 * @return start address of user reserved flash memory 00227 * @see reserved_flash_area_size() 00228 */ 00229 00230 char * IAP::reserved_flash_area_start( void ) 00231 { 00232 return ( (char *)USER_FLASH_AREA_START ); 00233 } 00234 00235 00236 /** Get user reserved flash size 00237 * 00238 * @return size of user reserved flash memory 00239 * @see reserved_flash_area_start() 00240 */ 00241 00242 int IAP::reserved_flash_area_size( void ) 00243 { 00244 return ( USER_FLASH_AREA_SIZE ); 00245 } 00246 00247 #if defined(TARGET_LPC11U24) 00248 /** Copy RAM to EEPROM (LPC11U24) 00249 * 00250 * @param source_addr Source RAM address from which data bytes are to be read. 00251 * @param target_addr Destination EEPROM address where data bytes are to be written. 00252 * @param size Number of bytes to be written. 00253 * @return error code: CMD_SUCCESS | SRC_ADDR_NOT_MAPPED | DST_ADDR_NOT_MAPPED 00254 * Remark: The top 64 bytes of the EEPROM memory are reserved and cannot be written to. 00255 */ 00256 int IAP::write_eeprom( char *source_addr, char *target_addr, int size ) { 00257 IAP_command[ 0 ] = IAPCommand_EEPROM_Write; 00258 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. 00259 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. 00260 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00261 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz. 00262 00263 iap_entry( IAP_command, IAP_result ); 00264 00265 return ( (int)IAP_result[ 0 ] ); 00266 } 00267 00268 /** Copy EEPROM to RAM (LPC11U24) 00269 * 00270 * @param source_addr Source EEPROM address from which data bytes are to be read. 00271 * @param target_addr Destination RAM address where data bytes are to be written. 00272 * @param size Number of bytes to be written. 00273 * @return error code: CMD_SUCCESS | SRC_ADDR_NOT_MAPPED | DST_ADDR_NOT_MAPPED 00274 * Remark: The top 64 bytes of the EEPROM memory are reserved and cannot be written to. 00275 */ 00276 int IAP::read_eeprom( char *source_addr, char *target_addr, int size ) { 00277 IAP_command[ 0 ] = IAPCommand_EEPROM_Read; 00278 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. 00279 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. 00280 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00281 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz. 00282 00283 iap_entry( IAP_command, IAP_result ); 00284 00285 return ( (int)IAP_result[ 0 ] ); 00286 } 00287 #endif
Generated on Thu Jul 14 2022 06:21:59 by
1.7.2
