Dave Tech
/
EepromTest
11u24 Eeprom utility.
Embed:
(wiki syntax)
Show/hide line numbers
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