this transfers data (which is stored in "bin" file in mbed storage) into LPC1114, LPC1115, LPC81x, LPC82x, LPC1768/LPC1769 and LPC11U68/LPC11E68 internal flash memory through ISP.

Dependencies:   mbed MODSERIAL DirectoryList

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers writing.cpp Source File

writing.cpp

00001 
00002 #include    "mbed.h"
00003 #include    "writing.h"
00004 #include    "command_interface.h"
00005 #include    "uu_coding.h"
00006 #include    "serial_utilities.h"
00007 #include    "isp.h"
00008 #include    "_user_settings.h"
00009 
00010 
00011 int     write_uuencoded_data( FILE *fp, target_param *tpp, int *total_size_p, int file_size );
00012 int     write_binary_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start, int *total_size_p, int file_size );
00013 int     get_flash_writing_size( int ram_size, unsigned int ram_start );
00014 void    show_progress( int total_size, int file_size );
00015 
00016 
00017 int write_flash( FILE *fp, target_param *tpp, int *transferred_size_p, int file_size )
00018 {
00019     if ( tpp->write_type == BINARY )
00020         return ( write_binary_data(  fp, tpp->ram_size, tpp->sector_size, tpp->ram_start_address, transferred_size_p, file_size ) );
00021     else // UUENCODE
00022         return ( write_uuencoded_data( fp, tpp, transferred_size_p, file_size ) );
00023 }
00024 
00025 
00026 
00027 
00028 
00029 int write_uuencoded_data( FILE *fp, target_param *tpp, int *total_size_p, int file_size )
00030 {
00031 #define     BYTES_PER_LINE      45
00032 
00033     char    command_str[ STR_BUFF_SIZE ];
00034     long    checksum        = 0;
00035     int     size;
00036     int     total_size      = 0;
00037     int     sector_number;
00038 
00039     int     flash_writing_size;
00040     int     lines_per_transfer;
00041     int     transfer_size;
00042 
00043     char    *b;
00044 
00045     int ram_size            = tpp->ram_size;
00046     unsigned int ram_start  = tpp->ram_start_address;
00047 
00048     initialize_uue_table();
00049 
00050     flash_writing_size  = get_flash_writing_size( ram_size, ram_start );
00051     lines_per_transfer  = ((flash_writing_size / BYTES_PER_LINE) + 1);
00052     transfer_size       = (((flash_writing_size + 11) / 12) * 12);
00053 
00054     //  char    b[ transfer_size ]; // this can be done in mbed-compiler. but I should do it in common way
00055 
00056     if ( NULL == (b = (char *)malloc( transfer_size * sizeof( char ) )) )
00057         return( ERROR_AT_MALLOC_FOR_WRITE_BUFF );
00058 
00059     for ( int i = flash_writing_size; i < transfer_size; i++ )
00060         b[ i ]  = 0;    //  this is not neccesary but just stuffing stuffing bytes
00061 
00062     while ( size    = fread( b, sizeof( char ), flash_writing_size, fp ) ) {
00063 
00064         if ( !total_size ) {
00065             //  overwriting 4 bytes data for address=0x1C
00066             //  there is a slot for checksum that is checked in (target's) boot process
00067             add_isp_checksum( b );
00068         }
00069 
00070         sprintf( command_str, "W %ld %ld\r\n", ram_start, transfer_size );
00071         if ( try_and_check( command_str, "0" ) )
00072             return ( ERROR_AT_WRITE_COMMAND );
00073 
00074         for ( int i = 0; i < lines_per_transfer; i++ ) {
00075 
00076             checksum   += bin2uue( b + (i * BYTES_PER_LINE), command_str, i == (lines_per_transfer - 1) ? (transfer_size % BYTES_PER_LINE) : BYTES_PER_LINE );
00077 
00078             //  printf( "  data -- %02d %s\r", i, command_str );
00079 
00080             put_string( command_str );
00081 
00082             if ( !((i + 1) % 20) ) {
00083                 if ( send_RAM_transfer_checksum( checksum ) )
00084                     return ( ERROR_AT_SENDING_CHECKSUM );
00085 
00086                 checksum   = 0;
00087             }
00088         }
00089 
00090         if ( send_RAM_transfer_checksum( checksum ) )
00091             return ( ERROR_AT_SENDING_CHECKSUM );
00092 
00093         checksum   = 0;
00094 
00095 //        sprintf( command_str, "P %d %d\r\n", total_size / sector_size, total_size / sector_size );
00096 
00097         sector_number   = find_sector( total_size, tpp );
00098         sprintf( command_str, "P %d %d\r\n", sector_number, sector_number );
00099 
00100         if ( try_and_check( command_str, "0" ) )
00101             return ( ERROR_AT_PREPARE_COMMAND );
00102 
00103         sprintf( command_str, "C %d %d %d\r\n", total_size, ram_start, flash_writing_size );
00104         if ( try_and_check( command_str, "0" ) )
00105             return ( ERROR_AT_COPY_COMMAND );
00106 
00107         total_size  += size;
00108 
00109 #ifdef ENABLE_PROGRESS_DISPLAY
00110         show_progress( total_size, file_size );
00111 #endif
00112     }
00113 
00114     free( b );
00115     *total_size_p   = total_size;
00116 
00117     return ( NO_ERROR );
00118 }
00119 
00120 
00121 int write_binary_data( FILE *fp, int ram_size, int sector_size, unsigned int ram_start, int *total_size_p, int file_size )
00122 {
00123     char    command_str[ STR_BUFF_SIZE ];
00124     int     total_size  = 0;
00125     int     size;
00126     int     flash_writing_size;
00127     char    *b;
00128 
00129     flash_writing_size  = 256;
00130 
00131     if ( NULL == (b     = (char *)malloc( flash_writing_size * sizeof( char ) )) )
00132         return( ERROR_AT_MALLOC_FOR_WRITE_BUFF );
00133 
00134     while ( size    = fread( b, sizeof( char ), flash_writing_size, fp ) ) {
00135 
00136         if ( !total_size ) {
00137             //  overwriting 4 bytes data for address=0x1C
00138             //  there is a slot for checksum that is checked in (target's) boot process
00139             add_isp_checksum( b );
00140         }
00141 
00142         sprintf( command_str, "W %ld %ld\r\n", ram_start, flash_writing_size );
00143         if ( try_and_check( command_str, "0" ) )
00144             return ( ERROR_AT_WRITE_COMMAND );
00145 
00146         put_binary( b, flash_writing_size );
00147         put_string( "\r\n" );
00148 
00149         sprintf( command_str, "P %d %d\r\n", total_size / sector_size, total_size / sector_size );
00150         if ( try_and_check( command_str, "0" ) )
00151             return ( ERROR_AT_PREPARE_COMMAND );
00152 
00153         sprintf( command_str, "C %d %d %d\r\n", total_size, ram_start, flash_writing_size );
00154         if ( try_and_check( command_str, "0" ) )
00155             return ( ERROR_AT_COPY_COMMAND );
00156 
00157         total_size  += size;
00158         //printf( "  total %d bytes transferred\r", total_size );
00159 
00160 #ifdef ENABLE_PROGRESS_DISPLAY
00161         show_progress( total_size, file_size );
00162 #endif
00163     }
00164 
00165     free( b );
00166     *total_size_p   = total_size;
00167 
00168     return ( NO_ERROR );
00169 }
00170 
00171 
00172 void add_isp_checksum( char *b )
00173 {
00174     //  see http://www.lpcware.com/content/nxpfile/lpc177x8x-checksum-insertion-program
00175 
00176     unsigned int    *p;
00177     unsigned int    cksum   = 0;
00178 
00179     p  = (unsigned int *)b;
00180 
00181     for ( int i = 0; i < 7; i++ ) {
00182         cksum   += *p++;
00183     }
00184 
00185     printf( "  -- value at checksum slot : 0x%08X\r\n", *p );
00186 
00187     *p  = 0xFFFFFFFF - cksum + 1;
00188     printf( "  -- calculated checksum    : 0x%08X\r\n", *p );
00189 
00190     printf( "     new checksum will be used programing flash\r\n" );
00191 }
00192 
00193 
00194 int get_flash_writing_size( int ram_size, unsigned int ram_start )
00195 {
00196     int flash_writing_size[]    = {
00197         4096,
00198         1024,
00199         512,
00200         256
00201     };
00202     int     available_size;
00203     int     i;
00204 
00205     available_size  = ram_size - (ram_start & 0xFFFF);
00206 
00207     for ( i = 0; i < sizeof( flash_writing_size ) / sizeof( int ); i++ ) {
00208         if ( flash_writing_size[ i ] < available_size )
00209             break;
00210     }
00211 
00212     return ( flash_writing_size[ i ] );
00213 }
00214 
00215 
00216 int post_writing_process( target_param *tpp )
00217 {
00218     if ( tpp->write_type == UUENCODE )
00219         return ( try_and_check( "G 0 T\r\n", "0" ) );
00220     else
00221         return ( 0 );
00222 }