Add to 11U68 11E68
Dependencies: DirectoryList MODSERIAL mbed
Fork of ika_shouyu_poppoyaki by
writing.cpp@29:96e28bc1bd99, 2013-09-20 (annotated)
- Committer:
- okano
- Date:
- Fri Sep 20 01:48:26 2013 +0000
- Revision:
- 29:96e28bc1bd99
- Parent:
- 28:689c3880e0e4
- Child:
- 30:e0d7524661ca
parameter added to writing and verifying functions to report transferred size
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
okano | 22:bd98a782fba6 | 1 | |
okano | 22:bd98a782fba6 | 2 | #include "mbed.h" |
okano | 22:bd98a782fba6 | 3 | #include "writing.h" |
okano | 22:bd98a782fba6 | 4 | #include "command_interface.h" |
okano | 22:bd98a782fba6 | 5 | #include "uu_coding.h" |
okano | 22:bd98a782fba6 | 6 | #include "serial_utilities.h" |
okano | 24:9830b4f1207b | 7 | #include "ika.h" |
okano | 28:689c3880e0e4 | 8 | #include "error_code.h" |
okano | 22:bd98a782fba6 | 9 | |
okano | 22:bd98a782fba6 | 10 | |
okano | 29:96e28bc1bd99 | 11 | int write_uuencoded_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start, int *total_size_p ); |
okano | 29:96e28bc1bd99 | 12 | int write_binary_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start, int *total_size_p ); |
okano | 22:bd98a782fba6 | 13 | int get_flash_writing_size( int ram_size, unsigned int ram_start ); |
okano | 22:bd98a782fba6 | 14 | |
okano | 22:bd98a782fba6 | 15 | |
okano | 29:96e28bc1bd99 | 16 | int write_flash( FILE *fp, target_param *tpp, int *transferred_size_p ) |
okano | 22:bd98a782fba6 | 17 | { |
okano | 22:bd98a782fba6 | 18 | if ( tpp->write_type == BINARY ) |
okano | 29:96e28bc1bd99 | 19 | return ( write_binary_data( fp, tpp->ram_size, tpp->sector_size, tpp->ram_start_address, transferred_size_p ) ); |
okano | 22:bd98a782fba6 | 20 | else // UUENCODE |
okano | 29:96e28bc1bd99 | 21 | return ( write_uuencoded_data( fp, tpp->ram_size, tpp->sector_size, tpp->ram_start_address, transferred_size_p ) ); |
okano | 22:bd98a782fba6 | 22 | } |
okano | 22:bd98a782fba6 | 23 | |
okano | 22:bd98a782fba6 | 24 | |
okano | 29:96e28bc1bd99 | 25 | int write_uuencoded_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start, int *total_size_p ) |
okano | 22:bd98a782fba6 | 26 | { |
okano | 22:bd98a782fba6 | 27 | #define BYTES_PER_LINE 45 |
okano | 22:bd98a782fba6 | 28 | |
okano | 22:bd98a782fba6 | 29 | char command_str[ STR_BUFF_SIZE ]; |
okano | 22:bd98a782fba6 | 30 | long checksum = 0; |
okano | 29:96e28bc1bd99 | 31 | int size; |
okano | 22:bd98a782fba6 | 32 | int total_size = 0; |
okano | 22:bd98a782fba6 | 33 | |
okano | 22:bd98a782fba6 | 34 | int flash_writing_size; |
okano | 22:bd98a782fba6 | 35 | int lines_per_transfer; |
okano | 22:bd98a782fba6 | 36 | int transfer_size; |
okano | 22:bd98a782fba6 | 37 | |
okano | 22:bd98a782fba6 | 38 | char *b; |
okano | 22:bd98a782fba6 | 39 | |
okano | 29:96e28bc1bd99 | 40 | |
okano | 22:bd98a782fba6 | 41 | initialize_uue_table(); |
okano | 22:bd98a782fba6 | 42 | |
okano | 22:bd98a782fba6 | 43 | flash_writing_size = get_flash_writing_size( ram_size, ram_start ); |
okano | 22:bd98a782fba6 | 44 | lines_per_transfer = ((flash_writing_size / BYTES_PER_LINE) + 1); |
okano | 22:bd98a782fba6 | 45 | transfer_size = (((flash_writing_size + 11) / 12) * 12); |
okano | 22:bd98a782fba6 | 46 | |
okano | 22:bd98a782fba6 | 47 | // char b[ transfer_size ]; // this can be done in mbed-compiler. but I should do it in common way |
okano | 22:bd98a782fba6 | 48 | |
okano | 22:bd98a782fba6 | 49 | if ( NULL == (b = (char *)malloc( transfer_size * sizeof( char ) )) ) |
okano | 28:689c3880e0e4 | 50 | return( ERROR_AT_MALLOC_FOR_WRITE_BUFF ); |
okano | 22:bd98a782fba6 | 51 | |
okano | 22:bd98a782fba6 | 52 | for ( int i = flash_writing_size; i < transfer_size; i++ ) |
okano | 22:bd98a782fba6 | 53 | b[ i ] = 0; // this is not neccesary but just stuffing stuffing bytes |
okano | 22:bd98a782fba6 | 54 | |
okano | 22:bd98a782fba6 | 55 | while ( size = fread( b, sizeof( char ), flash_writing_size, fp ) ) { |
okano | 22:bd98a782fba6 | 56 | |
okano | 22:bd98a782fba6 | 57 | if ( !total_size ) { |
okano | 22:bd98a782fba6 | 58 | // overwriting 4 bytes data for address=0x1C |
okano | 22:bd98a782fba6 | 59 | // there is a slot for checksum that is checked in (target's) boot process |
okano | 22:bd98a782fba6 | 60 | add_isp_checksum( b ); |
okano | 22:bd98a782fba6 | 61 | } |
okano | 22:bd98a782fba6 | 62 | |
okano | 22:bd98a782fba6 | 63 | sprintf( command_str, "W %ld %ld\r\n", ram_start, transfer_size ); |
okano | 27:2b5c1eb39bb5 | 64 | if ( try_and_check( command_str, "0", 0 ) ) |
okano | 27:2b5c1eb39bb5 | 65 | return ( ERROR_AT_WRITE_COMMAND ); |
okano | 22:bd98a782fba6 | 66 | |
okano | 22:bd98a782fba6 | 67 | for ( int i = 0; i < lines_per_transfer; i++ ) { |
okano | 22:bd98a782fba6 | 68 | |
okano | 22:bd98a782fba6 | 69 | checksum += bin2uue( b + (i * BYTES_PER_LINE), command_str, i == (lines_per_transfer - 1) ? (transfer_size % BYTES_PER_LINE) : BYTES_PER_LINE ); |
okano | 22:bd98a782fba6 | 70 | |
okano | 22:bd98a782fba6 | 71 | // printf( " data -- %02d %s\r", i, command_str ); |
okano | 22:bd98a782fba6 | 72 | |
okano | 22:bd98a782fba6 | 73 | put_string( command_str ); |
okano | 22:bd98a782fba6 | 74 | |
okano | 22:bd98a782fba6 | 75 | if ( !((i + 1) % 20) ) { |
okano | 28:689c3880e0e4 | 76 | if ( send_RAM_transfer_checksum( checksum ) ) |
okano | 28:689c3880e0e4 | 77 | return ( ERROR_AT_SENDING_CHECKSUM ); |
okano | 28:689c3880e0e4 | 78 | |
okano | 22:bd98a782fba6 | 79 | checksum = 0; |
okano | 22:bd98a782fba6 | 80 | } |
okano | 22:bd98a782fba6 | 81 | } |
okano | 22:bd98a782fba6 | 82 | |
okano | 28:689c3880e0e4 | 83 | if ( send_RAM_transfer_checksum( checksum ) ) |
okano | 28:689c3880e0e4 | 84 | return ( ERROR_AT_SENDING_CHECKSUM ); |
okano | 28:689c3880e0e4 | 85 | |
okano | 22:bd98a782fba6 | 86 | checksum = 0; |
okano | 22:bd98a782fba6 | 87 | |
okano | 22:bd98a782fba6 | 88 | sprintf( command_str, "P %d %d\r\n", total_size / sector_size, total_size / sector_size ); |
okano | 27:2b5c1eb39bb5 | 89 | if ( try_and_check( command_str, "0", 0 ) ) |
okano | 28:689c3880e0e4 | 90 | return ( ERROR_AT_PREPARE_COMMAND ); |
okano | 22:bd98a782fba6 | 91 | |
okano | 22:bd98a782fba6 | 92 | sprintf( command_str, "C %d %d %d\r\n", total_size, ram_start, flash_writing_size ); |
okano | 27:2b5c1eb39bb5 | 93 | if ( try_and_check( command_str, "0", 0 ) ) |
okano | 27:2b5c1eb39bb5 | 94 | return ( ERROR_AT_COPY_COMMAND ); |
okano | 22:bd98a782fba6 | 95 | |
okano | 22:bd98a782fba6 | 96 | total_size += size; |
okano | 22:bd98a782fba6 | 97 | } |
okano | 22:bd98a782fba6 | 98 | |
okano | 22:bd98a782fba6 | 99 | free( b ); |
okano | 29:96e28bc1bd99 | 100 | *total_size_p = total_size; |
okano | 22:bd98a782fba6 | 101 | |
okano | 27:2b5c1eb39bb5 | 102 | return ( NO_ERROR ); |
okano | 22:bd98a782fba6 | 103 | } |
okano | 22:bd98a782fba6 | 104 | |
okano | 22:bd98a782fba6 | 105 | |
okano | 29:96e28bc1bd99 | 106 | int write_binary_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start, int *total_size_p ) |
okano | 22:bd98a782fba6 | 107 | { |
okano | 22:bd98a782fba6 | 108 | char command_str[ STR_BUFF_SIZE ]; |
okano | 29:96e28bc1bd99 | 109 | int total_size = 0; |
okano | 22:bd98a782fba6 | 110 | int size; |
okano | 22:bd98a782fba6 | 111 | int flash_writing_size; |
okano | 22:bd98a782fba6 | 112 | char *b; |
okano | 22:bd98a782fba6 | 113 | |
okano | 29:96e28bc1bd99 | 114 | |
okano | 22:bd98a782fba6 | 115 | flash_writing_size = 256; |
okano | 22:bd98a782fba6 | 116 | |
okano | 22:bd98a782fba6 | 117 | if ( NULL == (b = (char *)malloc( flash_writing_size * sizeof( char ) )) ) |
okano | 28:689c3880e0e4 | 118 | return( ERROR_AT_MALLOC_FOR_WRITE_BUFF ); |
okano | 22:bd98a782fba6 | 119 | |
okano | 22:bd98a782fba6 | 120 | while ( size = fread( b, sizeof( char ), flash_writing_size, fp ) ) { |
okano | 22:bd98a782fba6 | 121 | |
okano | 22:bd98a782fba6 | 122 | if ( !total_size ) { |
okano | 22:bd98a782fba6 | 123 | // overwriting 4 bytes data for address=0x1C |
okano | 22:bd98a782fba6 | 124 | // there is a slot for checksum that is checked in (target's) boot process |
okano | 22:bd98a782fba6 | 125 | add_isp_checksum( b ); |
okano | 22:bd98a782fba6 | 126 | } |
okano | 22:bd98a782fba6 | 127 | |
okano | 22:bd98a782fba6 | 128 | sprintf( command_str, "W %ld %ld\r\n", ram_start, flash_writing_size ); |
okano | 27:2b5c1eb39bb5 | 129 | if ( try_and_check( command_str, "0", 0 ) ) |
okano | 27:2b5c1eb39bb5 | 130 | return ( ERROR_AT_WRITE_COMMAND ); |
okano | 22:bd98a782fba6 | 131 | |
okano | 22:bd98a782fba6 | 132 | put_binary( b, flash_writing_size ); |
okano | 22:bd98a782fba6 | 133 | put_string( "\r\n" ); |
okano | 22:bd98a782fba6 | 134 | |
okano | 22:bd98a782fba6 | 135 | sprintf( command_str, "P %d %d\r\n", total_size / sector_size, total_size / sector_size ); |
okano | 27:2b5c1eb39bb5 | 136 | if ( try_and_check( command_str, "0", 0 ) ) |
okano | 28:689c3880e0e4 | 137 | return ( ERROR_AT_PREPARE_COMMAND ); |
okano | 22:bd98a782fba6 | 138 | |
okano | 22:bd98a782fba6 | 139 | sprintf( command_str, "C %d %d %d\r\n", total_size, ram_start, flash_writing_size ); |
okano | 27:2b5c1eb39bb5 | 140 | if ( try_and_check( command_str, "0", 0 ) ) |
okano | 27:2b5c1eb39bb5 | 141 | return ( ERROR_AT_COPY_COMMAND ); |
okano | 22:bd98a782fba6 | 142 | |
okano | 22:bd98a782fba6 | 143 | total_size += size; |
okano | 22:bd98a782fba6 | 144 | //printf( " total %d bytes transferred\r", total_size ); |
okano | 22:bd98a782fba6 | 145 | |
okano | 22:bd98a782fba6 | 146 | } |
okano | 22:bd98a782fba6 | 147 | |
okano | 22:bd98a782fba6 | 148 | free( b ); |
okano | 29:96e28bc1bd99 | 149 | *total_size_p = total_size; |
okano | 22:bd98a782fba6 | 150 | |
okano | 27:2b5c1eb39bb5 | 151 | return ( NO_ERROR ); |
okano | 22:bd98a782fba6 | 152 | } |
okano | 22:bd98a782fba6 | 153 | |
okano | 22:bd98a782fba6 | 154 | |
okano | 22:bd98a782fba6 | 155 | void add_isp_checksum( char *b ) |
okano | 22:bd98a782fba6 | 156 | { |
okano | 22:bd98a782fba6 | 157 | // see http://www.lpcware.com/content/nxpfile/lpc177x8x-checksum-insertion-program |
okano | 22:bd98a782fba6 | 158 | |
okano | 22:bd98a782fba6 | 159 | unsigned int *p; |
okano | 22:bd98a782fba6 | 160 | unsigned int cksum = 0; |
okano | 22:bd98a782fba6 | 161 | |
okano | 22:bd98a782fba6 | 162 | p = (unsigned int *)b; |
okano | 22:bd98a782fba6 | 163 | |
okano | 22:bd98a782fba6 | 164 | for ( int i = 0; i < 7; i++ ) { |
okano | 22:bd98a782fba6 | 165 | cksum += *p++; |
okano | 22:bd98a782fba6 | 166 | } |
okano | 22:bd98a782fba6 | 167 | |
okano | 22:bd98a782fba6 | 168 | printf( " -- value at checksum slot : 0x%08X\r\n", *p ); |
okano | 22:bd98a782fba6 | 169 | |
okano | 22:bd98a782fba6 | 170 | *p = 0xFFFFFFFF - cksum + 1; |
okano | 22:bd98a782fba6 | 171 | printf( " -- calculated checksum : 0x%08X\r\n", *p ); |
okano | 22:bd98a782fba6 | 172 | |
okano | 26:a63e73885b21 | 173 | printf( " new checksum will be used programing flash\r\n" ); |
okano | 22:bd98a782fba6 | 174 | } |
okano | 22:bd98a782fba6 | 175 | |
okano | 22:bd98a782fba6 | 176 | |
okano | 22:bd98a782fba6 | 177 | int get_flash_writing_size( int ram_size, unsigned int ram_start ) |
okano | 22:bd98a782fba6 | 178 | { |
okano | 22:bd98a782fba6 | 179 | int flash_writing_size[] = { |
okano | 22:bd98a782fba6 | 180 | 4096, |
okano | 22:bd98a782fba6 | 181 | 1024, |
okano | 22:bd98a782fba6 | 182 | 512, |
okano | 22:bd98a782fba6 | 183 | 256 |
okano | 22:bd98a782fba6 | 184 | }; |
okano | 22:bd98a782fba6 | 185 | int available_size; |
okano | 22:bd98a782fba6 | 186 | int i; |
okano | 22:bd98a782fba6 | 187 | |
okano | 22:bd98a782fba6 | 188 | available_size = ram_size - (ram_start & 0xFFFF); |
okano | 22:bd98a782fba6 | 189 | |
okano | 22:bd98a782fba6 | 190 | for ( i = 0; i < sizeof( flash_writing_size ) / sizeof( int ); i++ ) { |
okano | 22:bd98a782fba6 | 191 | if ( flash_writing_size[ i ] < available_size ) |
okano | 22:bd98a782fba6 | 192 | break; |
okano | 22:bd98a782fba6 | 193 | } |
okano | 22:bd98a782fba6 | 194 | |
okano | 22:bd98a782fba6 | 195 | return ( flash_writing_size[ i ] ); |
okano | 28:689c3880e0e4 | 196 | } |
okano | 28:689c3880e0e4 | 197 | |
okano | 28:689c3880e0e4 | 198 | |
okano | 28:689c3880e0e4 | 199 | int post_writing_process( target_param *tpp ) |
okano | 28:689c3880e0e4 | 200 | { |
okano | 28:689c3880e0e4 | 201 | if ( tpp->write_type == UUENCODE ) |
okano | 28:689c3880e0e4 | 202 | return ( try_and_check( "G 0 T\r\n", "0", 0 ) ); |
okano | 28:689c3880e0e4 | 203 | else |
okano | 28:689c3880e0e4 | 204 | return ( 0 ); |
okano | 28:689c3880e0e4 | 205 | } |
okano | 28:689c3880e0e4 | 206 |