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