Ika Shouyu Poppoyaki - LPC82x supported

Dependencies:   MODSERIAL mbed

Fork of ika_shouyu_poppoyaki by Tedd OKANO

Committer:
okano
Date:
Thu Sep 12 19:51:33 2013 +0000
Revision:
19:7a7381e78025
Parent:
18:b401da200216
Child:
20:98d7b5878e3e
verification function is available for "BINARY transfer" device (LPC810)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okano 11:8dfc3217d1ca 1 /**
okano 11:8dfc3217d1ca 2 * Sample of ISP operation for NXP MCUs
okano 11:8dfc3217d1ca 3 *
okano 14:a7b9f74fb856 4 * @author Tedd OKANO
okano 19:7a7381e78025 5 * @version 0.8
okano 18:b401da200216 6 * @date Sep-2013
okano 14:a7b9f74fb856 7 *
okano 14:a7b9f74fb856 8 * This program programs MCU flash memory through UART. It uses
okano 14:a7b9f74fb856 9 * "In-System Programming (ISP)" interface in target MCU (NXP LPC micro-
okano 14:a7b9f74fb856 10 * controllers).
okano 14:a7b9f74fb856 11 *
okano 14:a7b9f74fb856 12 * The ISP is done by PC and serial cable normally. The ISP protocol is
okano 14:a7b9f74fb856 13 * executed software on a PC. The software reads a data file and transfers
okano 14:a7b9f74fb856 14 * the data with the ISP protocol.
okano 14:a7b9f74fb856 15 * This program does same process of that. The mbed perform the function like
okano 14:a7b9f74fb856 16 * "FlashMagic" and "lpc21isp".
okano 14:a7b9f74fb856 17 * (This program not just copies the binary but also insert 4 byte checksum at
okano 14:a7b9f74fb856 18 * address 0x1C.)
okano 14:a7b9f74fb856 19 *
okano 14:a7b9f74fb856 20 * This program currently supports LPC1114(LPC1114FN28/102 - DIP28-ARM) and
okano 14:a7b9f74fb856 21 * LPC810(LPC810M021FN8 - DIP8-ARM).
okano 11:8dfc3217d1ca 22 */
okano 11:8dfc3217d1ca 23
okano 5:ff30f5b58617 24 #include "mbed.h"
okano 5:ff30f5b58617 25 #include "target_table.h"
okano 0:6baefda2e511 26
okano 2:8d75eb0ecd20 27 BusOut leds( LED4, LED3, LED2, LED1 );
okano 2:8d75eb0ecd20 28 DigitalOut reset_pin( p26 );
okano 2:8d75eb0ecd20 29 DigitalOut isp_pin( p25 );
okano 16:cac2348cfcfb 30 Serial pc ( USBTX,USBRX );
okano 2:8d75eb0ecd20 31 LocalFileSystem local( "local" );
okano 16:cac2348cfcfb 32 Ticker success;
okano 0:6baefda2e511 33
okano 19:7a7381e78025 34
okano 19:7a7381e78025 35 #if 0
okano 19:7a7381e78025 36 Serial target( p28, p27 );
okano 19:7a7381e78025 37 #else
okano 19:7a7381e78025 38 #define MODSERIAL_DEFAULT_RX_BUFFER_SIZE 512
okano 19:7a7381e78025 39 #define MODSERIAL_DEFAULT_TX_BUFFER_SIZE 512
okano 19:7a7381e78025 40 #include "MODSERIAL.h"
okano 19:7a7381e78025 41 MODSERIAL target( p28, p27 ); //
okano 19:7a7381e78025 42 #endif
okano 19:7a7381e78025 43
okano 19:7a7381e78025 44
okano 19:7a7381e78025 45
okano 12:5a33b5d39792 46 #define ENTER_TO_ISP_MODE 0
okano 12:5a33b5d39792 47 #define NO_ISP_MODE 1
okano 12:5a33b5d39792 48 #define STR_BUFF_SIZE 64
okano 12:5a33b5d39792 49
okano 1:54e619428ae6 50 #define SOURCE_FILE "/local/bin"
okano 18:b401da200216 51
okano 18:b401da200216 52 // "ISP_BAUD_RATE" is baud rate for ISP operation
okano 18:b401da200216 53
okano 16:cac2348cfcfb 54 #define ISP_BAUD_RATE 115200
okano 16:cac2348cfcfb 55 //#define ISP_BAUD_RATE 57600
okano 16:cac2348cfcfb 56 //#define ISP_BAUD_RATE 9600
okano 16:cac2348cfcfb 57
okano 18:b401da200216 58 // "TARGET_OPERATION_BAUD_RATE" is baud rate for USB-serial bridge operation after
okano 18:b401da200216 59 // ISP completion.
okano 18:b401da200216 60 // if the target application uses serial(UART) and you use the bridge feature,
okano 18:b401da200216 61 // please set this value correctly.
okano 18:b401da200216 62
okano 16:cac2348cfcfb 63 #define TARGET_OPERATION_BAUD_RATE 9600
okano 4:55f1977bd11a 64
okano 8:b220fadbb3d8 65 int error_state = 0;
okano 7:815366f003ee 66
okano 7:815366f003ee 67 int file_size( FILE *fp );
okano 7:815366f003ee 68 void reset_target( int isp_pin_state );
okano 7:815366f003ee 69 int try_and_check( char *command, char *expected_return_str, int mode );
okano 7:815366f003ee 70 int try_and_check2( char *command, char *expected_return_str, int mode );
okano 7:815366f003ee 71 void print_command( char *command );
okano 7:815366f003ee 72 void print_result( int r );
okano 7:815366f003ee 73 char read_byte( void );
okano 7:815366f003ee 74 void erase_sectors( int last_sector );
okano 12:5a33b5d39792 75 int write_uuencoded_data( FILE *fp, int ram_size, int sector_size, unsigned int );
okano 12:5a33b5d39792 76 int write_binary_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start );
okano 19:7a7381e78025 77 int verify_binary_data( FILE *fp );
okano 7:815366f003ee 78 void initialize_uue_table( void );
okano 11:8dfc3217d1ca 79 long bin2uue( char *bin, char *str, int size );
okano 12:5a33b5d39792 80 int get_flash_writing_size( int ram_size, unsigned int ram_start );
okano 7:815366f003ee 81 void add_isp_checksum( char *b );
okano 7:815366f003ee 82 void send_RAM_transfer_checksum( int checksum );
okano 7:815366f003ee 83 void put_string( char *s );
okano 12:5a33b5d39792 84 void put_binary( char *b, int size );
okano 7:815366f003ee 85 void get_string( char *s );
okano 19:7a7381e78025 86 int get_binary( char *b, int length );
okano 16:cac2348cfcfb 87 void success_indicator();
okano 7:815366f003ee 88
okano 19:7a7381e78025 89
okano 12:5a33b5d39792 90 #pragma diag_suppress 1293 // surpressing a warning message of "assignment in condition" ;)
okano 12:5a33b5d39792 91
okano 7:815366f003ee 92
okano 7:815366f003ee 93 int main()
okano 7:815366f003ee 94 {
okano 7:815366f003ee 95 FILE *fp;
okano 7:815366f003ee 96 char str_buf0[ STR_BUFF_SIZE ];
okano 7:815366f003ee 97 char str_buf1[ STR_BUFF_SIZE ];
okano 7:815366f003ee 98 int data_size;
okano 7:815366f003ee 99 int last_sector;
okano 7:815366f003ee 100 target_param *tpp;
okano 8:b220fadbb3d8 101
okano 7:815366f003ee 102 printf( "\r\n\r\n\r\nmbed ISP program : programming LPC device from mbed\r\n" );
okano 7:815366f003ee 103
okano 16:cac2348cfcfb 104 target.baud( ISP_BAUD_RATE );
okano 8:b220fadbb3d8 105
okano 7:815366f003ee 106 reset_target( ENTER_TO_ISP_MODE );
okano 8:b220fadbb3d8 107
okano 7:815366f003ee 108 try_and_check( "?", "Synchronized", 0 );
okano 8:b220fadbb3d8 109
okano 7:815366f003ee 110 try_and_check2( "Synchronized\r\n", "OK", 0 );
okano 7:815366f003ee 111 try_and_check2( "12000\r\n", "OK", 0 );
okano 7:815366f003ee 112 try_and_check2( "U 23130\r\n", "0", 0 );
okano 7:815366f003ee 113 try_and_check2( "A 0\r\n", "0", 0 );
okano 8:b220fadbb3d8 114
okano 7:815366f003ee 115 try_and_check( "K\r\n", "0", 0 );
okano 7:815366f003ee 116 get_string( str_buf0 );
okano 7:815366f003ee 117 get_string( str_buf1 );
okano 8:b220fadbb3d8 118
okano 7:815366f003ee 119 printf( " result of \"K\" = %s %s\r\n", str_buf0, str_buf1 );
okano 8:b220fadbb3d8 120
okano 7:815366f003ee 121 try_and_check( "J\r\n", "0", 0 );
okano 7:815366f003ee 122 get_string( str_buf0 );
okano 8:b220fadbb3d8 123
okano 7:815366f003ee 124 printf( " result of \"J\" = %s\r\n", str_buf0 );
okano 8:b220fadbb3d8 125
okano 7:815366f003ee 126 tpp = find_target_param( str_buf0 );
okano 8:b220fadbb3d8 127 printf( " target device found : type = \"%s\"\r\n", tpp->type_name );
okano 8:b220fadbb3d8 128 printf( " ID = 0x%08X\r\n", tpp->id );
okano 8:b220fadbb3d8 129 printf( " RAM size = %10d bytes\r\n", tpp->ram_size );
okano 8:b220fadbb3d8 130 printf( " flash size = %10d bytes\r\n", tpp->flash_size );
okano 8:b220fadbb3d8 131
okano 12:5a33b5d39792 132 printf( " opening file: \"%s\"\r\n", SOURCE_FILE );
okano 12:5a33b5d39792 133
okano 12:5a33b5d39792 134 if ( NULL == (fp = fopen( SOURCE_FILE, "rb" )) ) {
okano 12:5a33b5d39792 135 error( "couldn't open source file" );
okano 12:5a33b5d39792 136 return ( 1 );
okano 12:5a33b5d39792 137 }
okano 12:5a33b5d39792 138
okano 12:5a33b5d39792 139 data_size = file_size( fp );
okano 12:5a33b5d39792 140 last_sector = data_size / tpp->sector_size;
okano 12:5a33b5d39792 141
okano 12:5a33b5d39792 142 printf( " data size = %d bytes, it takes %d secotrs in flash area\r\n", data_size, last_sector + 1 );
okano 12:5a33b5d39792 143 printf( " resetting target\r\n" );
okano 12:5a33b5d39792 144
okano 7:815366f003ee 145 erase_sectors( last_sector );
okano 12:5a33b5d39792 146
okano 12:5a33b5d39792 147 if ( tpp->write_type == BINARY )
okano 12:5a33b5d39792 148 write_binary_data( fp, tpp->ram_size, tpp->sector_size, tpp->ram_start_address );
okano 12:5a33b5d39792 149 else // UUENCODE
okano 12:5a33b5d39792 150 write_uuencoded_data( fp, tpp->ram_size, tpp->sector_size, tpp->ram_start_address );
okano 12:5a33b5d39792 151
okano 7:815366f003ee 152 fclose( fp );
okano 8:b220fadbb3d8 153
okano 8:b220fadbb3d8 154 printf( "\r\n %s\r\n\r\n",
okano 8:b220fadbb3d8 155 error_state ?
okano 8:b220fadbb3d8 156 "** The data could not be written :(" :
okano 8:b220fadbb3d8 157 "** The data has been written successflly :)"
okano 8:b220fadbb3d8 158 );
okano 19:7a7381e78025 159
okano 19:7a7381e78025 160 if ( error_state )
okano 19:7a7381e78025 161 error( " ** ISP failed\r\n" );
okano 8:b220fadbb3d8 162
okano 16:cac2348cfcfb 163 #define AUTO_PROGRAM_START
okano 14:a7b9f74fb856 164 #ifdef AUTO_PROGRAM_START
okano 16:cac2348cfcfb 165 target.baud( TARGET_OPERATION_BAUD_RATE );
okano 16:cac2348cfcfb 166
okano 14:a7b9f74fb856 167 reset_target( NO_ISP_MODE );
okano 16:cac2348cfcfb 168 printf( " ** The program in flash has been started!!\r\n" );
okano 14:a7b9f74fb856 169 #endif
okano 14:a7b9f74fb856 170
okano 16:cac2348cfcfb 171 printf( " (now the mbed is working in \"serial through mode\")\r\n\r\n" );
okano 16:cac2348cfcfb 172
okano 16:cac2348cfcfb 173 success.attach( &success_indicator, 0.1 );
okano 16:cac2348cfcfb 174
okano 16:cac2348cfcfb 175 while (1) {
okano 8:b220fadbb3d8 176
okano 16:cac2348cfcfb 177 if ( pc.readable() ) {
okano 16:cac2348cfcfb 178 target.putc( pc.getc() );
okano 16:cac2348cfcfb 179 }
okano 16:cac2348cfcfb 180
okano 16:cac2348cfcfb 181 if ( target.readable() ) {
okano 16:cac2348cfcfb 182 pc.putc( target.getc() );
okano 16:cac2348cfcfb 183 }
okano 16:cac2348cfcfb 184
okano 7:815366f003ee 185 }
okano 7:815366f003ee 186 }
okano 7:815366f003ee 187
okano 7:815366f003ee 188
okano 7:815366f003ee 189 int file_size( FILE *fp )
okano 7:815366f003ee 190 {
okano 7:815366f003ee 191 int size;
okano 8:b220fadbb3d8 192
okano 7:815366f003ee 193 fseek( fp, 0, SEEK_END ); // seek to end of file
okano 7:815366f003ee 194 size = ftell( fp ); // get current file pointer
okano 7:815366f003ee 195 fseek( fp, 0, SEEK_SET ); // seek back to beginning of file
okano 8:b220fadbb3d8 196
okano 7:815366f003ee 197 return size;
okano 7:815366f003ee 198 }
okano 7:815366f003ee 199
okano 7:815366f003ee 200
okano 7:815366f003ee 201 void reset_target( int isp_pin_state )
okano 7:815366f003ee 202 {
okano 7:815366f003ee 203 reset_pin = 1;
okano 13:60995bf8b2c7 204 isp_pin = isp_pin_state;
okano 7:815366f003ee 205 wait_ms( 100 );
okano 13:60995bf8b2c7 206
okano 7:815366f003ee 207 reset_pin = 0;
okano 7:815366f003ee 208 wait_ms( 100 );
okano 13:60995bf8b2c7 209
okano 7:815366f003ee 210 reset_pin = 1;
okano 7:815366f003ee 211 wait_ms( 100 );
okano 7:815366f003ee 212 }
okano 7:815366f003ee 213
okano 7:815366f003ee 214
okano 7:815366f003ee 215 int try_and_check( char *command, char *expected_return_str, int mode )
okano 7:815366f003ee 216 {
okano 7:815366f003ee 217 char rtn_str[ STR_BUFF_SIZE ];
okano 8:b220fadbb3d8 218 int result = 1;
okano 8:b220fadbb3d8 219
okano 7:815366f003ee 220 print_command( command );
okano 7:815366f003ee 221 put_string( command );
okano 8:b220fadbb3d8 222
okano 7:815366f003ee 223 get_string( rtn_str );
okano 7:815366f003ee 224 print_result( result = strcmp( expected_return_str, rtn_str ) );
okano 8:b220fadbb3d8 225
okano 8:b220fadbb3d8 226 if ( result && !mode )
okano 8:b220fadbb3d8 227 error( "command failed\r\n" );
okano 8:b220fadbb3d8 228
okano 8:b220fadbb3d8 229 error_state |= result;
okano 8:b220fadbb3d8 230
okano 7:815366f003ee 231 return ( result );
okano 7:815366f003ee 232 }
okano 7:815366f003ee 233
okano 7:815366f003ee 234
okano 7:815366f003ee 235 int try_and_check2( char *command, char *expected_return_str, int mode )
okano 7:815366f003ee 236 {
okano 7:815366f003ee 237 char rtn_str[ STR_BUFF_SIZE ];
okano 8:b220fadbb3d8 238 int result = 1;
okano 8:b220fadbb3d8 239
okano 7:815366f003ee 240 print_command( command );
okano 7:815366f003ee 241 put_string( command );
okano 8:b220fadbb3d8 242
okano 7:815366f003ee 243 get_string( rtn_str ); // just readout echoback
okano 7:815366f003ee 244 get_string( rtn_str );
okano 7:815366f003ee 245 print_result( result = strcmp( expected_return_str, rtn_str ) );
okano 8:b220fadbb3d8 246
okano 8:b220fadbb3d8 247 if ( result && !mode )
okano 8:b220fadbb3d8 248 error( "command failed\r\n" );
okano 8:b220fadbb3d8 249
okano 8:b220fadbb3d8 250 error_state |= result;
okano 8:b220fadbb3d8 251
okano 7:815366f003ee 252 return ( result );
okano 7:815366f003ee 253 }
okano 7:815366f003ee 254
okano 7:815366f003ee 255
okano 7:815366f003ee 256 void print_command( char *command )
okano 7:815366f003ee 257 {
okano 7:815366f003ee 258 char s[ STR_BUFF_SIZE ];
okano 7:815366f003ee 259 char *pos;
okano 8:b220fadbb3d8 260
okano 7:815366f003ee 261 strcpy( s, command );
okano 8:b220fadbb3d8 262
okano 7:815366f003ee 263 if ( pos = strchr( s, '\r' ) )
okano 7:815366f003ee 264 *pos = '\0';
okano 8:b220fadbb3d8 265
okano 7:815366f003ee 266 if ( pos = strchr( s, '\n' ) )
okano 7:815366f003ee 267 *pos = '\0';
okano 8:b220fadbb3d8 268
okano 7:815366f003ee 269 printf( " command-\"%s\" : ", s );
okano 7:815366f003ee 270 }
okano 7:815366f003ee 271
okano 7:815366f003ee 272
okano 7:815366f003ee 273 void print_result( int r )
okano 7:815366f003ee 274 {
okano 7:815366f003ee 275 printf( "%s\r\n", r ? "Fail" : "Pass" );
okano 7:815366f003ee 276 }
okano 7:815366f003ee 277
okano 7:815366f003ee 278
okano 7:815366f003ee 279 char read_byte( void )
okano 7:815366f003ee 280 {
okano 7:815366f003ee 281 while ( !target.readable() )
okano 7:815366f003ee 282 ;
okano 8:b220fadbb3d8 283
okano 7:815366f003ee 284 return ( target.getc() );
okano 7:815366f003ee 285 }
okano 7:815366f003ee 286
okano 7:815366f003ee 287
okano 7:815366f003ee 288 void erase_sectors( int last_sector )
okano 7:815366f003ee 289 {
okano 7:815366f003ee 290 char command_str[ STR_BUFF_SIZE ];
okano 8:b220fadbb3d8 291
okano 7:815366f003ee 292 sprintf( command_str, "P 0 %d\r\n", last_sector );
okano 7:815366f003ee 293 try_and_check( command_str, "0", 0 );
okano 8:b220fadbb3d8 294
okano 7:815366f003ee 295 *(command_str) = 'E';
okano 7:815366f003ee 296 try_and_check( command_str, "0", 0 );
okano 7:815366f003ee 297 }
okano 7:815366f003ee 298
okano 12:5a33b5d39792 299 #define BYTES_PER_LINE 45
okano 12:5a33b5d39792 300 char uue_table[ 64 ];
okano 7:815366f003ee 301
okano 12:5a33b5d39792 302 int write_uuencoded_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start )
okano 7:815366f003ee 303 {
okano 7:815366f003ee 304 char command_str[ STR_BUFF_SIZE ];
okano 7:815366f003ee 305 long checksum = 0;
okano 7:815366f003ee 306 int total_size = 0;
okano 7:815366f003ee 307 int size;
okano 8:b220fadbb3d8 308
okano 7:815366f003ee 309 int flash_writing_size;
okano 7:815366f003ee 310 int lines_per_transfer;
okano 7:815366f003ee 311 int transfer_size;
okano 8:b220fadbb3d8 312
okano 12:5a33b5d39792 313 char *b;
okano 12:5a33b5d39792 314
okano 7:815366f003ee 315 initialize_uue_table();
okano 8:b220fadbb3d8 316
okano 12:5a33b5d39792 317 flash_writing_size = get_flash_writing_size( ram_size, ram_start );
okano 11:8dfc3217d1ca 318 lines_per_transfer = ((flash_writing_size / BYTES_PER_LINE) + 1);
okano 11:8dfc3217d1ca 319 transfer_size = (((flash_writing_size + 11) / 12) * 12);
okano 8:b220fadbb3d8 320
okano 7:815366f003ee 321 // char b[ transfer_size ]; // this can be done in mbed-compiler. but I should do it in common way
okano 8:b220fadbb3d8 322
okano 7:815366f003ee 323 if ( NULL == (b = (char *)malloc( transfer_size * sizeof( char ) )) )
okano 7:815366f003ee 324 error( "malloc error happened\r\n" );
okano 8:b220fadbb3d8 325
okano 7:815366f003ee 326 for ( int i = flash_writing_size; i < transfer_size; i++ )
okano 7:815366f003ee 327 b[ i ] = 0; // this is not neccesary but just stuffing stuffing bytes
okano 8:b220fadbb3d8 328
okano 7:815366f003ee 329 while ( size = fread( b, sizeof( char ), flash_writing_size, fp ) ) {
okano 8:b220fadbb3d8 330
okano 7:815366f003ee 331 if ( !total_size ) {
okano 7:815366f003ee 332 // overwriting 4 bytes data for address=0x1C
okano 7:815366f003ee 333 // there is a slot for checksum that is checked in (target's) boot process
okano 7:815366f003ee 334 add_isp_checksum( b );
okano 7:815366f003ee 335 }
okano 8:b220fadbb3d8 336
okano 12:5a33b5d39792 337 sprintf( command_str, "W %ld %ld\r\n", ram_start, transfer_size );
okano 7:815366f003ee 338 try_and_check( command_str, "0", 0 );
okano 8:b220fadbb3d8 339
okano 7:815366f003ee 340 for ( int i = 0; i < lines_per_transfer; i++ ) {
okano 12:5a33b5d39792 341
okano 11:8dfc3217d1ca 342 checksum += bin2uue( b + (i * BYTES_PER_LINE), command_str, i == (lines_per_transfer - 1) ? (transfer_size % BYTES_PER_LINE) : BYTES_PER_LINE );
okano 8:b220fadbb3d8 343
okano 13:60995bf8b2c7 344 // printf( " data -- %02d %s\r", i, command_str );
okano 8:b220fadbb3d8 345
okano 7:815366f003ee 346 put_string( command_str );
okano 8:b220fadbb3d8 347
okano 7:815366f003ee 348 if ( !((i + 1) % 20) ) {
okano 7:815366f003ee 349 send_RAM_transfer_checksum( checksum );
okano 7:815366f003ee 350 checksum = 0;
okano 7:815366f003ee 351 }
okano 7:815366f003ee 352 }
okano 8:b220fadbb3d8 353
okano 7:815366f003ee 354 send_RAM_transfer_checksum( checksum );
okano 7:815366f003ee 355 checksum = 0;
okano 8:b220fadbb3d8 356
okano 12:5a33b5d39792 357 sprintf( command_str, "P %d %d\r\n", total_size / sector_size, total_size / sector_size );
okano 7:815366f003ee 358 try_and_check( command_str, "0", 0 );
okano 8:b220fadbb3d8 359
okano 12:5a33b5d39792 360 sprintf( command_str, "C %d %d %d\r\n", total_size, ram_start, flash_writing_size );
okano 7:815366f003ee 361 try_and_check( command_str, "0", 0 );
okano 8:b220fadbb3d8 362
okano 7:815366f003ee 363 total_size += size;
okano 7:815366f003ee 364 }
okano 8:b220fadbb3d8 365
okano 7:815366f003ee 366 try_and_check( "G 0 T\r\n", "0", 0 );
okano 7:815366f003ee 367 free( b );
okano 8:b220fadbb3d8 368
okano 12:5a33b5d39792 369 return ( total_size );
okano 7:815366f003ee 370 }
okano 7:815366f003ee 371
okano 7:815366f003ee 372
okano 12:5a33b5d39792 373 int write_binary_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start )
okano 12:5a33b5d39792 374 {
okano 12:5a33b5d39792 375 char command_str[ STR_BUFF_SIZE ];
okano 12:5a33b5d39792 376 int total_size = 0;
okano 12:5a33b5d39792 377 int size;
okano 12:5a33b5d39792 378 int flash_writing_size;
okano 12:5a33b5d39792 379 char *b;
okano 12:5a33b5d39792 380
okano 12:5a33b5d39792 381 flash_writing_size = 256;
okano 12:5a33b5d39792 382
okano 12:5a33b5d39792 383 if ( NULL == (b = (char *)malloc( flash_writing_size * sizeof( char ) )) )
okano 12:5a33b5d39792 384 error( "malloc error happened\r\n" );
okano 12:5a33b5d39792 385
okano 19:7a7381e78025 386 printf( "\r\n ==== flash writing ====\r\n" );
okano 19:7a7381e78025 387
okano 12:5a33b5d39792 388 while ( size = fread( b, sizeof( char ), flash_writing_size, fp ) ) {
okano 12:5a33b5d39792 389
okano 12:5a33b5d39792 390 if ( !total_size ) {
okano 12:5a33b5d39792 391 // overwriting 4 bytes data for address=0x1C
okano 12:5a33b5d39792 392 // there is a slot for checksum that is checked in (target's) boot process
okano 12:5a33b5d39792 393 add_isp_checksum( b );
okano 12:5a33b5d39792 394 }
okano 12:5a33b5d39792 395
okano 12:5a33b5d39792 396 sprintf( command_str, "W %ld %ld\r\n", ram_start, flash_writing_size );
okano 12:5a33b5d39792 397 try_and_check( command_str, "0", 0 );
okano 12:5a33b5d39792 398
okano 12:5a33b5d39792 399 put_binary( b, flash_writing_size );
okano 12:5a33b5d39792 400 put_string( "\r\n" );
okano 12:5a33b5d39792 401
okano 12:5a33b5d39792 402 sprintf( command_str, "P %d %d\r\n", total_size / sector_size, total_size / sector_size );
okano 12:5a33b5d39792 403 try_and_check( command_str, "0", 0 );
okano 12:5a33b5d39792 404
okano 12:5a33b5d39792 405 sprintf( command_str, "C %d %d %d\r\n", total_size, ram_start, flash_writing_size );
okano 12:5a33b5d39792 406 try_and_check( command_str, "0", 0 );
okano 12:5a33b5d39792 407
okano 12:5a33b5d39792 408 total_size += size;
okano 19:7a7381e78025 409 //printf( " total %d bytes transferred\r", total_size );
okano 12:5a33b5d39792 410
okano 12:5a33b5d39792 411 }
okano 12:5a33b5d39792 412
okano 12:5a33b5d39792 413 free( b );
okano 12:5a33b5d39792 414
okano 19:7a7381e78025 415 verify_binary_data( fp );
okano 19:7a7381e78025 416
okano 12:5a33b5d39792 417 return ( total_size );
okano 12:5a33b5d39792 418 }
okano 12:5a33b5d39792 419
okano 19:7a7381e78025 420
okano 19:7a7381e78025 421 int verify_binary_data( FILE *fp )
okano 19:7a7381e78025 422 {
okano 19:7a7381e78025 423 char command_str[ STR_BUFF_SIZE ];
okano 19:7a7381e78025 424 int read_size = 0;
okano 19:7a7381e78025 425 int size;
okano 19:7a7381e78025 426 int flash_reading_size;
okano 19:7a7381e78025 427 char *bf;
okano 19:7a7381e78025 428 char *br;
okano 19:7a7381e78025 429 int error_flag = 0;
okano 19:7a7381e78025 430 unsigned long checksum = 0;
okano 19:7a7381e78025 431 unsigned long checksum_count = 0;
okano 19:7a7381e78025 432
okano 19:7a7381e78025 433 fseek( fp, 0, SEEK_SET ); // seek back to beginning of file
okano 19:7a7381e78025 434
okano 19:7a7381e78025 435 flash_reading_size = 128;
okano 19:7a7381e78025 436
okano 19:7a7381e78025 437 if ( NULL == (bf = (char *)malloc( flash_reading_size * sizeof( char ) )) )
okano 19:7a7381e78025 438 error( "malloc error happened (in verify process, file data buffer)\r\n" );
okano 19:7a7381e78025 439
okano 19:7a7381e78025 440 if ( NULL == (br = (char *)malloc( flash_reading_size * sizeof( char ) )) )
okano 19:7a7381e78025 441 error( "malloc error happened (in verify process, read data buffer)\r\n" );
okano 19:7a7381e78025 442
okano 19:7a7381e78025 443
okano 19:7a7381e78025 444 printf( "\r\n ==== flash reading and verifying ====\r\n" );
okano 19:7a7381e78025 445
okano 19:7a7381e78025 446 while ( size = fread( bf, sizeof( char ), flash_reading_size, fp ) ) {
okano 19:7a7381e78025 447
okano 19:7a7381e78025 448 if ( read_size < 0x20 ) {
okano 19:7a7381e78025 449 for ( int i = 0; i < flash_reading_size; i += 4 ) {
okano 19:7a7381e78025 450
okano 19:7a7381e78025 451 if ( checksum_count == 7 ) {
okano 19:7a7381e78025 452 checksum = 0xFFFFFFFF - checksum + 1;
okano 19:7a7381e78025 453 *((unsigned int *)(bf + i)) = checksum;
okano 19:7a7381e78025 454 //printf( "\r\n\r\n -- calculated checksum : 0x%08X\r\n", checksum );
okano 19:7a7381e78025 455 } else {
okano 19:7a7381e78025 456 checksum += *((unsigned int *)(bf + i));
okano 19:7a7381e78025 457 }
okano 19:7a7381e78025 458
okano 19:7a7381e78025 459 checksum_count++;
okano 19:7a7381e78025 460 }
okano 19:7a7381e78025 461 }
okano 19:7a7381e78025 462
okano 19:7a7381e78025 463
okano 19:7a7381e78025 464 sprintf( command_str, "R %ld %ld\r\n", read_size, size );
okano 19:7a7381e78025 465 // try_and_check( command_str, "0", MODE_SILENT );
okano 19:7a7381e78025 466 try_and_check( command_str, "0", 0 );
okano 19:7a7381e78025 467
okano 19:7a7381e78025 468 get_binary( br, 1 );
okano 19:7a7381e78025 469 get_binary( br, size );
okano 19:7a7381e78025 470
okano 19:7a7381e78025 471 for ( int i = 0; i < size; i++ ) {
okano 19:7a7381e78025 472 // printf( " %s 0x%02X --- 0x%02X\r\n", (*(bf + i) != *(br + i)) ? "***" : " ", *(bf + i), *(br + i) );
okano 19:7a7381e78025 473 if ( (*(bf + i) != *(br + i)) ) {
okano 19:7a7381e78025 474 // printf( " %s 0x%02X --- 0x%02X\r\n", (*(bf + i) != *(br + i)) ? "***" : " ", *(bf + i), *(br + i) );
okano 19:7a7381e78025 475 error_flag++;
okano 19:7a7381e78025 476 }
okano 19:7a7381e78025 477 }
okano 19:7a7381e78025 478
okano 19:7a7381e78025 479 if ( error_flag )
okano 19:7a7381e78025 480 break;
okano 19:7a7381e78025 481
okano 19:7a7381e78025 482 read_size += size;
okano 19:7a7381e78025 483
okano 19:7a7381e78025 484 // printf( " total %d bytes read\r\n", read_size );
okano 19:7a7381e78025 485 }
okano 19:7a7381e78025 486
okano 19:7a7381e78025 487 error_state |= error_flag;
okano 19:7a7381e78025 488
okano 19:7a7381e78025 489 printf( " total %d bytes read\r", read_size );
okano 19:7a7381e78025 490 printf( " verification result : \"%s\"\r\n", error_flag ? "Fail" : "Pass" );
okano 19:7a7381e78025 491
okano 19:7a7381e78025 492 free( bf );
okano 19:7a7381e78025 493 free( br );
okano 19:7a7381e78025 494
okano 19:7a7381e78025 495 return ( read_size );
okano 19:7a7381e78025 496 }
okano 19:7a7381e78025 497
okano 19:7a7381e78025 498
okano 7:815366f003ee 499 void initialize_uue_table( void )
okano 7:815366f003ee 500 {
okano 7:815366f003ee 501 int i;
okano 8:b220fadbb3d8 502
okano 7:815366f003ee 503 uue_table[0] = 0x60; // 0x20 is translated to 0x60 !
okano 8:b220fadbb3d8 504
okano 7:815366f003ee 505 for (i = 1; i < 64; i++) {
okano 7:815366f003ee 506 uue_table[i] = (char)(0x20 + i);
okano 7:815366f003ee 507 }
okano 7:815366f003ee 508 }
okano 7:815366f003ee 509
okano 7:815366f003ee 510
okano 11:8dfc3217d1ca 511 long bin2uue( char *bin, char *str, int size )
okano 7:815366f003ee 512 {
okano 7:815366f003ee 513 unsigned long v;
okano 7:815366f003ee 514 long checksum = 0;
okano 7:815366f003ee 515 int strpos = 0;
okano 8:b220fadbb3d8 516
okano 11:8dfc3217d1ca 517 *(str + strpos++) = ' ' + size;
okano 8:b220fadbb3d8 518
okano 11:8dfc3217d1ca 519 for ( int i = 0; i < size; i += 3 ) {
okano 7:815366f003ee 520 checksum += *(bin + i + 0) + *(bin + i + 1) + *(bin + i + 2);
okano 7:815366f003ee 521 v = (*(bin + i + 0) << 16) | (*(bin + i + 1) << 8) | (*(bin + i + 2) << 0);
okano 7:815366f003ee 522 *(str + strpos++) = uue_table[ (v >> 18) & 0x3F ];
okano 7:815366f003ee 523 *(str + strpos++) = uue_table[ (v >> 12) & 0x3F ];
okano 7:815366f003ee 524 *(str + strpos++) = uue_table[ (v >> 6) & 0x3F ];
okano 7:815366f003ee 525 *(str + strpos++) = uue_table[ (v >> 0) & 0x3F ];
okano 7:815366f003ee 526 }
okano 7:815366f003ee 527 *(str + strpos++) = '\n';
okano 7:815366f003ee 528 *(str + strpos++) = '\0';
okano 8:b220fadbb3d8 529
okano 7:815366f003ee 530 return checksum;
okano 7:815366f003ee 531 }
okano 6:0ae6fe8c8512 532
okano 6:0ae6fe8c8512 533
okano 12:5a33b5d39792 534 int get_flash_writing_size( int ram_size, unsigned int ram_start )
okano 6:0ae6fe8c8512 535 {
okano 6:0ae6fe8c8512 536 int flash_writing_size[] = {
okano 6:0ae6fe8c8512 537 4096,
okano 6:0ae6fe8c8512 538 1024,
okano 6:0ae6fe8c8512 539 512,
okano 6:0ae6fe8c8512 540 256
okano 6:0ae6fe8c8512 541 };
okano 6:0ae6fe8c8512 542 int available_size;
okano 6:0ae6fe8c8512 543 int i;
okano 8:b220fadbb3d8 544
okano 12:5a33b5d39792 545 available_size = ram_size - (ram_start & 0xFFFF);
okano 8:b220fadbb3d8 546
okano 6:0ae6fe8c8512 547 for ( i = 0; i < sizeof( flash_writing_size ) / sizeof( int ); i++ ) {
okano 6:0ae6fe8c8512 548 if ( flash_writing_size[ i ] < available_size )
okano 6:0ae6fe8c8512 549 break;
okano 6:0ae6fe8c8512 550 }
okano 8:b220fadbb3d8 551
okano 6:0ae6fe8c8512 552 return ( flash_writing_size[ i ] );
okano 6:0ae6fe8c8512 553 }
okano 4:55f1977bd11a 554
okano 4:55f1977bd11a 555
okano 1:54e619428ae6 556 void add_isp_checksum( char *b )
okano 1:54e619428ae6 557 {
okano 1:54e619428ae6 558 // see http://www.lpcware.com/content/nxpfile/lpc177x8x-checksum-insertion-program
okano 8:b220fadbb3d8 559
okano 1:54e619428ae6 560 unsigned int *p;
okano 1:54e619428ae6 561 unsigned int cksum = 0;
okano 8:b220fadbb3d8 562
okano 1:54e619428ae6 563 p = (unsigned int *)b;
okano 8:b220fadbb3d8 564
okano 1:54e619428ae6 565 for ( int i = 0; i < 7; i++ ) {
okano 1:54e619428ae6 566 cksum += *p++;
okano 1:54e619428ae6 567 }
okano 8:b220fadbb3d8 568
okano 1:54e619428ae6 569 printf( " -- value at checksum slot : 0x%08X\r\n", *p );
okano 8:b220fadbb3d8 570
okano 1:54e619428ae6 571 *p = 0xFFFFFFFF - cksum + 1;
okano 1:54e619428ae6 572 printf( " -- calculated checksum : 0x%08X\r\n", *p );
okano 8:b220fadbb3d8 573
okano 1:54e619428ae6 574 printf( " new checksum will be used to program flash\r\n" );
okano 1:54e619428ae6 575 }
okano 1:54e619428ae6 576
okano 1:54e619428ae6 577
okano 4:55f1977bd11a 578 void send_RAM_transfer_checksum( int checksum )
okano 4:55f1977bd11a 579 {
okano 4:55f1977bd11a 580 char command[ 16 ];
okano 8:b220fadbb3d8 581
okano 4:55f1977bd11a 582 sprintf( command, "%d\n", checksum );
okano 4:55f1977bd11a 583 try_and_check( command, "OK", 0 );
okano 4:55f1977bd11a 584 }
okano 4:55f1977bd11a 585
okano 0:6baefda2e511 586
okano 0:6baefda2e511 587 void put_string( char *s )
okano 0:6baefda2e511 588 {
okano 2:8d75eb0ecd20 589 char c;
okano 2:8d75eb0ecd20 590 static int i = 0;
okano 8:b220fadbb3d8 591
okano 3:3c380e643e74 592 while ( c = *s++ ) {
okano 0:6baefda2e511 593 target.putc( c );
okano 2:8d75eb0ecd20 594 leds = i++ & 0x1;
okano 2:8d75eb0ecd20 595 }
okano 0:6baefda2e511 596 }
okano 0:6baefda2e511 597
okano 7:815366f003ee 598
okano 12:5a33b5d39792 599 void put_binary( char *b, int size )
okano 12:5a33b5d39792 600 {
okano 12:5a33b5d39792 601 for ( int i = 0; i < size; i++ )
okano 12:5a33b5d39792 602 target.putc( *b++ );
okano 12:5a33b5d39792 603 }
okano 12:5a33b5d39792 604
okano 12:5a33b5d39792 605
okano 9:ca4c9a2ac8e1 606 Timeout timeout;
okano 9:ca4c9a2ac8e1 607
okano 9:ca4c9a2ac8e1 608 int timeout_flag = 0;
okano 9:ca4c9a2ac8e1 609
okano 9:ca4c9a2ac8e1 610 void set_flag()
okano 9:ca4c9a2ac8e1 611 {
okano 9:ca4c9a2ac8e1 612 timeout_flag = 1;
okano 9:ca4c9a2ac8e1 613 }
okano 9:ca4c9a2ac8e1 614
okano 9:ca4c9a2ac8e1 615
okano 0:6baefda2e511 616 void get_string( char *s )
okano 0:6baefda2e511 617 {
okano 0:6baefda2e511 618 int i = 0;
okano 0:6baefda2e511 619 char c = 0;
okano 9:ca4c9a2ac8e1 620 timeout_flag = 0;
okano 9:ca4c9a2ac8e1 621
okano 9:ca4c9a2ac8e1 622 timeout.attach( &set_flag, 1 );
okano 8:b220fadbb3d8 623
okano 0:6baefda2e511 624 do {
okano 0:6baefda2e511 625 do {
okano 0:6baefda2e511 626 if ( target.readable() ) {
okano 0:6baefda2e511 627 c = target.getc();
okano 8:b220fadbb3d8 628
okano 0:6baefda2e511 629 if ( ( c == '\n') || (c == '\r') )
okano 0:6baefda2e511 630 break;
okano 8:b220fadbb3d8 631
okano 0:6baefda2e511 632 *s++ = c;
okano 0:6baefda2e511 633 i++;
okano 0:6baefda2e511 634 }
okano 9:ca4c9a2ac8e1 635
okano 9:ca4c9a2ac8e1 636 if ( timeout_flag )
okano 9:ca4c9a2ac8e1 637 return;
okano 0:6baefda2e511 638 } while ( 1 );
okano 0:6baefda2e511 639 } while ( !i );
okano 8:b220fadbb3d8 640
okano 0:6baefda2e511 641 *s = '\0';
okano 0:6baefda2e511 642 }
okano 9:ca4c9a2ac8e1 643
okano 16:cac2348cfcfb 644
okano 19:7a7381e78025 645 int get_binary( char *b, int length )
okano 19:7a7381e78025 646 {
okano 19:7a7381e78025 647 int i;
okano 19:7a7381e78025 648
okano 19:7a7381e78025 649 timeout_flag = 0;
okano 19:7a7381e78025 650 timeout.attach( &set_flag, 1 );
okano 19:7a7381e78025 651
okano 19:7a7381e78025 652 for ( i = 0; i < length; i++ ) {
okano 19:7a7381e78025 653 if ( target.readable() )
okano 19:7a7381e78025 654 *b++ = target.getc();
okano 19:7a7381e78025 655
okano 19:7a7381e78025 656 if ( timeout_flag )
okano 19:7a7381e78025 657 return ( i );
okano 19:7a7381e78025 658 }
okano 19:7a7381e78025 659
okano 19:7a7381e78025 660 return ( i );
okano 19:7a7381e78025 661 }
okano 19:7a7381e78025 662
okano 19:7a7381e78025 663
okano 16:cac2348cfcfb 664 void success_indicator()
okano 16:cac2348cfcfb 665 {
okano 16:cac2348cfcfb 666 static int i = 0;
okano 16:cac2348cfcfb 667
okano 16:cac2348cfcfb 668 leds = 0x1 << (i++ & 0x3);
okano 16:cac2348cfcfb 669 }
okano 16:cac2348cfcfb 670