Sample code for how to erase/write LPC1768, LPC11U24, LPC1114, LPC812 and LPC824 internal flash memory. This program uses IAP call of MCU's ROM routines. The IAP library also supports read/write of EEPROM in LPC11U24.

Dependencies:   mbed IAP

Sample code for how to erase/write LPC1768, LPC11U24, LPC1114, LPC812 and LPC824 internal flash memory. This program uses IAP call of MCU's ROM routines.

No filesystem interface available. This program is just an interface to flash erasing and writing. User need manage where to store the data in the flash area.

This IAP library supports read/write of EEPROM in LPC11U24.

More information available in
http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/

Committer:
okano
Date:
Fri Mar 12 10:24:57 2010 +0000
Revision:
0:b802bd2f4cc9

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okano 0:b802bd2f4cc9 1 /** IAP : internal Flash memory access library
okano 0:b802bd2f4cc9 2 *
okano 0:b802bd2f4cc9 3 * The internal Flash memory access is described in the LPC1768 usermanual.
okano 0:b802bd2f4cc9 4 * http://www.nxp.com/documents/user_manual/UM10360.pdf
okano 0:b802bd2f4cc9 5 *
okano 0:b802bd2f4cc9 6 * Chapter 2: "LPC17xx Memory map"
okano 0:b802bd2f4cc9 7 * Chapter 32: "LPC17xx Flash memory interface and programming"
okano 0:b802bd2f4cc9 8 * refering Rev. 01 - 4 January 2010
okano 0:b802bd2f4cc9 9 *
okano 0:b802bd2f4cc9 10 * Released under the MIT License: http://mbed.org/license/mit
okano 0:b802bd2f4cc9 11 *
okano 0:b802bd2f4cc9 12 * revision 1.0 09-Mar-2010 1st release
okano 0:b802bd2f4cc9 13 * revision 1.1 12-Mar-2010 chaged: to make possible to reserve flash area for user
okano 0:b802bd2f4cc9 14 * it can be set by USER_FLASH_AREA_START and USER_FLASH_AREA_SIZE in IAP.h
okano 0:b802bd2f4cc9 15 */
okano 0:b802bd2f4cc9 16
okano 0:b802bd2f4cc9 17 #include "mbed.h"
okano 0:b802bd2f4cc9 18 #include "IAP.h"
okano 0:b802bd2f4cc9 19
okano 0:b802bd2f4cc9 20 #define USER_FLASH_AREA_START_STR( x ) STR( x )
okano 0:b802bd2f4cc9 21 #define STR( x ) #x
okano 0:b802bd2f4cc9 22
okano 0:b802bd2f4cc9 23 unsigned char user_area[ USER_FLASH_AREA_SIZE ] __attribute__((section( ".ARM.__at_" USER_FLASH_AREA_START_STR( USER_FLASH_AREA_START ) ), zero_init));
okano 0:b802bd2f4cc9 24
okano 0:b802bd2f4cc9 25
okano 0:b802bd2f4cc9 26 /*
okano 0:b802bd2f4cc9 27 * Reserve of flash area is explained by Igor. Please refer next URL
okano 0:b802bd2f4cc9 28 * http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/?page=1#comment-271
okano 0:b802bd2f4cc9 29 */
okano 0:b802bd2f4cc9 30
okano 0:b802bd2f4cc9 31 //unsigned char user_area[ size ] __attribute__((section(".ARM.__at_0x78000"), zero_init));
okano 0:b802bd2f4cc9 32
okano 0:b802bd2f4cc9 33 /*
okano 0:b802bd2f4cc9 34 * IAP command codes
okano 0:b802bd2f4cc9 35 * Table 589. "IAP Command Summary", Chapter 8. "IAP commands", usermanual
okano 0:b802bd2f4cc9 36 */
okano 0:b802bd2f4cc9 37
okano 0:b802bd2f4cc9 38 enum command_code
okano 0:b802bd2f4cc9 39 {
okano 0:b802bd2f4cc9 40 IAPCommand_Prepare_sector_for_write_operation = 50,
okano 0:b802bd2f4cc9 41 IAPCommand_Copy_RAM_to_Flash,
okano 0:b802bd2f4cc9 42 IAPCommand_Erase_sector,
okano 0:b802bd2f4cc9 43 IAPCommand_Blank_check_sector,
okano 0:b802bd2f4cc9 44 IAPCommand_Read_part_ID,
okano 0:b802bd2f4cc9 45 IAPCommand_Read_Boot_Code_version,
okano 0:b802bd2f4cc9 46 IAPCommand_Compare,
okano 0:b802bd2f4cc9 47 IAPCommand_Reinvoke_ISP,
okano 0:b802bd2f4cc9 48 IAPCommand_Read_device_serial_number
okano 0:b802bd2f4cc9 49 };
okano 0:b802bd2f4cc9 50
okano 0:b802bd2f4cc9 51
okano 0:b802bd2f4cc9 52 /** Read part identification number
okano 0:b802bd2f4cc9 53 *
okano 0:b802bd2f4cc9 54 * @return device ID
okano 0:b802bd2f4cc9 55 * @see read_serial()
okano 0:b802bd2f4cc9 56 */
okano 0:b802bd2f4cc9 57
okano 0:b802bd2f4cc9 58 int IAP::read_ID( void ) {
okano 0:b802bd2f4cc9 59 IAP_command[ 0 ] = IAPCommand_Read_part_ID;
okano 0:b802bd2f4cc9 60
okano 0:b802bd2f4cc9 61 iap_entry( IAP_command, IAP_result );
okano 0:b802bd2f4cc9 62
okano 0:b802bd2f4cc9 63 // return ( (int)IAP_result[ 0 ] );
okano 0:b802bd2f4cc9 64 return ( (int)IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS)
okano 0:b802bd2f4cc9 65 }
okano 0:b802bd2f4cc9 66
okano 0:b802bd2f4cc9 67
okano 0:b802bd2f4cc9 68 /** Read device serial number
okano 0:b802bd2f4cc9 69 *
okano 0:b802bd2f4cc9 70 * @return device serial number
okano 0:b802bd2f4cc9 71 * @see read_ID()
okano 0:b802bd2f4cc9 72 */
okano 0:b802bd2f4cc9 73
okano 0:b802bd2f4cc9 74 int IAP::read_serial( void ) {
okano 0:b802bd2f4cc9 75 IAP_command[ 0 ] = IAPCommand_Read_device_serial_number;
okano 0:b802bd2f4cc9 76
okano 0:b802bd2f4cc9 77 iap_entry( IAP_command, IAP_result );
okano 0:b802bd2f4cc9 78
okano 0:b802bd2f4cc9 79 // return ( (int)IAP_result[ 0 ] );
okano 0:b802bd2f4cc9 80 return ( (int)IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS)
okano 0:b802bd2f4cc9 81 }
okano 0:b802bd2f4cc9 82
okano 0:b802bd2f4cc9 83
okano 0:b802bd2f4cc9 84 /** Blank check sector(s)
okano 0:b802bd2f4cc9 85 *
okano 0:b802bd2f4cc9 86 * @param start a Start Sector Number
okano 0:b802bd2f4cc9 87 * @param end an End Sector Number (should be greater than or equal to start sector number).
okano 0:b802bd2f4cc9 88 * @return error code: CMD_SUCCESS | BUSY | SECTOR_NOT_BLANK | INVALID_SECTOR
okano 0:b802bd2f4cc9 89 */
okano 0:b802bd2f4cc9 90
okano 0:b802bd2f4cc9 91 int IAP::blank_check( int start, int end ) {
okano 0:b802bd2f4cc9 92 IAP_command[ 0 ] = IAPCommand_Blank_check_sector;
okano 0:b802bd2f4cc9 93 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number
okano 0:b802bd2f4cc9 94 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number)
okano 0:b802bd2f4cc9 95
okano 0:b802bd2f4cc9 96 iap_entry( IAP_command, IAP_result );
okano 0:b802bd2f4cc9 97
okano 0:b802bd2f4cc9 98 return ( (int)IAP_result[ 0 ] );
okano 0:b802bd2f4cc9 99 }
okano 0:b802bd2f4cc9 100
okano 0:b802bd2f4cc9 101
okano 0:b802bd2f4cc9 102 /** Erase Sector(s)
okano 0:b802bd2f4cc9 103 *
okano 0:b802bd2f4cc9 104 * @param start a Start Sector Number
okano 0:b802bd2f4cc9 105 * @param end an End Sector Number (should be greater than or equal to start sector number).
okano 0:b802bd2f4cc9 106 * @return error code: CMD_SUCCESS | BUSY | SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION | INVALID_SECTOR
okano 0:b802bd2f4cc9 107 */
okano 0:b802bd2f4cc9 108
okano 0:b802bd2f4cc9 109 int IAP::erase( int start, int end ) {
okano 0:b802bd2f4cc9 110 IAP_command[ 0 ] = IAPCommand_Erase_sector;
okano 0:b802bd2f4cc9 111 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number
okano 0:b802bd2f4cc9 112 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number)
okano 0:b802bd2f4cc9 113 IAP_command[ 3 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz
okano 0:b802bd2f4cc9 114
okano 0:b802bd2f4cc9 115 iap_entry( IAP_command, IAP_result );
okano 0:b802bd2f4cc9 116
okano 0:b802bd2f4cc9 117 return ( (int)IAP_result[ 0 ] );
okano 0:b802bd2f4cc9 118 }
okano 0:b802bd2f4cc9 119
okano 0:b802bd2f4cc9 120
okano 0:b802bd2f4cc9 121 /** Prepare sector(s) for write operation
okano 0:b802bd2f4cc9 122 *
okano 0:b802bd2f4cc9 123 * @param start a Start Sector Number
okano 0:b802bd2f4cc9 124 * @param end an End Sector Number (should be greater than or equal to start sector number).
okano 0:b802bd2f4cc9 125 * @return error code: CMD_SUCCESS | BUSY | INVALID_SECTOR
okano 0:b802bd2f4cc9 126 */
okano 0:b802bd2f4cc9 127
okano 0:b802bd2f4cc9 128 int IAP::prepare( int start, int end ) {
okano 0:b802bd2f4cc9 129 IAP_command[ 0 ] = IAPCommand_Prepare_sector_for_write_operation;
okano 0:b802bd2f4cc9 130 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number
okano 0:b802bd2f4cc9 131 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number).
okano 0:b802bd2f4cc9 132
okano 0:b802bd2f4cc9 133 iap_entry( IAP_command, IAP_result );
okano 0:b802bd2f4cc9 134
okano 0:b802bd2f4cc9 135 return ( (int)IAP_result[ 0 ] );
okano 0:b802bd2f4cc9 136 }
okano 0:b802bd2f4cc9 137
okano 0:b802bd2f4cc9 138
okano 0:b802bd2f4cc9 139 /** Copy RAM to Flash
okano 0:b802bd2f4cc9 140 *
okano 0:b802bd2f4cc9 141 * @param source_addr Source RAM address from which data bytes are to be read. This address should be a word boundary.
okano 0:b802bd2f4cc9 142 * @param target_addr Destination flash address where data bytes are to be written. This address should be a 256 byte boundary.
okano 0:b802bd2f4cc9 143 * @param size Number of bytes to be written. Should be 256 | 512 | 1024 | 4096.
okano 0:b802bd2f4cc9 144 * @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
okano 0:b802bd2f4cc9 145 */
okano 0:b802bd2f4cc9 146
okano 0:b802bd2f4cc9 147 int IAP::write( char *source_addr, char *target_addr, int size ) {
okano 0:b802bd2f4cc9 148 IAP_command[ 0 ] = IAPCommand_Copy_RAM_to_Flash;
okano 0:b802bd2f4cc9 149 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.
okano 0:b802bd2f4cc9 150 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.
okano 0:b802bd2f4cc9 151 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096.
okano 0:b802bd2f4cc9 152 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz.
okano 0:b802bd2f4cc9 153
okano 0:b802bd2f4cc9 154 iap_entry( IAP_command, IAP_result );
okano 0:b802bd2f4cc9 155
okano 0:b802bd2f4cc9 156 return ( (int)IAP_result[ 0 ] );
okano 0:b802bd2f4cc9 157 }
okano 0:b802bd2f4cc9 158
okano 0:b802bd2f4cc9 159
okano 0:b802bd2f4cc9 160 /** Compare <address1> <address2> <no of bytes>
okano 0:b802bd2f4cc9 161 *
okano 0:b802bd2f4cc9 162 * @param source_addr Starting flash or RAM address of data bytes to be compared. This address should be a word boundary.
okano 0:b802bd2f4cc9 163 * @param target_addr Starting flash or RAM address of data bytes to be compared. This address should be a word boundary.
okano 0:b802bd2f4cc9 164 * @param size Number of bytes to be compared; should be a multiple of 4.
okano 0:b802bd2f4cc9 165 * @return error code: CMD_SUCCESS | COMPARE_ERROR | COUNT_ERROR (Byte count is not a multiple of 4) | ADDR_ERROR | ADDR_NOT_MAPPED
okano 0:b802bd2f4cc9 166 */
okano 0:b802bd2f4cc9 167
okano 0:b802bd2f4cc9 168 int IAP::compare( char *source_addr, char *target_addr, int size ) {
okano 0:b802bd2f4cc9 169 IAP_command[ 0 ] = IAPCommand_Compare;
okano 0:b802bd2f4cc9 170 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.
okano 0:b802bd2f4cc9 171 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.
okano 0:b802bd2f4cc9 172 IAP_command[ 3 ] = size; // Number of bytes to be compared; should be a multiple of 4.
okano 0:b802bd2f4cc9 173
okano 0:b802bd2f4cc9 174 iap_entry( IAP_command, IAP_result );
okano 0:b802bd2f4cc9 175
okano 0:b802bd2f4cc9 176 return ( (int)IAP_result[ 0 ] );
okano 0:b802bd2f4cc9 177 }
okano 0:b802bd2f4cc9 178
okano 0:b802bd2f4cc9 179
okano 0:b802bd2f4cc9 180 /** Get user reserved flash start address
okano 0:b802bd2f4cc9 181 *
okano 0:b802bd2f4cc9 182 * @return start address of user reserved flash memory
okano 0:b802bd2f4cc9 183 * @see reserved_flash_area_size()
okano 0:b802bd2f4cc9 184 */
okano 0:b802bd2f4cc9 185
okano 0:b802bd2f4cc9 186 char * IAP::reserved_flash_area_start( void )
okano 0:b802bd2f4cc9 187 {
okano 0:b802bd2f4cc9 188 return ( (char *)USER_FLASH_AREA_START );
okano 0:b802bd2f4cc9 189 }
okano 0:b802bd2f4cc9 190
okano 0:b802bd2f4cc9 191
okano 0:b802bd2f4cc9 192 /** Get user reserved flash size
okano 0:b802bd2f4cc9 193 *
okano 0:b802bd2f4cc9 194 * @return size of user reserved flash memory
okano 0:b802bd2f4cc9 195 * @see reserved_flash_area_start()
okano 0:b802bd2f4cc9 196 */
okano 0:b802bd2f4cc9 197
okano 0:b802bd2f4cc9 198 int IAP::reserved_flash_area_size( void )
okano 0:b802bd2f4cc9 199 {
okano 0:b802bd2f4cc9 200 return ( USER_FLASH_AREA_SIZE );
okano 0:b802bd2f4cc9 201 }
okano 0:b802bd2f4cc9 202