📄 lpc21isp.c
字号:
FileLength = lseek(fd, 0L, 2); // Get file size
if(FileLength == (size_t)-1)
{
DebugPrintf( 1, "\nFileLength = -1 !?!\n");
exit(1);
}
lseek(fd, 0L, 0);
FileContent = malloc(FileLength);
BinaryMemSize = FileLength * 2;
IspEnvironment->BinaryLength = 0; /* Increase length as needed. */
IspEnvironment->BinaryOffset = 0;
IspEnvironment->StartAddress = 0;
BinaryOffsetDefined = 0;
IspEnvironment->BinaryContent = malloc(BinaryMemSize);
read(fd, FileContent, FileLength);
close(fd);
DebugPrintf( 2, "File %s:\n\tloaded...\n", IspEnvironment->input_file);
// Intel-Hex -> Binary Conversion
if(IspEnvironment->FormatHex != 0)
{
unsigned char RecordLength;
unsigned short RecordAddress;
unsigned long RealAddress = 0;
unsigned char RecordType;
unsigned char Hexvalue;
unsigned long StartAddress;
DebugPrintf( 3, "Converting file %s to binary format...\n", IspEnvironment->input_file);
Pos = 0;
while(Pos < FileLength)
{
if(FileContent[Pos] == '\r')
{
Pos++;
continue;
}
if(FileContent[Pos] == '\n')
{
Pos++;
continue;
}
if(FileContent[Pos] != ':')
{
DebugPrintf( 1, "Missing start of record (':') wrong byte %c / %02X\n", FileContent[Pos], FileContent[Pos]);
exit(1);
}
Pos++;
RecordLength = Ascii2Hex(FileContent[Pos++]);
RecordLength <<= 4;
RecordLength |= Ascii2Hex(FileContent[Pos++]);
DebugPrintf( 4, "RecordLength = %02X\n", RecordLength);
RecordAddress = Ascii2Hex(FileContent[Pos++]);
RecordAddress <<= 4;
RecordAddress |= Ascii2Hex(FileContent[Pos++]);
RecordAddress <<= 4;
RecordAddress |= Ascii2Hex(FileContent[Pos++]);
RecordAddress <<= 4;
RecordAddress |= Ascii2Hex(FileContent[Pos++]);
DebugPrintf( 4, "RecordAddress = %04X\n", RecordAddress);
RealAddress = RealAddress - (RealAddress & 0xffff) + RecordAddress;
DebugPrintf( 4, "RealAddress = %08lX\n", RealAddress);
RecordType = Ascii2Hex(FileContent[Pos++]);
RecordType <<= 4;
RecordType |= Ascii2Hex(FileContent[Pos++]);
DebugPrintf( 4, "RecordType = %02X\n", RecordType);
if(RecordType == 0x00) // 00 - Data record
{
/*
* Binary Offset is defined as soon as first data record read
*/
BinaryOffsetDefined = 1;
// Memory for binary file big enough ?
while(RealAddress + RecordLength - IspEnvironment->BinaryOffset > BinaryMemSize)
{
BinaryMemSize <<= 1;
IspEnvironment->BinaryContent = realloc(IspEnvironment->BinaryContent, BinaryMemSize);
}
// We need to know, what the highest address is,
// how many bytes / sectors we must flash
if(RealAddress + RecordLength - IspEnvironment->BinaryOffset > IspEnvironment->BinaryLength)
{
IspEnvironment->BinaryLength = RealAddress + RecordLength - IspEnvironment->BinaryOffset;
DebugPrintf( 3, "Image size now: %ld\n", IspEnvironment->BinaryLength);
}
for(i = 0; i < RecordLength; i++)
{
Hexvalue = Ascii2Hex(FileContent[Pos++]);
Hexvalue <<= 4;
Hexvalue |= Ascii2Hex(FileContent[Pos++]);
IspEnvironment->BinaryContent[RealAddress + i - IspEnvironment->BinaryOffset] = Hexvalue;
}
}
else if(RecordType == 0x01) // 01 - End of file record
{
break;
}
else if(RecordType == 0x02) // 02 - Extended segment address record
{
for(i = 0; i < RecordLength * 2; i++) // double amount of nibbles
{
RealAddress <<= 4;
if(i == 0)
{
RealAddress = Ascii2Hex(FileContent[Pos++]);
}
else
{
RealAddress |= Ascii2Hex(FileContent[Pos++]);
}
}
RealAddress <<= 4;
}
else if(RecordType == 0x03) // 03 - Start segment address record
{
for(i = 0; i < RecordLength * 2; i++) // double amount of nibbles
{
RealAddress <<= 4;
if(i == 0)
{
RealAddress = Ascii2Hex(FileContent[Pos++]);
}
else
{
RealAddress |= Ascii2Hex(FileContent[Pos++]);
}
}
RealAddress <<= 8;
}
else if(RecordType == 0x04) // 04 - Extended linear address record, used by IAR
{
for(i = 0; i < RecordLength * 2; i++) // double amount of nibbles
{
RealAddress <<= 4;
if(i == 0)
{
RealAddress = Ascii2Hex(FileContent[Pos++]);
}
else
{
RealAddress |= Ascii2Hex(FileContent[Pos++]);
}
}
RealAddress <<= 16;
if(!BinaryOffsetDefined)
{
// set startaddress of BinaryContent
// use of LPC_FLASHMASK to allow a memory range, not taking the first
// [04] record as actual start-address.
IspEnvironment->BinaryOffset = RealAddress & LPC_FLASHMASK;
}
else
{
if((RealAddress & LPC_FLASHMASK) != IspEnvironment->BinaryOffset)
{
DebugPrintf(1, "New Extended Linear Address Record [04] out of memory range\n");
DebugPrintf(1, "Current Memory starts at: 0x%08X, new Address is: 0x%08X",
IspEnvironment->BinaryOffset, RealAddress);
exit(1);
}
}
}
else if(RecordType == 0x05) // 05 - Start linear address record
{
StartAddress = 0;
for(i = 0; i < RecordLength * 2; i++) // double amount of nibbles
{
StartAddress <<= 4;
if(i == 0)
{
StartAddress = Ascii2Hex(FileContent[Pos++]);
}
else
{
StartAddress |= Ascii2Hex(FileContent[Pos++]);
}
}
DebugPrintf( 1,"Start Address = 0x%8X\n", StartAddress);
IspEnvironment->StartAddress = StartAddress;
}
while(FileContent[Pos++] != 0x0a) // Search till line end
{
}
}
DebugPrintf( 2, "\tconverted to binary format...\n");
// When debugging is switched on, output result of conversion to file debugout.bin
if(debug_level >= 4)
{
int fdout;
fdout = open("debugout.bin", O_RDWR | O_BINARY | O_CREAT | O_TRUNC, 0777);
write(fdout, IspEnvironment->BinaryContent, IspEnvironment->BinaryLength);
close(fdout);
}
}
else
{
memcpy(IspEnvironment->BinaryContent, FileContent, FileLength);
IspEnvironment->BinaryLength = FileLength;
}
DebugPrintf( 2, "\timage size : %ld\n", IspEnvironment->BinaryLength);
// check length to flash for correct alignment, can happen with broken ld-scripts
if (IspEnvironment->BinaryLength % 4 != 0)
{
unsigned long NewBinaryLength = ((IspEnvironment->BinaryLength + 3)/4) * 4;
DebugPrintf( 2, "Warning: data not aligned to 32 bits, padded (length was %lX, now %lX)\n", IspEnvironment->BinaryLength, NewBinaryLength);
IspEnvironment->BinaryLength = NewBinaryLength;
}
}
#define ANALOG_DEVICES_SYNC_CHAR ((BINARY)0x08)
#define ANALOG_DEVICES_SYNC_RESPONSE ("ADuC")
#define ANALOG_DEVICES_SYNC_SIZE (strlen( ANALOG_DEVICES_SYNC_RESPONSE))
typedef struct {
BINARY product_id[15];
BINARY version[3];
BINARY reserved[4];
BINARY terminator[2];
} AD_SYNC_RESPONSE;
/***************************** AnalogDevicesSync ************************/
/** Attempt to synchronize with an Analog Device ARM micro. Sends a
backspace and reads back the microcontrollers response. Performs
multiple retries. Exits the program on error, returns to caller in the
case of success.
*/
static void AnalogDevicesSync(ISP_ENVIRONMENT *IspEnvironment)
{
BINARY sync; /* Holds sync command. */
AD_SYNC_RESPONSE response; /* Response from micro. */
int sync_attempts; /* Number of retries. */
/* Make sure we don't read garbage later instead of the */
/* response we expect from the micro. */
ClearSerialPortBuffers(IspEnvironment);
DebugPrintf( 2, "Synchronizing\n"); /* Progress report. */
sync = ANALOG_DEVICES_SYNC_CHAR; /* Build up sync command. */
/* Perform the actual sync attempt. First send the sync */
/* character, the attempt to read back the response. For the */
/* AD ARM micro this is a fixed length block. If response is */
/* received attempt to validate it by comparing the first */
/* characters to those expected. If the received block does */
/* not validate or is incomplete empty the serial buffer and */
/* retry. */
for(sync_attempts = 0; sync_attempts < 5; sync_attempts++)
{
SendComPortBlock( IspEnvironment, &sync, 1);
if( ReceiveComPortBlockComplete( IspEnvironment, &response, sizeof( response),
500) == 0)
{
if( memcmp( response.product_id, ANALOG_DEVICES_SYNC_RESPONSE,
ANALOG_DEVICES_SYNC_SIZE) == 0)
{
return;
}
else
{
DumpString( 3, &response, sizeof(response),
"Unexpected response to sync attempt ");
}
}
else
{
DebugPrintf( 3, "No (or incomplete) answer on sync attempt\n");
}
ClearSerialPortBuffers(IspEnvironment);
}
DebugPrintf( 1, "No (or unacceptable) answer on sync attempt\n");
exit(4);
}
typedef struct {
char start1;
char start2;
BINARY bytes;
char cmd;
BINARY address_h;
BINARY address_u;
BINARY address_m;
BINARY address_l;
BINARY data[251];
} AD_PACKET;
/**********
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -