Dependencies:   mbed

ISP.cpp

Committer:
daugihao
Date:
2011-09-30
Revision:
7:d0f98d61ec4c
Parent:
6:fab999f0e93b

File content as of revision 7:d0f98d61ec4c:

#include "mbed.h"
#include "LPC.h"

Serial pc(USBTX, USBRX);
LocalFileSystem local("fs");

int SerialBuffered::ProgramFile() {
    sum20 = 0; readAll = false; bytesfilled=45; lines=1; firstencode = true;
    char str0[] = "0";  //Command success string
    char strRAM[40];
    
    //Following arrays contain addresses and the size of the addresses 
    int sector[30] = {4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768};
    int startadd[30] = {0x0, 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000, 0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0x10000, 0x18000, 0x20000, 0x28000, 0x30000, 0x38000, 0x40000, 0x48000, 0x50000, 0x58000, 0x60000, 0x68000, 0x70000, 0x78000};
    
    pc.printf("\n\r**** LPCxxxx Flash Bootloader ****\n\r");
    if(CheckTargetPresent()==0) {
        pc.printf("ERROR: Communication failed with board. Ensure board reset and P2.10 pulled low before running mbed program! If the setup is correct, try lowering the baud rate, set in main.cpp.\r\n\n");  
        exit(0);
    }
    
    DIR *d = opendir("/fs"); //Opens the root directory of the local file system
    struct dirent *p;
    
    fname[0] = 0;
    while((p = readdir(d)) != NULL) { //Print the names of the files in the local file system
        if ( strcmp(p->d_name+strlen(p->d_name)-3,"LPC") == 0 )
        {
            strcpy(fname,"/fs/");
            strcat(fname,p->d_name);
        }
    }
    
    f = fopen(fname, "r");  //Opens the binary file for reading
    if (f == NULL) {
        pc.printf("ERROR: File not found. Ensure file exists in the mbed's local filesystem and is spelt correctly in the main.cpp\n\n\r");
        exit(0);
        return 1;
    } 
    else pc.printf("%s opened successfully\n\n\r", fname);
    
    sprintf(strRAM, "W %d 1024", RAM);
    TargetSendStringAndCR(strRAM);
    readBytes(buf, 3);
    if ( strncmp(buf,str0, 1) != 0 )
        return 0;
    
    pc.printf("Writing to chip (may take a couple of minutes)");
    
    FirstEncode();
    TargetSendString(uuline);
    fclose(f);
    f = fopen(fname, "r");
    fseek(f, 45, SEEK_SET);  //Skip forward past the 45 bytes already encoded in FirstEncode()
    remove("/fs/delete.bin");  //Remove temporary file
    
    int summation=0;
    for (int i=0; i<30; i++) {  //Works out number of sectors required and compares it with number available
        summation+=sector[i];
        if (summation>=filesize) {
            maxsector = i;
            break;
        }
    }
    if (lastSector<maxsector) {
            pc.printf("ERROR: File size too large for available FLASH memory\n\r");
            exit(0);
    }
    
    int totalloaded=0;
    for (int b=0; b<=maxsector; b++) {
        int data = sector[b];
        while (data>0) {
        SectorFill(startadd[b]+(sector[b]-data));
        data-=1024;
        totalloaded+=1024;
        if (totalloaded>=filesize)
            break;
        }
    }
        
    fclose(f);
    pc.printf("\n\n\rFLASH COMPLETED!\n\n\r");
    return 0;
}

