fork

Dependencies:   mbed

Fork of LG by igor Apu

Committer:
Kovalev_D
Date:
Tue Apr 12 13:50:34 2016 +0000
Revision:
130:1421dda4d7e7
iap

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Kovalev_D 130:1421dda4d7e7 1
Kovalev_D 130:1421dda4d7e7 2
Kovalev_D 130:1421dda4d7e7 3 #include "mbed.h"
Kovalev_D 130:1421dda4d7e7 4 #include "IAP.h"
Kovalev_D 130:1421dda4d7e7 5
Kovalev_D 130:1421dda4d7e7 6 #define USER_FLASH_AREA_START_STR( x ) STR( x )
Kovalev_D 130:1421dda4d7e7 7 #define STR( x ) #x
Kovalev_D 130:1421dda4d7e7 8
Kovalev_D 130:1421dda4d7e7 9 unsigned char user_area[ USER_FLASH_AREA_SIZE ] __attribute__((section( ".ARM.__at_" USER_FLASH_AREA_START_STR( USER_FLASH_AREA_START ) ), zero_init));
Kovalev_D 130:1421dda4d7e7 10
Kovalev_D 130:1421dda4d7e7 11 /*
Kovalev_D 130:1421dda4d7e7 12 * Reserve of flash area is explained by Igor. Please refer next URL
Kovalev_D 130:1421dda4d7e7 13 * http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/?page=1#comment-271
Kovalev_D 130:1421dda4d7e7 14 */
Kovalev_D 130:1421dda4d7e7 15
Kovalev_D 130:1421dda4d7e7 16 //unsigned char user_area[ size ] __attribute__((section(".ARM.__at_0x78000"), zero_init));
Kovalev_D 130:1421dda4d7e7 17
Kovalev_D 130:1421dda4d7e7 18 /*
Kovalev_D 130:1421dda4d7e7 19 * IAP command codes
Kovalev_D 130:1421dda4d7e7 20 * Table 589. "IAP Command Summary", Chapter 8. "IAP commands", usermanual
Kovalev_D 130:1421dda4d7e7 21 */
Kovalev_D 130:1421dda4d7e7 22
Kovalev_D 130:1421dda4d7e7 23 enum command_code {
Kovalev_D 130:1421dda4d7e7 24 IAPCommand_Prepare_sector_for_write_operation = 50,
Kovalev_D 130:1421dda4d7e7 25 IAPCommand_Copy_RAM_to_Flash,
Kovalev_D 130:1421dda4d7e7 26 IAPCommand_Erase_sector,
Kovalev_D 130:1421dda4d7e7 27 IAPCommand_Blank_check_sector,
Kovalev_D 130:1421dda4d7e7 28 IAPCommand_Read_part_ID,
Kovalev_D 130:1421dda4d7e7 29 IAPCommand_Read_Boot_Code_version,
Kovalev_D 130:1421dda4d7e7 30 IAPCommand_Compare,
Kovalev_D 130:1421dda4d7e7 31 IAPCommand_Reinvoke_ISP,
Kovalev_D 130:1421dda4d7e7 32 IAPCommand_Read_device_serial_number,
Kovalev_D 130:1421dda4d7e7 33 #if defined(TARGET_LPC11UXX)
Kovalev_D 130:1421dda4d7e7 34 IAPCommand_EEPROM_Write = 61,
Kovalev_D 130:1421dda4d7e7 35 IAPCommand_EEPROM_Read,
Kovalev_D 130:1421dda4d7e7 36 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X)
Kovalev_D 130:1421dda4d7e7 37 IAPCommand_Erase_page = 59,
Kovalev_D 130:1421dda4d7e7 38 #endif
Kovalev_D 130:1421dda4d7e7 39 };
Kovalev_D 130:1421dda4d7e7 40
Kovalev_D 130:1421dda4d7e7 41 int IAP::reinvoke_isp( void ) {
Kovalev_D 130:1421dda4d7e7 42 __disable_irq();
Kovalev_D 130:1421dda4d7e7 43
Kovalev_D 130:1421dda4d7e7 44 IAP_command[ 0 ] = IAPCommand_Reinvoke_ISP;
Kovalev_D 130:1421dda4d7e7 45
Kovalev_D 130:1421dda4d7e7 46 iap_entry( IAP_command, IAP_result );
Kovalev_D 130:1421dda4d7e7 47
Kovalev_D 130:1421dda4d7e7 48 return ( (int)IAP_result[ 0 ] );
Kovalev_D 130:1421dda4d7e7 49 }
Kovalev_D 130:1421dda4d7e7 50
Kovalev_D 130:1421dda4d7e7 51 /** Read part identification number
Kovalev_D 130:1421dda4d7e7 52 *
Kovalev_D 130:1421dda4d7e7 53 * @return device ID
Kovalev_D 130:1421dda4d7e7 54 * @see read_serial()
Kovalev_D 130:1421dda4d7e7 55 */
Kovalev_D 130:1421dda4d7e7 56 int IAP::read_ID( void )
Kovalev_D 130:1421dda4d7e7 57 {
Kovalev_D 130:1421dda4d7e7 58 IAP_command[ 0 ] = IAPCommand_Read_part_ID;
Kovalev_D 130:1421dda4d7e7 59
Kovalev_D 130:1421dda4d7e7 60 iap_entry( IAP_command, IAP_result );
Kovalev_D 130:1421dda4d7e7 61
Kovalev_D 130:1421dda4d7e7 62 // return ( (int)IAP_result[ 0 ] );
Kovalev_D 130:1421dda4d7e7 63 return ( (int)IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS)
Kovalev_D 130:1421dda4d7e7 64 }
Kovalev_D 130:1421dda4d7e7 65
Kovalev_D 130:1421dda4d7e7 66 int *IAP::read_serial( void ) {
Kovalev_D 130:1421dda4d7e7 67 IAP_command[ 0 ] = IAPCommand_Read_device_serial_number;
Kovalev_D 130:1421dda4d7e7 68
Kovalev_D 130:1421dda4d7e7 69 iap_entry( IAP_command, IAP_result );
Kovalev_D 130:1421dda4d7e7 70
Kovalev_D 130:1421dda4d7e7 71 // return ( (int)IAP_result[ 0 ] );
Kovalev_D 130:1421dda4d7e7 72 return ( (int *)&IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS)
Kovalev_D 130:1421dda4d7e7 73 }
Kovalev_D 130:1421dda4d7e7 74
Kovalev_D 130:1421dda4d7e7 75 int IAP::blank_check( int start, int end )
Kovalev_D 130:1421dda4d7e7 76 {
Kovalev_D 130:1421dda4d7e7 77 IAP_command[ 0 ] = IAPCommand_Blank_check_sector;
Kovalev_D 130:1421dda4d7e7 78 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number
Kovalev_D 130:1421dda4d7e7 79 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number)
Kovalev_D 130:1421dda4d7e7 80
Kovalev_D 130:1421dda4d7e7 81 iap_entry( IAP_command, IAP_result );
Kovalev_D 130:1421dda4d7e7 82
Kovalev_D 130:1421dda4d7e7 83 return ( (int)IAP_result[ 0 ] );
Kovalev_D 130:1421dda4d7e7 84 }
Kovalev_D 130:1421dda4d7e7 85
Kovalev_D 130:1421dda4d7e7 86 int IAP::erase( int start, int end )
Kovalev_D 130:1421dda4d7e7 87 {
Kovalev_D 130:1421dda4d7e7 88 IAP_command[ 0 ] = IAPCommand_Erase_sector;
Kovalev_D 130:1421dda4d7e7 89 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number
Kovalev_D 130:1421dda4d7e7 90 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number)
Kovalev_D 130:1421dda4d7e7 91 IAP_command[ 3 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz
Kovalev_D 130:1421dda4d7e7 92
Kovalev_D 130:1421dda4d7e7 93 iap_entry( IAP_command, IAP_result );
Kovalev_D 130:1421dda4d7e7 94
Kovalev_D 130:1421dda4d7e7 95 return ( (int)IAP_result[ 0 ] );
Kovalev_D 130:1421dda4d7e7 96 }
Kovalev_D 130:1421dda4d7e7 97
Kovalev_D 130:1421dda4d7e7 98 int IAP::prepare( int start, int end )
Kovalev_D 130:1421dda4d7e7 99 {
Kovalev_D 130:1421dda4d7e7 100 IAP_command[ 0 ] = IAPCommand_Prepare_sector_for_write_operation;
Kovalev_D 130:1421dda4d7e7 101 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number
Kovalev_D 130:1421dda4d7e7 102 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number).
Kovalev_D 130:1421dda4d7e7 103
Kovalev_D 130:1421dda4d7e7 104 iap_entry( IAP_command, IAP_result );
Kovalev_D 130:1421dda4d7e7 105
Kovalev_D 130:1421dda4d7e7 106 return ( (int)IAP_result[ 0 ] );
Kovalev_D 130:1421dda4d7e7 107 }
Kovalev_D 130:1421dda4d7e7 108
Kovalev_D 130:1421dda4d7e7 109 int IAP::write( char *source_addr, char *target_addr, int size )
Kovalev_D 130:1421dda4d7e7 110 {
Kovalev_D 130:1421dda4d7e7 111 IAP_command[ 0 ] = IAPCommand_Copy_RAM_to_Flash;
Kovalev_D 130:1421dda4d7e7 112 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.
Kovalev_D 130:1421dda4d7e7 113 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.
Kovalev_D 130:1421dda4d7e7 114 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096.
Kovalev_D 130:1421dda4d7e7 115 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz.
Kovalev_D 130:1421dda4d7e7 116
Kovalev_D 130:1421dda4d7e7 117 iap_entry( IAP_command, IAP_result );
Kovalev_D 130:1421dda4d7e7 118
Kovalev_D 130:1421dda4d7e7 119 return ( (int)IAP_result[ 0 ] );
Kovalev_D 130:1421dda4d7e7 120 }
Kovalev_D 130:1421dda4d7e7 121
Kovalev_D 130:1421dda4d7e7 122 int IAP::compare( char *source_addr, char *target_addr, int size )
Kovalev_D 130:1421dda4d7e7 123 {
Kovalev_D 130:1421dda4d7e7 124 IAP_command[ 0 ] = IAPCommand_Compare;
Kovalev_D 130:1421dda4d7e7 125 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.
Kovalev_D 130:1421dda4d7e7 126 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.
Kovalev_D 130:1421dda4d7e7 127 IAP_command[ 3 ] = size; // Number of bytes to be compared; should be a multiple of 4.
Kovalev_D 130:1421dda4d7e7 128
Kovalev_D 130:1421dda4d7e7 129 iap_entry( IAP_command, IAP_result );
Kovalev_D 130:1421dda4d7e7 130
Kovalev_D 130:1421dda4d7e7 131 return ( (int)IAP_result[ 0 ] );
Kovalev_D 130:1421dda4d7e7 132 }
Kovalev_D 130:1421dda4d7e7 133
Kovalev_D 130:1421dda4d7e7 134 int IAP::read_BootVer(void)
Kovalev_D 130:1421dda4d7e7 135 {
Kovalev_D 130:1421dda4d7e7 136 IAP_command[0] = IAPCommand_Read_Boot_Code_version;
Kovalev_D 130:1421dda4d7e7 137 IAP_result[1] = 0; // not sure if in high or low bits.
Kovalev_D 130:1421dda4d7e7 138 iap_entry(IAP_command, IAP_result);
Kovalev_D 130:1421dda4d7e7 139 return ((int)IAP_result[1]);
Kovalev_D 130:1421dda4d7e7 140 }
Kovalev_D 130:1421dda4d7e7 141
Kovalev_D 130:1421dda4d7e7 142 char * IAP::reserved_flash_area_start( void )
Kovalev_D 130:1421dda4d7e7 143 {
Kovalev_D 130:1421dda4d7e7 144 return ( (char *)USER_FLASH_AREA_START );
Kovalev_D 130:1421dda4d7e7 145 }
Kovalev_D 130:1421dda4d7e7 146
Kovalev_D 130:1421dda4d7e7 147 int IAP::reserved_flash_area_size( void )
Kovalev_D 130:1421dda4d7e7 148 {
Kovalev_D 130:1421dda4d7e7 149 return ( USER_FLASH_AREA_SIZE );
Kovalev_D 130:1421dda4d7e7 150 }
Kovalev_D 130:1421dda4d7e7 151
Kovalev_D 130:1421dda4d7e7 152 #if defined(TARGET_LPC11UXX)
Kovalev_D 130:1421dda4d7e7 153
Kovalev_D 130:1421dda4d7e7 154 int IAP::write_eeprom( char *source_addr, char *target_addr, int size )
Kovalev_D 130:1421dda4d7e7 155 {
Kovalev_D 130:1421dda4d7e7 156 IAP_command[ 0 ] = IAPCommand_EEPROM_Write;
Kovalev_D 130:1421dda4d7e7 157 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.
Kovalev_D 130:1421dda4d7e7 158 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.
Kovalev_D 130:1421dda4d7e7 159 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096.
Kovalev_D 130:1421dda4d7e7 160 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz.
Kovalev_D 130:1421dda4d7e7 161
Kovalev_D 130:1421dda4d7e7 162 iap_entry( IAP_command, IAP_result );
Kovalev_D 130:1421dda4d7e7 163
Kovalev_D 130:1421dda4d7e7 164 return ( (int)IAP_result[ 0 ] );
Kovalev_D 130:1421dda4d7e7 165 }
Kovalev_D 130:1421dda4d7e7 166
Kovalev_D 130:1421dda4d7e7 167 int IAP::read_eeprom( char *source_addr, char *target_addr, int size )
Kovalev_D 130:1421dda4d7e7 168 {
Kovalev_D 130:1421dda4d7e7 169 IAP_command[ 0 ] = IAPCommand_EEPROM_Read;
Kovalev_D 130:1421dda4d7e7 170 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.
Kovalev_D 130:1421dda4d7e7 171 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.
Kovalev_D 130:1421dda4d7e7 172 IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096.
Kovalev_D 130:1421dda4d7e7 173 IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz.
Kovalev_D 130:1421dda4d7e7 174
Kovalev_D 130:1421dda4d7e7 175 iap_entry( IAP_command, IAP_result );
Kovalev_D 130:1421dda4d7e7 176
Kovalev_D 130:1421dda4d7e7 177 return ( (int)IAP_result[ 0 ] );
Kovalev_D 130:1421dda4d7e7 178 }
Kovalev_D 130:1421dda4d7e7 179
Kovalev_D 130:1421dda4d7e7 180 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X)
Kovalev_D 130:1421dda4d7e7 181
Kovalev_D 130:1421dda4d7e7 182 int IAP::erase_page( int start, int end )
Kovalev_D 130:1421dda4d7e7 183 {
Kovalev_D 130:1421dda4d7e7 184 IAP_command[ 0 ] = IAPCommand_Erase_page;
Kovalev_D 130:1421dda4d7e7 185 IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number
Kovalev_D 130:1421dda4d7e7 186 IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number)
Kovalev_D 130:1421dda4d7e7 187 IAP_command[ 3 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz
Kovalev_D 130:1421dda4d7e7 188
Kovalev_D 130:1421dda4d7e7 189 iap_entry( IAP_command, IAP_result );
Kovalev_D 130:1421dda4d7e7 190
Kovalev_D 130:1421dda4d7e7 191 return ( (int)IAP_result[ 0 ] );
Kovalev_D 130:1421dda4d7e7 192 }
Kovalev_D 130:1421dda4d7e7 193
Kovalev_D 130:1421dda4d7e7 194 #endif