supported LPC11U35

Fork of IAP by Tedd OKANO

Committer:
okano
Date:
Tue Jan 13 09:11:41 2015 +0000
Revision:
3:87e117b1bdf2
Parent:
2:17f3464672c1
Child:
4:cee1a2a734c9
ver3.1 : LPC1114 support

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okano 0:ada7fb504504 1 /** IAP : internal Flash memory access library
okano 0:ada7fb504504 2 *
okano 2:17f3464672c1 3 * The internal Flash memory access is described in the LPC1768 and LPC11U24 usermanual.
okano 0:ada7fb504504 4 * http://www.nxp.com/documents/user_manual/UM10360.pdf
okano 0:ada7fb504504 5 * http://www.nxp.com/documents/user_manual/UM10462.pdf
okano 0:ada7fb504504 6 *
okano 0:ada7fb504504 7 * LPC1768 --
okano 0:ada7fb504504 8 * Chapter 2: "LPC17xx Memory map"
okano 0:ada7fb504504 9 * Chapter 32: "LPC17xx Flash memory interface and programming"
okano 0:ada7fb504504 10 * refering Rev. 01 - 4 January 2010
okano 2:17f3464672c1 11 *
okano 0:ada7fb504504 12 * LPC11U24 --
okano 0:ada7fb504504 13 * Chapter 2: "LPC11Uxx Memory mapping"
okano 0:ada7fb504504 14 * Chapter 20: "LPC11Uxx Flash programming firmware"
okano 0:ada7fb504504 15 * refering Rev. 03 - 16 July 2012
okano 2:17f3464672c1 16 *
okano 0:ada7fb504504 17 * Released under the MIT License: http://mbed.org/license/mit
okano 0:ada7fb504504 18 *
okano 0:ada7fb504504 19 * revision 1.0 09-Mar-2010 1st release
okano 0:ada7fb504504 20 * revision 1.1 12-Mar-2010 chaged: to make possible to reserve flash area for user
okano 0:ada7fb504504 21 * it can be set by USER_FLASH_AREA_START and USER_FLASH_AREA_SIZE in IAP.h
okano 1:ff906ad52cf9 22 * revision 2.0 26-Nov-2012 LPC11U24 code added
okano 1:ff906ad52cf9 23 * revision 2.1 26-Nov-2012 EEPROM access code imported from Suga koubou san's (http://mbed.org/users/okini3939/) library
okano 1:ff906ad52cf9 24 * http://mbed.org/users/okini3939/code/M0_EEPROM_test/
okano 2:17f3464672c1 25 * revision 3.0 09-Jan-2014 LPC812 and LPC824 support added
okano 3:87e117b1bdf2 26 * revision 3.1 13-Jan-2014 LPC1114 support added
okano 0:ada7fb504504 27 */
okano 0:ada7fb504504 28
okano 0:ada7fb504504 29 #include "mbed.h"
okano 0:ada7fb504504 30 #include "IAP.h"
okano 0:ada7fb504504 31
okano 0:ada7fb504504 32 #define USER_FLASH_AREA_START_STR( x ) STR( x )
okano 0:ada7fb504504 33 #define STR( x ) #x
okano 0:ada7fb504504 34
okano 0:ada7fb504504 35 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:ada7fb504504 36
okano 0:ada7fb504504 37 /*
okano 0:ada7fb504504 38 * Reserve of flash area is explained by Igor. Please refer next URL
okano 0:ada7fb504504 39 * http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/?page=1#comment-271
okano 0:ada7fb504504 40 */
okano 2:17f3464672c1 41
okano 0:ada7fb504504 42 //unsigned char user_area[ size ] __attribute__((section(".ARM.__at_0x78000"), zero_init));
okano 0:ada7fb504504 43
okano 0:ada7fb504504 44 /*
okano 0:ada7fb504504 45 * IAP command codes
okano 0:ada7fb504504 46 * Table 589. "IAP Command Summary", Chapter 8. "IAP commands", usermanual
okano 0:ada7fb504504 47 */
okano 0:ada7fb504504 48
okano 2:17f3464672c1 49 enum command_code {
okano 2:17f3464672c1 50 IAPCommand_Prepare_sector_for_write_operation = 50,
okano 2:17f3464672c1 51 IAPCommand_Copy_RAM_to_Flash,
okano 2:17f3464672c1 52 IAPCommand_Erase_sector,
okano 2:17f3464672c1 53 IAPCommand_Blank_check_sector,
okano 2:17f3464672c1 54 IAPCommand_Read_part_ID,
okano 2:17f3464672c1 55 IAPCommand_Read_Boot_Code_version,
okano 2:17f3464672c1 56 IAPCommand_Compare,
okano 2:17f3464672c1 57 IAPCommand_Reinvoke_ISP,
okano 2:17f3464672c1 58 IAPCommand_Read_device_serial_number,
okano 1:ff906ad52cf9 59 #if defined(TARGET_LPC11U24)
okano 2:17f3464672c1 60 IAPCommand_EEPROM_Write = 61,
okano 2:17f3464672c1 61 IAPCommand_EEPROM_Read,
okano 2:17f3464672c1 62 #elif defined(TARGET_LPC812) || defined(TARGET_LPC824)
okano 2:17f3464672c1 63 IAPCommand_Erase_page = 59,
okano 1:ff906ad52cf9 64 #endif
okano 2:17f3464672c1 65 };
okano 0:ada7fb504504 66
okano 2:17f3464672c1 67 int IAP::read_ID( void )
okano 2:17f3464672c1 68 {
okano 2:17f3464672c1 69 IAP_command[ 0 ] = IAPCommand_Read_part_ID;
okano 0:ada7fb504504 70
okano 0:ada7fb504504 71 iap_entry( IAP_command, IAP_result );
okano 2:17f3464672c1 72
okano 0:ada7fb504504 73 // return ( (int)IAP_result[ 0 ] );
okano 0:ada7fb504504 74 return ( (int)IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS)
okano 0:ada7fb504504 75 }
okano 0:ada7fb504504 76
okano 2:17f3464672c1 77 int IAP::read_serial( void )
okano 2:17f3464672c1 78 {
okano 2:17f3464672c1 79 IAP_command[ 0 ] = IAPCommand_Read_device_serial_number;
okano 0:ada7fb504504 80
okano 2:17f3464672c1 81 iap_entry( IAP_command, IAP_result );
okano 0:ada7fb504504 82
okano 0:ada7fb504504 83 // return ( (int)IAP_result[ 0 ] );
okano 0:ada7fb504504 84 return ( (int)IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS)
okano 0:ada7fb504504 85 }
okano 0:ada7fb504504 86
okano 2:17f3464672c1 87 int IAP::blank_check( int start, int end )
okano 2:17f3464672c1 88 {
okano 0:ada7fb504504 89 IAP_command[ 0 ] = IAPCommand_Blank_check_sector;
okano 0:ada7fb504504 90 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number
okano 0:ada7fb504504 91 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number)
okano 0:ada7fb504504 92
okano 0:ada7fb504504 93 iap_entry( IAP_command, IAP_result );
okano 0:ada7fb504504 94
okano 0:ada7fb504504 95 return ( (int)IAP_result[ 0 ] );
okano 0:ada7fb504504 96 }
okano 0:ada7fb504504 97
okano 2:17f3464672c1 98 int IAP::erase( int start, int end )
okano 2:17f3464672c1 99 {
okano 0:ada7fb504504 100 IAP_command[ 0 ] = IAPCommand_Erase_sector;
okano 0:ada7fb504504 101 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number
okano 0:ada7fb504504 102 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number)
okano 0:ada7fb504504 103 IAP_command[ 3 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz
okano 0:ada7fb504504 104
okano 0:ada7fb504504 105 iap_entry( IAP_command, IAP_result );
okano 0:ada7fb504504 106
okano 0:ada7fb504504 107 return ( (int)IAP_result[ 0 ] );
okano 0:ada7fb504504 108 }
okano 0:ada7fb504504 109
okano 2:17f3464672c1 110 int IAP::prepare( int start, int end )
okano 2:17f3464672c1 111 {
okano 0:ada7fb504504 112 IAP_command[ 0 ] = IAPCommand_Prepare_sector_for_write_operation;
okano 0:ada7fb504504 113 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number
okano 0:ada7fb504504 114 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number).
okano 2:17f3464672c1 115
okano 0:ada7fb504504 116 iap_entry( IAP_command, IAP_result );
okano 2:17f3464672c1 117
okano 0:ada7fb504504 118 return ( (int)IAP_result[ 0 ] );
okano 0:ada7fb504504 119 }
okano 0:ada7fb504504 120
okano 2:17f3464672c1 121 int IAP::write( char *source_addr, char *target_addr, int size )
okano 2:17f3464672c1 122 {
okano 0:ada7fb504504 123 IAP_command[ 0 ] = IAPCommand_Copy_RAM_to_Flash;
okano 0:ada7fb504504 124 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:ada7fb504504 125 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:ada7fb504504 126 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096.
okano 0:ada7fb504504 127 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz.
okano 0:ada7fb504504 128
okano 0:ada7fb504504 129 iap_entry( IAP_command, IAP_result );
okano 0:ada7fb504504 130
okano 0:ada7fb504504 131 return ( (int)IAP_result[ 0 ] );
okano 0:ada7fb504504 132 }
okano 0:ada7fb504504 133
okano 2:17f3464672c1 134 int IAP::compare( char *source_addr, char *target_addr, int size )
okano 2:17f3464672c1 135 {
okano 0:ada7fb504504 136 IAP_command[ 0 ] = IAPCommand_Compare;
okano 0:ada7fb504504 137 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:ada7fb504504 138 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:ada7fb504504 139 IAP_command[ 3 ] = size; // Number of bytes to be compared; should be a multiple of 4.
okano 0:ada7fb504504 140
okano 0:ada7fb504504 141 iap_entry( IAP_command, IAP_result );
okano 0:ada7fb504504 142
okano 0:ada7fb504504 143 return ( (int)IAP_result[ 0 ] );
okano 0:ada7fb504504 144 }
okano 0:ada7fb504504 145
okano 2:17f3464672c1 146 int IAP::read_BootVer(void)
okano 2:17f3464672c1 147 {
okano 0:ada7fb504504 148 IAP_command[0] = IAPCommand_Read_Boot_Code_version;
okano 0:ada7fb504504 149 IAP_result[1] = 0; // not sure if in high or low bits.
okano 0:ada7fb504504 150 iap_entry(IAP_command, IAP_result);
okano 0:ada7fb504504 151 return ((int)IAP_result[1]);
okano 0:ada7fb504504 152 }
okano 0:ada7fb504504 153
okano 0:ada7fb504504 154 char * IAP::reserved_flash_area_start( void )
okano 0:ada7fb504504 155 {
okano 0:ada7fb504504 156 return ( (char *)USER_FLASH_AREA_START );
okano 0:ada7fb504504 157 }
okano 0:ada7fb504504 158
okano 0:ada7fb504504 159 int IAP::reserved_flash_area_size( void )
okano 0:ada7fb504504 160 {
okano 0:ada7fb504504 161 return ( USER_FLASH_AREA_SIZE );
okano 0:ada7fb504504 162 }
okano 0:ada7fb504504 163
okano 1:ff906ad52cf9 164 #if defined(TARGET_LPC11U24)
okano 2:17f3464672c1 165
okano 2:17f3464672c1 166 int IAP::write_eeprom( char *source_addr, char *target_addr, int size )
okano 2:17f3464672c1 167 {
okano 1:ff906ad52cf9 168 IAP_command[ 0 ] = IAPCommand_EEPROM_Write;
okano 1:ff906ad52cf9 169 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.
okano 1:ff906ad52cf9 170 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 1:ff906ad52cf9 171 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096.
okano 1:ff906ad52cf9 172 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz.
okano 2:17f3464672c1 173
okano 1:ff906ad52cf9 174 iap_entry( IAP_command, IAP_result );
okano 2:17f3464672c1 175
okano 1:ff906ad52cf9 176 return ( (int)IAP_result[ 0 ] );
okano 1:ff906ad52cf9 177 }
okano 2:17f3464672c1 178
okano 2:17f3464672c1 179 int IAP::read_eeprom( char *source_addr, char *target_addr, int size )
okano 2:17f3464672c1 180 {
okano 1:ff906ad52cf9 181 IAP_command[ 0 ] = IAPCommand_EEPROM_Read;
okano 1:ff906ad52cf9 182 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.
okano 1:ff906ad52cf9 183 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.
okano 1:ff906ad52cf9 184 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096.
okano 1:ff906ad52cf9 185 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz.
okano 2:17f3464672c1 186
okano 1:ff906ad52cf9 187 iap_entry( IAP_command, IAP_result );
okano 2:17f3464672c1 188
okano 1:ff906ad52cf9 189 return ( (int)IAP_result[ 0 ] );
okano 1:ff906ad52cf9 190 }
okano 2:17f3464672c1 191
okano 2:17f3464672c1 192 #elif defined(TARGET_LPC812) || defined(TARGET_LPC824)
okano 2:17f3464672c1 193
okano 2:17f3464672c1 194 int IAP::erase_page( int start, int end )
okano 2:17f3464672c1 195 {
okano 2:17f3464672c1 196 IAP_command[ 0 ] = IAPCommand_Erase_page;
okano 2:17f3464672c1 197 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number
okano 2:17f3464672c1 198 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number)
okano 2:17f3464672c1 199 IAP_command[ 3 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz
okano 2:17f3464672c1 200
okano 2:17f3464672c1 201 iap_entry( IAP_command, IAP_result );
okano 2:17f3464672c1 202
okano 2:17f3464672c1 203 return ( (int)IAP_result[ 0 ] );
okano 2:17f3464672c1 204 }
okano 2:17f3464672c1 205
okano 1:ff906ad52cf9 206 #endif