![](/media/cache/profiles/795c7a7a5ec6b460ec00c5841019b9e9.jpg.50x50_q85.jpg)
Sample code for how to erase/write LPC1768, LPC11U24, LPC1114, LPC812 and LPC824 internal flash memory. This program uses IAP call of MCU's ROM routines. The IAP library also supports read/write of EEPROM in LPC11U24.
Sample code for how to erase/write LPC1768, LPC11U24, LPC1114, LPC812 and LPC824 internal flash memory. This program uses IAP call of MCU's ROM routines.
No filesystem interface available. This program is just an interface to flash erasing and writing. User need manage where to store the data in the flash area.
This IAP library supports read/write of EEPROM in LPC11U24.
More information available in
http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/
main.cpp@9:382f38b15c22, 2018-08-16 (annotated)
- Committer:
- okano
- Date:
- Thu Aug 16 06:28:27 2018 +0000
- Revision:
- 9:382f38b15c22
- Parent:
- 8:7d4d4edcb133
to include latest library
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
okano | 0:b802bd2f4cc9 | 1 | /** IAP demo : demo code for internal Flash memory access library |
okano | 0:b802bd2f4cc9 | 2 | * |
okano | 3:63a0993315e5 | 3 | * The internal Flash memory access is described in the LPC1768 and LPC11U24 usermanual. |
okano | 0:b802bd2f4cc9 | 4 | * http://www.nxp.com/documents/user_manual/UM10360.pdf |
okano | 1:a85b51eeb446 | 5 | * http://www.nxp.com/documents/user_manual/UM10462.pdf |
okano | 0:b802bd2f4cc9 | 6 | * |
okano | 1:a85b51eeb446 | 7 | * LPC1768 -- |
okano | 1:a85b51eeb446 | 8 | * Chapter 2: "LPC17xx Memory map" |
okano | 1:a85b51eeb446 | 9 | * Chapter 32: "LPC17xx Flash memory interface and programming" |
okano | 1:a85b51eeb446 | 10 | * refering Rev. 01 - 4 January 2010 |
okano | 3:63a0993315e5 | 11 | * |
okano | 1:a85b51eeb446 | 12 | * LPC11U24 -- |
okano | 1:a85b51eeb446 | 13 | * Chapter 2: "LPC11Uxx Memory mapping" |
okano | 1:a85b51eeb446 | 14 | * Chapter 20: "LPC11Uxx Flash programming firmware" |
okano | 1:a85b51eeb446 | 15 | * refering Rev. 03 - 16 July 2012 |
okano | 3:63a0993315e5 | 16 | * |
okano | 0:b802bd2f4cc9 | 17 | * This main.cpp demonstrates how the flash can be erased and wrote. |
okano | 0:b802bd2f4cc9 | 18 | * |
okano | 0:b802bd2f4cc9 | 19 | * This program tries to... |
okano | 0:b802bd2f4cc9 | 20 | * 0. read device ID and serial# |
okano | 0:b802bd2f4cc9 | 21 | * 1. check if the targat sector blank |
okano | 0:b802bd2f4cc9 | 22 | * 2. erase the sector if it was not blank |
okano | 0:b802bd2f4cc9 | 23 | * 3. write into the flash (prepare before write) |
okano | 0:b802bd2f4cc9 | 24 | * 4. verify the data by IAP command |
okano | 0:b802bd2f4cc9 | 25 | * 5. show the content of the flash |
okano | 0:b802bd2f4cc9 | 26 | * |
okano | 3:63a0993315e5 | 27 | * The Flash must be erased as sectors. No overwrite can be done like SRAM. |
okano | 3:63a0993315e5 | 28 | * So erase should be done in size of 4K or 32K. |
okano | 0:b802bd2f4cc9 | 29 | * |
okano | 3:63a0993315e5 | 30 | * Writing sector can be done with size of 256, 512, 1024 or 4096. |
okano | 3:63a0993315e5 | 31 | * If other size is used, the IAP returns an error. |
okano | 3:63a0993315e5 | 32 | * The SRAM memory should be allocated in |
okano | 0:b802bd2f4cc9 | 33 | * |
okano | 0:b802bd2f4cc9 | 34 | * |
okano | 1:a85b51eeb446 | 35 | * Released under the MIT License: http://mbed.org/license/mit |
okano | 0:b802bd2f4cc9 | 36 | * |
okano | 0:b802bd2f4cc9 | 37 | * revision 1.0 09-Mar-2010 1st release |
okano | 0:b802bd2f4cc9 | 38 | * revision 1.1 12-Mar-2010 chaged: to make possible to reserve flash area for user |
okano | 0:b802bd2f4cc9 | 39 | * it can be set by USER_FLASH_AREA_START and USER_FLASH_AREA_SIZE in IAP.h |
okano | 1:a85b51eeb446 | 40 | * revision 2.0 26-Nov.2012 LPC11U24 code added |
okano | 2:c22f0c87fee6 | 41 | * revision 2.1 26-Nov-2012 EEPROM access code imported from Suga koubou san's (http://mbed.org/users/okini3939/) library |
okano | 2:c22f0c87fee6 | 42 | * http://mbed.org/users/okini3939/code/M0_EEPROM_test/ |
okano | 5:806960ca964e | 43 | * revision 3.0 09-Jan-2015 LPC812 and LPC824 support added |
okano | 5:806960ca964e | 44 | * revision 3.1 13-Jan-2015 LPC1114 support added |
okano | 5:806960ca964e | 45 | * revision 3.1.1 16-Jan-2015 Target MCU name changed for better compatibility across the platforms |
okano | 6:2357a04a16ff | 46 | * revision 3.1.2 10-Mar-2015 merged with pull requests. reinvoke_isp() added and modified read_serial() to return a pointer. |
okano | 7:e140563d4aad | 47 | * revision 3.1.2.1 15-Aug-2018 added: just minor feature in "memdump()" function |
okano | 8:7d4d4edcb133 | 48 | * revision 3.1.3 16-Aug-2018 "write page" function demo for LPC81X/LPC82X |
okano | 0:b802bd2f4cc9 | 49 | */ |
okano | 0:b802bd2f4cc9 | 50 | |
okano | 0:b802bd2f4cc9 | 51 | #include "mbed.h" |
okano | 0:b802bd2f4cc9 | 52 | #include "IAP.h" |
okano | 0:b802bd2f4cc9 | 53 | |
okano | 0:b802bd2f4cc9 | 54 | #define MEM_SIZE 256 |
okano | 1:a85b51eeb446 | 55 | |
okano | 5:806960ca964e | 56 | #if defined(TARGET_LPC176X) |
okano | 1:a85b51eeb446 | 57 | #define TARGET_SECTOR 29 // use sector 29 as target sector if it is on LPC1768 |
okano | 5:806960ca964e | 58 | #elif defined(TARGET_LPC11UXX) || defined(TARGET_LPC11XX) |
okano | 1:a85b51eeb446 | 59 | #define TARGET_SECTOR 7 // use sector 7 as target sector if it is on LPC11U24 |
okano | 2:c22f0c87fee6 | 60 | #define TARGET_EEPROM_ADDRESS 64 |
okano | 3:63a0993315e5 | 61 | #define TARGET_EEPROM_ADDRESS 64 |
okano | 5:806960ca964e | 62 | #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X) |
okano | 3:63a0993315e5 | 63 | #define TARGET_SECTOR 15 // use sector 15 as target sector if it is on LPC812 |
okano | 1:a85b51eeb446 | 64 | #endif |
okano | 0:b802bd2f4cc9 | 65 | |
okano | 0:b802bd2f4cc9 | 66 | void memdump( char *p, int n ); |
okano | 8:7d4d4edcb133 | 67 | int write_page( char *src, int target_page ); |
okano | 0:b802bd2f4cc9 | 68 | |
okano | 0:b802bd2f4cc9 | 69 | IAP iap; |
okano | 0:b802bd2f4cc9 | 70 | |
okano | 0:b802bd2f4cc9 | 71 | |
okano | 3:63a0993315e5 | 72 | int main() |
okano | 3:63a0993315e5 | 73 | { |
okano | 0:b802bd2f4cc9 | 74 | char mem[ MEM_SIZE ]; // memory, it should be aligned to word boundary |
okano | 6:2357a04a16ff | 75 | int *serial_number; |
okano | 0:b802bd2f4cc9 | 76 | int r; |
okano | 0:b802bd2f4cc9 | 77 | |
okano | 3:63a0993315e5 | 78 | printf( "\r\n\r\n=== IAP: Flash memory writing test ===\r\n" ); |
okano | 6:2357a04a16ff | 79 | printf( " device-ID = 0x%08X\r\n", iap.read_ID() ); |
okano | 6:2357a04a16ff | 80 | |
okano | 6:2357a04a16ff | 81 | serial_number = iap.read_serial(); |
okano | 6:2357a04a16ff | 82 | |
okano | 6:2357a04a16ff | 83 | printf( " serial# =" ); |
okano | 6:2357a04a16ff | 84 | for ( int i = 0; i < 4; i++ ) |
okano | 6:2357a04a16ff | 85 | printf( " %08X", *(serial_number + i) ); |
okano | 6:2357a04a16ff | 86 | printf( "\r\n" ); |
okano | 6:2357a04a16ff | 87 | |
okano | 6:2357a04a16ff | 88 | printf( " CPU running %dkHz\r\n", SystemCoreClock / 1000 ); |
okano | 1:a85b51eeb446 | 89 | printf( " user reserved flash area: start_address=0x%08X, size=%d bytes\r\n", iap.reserved_flash_area_start(), iap.reserved_flash_area_size() ); |
okano | 1:a85b51eeb446 | 90 | printf( " read_BootVer=0x%08X\r\r\n", iap.read_BootVer() ); |
okano | 0:b802bd2f4cc9 | 91 | |
okano | 0:b802bd2f4cc9 | 92 | for ( int i = 0; i < MEM_SIZE; i++ ) |
okano | 0:b802bd2f4cc9 | 93 | mem[ i ] = i & 0xFF; |
okano | 0:b802bd2f4cc9 | 94 | |
okano | 0:b802bd2f4cc9 | 95 | // blank check: The mbed will erase all flash contents after downloading new executable |
okano | 0:b802bd2f4cc9 | 96 | |
okano | 0:b802bd2f4cc9 | 97 | r = iap.blank_check( TARGET_SECTOR, TARGET_SECTOR ); |
okano | 1:a85b51eeb446 | 98 | printf( "blank check result = 0x%08X\r\n", r ); |
okano | 0:b802bd2f4cc9 | 99 | |
okano | 0:b802bd2f4cc9 | 100 | // erase sector, if required |
okano | 3:63a0993315e5 | 101 | |
okano | 0:b802bd2f4cc9 | 102 | if ( r == SECTOR_NOT_BLANK ) { |
okano | 0:b802bd2f4cc9 | 103 | iap.prepare( TARGET_SECTOR, TARGET_SECTOR ); |
okano | 0:b802bd2f4cc9 | 104 | r = iap.erase( TARGET_SECTOR, TARGET_SECTOR ); |
okano | 1:a85b51eeb446 | 105 | printf( "erase result = 0x%08X\r\n", r ); |
okano | 0:b802bd2f4cc9 | 106 | } |
okano | 3:63a0993315e5 | 107 | |
okano | 0:b802bd2f4cc9 | 108 | // copy RAM to Flash |
okano | 0:b802bd2f4cc9 | 109 | |
okano | 0:b802bd2f4cc9 | 110 | iap.prepare( TARGET_SECTOR, TARGET_SECTOR ); |
okano | 0:b802bd2f4cc9 | 111 | r = iap.write( mem, sector_start_adress[ TARGET_SECTOR ], MEM_SIZE ); |
okano | 1:a85b51eeb446 | 112 | printf( "copied: SRAM(0x%08X)->Flash(0x%08X) for %d bytes. (result=0x%08X)\r\n", mem, sector_start_adress[ TARGET_SECTOR ], MEM_SIZE, r ); |
okano | 0:b802bd2f4cc9 | 113 | |
okano | 0:b802bd2f4cc9 | 114 | // compare |
okano | 0:b802bd2f4cc9 | 115 | |
okano | 0:b802bd2f4cc9 | 116 | r = iap.compare( mem, sector_start_adress[ TARGET_SECTOR ], MEM_SIZE ); |
okano | 1:a85b51eeb446 | 117 | printf( "compare result = \"%s\"\r\n", r ? "FAILED" : "OK" ); |
okano | 0:b802bd2f4cc9 | 118 | |
okano | 0:b802bd2f4cc9 | 119 | //#define WRITE_NEXT_BLOCK |
okano | 0:b802bd2f4cc9 | 120 | #ifdef WRITE_NEXT_BLOCK |
okano | 0:b802bd2f4cc9 | 121 | |
okano | 0:b802bd2f4cc9 | 122 | // copy RAM to Flash |
okano | 0:b802bd2f4cc9 | 123 | |
okano | 0:b802bd2f4cc9 | 124 | iap.prepare( TARGET_SECTOR, TARGET_SECTOR ); |
okano | 0:b802bd2f4cc9 | 125 | r = iap.write( mem, sector_start_adress[ TARGET_SECTOR ] + 256, MEM_SIZE ); |
okano | 1:a85b51eeb446 | 126 | printf( "copied: SRAM(0x%08X)->Flash(0x%08X) for %d bytes. (result=0x%08X)\r\n", mem, sector_start_adress[ TARGET_SECTOR ], MEM_SIZE, r ); |
okano | 0:b802bd2f4cc9 | 127 | |
okano | 0:b802bd2f4cc9 | 128 | // compare |
okano | 0:b802bd2f4cc9 | 129 | |
okano | 0:b802bd2f4cc9 | 130 | r = iap.compare( mem, sector_start_adress[ TARGET_SECTOR ] + 256, MEM_SIZE ); |
okano | 1:a85b51eeb446 | 131 | printf( "compare result = \"%s\"\r\n", r ? "FAILED" : "OK" ); |
okano | 0:b802bd2f4cc9 | 132 | |
okano | 0:b802bd2f4cc9 | 133 | #endif |
okano | 0:b802bd2f4cc9 | 134 | |
okano | 1:a85b51eeb446 | 135 | printf( "showing the flash contents...\r\n" ); |
okano | 0:b802bd2f4cc9 | 136 | memdump( sector_start_adress[ TARGET_SECTOR ], MEM_SIZE * 3 ); |
okano | 3:63a0993315e5 | 137 | |
okano | 3:63a0993315e5 | 138 | |
okano | 5:806960ca964e | 139 | #if defined(TARGET_LPC81X) || defined(TARGET_LPC82X) |
okano | 3:63a0993315e5 | 140 | iap.prepare( TARGET_SECTOR, TARGET_SECTOR ); |
okano | 3:63a0993315e5 | 141 | r = iap.erase_page( 241, 241 ); // 241 is page number for sector 7 with 64 byte offset |
okano | 3:63a0993315e5 | 142 | |
okano | 3:63a0993315e5 | 143 | printf( "\r\nerase page test\r\n" ); |
okano | 3:63a0993315e5 | 144 | printf( "erase page result = \"%s\"\r\n", r ? "FAILED" : "OK" ); |
okano | 8:7d4d4edcb133 | 145 | printf( "showing memory dump to confirm 0x00003C40 to 0x00003C7F are erased\r\n(should be changed to 0xFF)\r\n" ); |
okano | 3:63a0993315e5 | 146 | |
okano | 3:63a0993315e5 | 147 | memdump( sector_start_adress[ TARGET_SECTOR ], MEM_SIZE ); |
okano | 8:7d4d4edcb133 | 148 | |
okano | 8:7d4d4edcb133 | 149 | |
okano | 8:7d4d4edcb133 | 150 | char test_data[ 64 ]; |
okano | 8:7d4d4edcb133 | 151 | |
okano | 8:7d4d4edcb133 | 152 | for ( int i = 0; i < 64; i++ ) |
okano | 8:7d4d4edcb133 | 153 | test_data[ i ] = 0xAA; |
okano | 8:7d4d4edcb133 | 154 | |
okano | 8:7d4d4edcb133 | 155 | r = iap.write_page( test_data, 241 ); // 241 is page number for sector 7 with 64 byte offset |
okano | 8:7d4d4edcb133 | 156 | |
okano | 8:7d4d4edcb133 | 157 | printf( "\r\nwrite page test\r\n" ); |
okano | 8:7d4d4edcb133 | 158 | printf( "write page result = \"%s\"\r\n", r ? "FAILED" : "OK" ); |
okano | 8:7d4d4edcb133 | 159 | printf( "showing memory dump to confirm 0x00003C40 to 0x00003C7F are written\r\n(should be changed to 0xAA)\r\n" ); |
okano | 8:7d4d4edcb133 | 160 | |
okano | 8:7d4d4edcb133 | 161 | memdump( sector_start_adress[ TARGET_SECTOR ], MEM_SIZE ); |
okano | 8:7d4d4edcb133 | 162 | |
okano | 3:63a0993315e5 | 163 | #endif |
okano | 3:63a0993315e5 | 164 | |
okano | 3:63a0993315e5 | 165 | |
okano | 5:806960ca964e | 166 | #if defined(TARGET_LPC11UXX) // SAMPLE OF EEPROM ACCESS (LPC11U24 only) |
okano | 2:c22f0c87fee6 | 167 | printf( "IAP: EEPROM writing test\r\n" ); |
okano | 2:c22f0c87fee6 | 168 | char mem2[ MEM_SIZE ]; |
okano | 2:c22f0c87fee6 | 169 | |
okano | 2:c22f0c87fee6 | 170 | r = iap.write_eeprom( mem, (char*)TARGET_EEPROM_ADDRESS, MEM_SIZE ); |
okano | 2:c22f0c87fee6 | 171 | printf( "copied: SRAM(0x%08X)->EEPROM(0x%08X) for %d bytes. (result=0x%08X)\r\n", mem, TARGET_EEPROM_ADDRESS, MEM_SIZE, r ); |
okano | 3:63a0993315e5 | 172 | |
okano | 2:c22f0c87fee6 | 173 | r = iap.read_eeprom( (char*)TARGET_EEPROM_ADDRESS, mem2, MEM_SIZE ); |
okano | 2:c22f0c87fee6 | 174 | printf( "copied: EEPROM(0x%08X)->SRAM(0x%08X) for %d bytes. (result=0x%08X)\r\n", TARGET_EEPROM_ADDRESS, mem, MEM_SIZE, r ); |
okano | 3:63a0993315e5 | 175 | |
okano | 2:c22f0c87fee6 | 176 | // compare |
okano | 2:c22f0c87fee6 | 177 | r = memcmp(mem, mem2, MEM_SIZE); |
okano | 2:c22f0c87fee6 | 178 | printf( "compare result = \"%s\"\r\n", r ? "FAILED" : "OK" ); |
okano | 3:63a0993315e5 | 179 | |
okano | 2:c22f0c87fee6 | 180 | printf( "showing the EEPROM contents...\r\n" ); |
okano | 2:c22f0c87fee6 | 181 | memdump( mem2, MEM_SIZE ); |
okano | 2:c22f0c87fee6 | 182 | #endif |
okano | 2:c22f0c87fee6 | 183 | |
okano | 8:7d4d4edcb133 | 184 | printf( "Done! (=== IAP: Flash memory writing test ===)\r\n\r\n" ); |
okano | 0:b802bd2f4cc9 | 185 | } |
okano | 0:b802bd2f4cc9 | 186 | |
okano | 7:e140563d4aad | 187 | #include <ctype.h> |
okano | 7:e140563d4aad | 188 | |
okano | 3:63a0993315e5 | 189 | void memdump( char *base, int n ) |
okano | 3:63a0993315e5 | 190 | { |
okano | 0:b802bd2f4cc9 | 191 | unsigned int *p; |
okano | 7:e140563d4aad | 192 | char s[17] = { '\x0' }; |
okano | 0:b802bd2f4cc9 | 193 | |
okano | 0:b802bd2f4cc9 | 194 | printf( " memdump from 0x%08X for %d bytes", (unsigned long)base, n ); |
okano | 0:b802bd2f4cc9 | 195 | |
okano | 0:b802bd2f4cc9 | 196 | p = (unsigned int *)((unsigned int)base & ~(unsigned int)0x3); |
okano | 0:b802bd2f4cc9 | 197 | |
okano | 0:b802bd2f4cc9 | 198 | for ( int i = 0; i < (n >> 2); i++, p++ ) { |
okano | 7:e140563d4aad | 199 | if ( !(i % 4) ) { |
okano | 7:e140563d4aad | 200 | printf( " : %s\r\n 0x%08X :", s, (unsigned int)p ); |
okano | 0:b802bd2f4cc9 | 201 | |
okano | 7:e140563d4aad | 202 | for ( int j = 0; j < 16; j++) |
okano | 7:e140563d4aad | 203 | s[ j ] = isgraph( (int)(*((char *)p + j)) ) ? (*((char *)p + j)) : ' '; |
okano | 7:e140563d4aad | 204 | } |
okano | 0:b802bd2f4cc9 | 205 | printf( " 0x%08X", *p ); |
okano | 0:b802bd2f4cc9 | 206 | } |
okano | 7:e140563d4aad | 207 | printf( " : %s\r\n", s ); |
okano | 0:b802bd2f4cc9 | 208 | } |