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 HansenMessage
Re: JTag Flash programming
2005-05-26 by tom_laffey
Attachments
- No local attachments were found for this message.