student project

Dependencies:   mbed

Fork of myiot by joseph chen

Committer:
William_HO
Date:
Thu Jun 23 05:17:36 2016 +0000
Revision:
5:f6a5fc6e1ddd
Added an IAP example to read device ID and serial number.; For feature implement.

Who changed what in which revision?

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