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 provides support for read/write to FLASh on the LPC1768 platform. The code here is taken from: 00002 * 00003 * http://developer.mbed.org/users/okano/code/IAP/ 00004 * 00005 * All rights remain with Tedd OKANO, etc. 00006 */ 00007 00008 /** IAP : internal Flash memory access library 00009 * 00010 * The internal Flash memory access is described in the LPC1768 and LPC11U24 usermanual. 00011 * http://www.nxp.com/documents/user_manual/UM10360.pdf 00012 * http://www.nxp.com/documents/user_manual/UM10462.pdf 00013 * 00014 * LPC1768 -- 00015 * Chapter 2: "LPC17xx Memory map" 00016 * Chapter 32: "LPC17xx Flash memory interface and programming" 00017 * refering Rev. 01 - 4 January 2010 00018 * 00019 * LPC11U24 -- 00020 * Chapter 2: "LPC11Uxx Memory mapping" 00021 * Chapter 20: "LPC11Uxx Flash programming firmware" 00022 * refering Rev. 03 - 16 July 2012 00023 * 00024 * Released under the MIT License: http://mbed.org/license/mit 00025 * 00026 * revision 1.0 09-Mar-2010 1st release 00027 * revision 1.1 12-Mar-2010 chaged: to make possible to reserve flash area for user 00028 * it can be set by USER_FLASH_AREA_START and USER_FLASH_AREA_SIZE in IAP.h 00029 * revision 2.0 26-Nov-2012 LPC11U24 code added 00030 * revision 2.1 26-Nov-2012 EEPROM access code imported from Suga koubou san's (http://mbed.org/users/okini3939/) library 00031 * http://mbed.org/users/okini3939/code/M0_EEPROM_test/ 00032 * revision 3.0 09-Jan-2015 LPC812 and LPC824 support added 00033 * revision 3.1 13-Jan-2015 LPC1114 support added 00034 * revision 3.1.1 16-Jan-2015 Target MCU name changed for better compatibility across the platforms 00035 */ 00036 00037 #include "mbed.h" 00038 #include "IapApi.h" 00039 00040 #define USER_FLASH_AREA_START_STR( x ) STR( x ) 00041 #define STR( x ) #x 00042 00043 /* 00044 * Reserve of flash area is explained by Igor. Please refer next URL 00045 * http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/?page=1#comment-271 00046 */ 00047 00048 //unsigned char user_area[ size ] __attribute__((section(".ARM.__at_0x78000"), zero_init)); 00049 00050 /* 00051 * IAP command codes 00052 * Table 589. "IAP Command Summary", Chapter 8. "IAP commands", usermanual 00053 */ 00054 00055 enum command_code { 00056 IAPCommand_Prepare_sector_for_write_operation = 50, 00057 IAPCommand_Copy_RAM_to_Flash, 00058 IAPCommand_Erase_sector, 00059 IAPCommand_Blank_check_sector, 00060 IAPCommand_Read_part_ID, 00061 IAPCommand_Read_Boot_Code_version, 00062 IAPCommand_Compare, 00063 IAPCommand_Reinvoke_ISP, 00064 IAPCommand_Read_device_serial_number, 00065 #if defined(TARGET_LPC11UXX) 00066 IAPCommand_EEPROM_Write = 61, 00067 IAPCommand_EEPROM_Read, 00068 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X) 00069 IAPCommand_Erase_page = 59, 00070 #endif 00071 }; 00072 00073 int IAP::read_ID( void ) 00074 { 00075 IAP_command[ 0 ] = IAPCommand_Read_part_ID; 00076 00077 iap_entry( IAP_command, IAP_result ); 00078 00079 // return ( (int)IAP_result[ 0 ] ); 00080 return ( (int)IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS) 00081 } 00082 00083 int IAP::read_serial( void ) 00084 { 00085 IAP_command[ 0 ] = IAPCommand_Read_device_serial_number; 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::blank_check( int start, int end ) 00094 { 00095 IAP_command[ 0 ] = IAPCommand_Blank_check_sector; 00096 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00097 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number) 00098 00099 iap_entry( IAP_command, IAP_result ); 00100 00101 return ( (int)IAP_result[ 0 ] ); 00102 } 00103 00104 int IAP::erase( int start, int end ) 00105 { 00106 IAP_command[ 0 ] = IAPCommand_Erase_sector; 00107 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00108 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number) 00109 IAP_command[ 3 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz 00110 00111 iap_entry( IAP_command, IAP_result ); 00112 00113 return ( (int)IAP_result[ 0 ] ); 00114 } 00115 00116 int IAP::prepare( int start, int end ) 00117 { 00118 IAP_command[ 0 ] = IAPCommand_Prepare_sector_for_write_operation; 00119 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00120 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number). 00121 00122 iap_entry( IAP_command, IAP_result ); 00123 00124 return ( (int)IAP_result[ 0 ] ); 00125 } 00126 00127 int IAP::write( char *source_addr, char *target_addr, int size ) 00128 { 00129 IAP_command[ 0 ] = IAPCommand_Copy_RAM_to_Flash; 00130 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. 00131 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. 00132 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00133 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz. 00134 00135 iap_entry( IAP_command, IAP_result ); 00136 00137 return ( (int)IAP_result[ 0 ] ); 00138 } 00139 00140 int IAP::compare( char *source_addr, char *target_addr, int size ) 00141 { 00142 IAP_command[ 0 ] = IAPCommand_Compare; 00143 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. 00144 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. 00145 IAP_command[ 3 ] = size; // Number of bytes to be compared; should be a multiple of 4. 00146 00147 iap_entry( IAP_command, IAP_result ); 00148 00149 return ( (int)IAP_result[ 0 ] ); 00150 } 00151 00152 int IAP::read_BootVer(void) 00153 { 00154 IAP_command[0] = IAPCommand_Read_Boot_Code_version; 00155 IAP_result[1] = 0; // not sure if in high or low bits. 00156 iap_entry(IAP_command, IAP_result); 00157 return ((int)IAP_result[1]); 00158 } 00159 00160 char * IAP::reserved_flash_area_start( void ) 00161 { 00162 return ( (char *)USER_FLASH_AREA_START ); 00163 } 00164 00165 int IAP::reserved_flash_area_size( void ) 00166 { 00167 return ( USER_FLASH_AREA_SIZE ); 00168 } 00169 00170 #if defined(TARGET_LPC11UXX) 00171 00172 int IAP::write_eeprom( char *source_addr, char *target_addr, int size ) 00173 { 00174 IAP_command[ 0 ] = IAPCommand_EEPROM_Write; 00175 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. 00176 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. 00177 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00178 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz. 00179 00180 iap_entry( IAP_command, IAP_result ); 00181 00182 return ( (int)IAP_result[ 0 ] ); 00183 } 00184 00185 int IAP::read_eeprom( char *source_addr, char *target_addr, int size ) 00186 { 00187 IAP_command[ 0 ] = IAPCommand_EEPROM_Read; 00188 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. 00189 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. 00190 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00191 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz. 00192 00193 iap_entry( IAP_command, IAP_result ); 00194 00195 return ( (int)IAP_result[ 0 ] ); 00196 } 00197 00198 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X) 00199 00200 int IAP::erase_page( int start, int end ) 00201 { 00202 IAP_command[ 0 ] = IAPCommand_Erase_page; 00203 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00204 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number) 00205 IAP_command[ 3 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz 00206 00207 iap_entry( IAP_command, IAP_result ); 00208 00209 return ( (int)IAP_result[ 0 ] ); 00210 } 00211 00212 #endif
Generated on Sat Jul 23 2022 07:58:43 by
1.7.2