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 */ 00018 00019 #include "mbed.h" 00020 #include "IAP.h" 00021 00022 #define USER_FLASH_AREA_START_STR( x ) STR( x ) 00023 #define STR( x ) #x 00024 00025 unsigned char user_area[ USER_FLASH_AREA_SIZE ] __attribute__((section( ".ARM.__at_" USER_FLASH_AREA_START_STR( USER_FLASH_AREA_START ) ), zero_init)); 00026 00027 00028 /* 00029 * Reserve of flash area is explained by Igor. Please refer next URL 00030 * http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/?page=1#comment-271 00031 */ 00032 00033 //unsigned char user_area[ size ] __attribute__((section(".ARM.__at_0x78000"), zero_init)); 00034 00035 /* 00036 * IAP command codes 00037 * Table 589. "IAP Command Summary", Chapter 8. "IAP commands", usermanual 00038 */ 00039 00040 enum command_code 00041 { 00042 IAPCommand_Prepare_sector_for_write_operation = 50, 00043 IAPCommand_Copy_RAM_to_Flash, 00044 IAPCommand_Erase_sector, 00045 IAPCommand_Blank_check_sector, 00046 IAPCommand_Read_part_ID, 00047 IAPCommand_Read_Boot_Code_version, 00048 IAPCommand_Compare, 00049 IAPCommand_Reinvoke_ISP, 00050 IAPCommand_Read_device_serial_number 00051 }; 00052 00053 00054 /** Read part identification number 00055 * 00056 * @return device ID 00057 * @see read_serial() 00058 */ 00059 00060 int IAP::read_ID( void ) { 00061 IAP_command[ 0 ] = IAPCommand_Read_part_ID; 00062 00063 iap_entry( IAP_command, IAP_result ); 00064 00065 // return ( (int)IAP_result[ 0 ] ); 00066 return ( (int)IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS) 00067 } 00068 00069 00070 /** Read device serial number 00071 * 00072 * @return device serial number 00073 * @see read_ID() 00074 */ 00075 00076 int IAP::read_serial( void ) { 00077 IAP_command[ 0 ] = IAPCommand_Read_device_serial_number; 00078 00079 iap_entry( IAP_command, IAP_result ); 00080 00081 // return ( (int)IAP_result[ 0 ] ); 00082 return ( (int)IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS) 00083 } 00084 00085 00086 /** Blank check sector(s) 00087 * 00088 * @param start a Start Sector Number 00089 * @param end an End Sector Number (should be greater than or equal to start sector number). 00090 * @return error code: CMD_SUCCESS | BUSY | SECTOR_NOT_BLANK | INVALID_SECTOR 00091 */ 00092 00093 int IAP::blank_check( int start, int end ) { 00094 IAP_command[ 0 ] = IAPCommand_Blank_check_sector; 00095 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00096 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number) 00097 00098 iap_entry( IAP_command, IAP_result ); 00099 00100 return ( (int)IAP_result[ 0 ] ); 00101 } 00102 00103 00104 /** Erase Sector(s) 00105 * 00106 * @param start a Start Sector Number 00107 * @param end an End Sector Number (should be greater than or equal to start sector number). 00108 * @return error code: CMD_SUCCESS | BUSY | SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION | INVALID_SECTOR 00109 */ 00110 00111 int IAP::erase( int start, int end ) { 00112 IAP_command[ 0 ] = IAPCommand_Erase_sector; 00113 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00114 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number) 00115 IAP_command[ 3 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz 00116 00117 iap_entry( IAP_command, IAP_result ); 00118 00119 return ( (int)IAP_result[ 0 ] ); 00120 } 00121 00122 00123 /** Prepare sector(s) for write operation 00124 * 00125 * @param start a Start Sector Number 00126 * @param end an End Sector Number (should be greater than or equal to start sector number). 00127 * @return error code: CMD_SUCCESS | BUSY | INVALID_SECTOR 00128 */ 00129 00130 int IAP::prepare( int start, int end ) { 00131 IAP_command[ 0 ] = IAPCommand_Prepare_sector_for_write_operation; 00132 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number 00133 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number). 00134 00135 iap_entry( IAP_command, IAP_result ); 00136 00137 return ( (int)IAP_result[ 0 ] ); 00138 } 00139 00140 00141 /** Copy RAM to Flash 00142 * 00143 * @param source_addr Source RAM address from which data bytes are to be read. This address should be a word boundary. 00144 * @param target_addr Destination flash address where data bytes are to be written. This address should be a 256 byte boundary. 00145 * @param size Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00146 * @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 00147 */ 00148 00149 int IAP::write( char *source_addr, char *target_addr, int size ) { 00150 IAP_command[ 0 ] = IAPCommand_Copy_RAM_to_Flash; 00151 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. 00152 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. 00153 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096. 00154 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz. 00155 00156 iap_entry( IAP_command, IAP_result ); 00157 00158 return ( (int)IAP_result[ 0 ] ); 00159 } 00160 00161 00162 /** Compare <address1> <address2> <no of bytes> 00163 * 00164 * @param source_addr Starting flash or RAM address of data bytes to be compared. This address should be a word boundary. 00165 * @param target_addr Starting flash or RAM address of data bytes to be compared. This address should be a word boundary. 00166 * @param size Number of bytes to be compared; should be a multiple of 4. 00167 * @return error code: CMD_SUCCESS | COMPARE_ERROR | COUNT_ERROR (Byte count is not a multiple of 4) | ADDR_ERROR | ADDR_NOT_MAPPED 00168 */ 00169 00170 int IAP::compare( char *source_addr, char *target_addr, int size ) { 00171 IAP_command[ 0 ] = IAPCommand_Compare; 00172 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. 00173 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. 00174 IAP_command[ 3 ] = size; // Number of bytes to be compared; should be a multiple of 4. 00175 00176 iap_entry( IAP_command, IAP_result ); 00177 00178 return ( (int)IAP_result[ 0 ] ); 00179 } 00180 00181 00182 /** Get user reserved flash start address 00183 * 00184 * @return start address of user reserved flash memory 00185 * @see reserved_flash_area_size() 00186 */ 00187 00188 char * IAP::reserved_flash_area_start( void ) 00189 { 00190 return ( (char *)USER_FLASH_AREA_START ); 00191 } 00192 00193 00194 /** Get user reserved flash size 00195 * 00196 * @return size of user reserved flash memory 00197 * @see reserved_flash_area_start() 00198 */ 00199 00200 int IAP::reserved_flash_area_size( void ) 00201 { 00202 return ( USER_FLASH_AREA_SIZE ); 00203 } 00204
Generated on Sat Jul 16 2022 13:37:35 by
1.7.2