Add to 11U68 11E68
Dependencies: DirectoryList MODSERIAL mbed
Fork of ika_shouyu_poppoyaki by
main.cpp
- Committer:
- okano
- Date:
- 2013-09-13
- Revision:
- 22:bd98a782fba6
- Parent:
- 21:e149d0bdbf4a
- Child:
- 23:017f306cf3ca
File content as of revision 22:bd98a782fba6:
/** * Sample of ISP operation for NXP MCUs * * @author Tedd OKANO * @version 0.8 * @date Sep-2013 * * This program programs MCU flash memory through UART. It uses * "In-System Programming (ISP)" interface in target MCU (NXP LPC micro- * controllers). * * The ISP is done by PC and serial cable normally. The ISP protocol is * executed software on a PC. The software reads a data file and transfers * the data with the ISP protocol. * This program does same process of that. The mbed perform the function like * "FlashMagic" and "lpc21isp". * (This program not just copies the binary but also insert 4 byte checksum at * address 0x1C.) * * This program currently supports LPC1114(LPC1114FN28/102 - DIP28-ARM) and * LPC810(LPC810M021FN8 - DIP8-ARM). */ #include "mbed.h" #include "target_table.h" #include "serial_utilities.h" #include "command_interface.h" #include "writing.h" #include "uu_coding.h" #include "ika.h" BusOut leds( LED4, LED3, LED2, LED1 ); DigitalOut reset_pin( p26 ); DigitalOut isp_pin( p25 ); LocalFileSystem local( "local" ); Ticker success; #define ENTER_TO_ISP_MODE 0 #define NO_ISP_MODE 1 #define SOURCE_FILE "/local/bin" // "ISP_BAUD_RATE" is baud rate for ISP operation #define ISP_BAUD_RATE 115200 //#define ISP_BAUD_RATE 57600 //#define ISP_BAUD_RATE 9600 // "TARGET_OPERATION_BAUD_RATE" is baud rate for USB-serial bridge operation after // ISP completion. // if the target application uses serial(UART) and you use the bridge feature, // please set this value correctly. #define TARGET_OPERATION_BAUD_RATE 9600 int error_state = 0; target_param *open_target( int baud_date ); int verify_flash( FILE *fp, target_param *tpp ); int post_writing_process( target_param *tpp ); int file_size( FILE *fp ); void reset_target( int isp_pin_state ); char read_byte( void ); void erase_sectors( int last_sector ); int verify_binary_data( FILE *fp ); int verify_uucoded_data( FILE *fp ); void get_binary_from_uucode_str( char *b, int size ); void success_indicator(); #pragma diag_suppress 1293 // surpressing a warning message of "assignment in condition" ;) int main() { FILE *fp; target_param *tpp; int data_size; int last_sector; printf( "\r\n\r\n\r\nmbed ISP program : programming LPC device from mbed\r\n" ); if ( NULL == (tpp = open_target( ISP_BAUD_RATE )) ) { error( "couldn't open the taget" ); return ( 1 ); } printf( " target device found : type = \"%s\"\r\n", tpp->type_name ); printf( " ID = 0x%08X\r\n", tpp->id ); printf( " RAM size = %10d bytes\r\n", tpp->ram_size ); printf( " flash size = %10d bytes\r\n", tpp->flash_size ); printf( " opening file: \"%s\"\r\n", SOURCE_FILE ); if ( NULL == (fp = fopen( SOURCE_FILE, "rb" )) ) { error( "couldn't open source file" ); return ( 1 ); } data_size = file_size( fp ); last_sector = data_size / tpp->sector_size; printf( " data size = %d bytes, it takes %d secotrs in flash area\r\n", data_size, last_sector + 1 ); printf( " resetting target\r\n" ); erase_sectors( last_sector ); write_flash( fp, tpp ); verify_flash( fp, tpp ); fclose( fp ); printf( "\r\n %s\r\n\r\n", error_state ? "** The data could not be written :(" : "** The data has been written successflly :)" ); if ( error_state ) error( " ** ISP failed\r\n" ); post_writing_process( tpp ); #define AUTO_PROGRAM_START #ifdef AUTO_PROGRAM_START set_target_baud_rate( TARGET_OPERATION_BAUD_RATE ); reset_target( NO_ISP_MODE ); printf( " ** The program in flash has been started!!\r\n" ); #endif printf( " (now the mbed is working in \"serial through mode\")\r\n\r\n" ); success.attach( &success_indicator, 0.1 ); usb_serial_bridge_operation(); // doesn't return. infinite loop in this function } int verify_flash( FILE *fp, target_param *tpp ) { if ( tpp->write_type == BINARY ) verify_binary_data( fp ); else verify_uucoded_data( fp ); } int post_writing_process( target_param *tpp ) { if ( tpp->write_type == UUENCODE ) try_and_check( "G 0 T\r\n", "0", 0 ); } int file_size( FILE *fp ) { int size; fseek( fp, 0, SEEK_END ); // seek to end of file size = ftell( fp ); // get current file pointer fseek( fp, 0, SEEK_SET ); // seek back to beginning of file return size; } target_param *open_target( int baud_date ) { target_param *tpp; char str_buf0[ STR_BUFF_SIZE ]; char str_buf1[ STR_BUFF_SIZE ]; set_target_baud_rate( baud_date ); reset_target( ENTER_TO_ISP_MODE ); try_and_check( "?", "Synchronized", 0 ); try_and_check2( "Synchronized\r\n", "OK", 0 ); try_and_check2( "12000\r\n", "OK", 0 ); try_and_check2( "U 23130\r\n", "0", 0 ); try_and_check2( "A 0\r\n", "0", 0 ); try_and_check( "K\r\n", "0", 0 ); get_string( str_buf0 ); get_string( str_buf1 ); printf( " result of \"K\" = %s %s\r\n", str_buf0, str_buf1 ); try_and_check( "J\r\n", "0", 0 ); get_string( str_buf0 ); printf( " result of \"J\" = %s\r\n", str_buf0 ); tpp = find_target_param( str_buf0 ); return ( tpp ); } void reset_target( int isp_pin_state ) { reset_pin = 1; isp_pin = isp_pin_state; wait_ms( 100 ); reset_pin = 0; wait_ms( 100 ); reset_pin = 1; wait_ms( 100 ); } void erase_sectors( int last_sector ) { char command_str[ STR_BUFF_SIZE ]; sprintf( command_str, "P 0 %d\r\n", last_sector ); try_and_check( command_str, "0", 0 ); *(command_str) = 'E'; try_and_check( command_str, "0", 0 ); } int verify_binary_data( FILE *fp ) { char command_str[ STR_BUFF_SIZE ]; int read_size = 0; int size; int flash_reading_size; char *bf; char *br; int error_flag = 0; unsigned long checksum = 0; unsigned long checksum_count = 0; fseek( fp, 0, SEEK_SET ); // seek back to beginning of file flash_reading_size = 128; if ( NULL == (bf = (char *)malloc( flash_reading_size * sizeof( char ) )) ) error( "malloc error happened (in verify process, file data buffer)\r\n" ); if ( NULL == (br = (char *)malloc( flash_reading_size * sizeof( char ) )) ) error( "malloc error happened (in verify process, read data buffer)\r\n" ); printf( "\r\n ==== flash reading and verifying ====\r\n" ); while ( size = fread( bf, sizeof( char ), flash_reading_size, fp ) ) { if ( read_size < 0x20 ) { for ( int i = 0; i < flash_reading_size; i += 4 ) { if ( checksum_count == 7 ) { checksum = 0xFFFFFFFF - checksum + 1; *((unsigned int *)(bf + i)) = checksum; //printf( "\r\n\r\n -- calculated checksum : 0x%08X\r\n", checksum ); } else { checksum += *((unsigned int *)(bf + i)); } checksum_count++; } } sprintf( command_str, "R %ld %ld\r\n", read_size, size ); // try_and_check( command_str, "0", MODE_SILENT ); try_and_check( command_str, "0", 0 ); get_binary( br, 1 ); get_binary( br, size ); for ( int i = 0; i < size; i++ ) { // printf( " %s 0x%02X --- 0x%02X\r\n", (*(bf + i) != *(br + i)) ? "***" : " ", *(bf + i), *(br + i) ); if ( (*(bf + i) != *(br + i)) ) { // printf( " %s 0x%02X --- 0x%02X\r\n", (*(bf + i) != *(br + i)) ? "***" : " ", *(bf + i), *(br + i) ); error_flag++; } } if ( error_flag ) break; read_size += size; // printf( " total %d bytes read\r\n", read_size ); } error_state |= error_flag; printf( " total %d bytes read\r", read_size ); printf( " verification result : \"%s\"\r\n", error_flag ? "Fail" : "Pass" ); free( bf ); free( br ); return ( read_size ); } int verify_uucoded_data( FILE *fp ) { char command_str[ STR_BUFF_SIZE ]; int read_size = 0; int size; int flash_reading_size; char *bf; char *br; int error_flag = 0; flash_reading_size = 176; initialize_uud_table(); if ( NULL == (bf = (char *)malloc( flash_reading_size * sizeof( char ) )) ) error( "malloc error happened (in verify process, file data buffer)\r\n" ); if ( NULL == (br = (char *)malloc( flash_reading_size * sizeof( char ) )) ) error( "malloc error happened (in verify process, read data buffer)\r\n" ); fseek( fp, 0, SEEK_SET ); // seek back to beginning of file while ( size = fread( bf, sizeof( char ), flash_reading_size, fp ) ) { if ( !read_size ) { // overwriting 4 bytes data for address=0x1C // there is a slot for checksum that is checked in (target's) boot process add_isp_checksum( bf ); } sprintf( command_str, "R %ld %ld\r\n", read_size, size ); try_and_check( command_str, "0", 0 ); get_binary_from_uucode_str( br, size ); for ( int i = 0; i < size; i++ ) { // printf( " %s 0x%02X --- 0x%02X\r\n", (*(bf + i) != *(br + i)) ? "***" : " ", *(bf + i), *(br + i) ); if ( (*(bf + i) != *(br + i)) ) { printf( " %s 0x%02X --- 0x%02X\r\n", (*(bf + i) != *(br + i)) ? "***" : " ", *(bf + i), *(br + i) ); error_flag++; } } if ( error_flag ) break; read_size += size; // printf( " total %d bytes read\r", read_size ); } error_state |= error_flag; printf( " total %d bytes read\r", read_size ); printf( " verification result : \"%s\"\r\n", error_flag ? "Fail" : "Pass" ); free( bf ); free( br ); return ( read_size ); } void get_binary_from_uucode_str( char *b, int size ) { #define N 4 char s[ N ][ STR_BUFF_SIZE ]; char ss[ STR_BUFF_SIZE ]; long checksum = 0; int line_count = 0; int read_size = 0; int retry_count = 3; while ( retry_count-- ) { for ( int i = 0; i < N; i++ ) get_string( s[ i ] ); get_string( ss ); while ( size ) { read_size = uudecode_a_line( b, s[ line_count ] ); for ( int i = 0; i < read_size; i++ ) checksum += *b++; size -= read_size; line_count++; } // printf( " checksum -- %s (internal = %ld)\r\n", ss, checksum ); if ( checksum == atol( ss ) ) { put_string( "OK\r\n" ); return; // printf( " checksum OK\r\n" ); } else { printf( " checksum RESEND\r\n" ); put_string( "RESEND\r\n" ); } } } void success_indicator() { static int i = 0; leds = 0x1 << (i++ & 0x3); } void set_leds( char v ) { leds = v; }