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 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 unsigned char user_area[ USER_FLASH_AREA_SIZE ] __attribute__((section( ".ARM.__at_" USER_FLASH_AREA_START_STR( USER_FLASH_AREA_START ) ), zero_init)); 00037 00038 /* 00039 * Reserve of flash area is explained by Igor. Please refer next URL 00040 * http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/?page=1#comment-271 00041 */ 00042 00043 //unsigned char user_area[ size ] __attribute__((section(".ARM.__at_0x78000"), zero_init)); 00044 00045 /* 00046 * IAP command codes 00047 * Table 589. "IAP Command Summary", Chapter 8. "IAP commands", usermanual 00048 */ 00049 00050 enum command_code { 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_LPC11UXX) 00061 IAPCommand_EEPROM_Write = 61, 00062 IAPCommand_EEPROM_Read, 00063 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X) 00064 IAPCommand_Erase_page = 59, 00065 #endif 00066 }; 00067 00068 int IAP::reinvoke_isp( void ) { 00069 __disable_irq(); 00070 00071 IAP_command[ 0 ] = IAPCommand_Reinvoke_ISP; 00072 00073 iap_entry( IAP_command, IAP_result ); 00074 00075 return ( (int)IAP_result[ 0 ] ); 00076 } 00077 00078 /** Read part identification number 00079 * 00080 * @return device ID 00081 * @see read_serial() 00082 */ 00083 int IAP::read_ID( void ) 00084 { 00085 IAP_command[ 0 ] = IAPCommand_Read_part_ID; 00086 00087 iap_entry( IAP_command, IAP_result ); 00088 00089 // return ( (int)IAP_result[ 0 ] ); 00090 return ( (int)IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS) 00091 } 00092 00093 int *IAP::read_serial( void ) { 00094 IAP_command[ 0 ] = IAPCommand_Read_device_serial_number; 00095 00096 iap_entry( IAP_command, IAP_result ); 00097 00098 // return ( (int)IAP_result[ 0 ] ); 00099 return ( (int *)&IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS) 00100 } 00101 00102 int IAP::blank_check( int start, int end ) 00103 { 00104 IAP_command[ 0 ] = IAPCommand_Blank_check_sector; 00105 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00106 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number) 00107 00108 iap_entry( IAP_command, IAP_result ); 00109 00110 return ( (int)IAP_result[ 0 ] ); 00111 } 00112 00113 int IAP::erase( int start, int end ) 00114 { 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 int IAP::prepare( int start, int end ) 00126 { 00127 IAP_command[ 0 ] = IAPCommand_Prepare_sector_for_write_operation; 00128 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00129 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number). 00130 00131 iap_entry( IAP_command, IAP_result ); 00132 00133 return ( (int)IAP_result[ 0 ] ); 00134 } 00135 00136 int IAP::write( char *source_addr, char *target_addr, int size ) 00137 { 00138 IAP_command[ 0 ] = IAPCommand_Copy_RAM_to_Flash; 00139 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. 00140 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. 00141 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00142 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz. 00143 00144 iap_entry( IAP_command, IAP_result ); 00145 00146 return ( (int)IAP_result[ 0 ] ); 00147 } 00148 00149 int IAP::compare( char *source_addr, char *target_addr, int size ) 00150 { 00151 IAP_command[ 0 ] = IAPCommand_Compare; 00152 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. 00153 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. 00154 IAP_command[ 3 ] = size; // Number of bytes to be compared; should be a multiple of 4. 00155 00156 iap_entry( IAP_command, IAP_result ); 00157 00158 return ( (int)IAP_result[ 0 ] ); 00159 } 00160 00161 int IAP::read_BootVer(void) 00162 { 00163 IAP_command[0] = IAPCommand_Read_Boot_Code_version; 00164 IAP_result[1] = 0; // not sure if in high or low bits. 00165 iap_entry(IAP_command, IAP_result); 00166 return ((int)IAP_result[1]); 00167 } 00168 00169 char * IAP::reserved_flash_area_start( void ) 00170 { 00171 return ( (char *)USER_FLASH_AREA_START ); 00172 } 00173 00174 int IAP::reserved_flash_area_size( void ) 00175 { 00176 return ( USER_FLASH_AREA_SIZE ); 00177 } 00178 00179 #if defined(TARGET_LPC11UXX) 00180 00181 int IAP::write_eeprom( char *source_addr, char *target_addr, int size ) 00182 { 00183 IAP_command[ 0 ] = IAPCommand_EEPROM_Write; 00184 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. 00185 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. 00186 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00187 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz. 00188 00189 iap_entry( IAP_command, IAP_result ); 00190 00191 return ( (int)IAP_result[ 0 ] ); 00192 } 00193 00194 int IAP::read_eeprom( char *source_addr, char *target_addr, int size ) 00195 { 00196 IAP_command[ 0 ] = IAPCommand_EEPROM_Read; 00197 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. 00198 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. 00199 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00200 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz. 00201 00202 iap_entry( IAP_command, IAP_result ); 00203 00204 return ( (int)IAP_result[ 0 ] ); 00205 } 00206 00207 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X) 00208 00209 int IAP::erase_page( int start, int end ) 00210 { 00211 IAP_command[ 0 ] = IAPCommand_Erase_page; 00212 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00213 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number) 00214 IAP_command[ 3 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz 00215 00216 iap_entry( IAP_command, IAP_result ); 00217 00218 return ( (int)IAP_result[ 0 ] ); 00219 } 00220 00221 #endif 00222
Generated on Fri Jul 15 2022 02:25:27 by
1.7.2