Ika Shouyu Poppoyaki - LPC82x supported

Dependencies:   MODSERIAL mbed

Fork of ika_shouyu_poppoyaki by Tedd OKANO

Committer:
okano
Date:
Sun Aug 25 00:41:56 2013 +0000
Revision:
4:55f1977bd11a
Parent:
3:3c380e643e74
Child:
5:ff30f5b58617
going to be more generic for transfer size

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okano 0:6baefda2e511 1 #include "mbed.h"
okano 0:6baefda2e511 2
okano 2:8d75eb0ecd20 3 BusOut leds( LED4, LED3, LED2, LED1 );
okano 2:8d75eb0ecd20 4 DigitalOut reset_pin( p26 );
okano 2:8d75eb0ecd20 5 DigitalOut isp_pin( p25 );
okano 2:8d75eb0ecd20 6 Serial target ( p28, p27 );
okano 2:8d75eb0ecd20 7 LocalFileSystem local( "local" );
okano 0:6baefda2e511 8
okano 1:54e619428ae6 9 #define SOURCE_FILE "/local/bin"
okano 4:55f1977bd11a 10 //#define BAUD_RATE 9600
okano 4:55f1977bd11a 11 //#define BAUD_RATE 57600
okano 4:55f1977bd11a 12 #define BAUD_RATE 115200
okano 4:55f1977bd11a 13
okano 1:54e619428ae6 14 #define STR_BUFF_SIZE 64
okano 1:54e619428ae6 15 #define RAM_START_ADDRESS 0x10000300L
okano 4:55f1977bd11a 16 //#define RAM_START_ADDRESS 0x10000100L
okano 1:54e619428ae6 17 #define SECTOR_SIZE 4096
okano 0:6baefda2e511 18
okano 4:55f1977bd11a 19 #define FLASH_WRITING_SIZE 1024 // This value should be 256, 512, 1024 or 4096
okano 4:55f1977bd11a 20 #define LINES_PER_TRANSFER (((FLASH_WRITING_SIZE / 45) + 3) & ~0x3)
okano 4:55f1977bd11a 21 #define TRANSFER_SIZE (LINES_PER_TRANSFER * 45)
okano 4:55f1977bd11a 22
okano 4:55f1977bd11a 23
okano 2:8d75eb0ecd20 24 enum {
okano 2:8d75eb0ecd20 25 ENTER_TO_ISP_MODE,
okano 2:8d75eb0ecd20 26 NO_ISP_MODE
okano 2:8d75eb0ecd20 27 };
okano 2:8d75eb0ecd20 28
okano 0:6baefda2e511 29 void put_string( char *s );
okano 0:6baefda2e511 30 void get_string( char *s );
okano 0:6baefda2e511 31
okano 3:3c380e643e74 32 #pragma diag_suppress 1293
okano 3:3c380e643e74 33
okano 3:3c380e643e74 34
okano 2:8d75eb0ecd20 35 void print_command( char *command )
okano 2:8d75eb0ecd20 36 {
okano 2:8d75eb0ecd20 37 char s[ STR_BUFF_SIZE ];
okano 2:8d75eb0ecd20 38 char *pos;
okano 2:8d75eb0ecd20 39
okano 2:8d75eb0ecd20 40 strcpy( s, command );
okano 2:8d75eb0ecd20 41
okano 2:8d75eb0ecd20 42 if ( pos = strchr( s, '\r' ) )
okano 2:8d75eb0ecd20 43 *pos = '\0';
okano 2:8d75eb0ecd20 44
okano 2:8d75eb0ecd20 45 if ( pos = strchr( s, '\n' ) )
okano 2:8d75eb0ecd20 46 *pos = '\0';
okano 2:8d75eb0ecd20 47
okano 2:8d75eb0ecd20 48 printf( " command-\"%s\" : ", s );
okano 2:8d75eb0ecd20 49 }
okano 2:8d75eb0ecd20 50
okano 2:8d75eb0ecd20 51 void print_result( int r )
okano 2:8d75eb0ecd20 52 {
okano 2:8d75eb0ecd20 53 printf( "%s\r\n", r ? "Fail" : "Pass" );
okano 2:8d75eb0ecd20 54 }
okano 0:6baefda2e511 55
okano 0:6baefda2e511 56 int try_and_check( char *command, char *expected_return_str, int mode )
okano 0:6baefda2e511 57 {
okano 0:6baefda2e511 58 char rtn_str[ STR_BUFF_SIZE ];
okano 2:8d75eb0ecd20 59 int result;
okano 0:6baefda2e511 60
okano 2:8d75eb0ecd20 61 print_command( command );
okano 0:6baefda2e511 62 put_string( command );
okano 2:8d75eb0ecd20 63
okano 0:6baefda2e511 64 get_string( rtn_str );
okano 2:8d75eb0ecd20 65 print_result( result = strcmp( expected_return_str, rtn_str ) );
okano 0:6baefda2e511 66
okano 2:8d75eb0ecd20 67 return ( result );
okano 0:6baefda2e511 68 }
okano 0:6baefda2e511 69
okano 0:6baefda2e511 70 int try_and_check2( char *command, char *expected_return_str, int mode )
okano 0:6baefda2e511 71 {
okano 0:6baefda2e511 72 char rtn_str[ STR_BUFF_SIZE ];
okano 2:8d75eb0ecd20 73 int result;
okano 2:8d75eb0ecd20 74 print_command( command );
okano 0:6baefda2e511 75
okano 0:6baefda2e511 76 put_string( command );
okano 0:6baefda2e511 77
okano 0:6baefda2e511 78 get_string( rtn_str ); // just readout echoback
okano 0:6baefda2e511 79 get_string( rtn_str );
okano 2:8d75eb0ecd20 80 print_result( result = strcmp( expected_return_str, rtn_str ) );
okano 0:6baefda2e511 81
okano 2:8d75eb0ecd20 82 return ( result );
okano 0:6baefda2e511 83 }
okano 0:6baefda2e511 84
okano 0:6baefda2e511 85 char read_byte( void )
okano 0:6baefda2e511 86 {
okano 0:6baefda2e511 87 while ( !target.readable() )
okano 0:6baefda2e511 88 ;
okano 0:6baefda2e511 89
okano 0:6baefda2e511 90 return ( target.getc() );
okano 0:6baefda2e511 91 }
okano 0:6baefda2e511 92 char uue_table[ 64 ];
okano 0:6baefda2e511 93
okano 0:6baefda2e511 94 void initialize_uue_table( void )
okano 0:6baefda2e511 95 {
okano 0:6baefda2e511 96 int i;
okano 0:6baefda2e511 97
okano 0:6baefda2e511 98 uue_table[0] = 0x60; // 0x20 is translated to 0x60 !
okano 0:6baefda2e511 99
okano 0:6baefda2e511 100 for (i = 1; i < 64; i++) {
okano 0:6baefda2e511 101 uue_table[i] = (char)(0x20 + i);
okano 0:6baefda2e511 102 }
okano 0:6baefda2e511 103 }
okano 0:6baefda2e511 104
okano 0:6baefda2e511 105 long bin2uue( char *bin, char *str )
okano 0:6baefda2e511 106 {
okano 0:6baefda2e511 107 unsigned long v;
okano 1:54e619428ae6 108 long checksum = 0;
okano 0:6baefda2e511 109 int strpos = 0;
okano 0:6baefda2e511 110
okano 0:6baefda2e511 111 *(str + strpos++) = ' ' + 45;
okano 0:6baefda2e511 112
okano 0:6baefda2e511 113 for ( int i = 0; i < 45; i += 3 ) {
okano 1:54e619428ae6 114 checksum += *(bin + i + 0) + *(bin + i + 1) + *(bin + i + 2);
okano 0:6baefda2e511 115 v = (*(bin + i + 0) << 16) | (*(bin + i + 1) << 8) | (*(bin + i + 2) << 0);
okano 0:6baefda2e511 116 *(str + strpos++) = uue_table[ (v >> 18) & 0x3F ];
okano 0:6baefda2e511 117 *(str + strpos++) = uue_table[ (v >> 12) & 0x3F ];
okano 0:6baefda2e511 118 *(str + strpos++) = uue_table[ (v >> 6) & 0x3F ];
okano 0:6baefda2e511 119 *(str + strpos++) = uue_table[ (v >> 0) & 0x3F ];
okano 0:6baefda2e511 120 }
okano 0:6baefda2e511 121 *(str + strpos++) = '\n';
okano 0:6baefda2e511 122 *(str + strpos++) = '\0';
okano 0:6baefda2e511 123
okano 1:54e619428ae6 124 return checksum;
okano 0:6baefda2e511 125 }
okano 0:6baefda2e511 126
okano 1:54e619428ae6 127 void add_isp_checksum( char *b )
okano 1:54e619428ae6 128 {
okano 1:54e619428ae6 129 // see http://www.lpcware.com/content/nxpfile/lpc177x8x-checksum-insertion-program
okano 1:54e619428ae6 130
okano 1:54e619428ae6 131 unsigned int *p;
okano 1:54e619428ae6 132 unsigned int cksum = 0;
okano 1:54e619428ae6 133
okano 1:54e619428ae6 134 p = (unsigned int *)b;
okano 1:54e619428ae6 135
okano 1:54e619428ae6 136 for ( int i = 0; i < 7; i++ ) {
okano 1:54e619428ae6 137 cksum += *p++;
okano 1:54e619428ae6 138 }
okano 1:54e619428ae6 139
okano 1:54e619428ae6 140 printf( " -- value at checksum slot : 0x%08X\r\n", *p );
okano 1:54e619428ae6 141
okano 1:54e619428ae6 142 *p = 0xFFFFFFFF - cksum + 1;
okano 1:54e619428ae6 143 printf( " -- calculated checksum : 0x%08X\r\n", *p );
okano 1:54e619428ae6 144
okano 1:54e619428ae6 145 printf( " new checksum will be used to program flash\r\n" );
okano 1:54e619428ae6 146 }
okano 1:54e619428ae6 147
okano 1:54e619428ae6 148
okano 1:54e619428ae6 149
okano 1:54e619428ae6 150 void erase_sectors( int last_sector )
okano 1:54e619428ae6 151 {
okano 1:54e619428ae6 152 char command_str[ STR_BUFF_SIZE ];
okano 1:54e619428ae6 153
okano 1:54e619428ae6 154 sprintf( command_str, "P 0 %d\r\n", last_sector );
okano 2:8d75eb0ecd20 155 try_and_check( command_str, "0", 0 );
okano 1:54e619428ae6 156
okano 1:54e619428ae6 157 *(command_str) = 'E';
okano 2:8d75eb0ecd20 158 try_and_check( command_str, "0", 0 );
okano 1:54e619428ae6 159 }
okano 0:6baefda2e511 160
okano 4:55f1977bd11a 161
okano 4:55f1977bd11a 162 void send_RAM_transfer_checksum( int checksum )
okano 4:55f1977bd11a 163 {
okano 4:55f1977bd11a 164 char command[ 16 ];
okano 4:55f1977bd11a 165
okano 4:55f1977bd11a 166 sprintf( command, "%d\n", checksum );
okano 4:55f1977bd11a 167 try_and_check( command, "OK", 0 );
okano 4:55f1977bd11a 168 }
okano 4:55f1977bd11a 169
okano 0:6baefda2e511 170
okano 0:6baefda2e511 171 char b[ TRANSFER_SIZE ];
okano 0:6baefda2e511 172
okano 1:54e619428ae6 173 void write_binary_data( FILE *fp )
okano 0:6baefda2e511 174 {
okano 0:6baefda2e511 175 char command_str[ STR_BUFF_SIZE ];
okano 4:55f1977bd11a 176 long checksum = 0;
okano 0:6baefda2e511 177 int transfer_count = 0;
okano 4:55f1977bd11a 178 int total_size = 0;
okano 0:6baefda2e511 179 int size;
okano 0:6baefda2e511 180
okano 0:6baefda2e511 181 initialize_uue_table();
okano 0:6baefda2e511 182
okano 0:6baefda2e511 183 for ( int i = FLASH_WRITING_SIZE; i < TRANSFER_SIZE; i++ )
okano 4:55f1977bd11a 184 b[ i ] = 0; // this is not neccesary but just stuffing stuffing bytes
okano 0:6baefda2e511 185
okano 0:6baefda2e511 186 while ( size = fread( b, sizeof( char ), FLASH_WRITING_SIZE, fp ) ) {
okano 0:6baefda2e511 187
okano 4:55f1977bd11a 188 if ( !total_size ) {
okano 4:55f1977bd11a 189 // overwriting 4 bytes data for address=0x1C
okano 4:55f1977bd11a 190 // there is a slot for checksum that is checked in (target's) boot process
okano 1:54e619428ae6 191 add_isp_checksum( b );
okano 1:54e619428ae6 192 }
okano 1:54e619428ae6 193
okano 4:55f1977bd11a 194 sprintf( command_str, "W %ld %ld\r\n", RAM_START_ADDRESS, TRANSFER_SIZE );
okano 2:8d75eb0ecd20 195 try_and_check( command_str, "0", 0 );
okano 0:6baefda2e511 196
okano 4:55f1977bd11a 197 for ( int i = 0; i < LINES_PER_TRANSFER; i++ ) {
okano 1:54e619428ae6 198 checksum += bin2uue( b + (i * 45), command_str );
okano 4:55f1977bd11a 199
okano 2:8d75eb0ecd20 200 printf( "%02d %s\r", i, command_str );
okano 4:55f1977bd11a 201
okano 0:6baefda2e511 202 put_string( command_str );
okano 0:6baefda2e511 203
okano 4:55f1977bd11a 204 if ( !((i + 1) % 20) ) {
okano 4:55f1977bd11a 205 send_RAM_transfer_checksum( checksum );
okano 1:54e619428ae6 206 checksum = 0;
okano 0:6baefda2e511 207 }
okano 0:6baefda2e511 208 }
okano 0:6baefda2e511 209
okano 4:55f1977bd11a 210 send_RAM_transfer_checksum( checksum );
okano 4:55f1977bd11a 211 checksum = 0;
okano 0:6baefda2e511 212
okano 4:55f1977bd11a 213 sprintf( command_str, "P %d %d\r\n", total_size / SECTOR_SIZE, total_size / SECTOR_SIZE );
okano 2:8d75eb0ecd20 214 try_and_check( command_str, "0", 0 );
okano 0:6baefda2e511 215
okano 4:55f1977bd11a 216 sprintf( command_str, "C %d %d %d\r\n", total_size, RAM_START_ADDRESS, FLASH_WRITING_SIZE );
okano 4:55f1977bd11a 217 try_and_check( command_str, "0", 0 );
okano 0:6baefda2e511 218
okano 4:55f1977bd11a 219 total_size += size;
okano 0:6baefda2e511 220 }
okano 2:8d75eb0ecd20 221 try_and_check( "G 0 T\r\n", "0", 0 );
okano 0:6baefda2e511 222 }
okano 0:6baefda2e511 223
okano 1:54e619428ae6 224 int file_size( FILE *fp )
okano 1:54e619428ae6 225 {
okano 1:54e619428ae6 226 int size;
okano 1:54e619428ae6 227
okano 1:54e619428ae6 228 fseek( fp, 0, SEEK_END ); // seek to end of file
okano 1:54e619428ae6 229 size = ftell( fp ); // get current file pointer
okano 1:54e619428ae6 230 fseek( fp, 0, SEEK_SET ); // seek back to beginning of file
okano 1:54e619428ae6 231
okano 1:54e619428ae6 232 return size;
okano 1:54e619428ae6 233 }
okano 1:54e619428ae6 234
okano 1:54e619428ae6 235 void reset_target( int isp_pin_state )
okano 1:54e619428ae6 236 {
okano 1:54e619428ae6 237 reset_pin = 1;
okano 1:54e619428ae6 238 isp_pin = 0;
okano 1:54e619428ae6 239 wait_ms( 100 );
okano 1:54e619428ae6 240 reset_pin = 0;
okano 1:54e619428ae6 241 wait_ms( 100 );
okano 1:54e619428ae6 242 reset_pin = 1;
okano 1:54e619428ae6 243 wait_ms( 100 );
okano 1:54e619428ae6 244 }
okano 1:54e619428ae6 245
okano 0:6baefda2e511 246 int main()
okano 0:6baefda2e511 247 {
okano 0:6baefda2e511 248 FILE *fp;
okano 0:6baefda2e511 249 char str_buf0[ STR_BUFF_SIZE ];
okano 0:6baefda2e511 250 char str_buf1[ STR_BUFF_SIZE ];
okano 1:54e619428ae6 251 int data_size;
okano 1:54e619428ae6 252 int last_sector;
okano 0:6baefda2e511 253
okano 4:55f1977bd11a 254 target.baud( BAUD_RATE );
okano 0:6baefda2e511 255
okano 0:6baefda2e511 256 if ( NULL == (fp = fopen( SOURCE_FILE, "rb" )) ) {
okano 0:6baefda2e511 257 error( "couldn't open source file" );
okano 0:6baefda2e511 258 return ( 1 );
okano 0:6baefda2e511 259 }
okano 0:6baefda2e511 260
okano 1:54e619428ae6 261 data_size = file_size( fp );
okano 1:54e619428ae6 262 last_sector = data_size / SECTOR_SIZE;
okano 0:6baefda2e511 263 printf( "\r\n\r\ntarget RESET\r\n" );
okano 1:54e619428ae6 264 printf( "data size = %d bytes, it takes %d secotrs in flash area\r\n", data_size, last_sector + 1 );
okano 0:6baefda2e511 265
okano 2:8d75eb0ecd20 266 reset_target( ENTER_TO_ISP_MODE );
okano 2:8d75eb0ecd20 267
okano 2:8d75eb0ecd20 268 try_and_check( "?", "Synchronized", 0 );
okano 0:6baefda2e511 269
okano 2:8d75eb0ecd20 270 try_and_check2( "Synchronized\r\n", "OK", 0 );
okano 2:8d75eb0ecd20 271 try_and_check2( "12000\r\n", "OK", 0 );
okano 2:8d75eb0ecd20 272 try_and_check2( "U 23130\r\n", "0", 0 );
okano 2:8d75eb0ecd20 273 try_and_check2( "A 0\r\n", "0", 0 );
okano 0:6baefda2e511 274
okano 2:8d75eb0ecd20 275 try_and_check( "K\r\n", "0", 0 );
okano 0:6baefda2e511 276 get_string( str_buf0 );
okano 0:6baefda2e511 277 get_string( str_buf1 );
okano 0:6baefda2e511 278 printf( " result of \"K\" = %s %s\r\n", str_buf0, str_buf1 );
okano 0:6baefda2e511 279
okano 2:8d75eb0ecd20 280 try_and_check( "J\r\n", "0", 0 );
okano 0:6baefda2e511 281 get_string( str_buf0 );
okano 0:6baefda2e511 282 printf( " result of \"J\" = %s\r\n", str_buf0 );
okano 0:6baefda2e511 283
okano 2:8d75eb0ecd20 284 erase_sectors( last_sector );
okano 2:8d75eb0ecd20 285 write_binary_data( fp );
okano 0:6baefda2e511 286
okano 0:6baefda2e511 287 fclose( fp );
okano 0:6baefda2e511 288
okano 2:8d75eb0ecd20 289 int i = 0;
okano 2:8d75eb0ecd20 290
okano 2:8d75eb0ecd20 291 while ( 1 ) {
okano 2:8d75eb0ecd20 292 leds = 0x1 << (i++ & 0x3);
okano 2:8d75eb0ecd20 293 wait( 0.1 );
okano 2:8d75eb0ecd20 294 }
okano 0:6baefda2e511 295 }
okano 0:6baefda2e511 296
okano 2:8d75eb0ecd20 297
okano 0:6baefda2e511 298 void put_string( char *s )
okano 0:6baefda2e511 299 {
okano 2:8d75eb0ecd20 300 char c;
okano 2:8d75eb0ecd20 301 static int i = 0;
okano 0:6baefda2e511 302
okano 3:3c380e643e74 303 while ( c = *s++ ) {
okano 0:6baefda2e511 304 target.putc( c );
okano 2:8d75eb0ecd20 305 leds = i++ & 0x1;
okano 2:8d75eb0ecd20 306 }
okano 0:6baefda2e511 307 }
okano 0:6baefda2e511 308
okano 0:6baefda2e511 309 void get_string( char *s )
okano 0:6baefda2e511 310 {
okano 0:6baefda2e511 311 int i = 0;
okano 0:6baefda2e511 312 char c = 0;
okano 0:6baefda2e511 313
okano 0:6baefda2e511 314 do {
okano 0:6baefda2e511 315 do {
okano 0:6baefda2e511 316 if ( target.readable() ) {
okano 0:6baefda2e511 317 c = target.getc();
okano 0:6baefda2e511 318
okano 0:6baefda2e511 319 if ( ( c == '\n') || (c == '\r') )
okano 0:6baefda2e511 320 break;
okano 0:6baefda2e511 321
okano 0:6baefda2e511 322 *s++ = c;
okano 0:6baefda2e511 323 i++;
okano 0:6baefda2e511 324 }
okano 0:6baefda2e511 325 } while ( 1 );
okano 0:6baefda2e511 326 } while ( !i );
okano 2:8d75eb0ecd20 327
okano 0:6baefda2e511 328 *s = '\0';
okano 0:6baefda2e511 329 }
okano 0:6baefda2e511 330