In Application Programming with support for both LPC1768 and LPC2368. Original library here http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/

Dependencies:   mbed

Committer:
tecnosys
Date:
Mon Jul 11 01:53:18 2011 +0000
Revision:
0:406ffaf4d93c

        

Who changed what in which revision?

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