Ika Shouyu Poppoyaki - LPC82x supported

Dependencies:   MODSERIAL mbed

Fork of ika_shouyu_poppoyaki by Tedd OKANO

main.cpp

Committer:
okano
Date:
2013-09-13
Revision:
23:017f306cf3ca
Parent:
22:bd98a782fba6
Child:
24:9830b4f1207b

File content as of revision 23:017f306cf3ca:

/**
 *  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    "target_handling.h"
#include    "ika.h"


BusOut          leds( LED4, LED3, LED2, LED1 );
LocalFileSystem local( "local" );
Ticker          success;





#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;

int     verify_flash( FILE *fp, target_param *tpp );
int     post_writing_process( target_param *tpp );

int     file_size( FILE *fp );
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;
}




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;
}