int SerialBuffered::SectorFill(int add) {
    char sendStr[64];
    char str0[] = "0";
    char strOK[] = "OK";
    char strRAM[40];
    sprintf(strRAM, "W %d 1024", RAM);
        
    if (!firstencode) {
        TargetSendStringAndCR(strRAM);
        readBytes(buf, 3);
    }
    firstencode = false;
    
    while (bytesfilled<1024) {
        if (bytesfilled>=990) {        //If not enough room for a full UUEncoded line use EndUUEncode()
            EndUUEncode();
            TargetSendString(enduuline);
            sprintf(sendStr, "%d", sum20);      //Checksum
            TargetSendStringAndCR(sendStr);
            readBytes(buf, 4);
            if (strncmp(buf,strOK,2)!=0)
                pc.printf("ERROR: Line corrupted!\n\r");
            sum20=0; lines=0;
            pc.printf(".");
            break;
        }
        UUEncode();
        TargetSendString(uuline);
        bytesfilled+=45;
        lines++;
        if (lines==20) {
            sprintf(sendStr, "%d", sum20);      //Checksum
            TargetSendStringAndCR(sendStr);
            readBytes(buf, 4);
            if (strncmp(buf,strOK,2)!=0)
                pc.printf("ERROR: Line corrupted!\n\r");
            sum20=0; lines=0;
        }
    }
    
    sprintf(sendStr, "P 0 %d", lastSector);     //Fills the sendStr string with the prepare function specific to the chip as specified in the switch function
    TargetSendStringAndCR(sendStr);             //Prepares the Flash for writing to
    readBytes(buf, 3);
    if (strncmp(buf,str0,1)!=0)
        return 0;
    
    sprintf(sendStr, "C %d %d 1024", add, RAM);  //Copies data from the RAM to FLASH
    TargetSendStringAndCR(sendStr);
    readBytes(buf, 3);
    bytesfilled = 0; lines=0; sum20=0;
    return 0;
}

int SerialBuffered::CheckTargetPresent() {  //Synchronises the board with the mbed and prepares the RAM for writing to
    char strQn[] = "?";
    char str0[] = "0";
    char strJ[] = "J";
    char strEcho[] = "A 0";
    char strSync[] = "Synchronized";
    char strOk[] = "OK";
    char strUnlock[] = "U 23130";
    char sendStr[64];
    
    TargetSendString(strQn);                    //Sends a question mark and looks for "Synchronized" (wish it was spelt with an 's') to be returned
    readBytes(buf, 14);
    if (strncmp(buf,strSync, 12) != 0 )
        return 0;
    TargetSendStringAndCR(strSync);             //Sends "Synchronized" back and looks for "OK" to be returned
    readBytes(buf, 17);
    if (strcspn(buf,strOk) == 17 )
        return 0;
        
    TargetSendStringAndCR(speed);            //Sends "0" and waits for "OK" to be returned
    readBytes(buf, 5+strlen(speed));
    if ( strcspn(buf,strOk) == 5+strlen(speed) )
        return 0;
    
    TargetSendStringAndCR(strEcho);
    readBytes(buf,7);
    if (strcspn(buf,str0) == 7 )
        return 0;

    TargetSendStringAndCR(strJ);                //Sends "J" (ID code request) and reads the returned int
    readBytes(buf, 3);
    if (strncmp(buf,str0,1) != 0 )
        return 0;
    
    readBytes(buf,1);    
    while(buf[0]!=0x0D) {
        id = (id*10)+buf[0]-'0';
        readBytes(buf,1);
    }
    readBytes(buf,1);
    
    int finish = IDCheck(id);
    pc.printf("Chip to bootload: %s\n\r", strChipType);
    if (finish==2) exit(0);
        
    TargetSendStringAndCR(strUnlock);           //Unlocks the Flash for writing to
    readBytes(buf, 3);
    if ( strncmp(buf,str0,1) != 0 )
        return 0;
    
    sprintf(sendStr, "P 0 %d", lastSector);     //Fills the sendStr string with the prepare function specific to the chip as specified in the switch function
    TargetSendStringAndCR(sendStr);             //Prepares the Flash for writing to
    readBytes(buf, 3);
    if ( strncmp(buf,str0,1) != 0 )
        return 0;
    
    sprintf(sendStr, "E 0 %d", lastSector);
    TargetSendStringAndCR(sendStr);             //Erases the Flash completely, ready to be loaded
    readBytes(buf, 3);
    if ( strncmp(buf,str0,1) != 0 )
        return 0;

    pc.printf("Ready to write to chip\n\r");
    return 1;
}