Ika Shouyu Poppoyaki - LPC82x supported

Dependencies:   MODSERIAL mbed

Fork of ika_shouyu_poppoyaki by Tedd OKANO

main.cpp

Committer:
okano
Date:
2013-08-25
Revision:
5:ff30f5b58617
Parent:
4:55f1977bd11a
Child:
6:0ae6fe8c8512

File content as of revision 5:ff30f5b58617:

#include    "mbed.h"
#include    "target_table.h"

BusOut          leds( LED4, LED3, LED2, LED1 );
DigitalOut      reset_pin( p26 );
DigitalOut      isp_pin( p25 );
Serial          target ( p28, p27 );
LocalFileSystem local( "local" );

#define     SOURCE_FILE         "/local/bin"
//#define     BAUD_RATE           9600
//#define     BAUD_RATE           57600
#define     BAUD_RATE           115200

#define     STR_BUFF_SIZE       64
//#define     RAM_START_ADDRESS   0x10000300L
#define     RAM_START_ADDRESS   0x10000200L
#define     SECTOR_SIZE         4096

//#define     FLASH_WRITING_SIZE  1024            //  This value should be 256, 512, 1024 or 4096
#define     FLASH_WRITING_SIZE  256            //  This value should be 256, 512, 1024 or 4096
#define     LINES_PER_TRANSFER  (((FLASH_WRITING_SIZE / 45) + 3) & ~0x3)
#define     TRANSFER_SIZE       (LINES_PER_TRANSFER * 45)


enum {
    ENTER_TO_ISP_MODE,
    NO_ISP_MODE
};

void put_string( char *s );
void get_string( char *s );

#pragma diag_suppress 1293


void print_command( char *command )
{
    char    s[ STR_BUFF_SIZE ];
    char    *pos;

    strcpy( s, command );

    if ( pos    = strchr( s, '\r' ) )
        *pos    = '\0';

    if ( pos    = strchr( s, '\n' ) )
        *pos    = '\0';

    printf( "  command-\"%s\" : ", s );
}

void print_result( int r )
{
    printf( "%s\r\n", r ? "Fail" : "Pass" );
}

int try_and_check( char *command, char *expected_return_str, int mode )
{
    char    rtn_str[ STR_BUFF_SIZE ];
    int     result;

    print_command( command );
    put_string( command );

    get_string( rtn_str );
    print_result( result  = strcmp( expected_return_str, rtn_str ) );

    return ( result );
}

int try_and_check2( char *command, char *expected_return_str, int mode )
{
    char    rtn_str[ STR_BUFF_SIZE ];
    int     result;
    print_command( command );

    put_string( command );

    get_string( rtn_str );  // just readout echoback
    get_string( rtn_str );
    print_result( result  = strcmp( expected_return_str, rtn_str ) );

    return ( result );
}

char read_byte( void )
{
    while ( !target.readable() )
        ;

    return ( target.getc() );
}
char uue_table[ 64 ];

void initialize_uue_table( void )
{
    int     i;

    uue_table[0] = 0x60;           // 0x20 is translated to 0x60 !

    for (i = 1; i < 64; i++) {
        uue_table[i] = (char)(0x20 + i);
    }
}

long bin2uue( char *bin, char *str )
{
    unsigned long   v;
    long            checksum    = 0;
    int             strpos      = 0;

    *(str + strpos++) = ' ' + 45;

    for ( int i = 0; i < 45; i += 3 ) {
        checksum    += *(bin + i + 0) + *(bin + i + 1) + *(bin + i + 2);
        v   = (*(bin + i + 0) << 16) | (*(bin + i + 1) << 8) | (*(bin + i + 2) << 0);
        *(str + strpos++) = uue_table[ (v >> 18) & 0x3F ];
        *(str + strpos++) = uue_table[ (v >> 12) & 0x3F ];
        *(str + strpos++) = uue_table[ (v >>  6) & 0x3F ];
        *(str + strpos++) = uue_table[ (v >>  0) & 0x3F ];
    }
    *(str + strpos++) = '\n';
    *(str + strpos++) = '\0';

    return checksum;
}

