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.
IAP.cpp
00001 /** IAP : internal Flash memory access library 00002 * 00003 * The internal Flash memory access is described in the LPC1768 usermanual. 00004 * http://www.nxp.com/documents/user_manual/UM10360.pdf 00005 * 00006 * Chapter 2: "LPC17xx Memory map" 00007 * Chapter 32: "LPC17xx Flash memory interface and programming" 00008 * refering Rev. 01 - 4 January 2010 00009 * 00010 * Released under the MIT License: http://mbed.org/license/mit 00011 * 00012 * revision 1.0 09-Mar-2010 1st release 00013 * revision 1.1 12-Mar-2010 chaged: to make possible to reserve flash area for user 00014 * it can be set by USER_FLASH_AREA_START and USER_FLASH_AREA_SIZE in IAP.h 00015 * 00016 * by Tedd OKANO http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/ 00017 * modified by Suga (supported to LPC11U24) 00018 */ 00019 00020 #include "mbed.h" 00021 #include "IAP.h" 00022 00023 #define USER_FLASH_AREA_START_STR( x ) STR( x ) 00024 #define STR( x ) #x 00025 00026 unsigned char user_area[ USER_FLASH_AREA_SIZE ] __attribute__((section( ".ARM.__at_" USER_FLASH_AREA_START_STR( USER_FLASH_AREA_START ) ), zero_init)); 00027 00028 00029 /* 00030 * Reserve of flash area is explained by Igor. Please refer next URL 00031 * http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/?page=1#comment-271 00032 */ 00033 00034 //unsigned char user_area[ size ] __attribute__((section(".ARM.__at_0x78000"), zero_init)); 00035 00036 /* 00037 * IAP command codes 00038 * Table 589. "IAP Command Summary", Chapter 8. "IAP commands", usermanual 00039 */ 00040 00041 enum command_code 00042 { 00043 IAPCommand_Prepare_sector_for_write_operation = 50, 00044 IAPCommand_Copy_RAM_to_Flash, 00045 IAPCommand_Erase_sector, 00046 IAPCommand_Blank_check_sector, 00047 IAPCommand_Read_part_ID, 00048 IAPCommand_Read_Boot_Code_version, 00049 IAPCommand_Compare, 00050 IAPCommand_Reinvoke_ISP, 00051 IAPCommand_Read_device_serial_number, 00052 IAPCommand_EEPROM_Write = 61, 00053 IAPCommand_EEPROM_Read, 00054 }; 00055 00056 00057 /** Read part identification number 00058 * 00059 * @return device ID 00060 * @see read_serial() 00061 */ 00062 00063 int IAP::read_ID( void ) { 00064 IAP_command[ 0 ] = IAPCommand_Read_part_ID; 00065 00066 iap_entry( IAP_command, IAP_result ); 00067 00068 // return ( (int)IAP_result[ 0 ] ); 00069 return ( (int)IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS) 00070 } 00071 00072 00073 /** Read device serial number 00074 * 00075 * @return device serial number 00076 * @see read_ID() 00077 */ 00078 00079 int IAP::read_serial( void ) { 00080 IAP_command[ 0 ] = IAPCommand_Read_device_serial_number; 00081 00082 iap_entry( IAP_command, IAP_result ); 00083 00084 // return ( (int)IAP_result[ 0 ] ); 00085 return ( (int)IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS) 00086 } 00087 00088 00089 /** Blank check sector(s) 00090 * 00091 * @param start a Start Sector Number 00092 * @param end an End Sector Number (should be greater than or equal to start sector number). 00093 * @return error code: CMD_SUCCESS | BUSY | SECTOR_NOT_BLANK | INVALID_SECTOR 00094 */ 00095 00096 int IAP::blank_check( int start, int end ) { 00097 IAP_command[ 0 ] = IAPCommand_Blank_check_sector; 00098 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00099 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number) 00100 00101 iap_entry( IAP_command, IAP_result ); 00102 00103 return ( (int)IAP_result[ 0 ] ); 00104 } 00105 00106 00107 /** Erase Sector(s) 00108 * 00109 * @param start a Start Sector Number 00110 * @param end an End Sector Number (should be greater than or equal to start sector number). 00111 * @return error code: CMD_SUCCESS | BUSY | SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION | INVALID_SECTOR 00112 */ 00113 00114 int IAP::erase( int start, int end ) { 00115 IAP_command[ 0 ] = IAPCommand_Erase_sector; 00116 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00117 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number) 00118 IAP_command[ 3 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz 00119 00120 iap_entry( IAP_command, IAP_result ); 00121 00122 return ( (int)IAP_result[ 0 ] ); 00123 } 00124 00125 00126 /** Prepare sector(s) for write operation 00127 * 00128 * @param start a Start Sector Number 00129 * @param end an End Sector Number (should be greater than or equal to start sector number). 00130 * @return error code: CMD_SUCCESS | BUSY | INVALID_SECTOR 00131 */ 00132 00133 int IAP::prepare( int start, int end ) { 00134 IAP_command[ 0 ] = IAPCommand_Prepare_sector_for_write_operation; 00135 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00136 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number). 00137 00138 iap_entry( IAP_command, IAP_result ); 00139 00140 return ( (int)IAP_result[ 0 ] ); 00141 } 00142 00143 00144 /** Copy RAM to Flash 00145 * 00146 * @param source_addr Source RAM address from which data bytes are to be read. This address should be a word boundary. 00147 * @param target_addr Destination flash address where data bytes are to be written. This address should be a 256 byte boundary. 00148 * @param size Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00149 * @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 00150 */ 00151 00152 int IAP::write( char *source_addr, char *target_addr, int size ) { 00153 IAP_command[ 0 ] = IAPCommand_Copy_RAM_to_Flash; 00154 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. 00155 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. 00156 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00157 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz. 00158 00159 iap_entry( IAP_command, IAP_result ); 00160 00161 return ( (int)IAP_result[ 0 ] ); 00162 } 00163 00164 00165 /** Compare <address1> <address2> <no of bytes> 00166 * 00167 * @param source_addr Starting flash or RAM address of data bytes to be compared. This address should be a word boundary. 00168 * @param target_addr Starting flash or RAM address of data bytes to be compared. This address should be a word boundary. 00169 * @param size Number of bytes to be compared; should be a multiple of 4. 00170 * @return error code: CMD_SUCCESS | COMPARE_ERROR | COUNT_ERROR (Byte count is not a multiple of 4) | ADDR_ERROR | ADDR_NOT_MAPPED 00171 */ 00172 00173 int IAP::compare( char *source_addr, char *target_addr, int size ) { 00174 IAP_command[ 0 ] = IAPCommand_Compare; 00175 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. 00176 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. 00177 IAP_command[ 3 ] = size; // Number of bytes to be compared; should be a multiple of 4. 00178 00179 iap_entry( IAP_command, IAP_result ); 00180 00181 return ( (int)IAP_result[ 0 ] ); 00182 } 00183 00184 00185 /** Get user reserved flash start address 00186 * 00187 * @return start address of user reserved flash memory 00188 * @see reserved_flash_area_size() 00189 */ 00190 00191 char * IAP::reserved_flash_area_start( void ) 00192 { 00193 return ( (char *)USER_FLASH_AREA_START ); 00194 } 00195 00196 00197 /** Get user reserved flash size 00198 * 00199 * @return size of user reserved flash memory 00200 * @see reserved_flash_area_start() 00201 */ 00202 00203 int IAP::reserved_flash_area_size( void ) 00204 { 00205 return ( USER_FLASH_AREA_SIZE ); 00206 } 00207 00208 #if defined(TARGET_LPC11U24) 00209 /** Copy RAM to EEPROM (LPC11U24) 00210 * 00211 * @param source_addr Source RAM address from which data bytes are to be read. 00212 * @param target_addr Destination EEPROM address where data bytes are to be written. 00213 * @param size Number of bytes to be written. 00214 * @return error code: CMD_SUCCESS | SRC_ADDR_NOT_MAPPED | DST_ADDR_NOT_MAPPED 00215 * Remark: The top 64 bytes of the EEPROM memory are reserved and cannot be written to. 00216 */ 00217 int IAP::write_eeprom( char *source_addr, char *target_addr, int size ) { 00218 IAP_command[ 0 ] = IAPCommand_EEPROM_Write; 00219 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. 00220 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. 00221 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00222 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz. 00223 00224 iap_entry( IAP_command, IAP_result ); 00225 00226 return ( (int)IAP_result[ 0 ] ); 00227 } 00228 00229 /** Copy EEPROM to RAM (LPC11U24) 00230 * 00231 * @param source_addr Source EEPROM address from which data bytes are to be read. 00232 * @param target_addr Destination RAM address where data bytes are to be written. 00233 * @param size Number of bytes to be written. 00234 * @return error code: CMD_SUCCESS | SRC_ADDR_NOT_MAPPED | DST_ADDR_NOT_MAPPED 00235 * Remark: The top 64 bytes of the EEPROM memory are reserved and cannot be written to. 00236 */ 00237 int IAP::read_eeprom( char *source_addr, char *target_addr, int size ) { 00238 IAP_command[ 0 ] = IAPCommand_EEPROM_Read; 00239 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. 00240 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. 00241 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00242 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz. 00243 00244 iap_entry( IAP_command, IAP_result ); 00245 00246 return ( (int)IAP_result[ 0 ] ); 00247 } 00248 #endif
Generated on Thu Jul 14 2022 03:49:24 by
1.7.2