Ika Shouyu Poppoyaki - LPC82x supported

Dependencies:   MODSERIAL mbed

Fork of ika_shouyu_poppoyaki by Tedd OKANO

Committer:
okano
Date:
Fri Sep 13 03:09:09 2013 +0000
Revision:
21:e149d0bdbf4a
Parent:
20:98d7b5878e3e
Child:
22:bd98a782fba6
"command_utilities" module made

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