void add_isp_checksum( char *b )
{
    //  see http://www.lpcware.com/content/nxpfile/lpc177x8x-checksum-insertion-program

    unsigned int    *p;
    unsigned int    cksum   = 0;

    p  = (unsigned int *)b;

    for ( int i = 0; i < 7; i++ ) {
        cksum   += *p++;
    }

    printf( "  -- value at checksum slot : 0x%08X\r\n", *p );

    *p  = 0xFFFFFFFF - cksum + 1;
    printf( "  -- calculated checksum    : 0x%08X\r\n", *p );

    printf( "     new checksum will be used to program flash\r\n" );
}



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


void send_RAM_transfer_checksum( int checksum )
{
    char    command[ 16 ];

    sprintf( command, "%d\n", checksum );
    try_and_check( command, "OK", 0 );
}


char    b[ TRANSFER_SIZE ];

void write_binary_data( FILE *fp )
{
    char    command_str[ STR_BUFF_SIZE ];
    long    checksum        = 0;
    int     transfer_count  = 0;
    int     total_size      = 0;
    int     size;

    initialize_uue_table();

    for ( int i = FLASH_WRITING_SIZE; i < TRANSFER_SIZE; i++ )
        b[ i ]  = 0;    //  this is not neccesary but just stuffing stuffing bytes

    while ( size    = fread( b, sizeof( char ), FLASH_WRITING_SIZE, fp ) ) {

        if ( !total_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( b );
        }

        sprintf( command_str, "W %ld %ld\r\n", RAM_START_ADDRESS, TRANSFER_SIZE );
        try_and_check( command_str, "0", 0 );

        for ( int i = 0; i < LINES_PER_TRANSFER; i++ ) {
            checksum   += bin2uue( b + (i * 45), command_str );

            printf( "%02d %s\r", i, command_str );

            put_string( command_str );

            if ( !((i + 1) % 20) ) {
                send_RAM_transfer_checksum( checksum );
                checksum   = 0;
            }
        }

        send_RAM_transfer_checksum( checksum );
        checksum   = 0;

        sprintf( command_str, "P %d %d\r\n", total_size / SECTOR_SIZE, total_size / SECTOR_SIZE );
        try_and_check( command_str, "0", 0 );

        sprintf( command_str, "C %d %d %d\r\n", total_size, RAM_START_ADDRESS, FLASH_WRITING_SIZE );
        try_and_check( command_str, "0", 0 );

        total_size  += size;
    }
    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 reset_target( int isp_pin_state )
{
    reset_pin   = 1;
    isp_pin = 0;
    wait_ms( 100 );
    reset_pin   = 0;
    wait_ms( 100 );
    reset_pin   = 1;
    wait_ms( 100 );
}

int main()
{
    FILE            *fp;
    char            str_buf0[ STR_BUFF_SIZE ];
    char            str_buf1[ STR_BUFF_SIZE ];
    int             data_size;
    int             last_sector;
    target_param    *tpp;

    target.baud( BAUD_RATE );

    if ( NULL == (fp    = fopen( SOURCE_FILE, "rb" )) ) {
        error( "couldn't open source file" );
        return ( 1 );
    }

    data_size   = file_size( fp );
    last_sector = data_size / SECTOR_SIZE;
    printf( "\r\n\r\ntarget RESET\r\n" );
    printf( "data size = %d bytes, it takes %d secotrs in flash area\r\n", data_size, last_sector + 1 );

    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 );
    printf( "target device found : type       = \"%s\"\r\n",   tpp->type_name );
    printf( "                      ID         = 0x%08X\r\n", tpp->id );
    printf( "                      RAM size   = %7d bytes\r\n", tpp->ram_size );
    printf( "                      flash size = %7d bytes\r\n", tpp->flash_size );

    erase_sectors( last_sector );
    write_binary_data( fp );

    fclose( fp );

    int i   = 0;

    while ( 1 ) {
        leds    = 0x1 << (i++ & 0x3);
        wait( 0.1 );
    }
}


void put_string( char *s )
{
    char            c;
    static int      i   = 0;

    while ( c = *s++ ) {
        target.putc( c );
        leds    = i++ & 0x1;
    }
}

void get_string( char *s )
{
    int     i   = 0;
    char    c   = 0;

    do {
        do {
            if ( target.readable() ) {
                c  = target.getc();

                if ( ( c == '\n') || (c == '\r') )
                    break;

                *s++    = c;
                i++;
            }
        } while ( 1 );
    } while ( !i );

    *s  = '\0';
}