Rob Meades / IapSupport
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Iap.cpp Source File

Iap.cpp

00001 /** IAP provides support for read/write to FLASh on the LPC1768 platform.  The code here is taken from:
00002 *
00003 * http://developer.mbed.org/users/okano/code/IAP/
00004 * 
00005 * All rights remain with Tedd OKANO, etc.
00006 */
00007 
00008 /**    IAP : internal Flash memory access library
00009  *
00010  *        The internal Flash memory access is described in the LPC1768 and LPC11U24 usermanual.
00011  *            http://www.nxp.com/documents/user_manual/UM10360.pdf
00012  *            http://www.nxp.com/documents/user_manual/UM10462.pdf
00013  *
00014  *               LPC1768 --
00015  *                    Chapter  2: "LPC17xx Memory map"
00016  *                    Chapter 32: "LPC17xx Flash memory interface and programming"
00017  *                    refering Rev. 01 - 4 January 2010
00018  *
00019  *               LPC11U24 --
00020  *                    Chapter  2: "LPC11Uxx Memory mapping"
00021  *                    Chapter 20: "LPC11Uxx Flash programming firmware"
00022  *                    refering Rev. 03 - 16 July 2012
00023  *
00024  *        Released under the MIT License: http://mbed.org/license/mit
00025  *
00026  *        revision 1.0  09-Mar-2010   1st release
00027  *        revision 1.1  12-Mar-2010   chaged: to make possible to reserve flash area for user
00028  *                                            it can be set by USER_FLASH_AREA_START and USER_FLASH_AREA_SIZE in IAP.h
00029  *        revision 2.0  26-Nov-2012   LPC11U24 code added
00030  *        revision 2.1  26-Nov-2012   EEPROM access code imported from Suga koubou san's (http://mbed.org/users/okini3939/) library
00031  *                                            http://mbed.org/users/okini3939/code/M0_EEPROM_test/
00032  *        revision 3.0  09-Jan-2015   LPC812 and LPC824 support added
00033  *        revision 3.1  13-Jan-2015   LPC1114 support added
00034  *        revision 3.1.1 16-Jan-2015  Target MCU name changed for better compatibility across the platforms
00035  */
00036 
00037 #include    "mbed.h"
00038 #include    "IapApi.h"
00039 
00040 #define     USER_FLASH_AREA_START_STR( x )      STR( x )
00041 #define     STR( x )                            #x
00042 
00043 /*
00044  *  Reserve of flash area is explained by Igor. Please refer next URL
00045  *    http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/?page=1#comment-271
00046  */
00047 
00048 //unsigned char user_area[ size ] __attribute__((section(".ARM.__at_0x78000"), zero_init));
00049 
00050 /*
00051  *  IAP command codes
00052  *  Table 589. "IAP Command Summary", Chapter 8. "IAP commands", usermanual
00053  */
00054 
00055 enum command_code {
00056     IAPCommand_Prepare_sector_for_write_operation    = 50,
00057     IAPCommand_Copy_RAM_to_Flash,
00058     IAPCommand_Erase_sector,
00059     IAPCommand_Blank_check_sector,
00060     IAPCommand_Read_part_ID,
00061     IAPCommand_Read_Boot_Code_version,
00062     IAPCommand_Compare,
00063     IAPCommand_Reinvoke_ISP,
00064     IAPCommand_Read_device_serial_number,
00065 #if defined(TARGET_LPC11UXX)
00066     IAPCommand_EEPROM_Write = 61,
00067     IAPCommand_EEPROM_Read,
00068 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X)
00069     IAPCommand_Erase_page = 59,
00070 #endif
00071 };
00072 
00073 int IAP::read_ID( void )
00074 {
00075     IAP_command[ 0 ]    = IAPCommand_Read_part_ID;
00076 
00077     iap_entry( IAP_command, IAP_result );
00078 
00079     //  return ( (int)IAP_result[ 0 ] );
00080     return ( (int)IAP_result[ 1 ] );    //  to return the number itself (this command always returns CMD_SUCCESS)
00081 }
00082 
00083 int IAP::read_serial( void )
00084 {
00085     IAP_command[ 0 ]    = IAPCommand_Read_device_serial_number;
00086 
00087     iap_entry( IAP_command, IAP_result );
00088 
00089     //  return ( (int)IAP_result[ 0 ] );
00090     return ( (int)IAP_result[ 1 ] );    //  to return the number itself (this command always returns CMD_SUCCESS)
00091 }
00092 
00093 int IAP::blank_check( int start, int end )
00094 {
00095     IAP_command[ 0 ]    = IAPCommand_Blank_check_sector;
00096     IAP_command[ 1 ]    = (unsigned int)start;  //  Start Sector Number
00097     IAP_command[ 2 ]    = (unsigned int)end;    //  End Sector Number (should be greater than or equal to start sector number)
00098 
00099     iap_entry( IAP_command, IAP_result );
00100 
00101     return ( (int)IAP_result[ 0 ] );
00102 }
00103 
00104 int IAP::erase( int start, int end )
00105 {
00106     IAP_command[ 0 ]    = IAPCommand_Erase_sector;
00107     IAP_command[ 1 ]    = (unsigned int)start;  //  Start Sector Number
00108     IAP_command[ 2 ]    = (unsigned int)end;    //  End Sector Number (should be greater than or equal to start sector number)
00109     IAP_command[ 3 ]    = cclk_kHz;             //  CPU Clock Frequency (CCLK) in kHz
00110 
00111     iap_entry( IAP_command, IAP_result );
00112 
00113     return ( (int)IAP_result[ 0 ] );
00114 }
00115 
00116 int IAP::prepare( int start, int end )
00117 {
00118     IAP_command[ 0 ]    = IAPCommand_Prepare_sector_for_write_operation;
00119     IAP_command[ 1 ]    = (unsigned int)start;  //  Start Sector Number
00120     IAP_command[ 2 ]    = (unsigned int)end;    //  End Sector Number (should be greater than or equal to start sector number).
00121 
00122     iap_entry( IAP_command, IAP_result );
00123 
00124     return ( (int)IAP_result[ 0 ] );
00125 }
00126 
00127 int IAP::write( char *source_addr, char *target_addr, int size )
00128 {
00129     IAP_command[ 0 ]    = IAPCommand_Copy_RAM_to_Flash;
00130     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.
00131     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.
00132     IAP_command[ 3 ]    = size;                         //  Number of bytes to be written. Should be 256 | 512 | 1024 | 4096.
00133     IAP_command[ 4 ]    = cclk_kHz;                     //  CPU Clock Frequency (CCLK) in kHz.
00134 
00135     iap_entry( IAP_command, IAP_result );
00136 
00137     return ( (int)IAP_result[ 0 ] );
00138 }
00139 
00140 int IAP::compare( char *source_addr, char *target_addr, int size )
00141 {
00142     IAP_command[ 0 ]    = IAPCommand_Compare;
00143     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.
00144     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.
00145     IAP_command[ 3 ]    = size;                         //  Number of bytes to be compared; should be a multiple of 4.
00146 
00147     iap_entry( IAP_command, IAP_result );
00148 
00149     return ( (int)IAP_result[ 0 ] );
00150 }
00151 
00152 int IAP::read_BootVer(void)
00153 {
00154     IAP_command[0] = IAPCommand_Read_Boot_Code_version;
00155     IAP_result[1] = 0; // not sure if in high or low bits.
00156     iap_entry(IAP_command, IAP_result);
00157     return ((int)IAP_result[1]);
00158 }
00159 
00160 char * IAP::reserved_flash_area_start( void )
00161 {
00162     return ( (char *)USER_FLASH_AREA_START );
00163 }
00164 
00165 int IAP::reserved_flash_area_size( void )
00166 {
00167     return ( USER_FLASH_AREA_SIZE );
00168 }
00169 
00170 #if defined(TARGET_LPC11UXX)
00171 
00172 int IAP::write_eeprom( char *source_addr, char *target_addr, int size )
00173 {
00174     IAP_command[ 0 ]    = IAPCommand_EEPROM_Write;
00175     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.
00176     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.
00177     IAP_command[ 3 ]    = size;                         //  Number of bytes to be written. Should be 256 | 512 | 1024 | 4096.
00178     IAP_command[ 4 ]    = cclk_kHz;                     //  CPU Clock Frequency (CCLK) in kHz.
00179 
00180     iap_entry( IAP_command, IAP_result );
00181 
00182     return ( (int)IAP_result[ 0 ] );
00183 }
00184 
00185 int IAP::read_eeprom( char *source_addr, char *target_addr, int size )
00186 {
00187     IAP_command[ 0 ]    = IAPCommand_EEPROM_Read;
00188     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.
00189     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.
00190     IAP_command[ 3 ]    = size;                         //  Number of bytes to be written. Should be 256 | 512 | 1024 | 4096.
00191     IAP_command[ 4 ]    = cclk_kHz;                     //  CPU Clock Frequency (CCLK) in kHz.
00192 
00193     iap_entry( IAP_command, IAP_result );
00194 
00195     return ( (int)IAP_result[ 0 ] );
00196 }
00197 
00198 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X)
00199 
00200 int IAP::erase_page( int start, int end )
00201 {
00202     IAP_command[ 0 ]    = IAPCommand_Erase_page;
00203     IAP_command[ 1 ]    = (unsigned int)start;  //  Start Sector Number
00204     IAP_command[ 2 ]    = (unsigned int)end;    //  End Sector Number (should be greater than or equal to start sector number)
00205     IAP_command[ 3 ]    = cclk_kHz;             //  CPU Clock Frequency (CCLK) in kHz
00206 
00207     iap_entry( IAP_command, IAP_result );
00208 
00209     return ( (int)IAP_result[ 0 ] );
00210 }
00211 
00212 #endif