Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

Re: JTag Flash programming

2005-05-26 by tom_laffey

Hi Søren,

I can't give you the whole program, but I can give you most of the 
pertinent sections.  I've cut'n'pasted the most applicable portions 
of the program here.

The program depends extensively on library functions that 
perform "semi-hosting."  I am using Greenhills tools; as far as I 
know, the other commercial tools provide this functionality also.  
Note that the printf() calls in the code also use semi-hosting and 
will print to a debugger window.

The program must be compiled and linked to run from LPC RAM.  You 
then use the debugger to load the program into RAM and run it like 
any other program.  The program uses the debugger connection to 
perform the file reads.

Best regards,


Tom




int main( int argc, int * argv )
{
    FILE    *inFile;

    char dwlndFile[200];

    int     bytesLeftInSector, endFile, len, rval, chkSum, index;
    ubit32  currOffset, hdrOffset, hdrState;
    run_dta_t * pHdr;
    startSector;

    /* need to ensure that the PLL is set up correctly in
     * order for flash program timing to be correct
     */
    lpcConfigPLL();

        startSector = SECTOR_FOR_THIS_IMAGE_TYPE;
        strcpy( &dwlndFile[0], "C:\\Documents and 
Settings\\<PATH>\\file.dld");	/* link to executable binary file, 
not ELF file */

    inFile = fopen(dwlndFile, "r");
    if( !inFile )
    {
        printf("Input file %s not accessible\n", dwlndFile);
        exit(1);
    }
    else
    {
        printf("\nFile opened, starting download at sector %d\n", 
startSector);
    }

    for( nextSector = startSector,
        currOffset = bytesLeftInSector = 0,
        endFile = FALSE;

        !endFile;

        currOffset = currOffset + len,
        bytesLeftInSector -= len
        )
    {
        /* check to see if we need to erase a sector */
        if( !bytesLeftInSector )
        {
            flashEraseSectorRange(nextSector, nextSector);
            bytesLeftInSector = flashSectors
[nextSector].sectorKB*1024;
            nextSector += 1;
        }

        /* fill flashBuf with erased value */
        memset( flashBuf, 0xFF, sizeof(flashBuf) );

        /* get some bytes */
        len = fread( flashBuf, 1, 512, inFile);

        if( (startSector == 0) && (currOffset == 0))
        {
            /* boot vector region must be checksummed */
            ubit32 oldChecksum;
            ubit32 * pVectors = (ubit32 *) flashBuf;

            oldChecksum = pVectors[VECTOR_CHECKSUM];
            pVectors[VECTOR_CHECKSUM] = 0;
            for( chkSum = index = 0; index <= VECTOR_FIQ; index++)
            {
                chkSum += pVectors[index];
            }
            pVectors[VECTOR_CHECKSUM]  = ~chkSum +1;    // 2's 
complement

            if( !oldChecksum || ( oldChecksum == pVectors
[VECTOR_CHECKSUM]))
            {
                printf( "Boot vector checksum is 0x%08X\n", pVectors
[VECTOR_CHECKSUM]);
            }
            else
            {
                printf( "WARNING: Boot vector checksum mismatch: 
Input file:0x%08X, Calculated flash value: 0x%08X\n",
                    oldChecksum, pVectors[VECTOR_CHECKSUM]);
            }

        }

        /* check len */
        if( len < 512 )
        {
            endFile = TRUE;

            while( len & 3 )
            {
                /* Need to align */
                len++;
            }
        }

        /* write the bytes to flash */
        rval = flashWritePage( (void *) flashSectors
[startSector].startOffset, currOffset, (ubit32 *) flashBuf );
        if( rval )
        {
            printf("Flash write failed. Error code is 0x%X\n", rval);
            exit(1);
        }

        rval = flashCompareFlashToBuffer((ubit8 *) flashSectors
[startSector].startOffset + currOffset, flashBuf, len);
        if( rval )
        {
            printf("Flash compare failed. Error code is 0x%X\n", 
rval);
            exit(1);
        }

    }
}




typedef struct _flash_appl_sectors
{
    ubit32  startOffset;
    ubit8   sectorKB;
    ubit8   sectorApplConst;
    ubit8   sectorRegionEnd;
    ubit8   reserved;
} flash_appl_sectors;

/* for the LPC2294 */
flash_appl_sectors const flashSectors[FLASH_NUM_SECTORS] =
{
    {0x0,       8,  TYPE_CONST,   1, 0},    // 0  
    {0x2000,    8,  TYPE_CONST, 1, 0},    // 1
    {0x4000,    8,  TYPE_CONST,   4, 0},    // 2
    {0x6000,    8,  TYPE_CONST,   4, 0},    // 3
    {0x8000,    8,  TYPE_CONST,   4, 0},    // 4
    {0xA000,    8,  TYPE_CONST,    8, 0},    // 5  
    {0xC000,    8,  TYPE_CONST,  8, 0},    // 6  
    {0xE000,    8,  TYPE_CONST,  8, 0},    // 7  
    {0x10000,   64, TYPE_CONST,  8, 0},    // 8  
    {0x20000,   64, TYPE_CONST,   12, 0},    // 9  
    {0x30000,   8,  TYPE_CONST, 12, 0},    // 10 
    {0x32000,   8,  TYPE_CONST, 12, 0},    // 11 
    {0x34000,   8,  TYPE_CONST, 12, 0},    // 12 
    {0x36000,   8,  TYPE_CONST,  13, 0},    // 13
    {0x38000,   8,  TYPE_CONST,  14, 0},    // 14
    {0x3A000,   8,  TYPE_CONST,  15, 0},    // 15
    {0x3C000,   8,  TYPE_CONST,  16, 0}     // 16
};


static void flashCallROMDisabled( ubit32 * command, ubit32 * result)
{
    ubit32 CPSR;
    IAP iap_entry = (IAP) IAP_LOCATION;		/* see philips app 
note */

    CPSR = __GETSR();
    __SETSR(CPSR | INT_MASK);

    iap_entry(command, result);

    __SETSR(CPSR);

}



bit32 flashWritePage(void * baseAddr, ubit32 offset, ubit32 *pBuf)
{
    ubit32 command[5];
    ubit32 result[3];
    ubit8 flashSector, dummy;

    /* figure out what sector number we want to access */
    if( SUCCESS != flashGetSectorIDs(baseAddr+offset, 
baseAddr+offset, &flashSector, &dummy ) )
    {
        return FAILURE;
    }

    command[0] = IAP_UNLOCK_SECTOR;
    command[1] = flashSector;
    command[2] = flashSector;

    flashCallROMDisabled( &command[0], &result[0] );
    if( result[0] != IAP_RSP_SUCCESS )
    {
        return result[0];
    }

    command[0] = IAP_CPY_TO_FLASH;
    command[1] = (ubit32) baseAddr + offset;            // DST 
address, 512-byte aligned
    command[2] = (ubit32)pBuf;                          // SRC, 4-
byte aligned
    command[3] = 512;                                   // page size 
in bytes
    command[4] = PLL_FREQ_KHZ;                          // cclk freq

    flashCallROMDisabled( &command[0], &result[0] );

    return result[0];
}





--- In lpc2000@yahoogroups.com, "soren_t_hansen" 
<soren_t_hansen@y...> wrote:
> Hi Tom,
> 
> I saw your reply reg. flash programming on a lpc2000 through Jtag 
and
> I was wondering if I could see this program that you have, that gets
> the code from the PC and downloads it to the flash.
> 
> Alternativly maybe you have some resources or articles you could 
give
> me a link to, regarding how to make such a program?
> 
> Best Regards
> Søren Hansen

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.