From e8425bb29bbf222114d4212586d14f96ab5b58e4 Mon Sep 17 00:00:00 2001 From: Taisuke Fukuno Date: Fri, 3 May 2019 18:35:03 +0900 Subject: [PATCH] add option : -sector, -controlwithoutwait --- lpc21isp.c | 40 +++++++++++--- lpc21isp.h | 2 + lpcprog.c | 155 ++++++++++++++++++++++++++++------------------------- 3 files changed, 118 insertions(+), 79 deletions(-) diff --git a/lpc21isp.c b/lpc21isp.c index 4cd2ec0..b1a3b4f 100644 --- a/lpc21isp.c +++ b/lpc21isp.c @@ -416,6 +416,9 @@ Change-History: Add support for LPC83x, LPC84x and LPC80x 2018-08-27 Jürgen Stuber Add support for LP15xx + 2019-05-03 Taisuke Fukuno + Add option -sector (ex. '-sector6' to upload to sector 6) + Add option -controlwithoutwait */ // Please don't use TABs in the source code !!! @@ -1499,6 +1502,13 @@ static void ReadArguments(ISP_ENVIRONMENT *IspEnvironment, unsigned int argc, ch continue; } + if (stricmp(argv[i], "-controlwithoutwait") == 0) + { + IspEnvironment->ControlLinesWithoutWait = 1; + DebugPrintf(3, "Reduce Sleep when use control lines.\n"); + continue; + } + if (stricmp(argv[i], "-halfduplex") == 0) { IspEnvironment->HalfDuplex = 1; @@ -1543,6 +1553,18 @@ static void ReadArguments(ISP_ENVIRONMENT *IspEnvironment, unsigned int argc, ch } #endif + if(strnicmp(argv[i],"-sector", 7) == 0) + { + int beginsector = atoi(&argv[i][7]); + if (beginsector > 0) { + IspEnvironment->BeginSector = beginsector; + DebugPrintf(3, "Begin Scetor: %d.\n", IspEnvironment->BeginSector); + } else { + fprintf(stderr,"invalid argument for -sector: \"%s\"\n", argv[i]); + } + continue; + } + #ifdef TERMINAL_SUPPORT if (CheckTerminalParameters(IspEnvironment, argv[i])) { @@ -1625,6 +1647,7 @@ static void ReadArguments(ISP_ENVIRONMENT *IspEnvironment, unsigned int argc, ch " (Reset = RTS, EnableBootLoader = DTR)\n" " -controlinv Invert state of RTS & DTR \n" " (0=true/assert/set, 1=false/deassert/clear).\n" + " -sector set the sector to upload\n" " -verify Verify the data in Flash after every writes to\n" " sector. To detect errors in writing to Flash ROM\n" " -logfile for enabling logging of terminal output to lpc21isp.log\n" @@ -1671,9 +1694,11 @@ void ResetTarget(ISP_ENVIRONMENT *IspEnvironment, TARGET_MODE mode) /* Reset and jump to boot loader. */ case PROGRAM_MODE: ControlModemLines(IspEnvironment, 1, 1); - Sleep(100); - ClearSerialPortBuffers(IspEnvironment); - Sleep(100); + if (!IspEnvironment->ControlLinesWithoutWait) { + Sleep(100); + ClearSerialPortBuffers(IspEnvironment); + Sleep(100); + } ControlModemLines(IspEnvironment, 0, 1); //Longer delay is the Reset signal is conected to an external rest controller Sleep(500); @@ -1688,9 +1713,11 @@ void ResetTarget(ISP_ENVIRONMENT *IspEnvironment, TARGET_MODE mode) /* Reset and start uploaded program */ case RUN_MODE: ControlModemLines(IspEnvironment, 1, 0); - Sleep(100); - ClearSerialPortBuffers(IspEnvironment); - Sleep(100); + if (!IspEnvironment->ControlLinesWithoutWait) { + Sleep(100); + ClearSerialPortBuffers(IspEnvironment); + Sleep(100); + } ControlModemLines(IspEnvironment, 0, 0); Sleep(100); break; @@ -2541,6 +2568,7 @@ int main(int argc, char *argv[]) IspEnvironment.nQuestionMarks = 100; IspEnvironment.DoNotStart = 0; IspEnvironment.BootHold = 0; + IspEnvironment.BeginSector = 0; ReadArguments(&IspEnvironment, argc, argv); // Read and parse the command line return PerformActions(&IspEnvironment); // Do as requested ! diff --git a/lpc21isp.h b/lpc21isp.h index b7f6927..abf27f9 100644 --- a/lpc21isp.h +++ b/lpc21isp.h @@ -172,6 +172,7 @@ typedef struct unsigned char ControlLines; unsigned char ControlLinesSwapped; unsigned char ControlLinesInverted; + unsigned char ControlLinesWithoutWait; unsigned char LogFile; FILE_LIST *f_list; // List of files to read in. int nQuestionMarks; // how many times to try to synchronise @@ -214,6 +215,7 @@ typedef struct unsigned long BinaryOffset; unsigned long StartAddress; unsigned long BinaryMemSize; + unsigned long BeginSector; #if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN HANDLE hCom; diff --git a/lpcprog.c b/lpcprog.c index cd227bf..4bba431 100644 --- a/lpcprog.c +++ b/lpcprog.c @@ -645,6 +645,8 @@ int NxpDownload(ISP_ENVIRONMENT *IspEnvironment) char tmp_string[64]; char * cmdstr; + int beginsector = IspEnvironment->BeginSector; // add by @taisukef + #if !defined COMPILE_FOR_LPC21 #if defined __BORLANDC__ @@ -824,6 +826,7 @@ int NxpDownload(ISP_ENVIRONMENT *IspEnvironment) if (strncmp(Answer + strlen(temp), "0\n", 2) == 0) { strippedAnswer = Answer + strlen(temp) + 2; + *(strippedAnswer + 1) = '.'; /* int maj, min, build; if (sscanf(strippedAnswer, "%d %d %d", &build, &min, &maj) == 2) { @@ -920,77 +923,79 @@ int NxpDownload(ISP_ENVIRONMENT *IspEnvironment) uuencode_table[i] = (char)(0x20 + i); } - if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX) - { - // Patch 0x14, otherwise it is not running and jumps to boot mode + if (beginsector == 0) { + if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX) + { + // Patch 0x14, otherwise it is not running and jumps to boot mode - ivt_CRC = 0; + ivt_CRC = 0; - // Clear the vector at 0x14 so it doesn't affect the checksum: - for (i = 0; i < 4; i++) - { - IspEnvironment->BinaryContent[i + 0x14] = 0; - } + // Clear the vector at 0x14 so it doesn't affect the checksum: + for (i = 0; i < 4; i++) + { + IspEnvironment->BinaryContent[i + 0x14] = 0; + } - // Calculate a native checksum of the little endian vector table: - for (i = 0; i < (4 * 8);) { - ivt_CRC += IspEnvironment->BinaryContent[i++]; - ivt_CRC += IspEnvironment->BinaryContent[i++] << 8; - ivt_CRC += IspEnvironment->BinaryContent[i++] << 16; - ivt_CRC += IspEnvironment->BinaryContent[i++] << 24; - } + // Calculate a native checksum of the little endian vector table: + for (i = 0; i < (4 * 8);) { + ivt_CRC += IspEnvironment->BinaryContent[i++]; + ivt_CRC += IspEnvironment->BinaryContent[i++] << 8; + ivt_CRC += IspEnvironment->BinaryContent[i++] << 16; + ivt_CRC += IspEnvironment->BinaryContent[i++] << 24; + } - /* Negate the result and place in the vector at 0x14 as little endian - * again. The resulting vector table should checksum to 0. */ - ivt_CRC = (unsigned long) (0 - ivt_CRC); - for (i = 0; i < 4; i++) - { - IspEnvironment->BinaryContent[i + 0x14] = (unsigned char)(ivt_CRC >> (8 * i)); + /* Negate the result and place in the vector at 0x14 as little endian + * again. The resulting vector table should checksum to 0. */ + ivt_CRC = (unsigned long) (0 - ivt_CRC); + for (i = 0; i < 4; i++) + { + IspEnvironment->BinaryContent[i + 0x14] = (unsigned char)(ivt_CRC >> (8 * i)); + } + + DebugPrintf(3, "Position 0x14 patched: ivt_CRC = 0x%08lX\n", ivt_CRC); } + else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX || + LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC40XX || + LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX || + LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX || + LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX || + LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX || + LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC8XX || + LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC15XX) + { + // Patch 0x1C, otherwise it is not running and jumps to boot mode - DebugPrintf(3, "Position 0x14 patched: ivt_CRC = 0x%08lX\n", ivt_CRC); - } - else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX || - LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC40XX || - LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX || - LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX || - LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX || - LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX || - LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC8XX || - LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC15XX) - { - // Patch 0x1C, otherwise it is not running and jumps to boot mode + ivt_CRC = 0; - ivt_CRC = 0; + // Clear the vector at 0x1C so it doesn't affect the checksum: + for (i = 0; i < 4; i++) + { + IspEnvironment->BinaryContent[i + 0x1C] = 0; + } - // Clear the vector at 0x1C so it doesn't affect the checksum: - for (i = 0; i < 4; i++) - { - IspEnvironment->BinaryContent[i + 0x1C] = 0; - } + // Calculate a native checksum of the little endian vector table: + for (i = 0; i < (4 * 8);) { + ivt_CRC += IspEnvironment->BinaryContent[i++]; + ivt_CRC += IspEnvironment->BinaryContent[i++] << 8; + ivt_CRC += IspEnvironment->BinaryContent[i++] << 16; + ivt_CRC += IspEnvironment->BinaryContent[i++] << 24; + } - // Calculate a native checksum of the little endian vector table: - for (i = 0; i < (4 * 8);) { - ivt_CRC += IspEnvironment->BinaryContent[i++]; - ivt_CRC += IspEnvironment->BinaryContent[i++] << 8; - ivt_CRC += IspEnvironment->BinaryContent[i++] << 16; - ivt_CRC += IspEnvironment->BinaryContent[i++] << 24; - } + /* Negate the result and place in the vector at 0x1C as little endian + * again. The resulting vector table should checksum to 0. */ + ivt_CRC = (unsigned long) (0 - ivt_CRC); + for (i = 0; i < 4; i++) + { + IspEnvironment->BinaryContent[i + 0x1C] = (unsigned char)(ivt_CRC >> (8 * i)); + } - /* Negate the result and place in the vector at 0x1C as little endian - * again. The resulting vector table should checksum to 0. */ - ivt_CRC = (unsigned long) (0 - ivt_CRC); - for (i = 0; i < 4; i++) + DebugPrintf(3, "Position 0x1C patched: ivt_CRC = 0x%08lX\n", ivt_CRC); + } + else { - IspEnvironment->BinaryContent[i + 0x1C] = (unsigned char)(ivt_CRC >> (8 * i)); + DebugPrintf(1, "Internal error: wrong chip variant %d (detected device %d)\n", LPCtypes[IspEnvironment->DetectedDevice].ChipVariant, IspEnvironment->DetectedDevice); + exit(1); } - - DebugPrintf(3, "Position 0x1C patched: ivt_CRC = 0x%08lX\n", ivt_CRC); - } - else - { - DebugPrintf(1, "Internal error: wrong chip variant %d (detected device %d)\n", LPCtypes[IspEnvironment->DetectedDevice].ChipVariant, IspEnvironment->DetectedDevice); - exit(1); } } @@ -1046,20 +1051,21 @@ int NxpDownload(ISP_ENVIRONMENT *IspEnvironment) ControlXonXoffSerialPort(IspEnvironment, 0); } + int offset = 0; // Start with sector 1 and go upward... Sector 0 containing the interrupt vectors // will be loaded last, since it contains a checksum and device will re-enter // bootloader mode as long as this checksum is invalid. DebugPrintf(2, "Will start programming at Sector 1 if possible, and conclude with Sector 0 to ensure that checksum is written last.\n"); - if (LPCtypes[IspEnvironment->DetectedDevice].SectorTable[0] >= IspEnvironment->BinaryLength) + if (beginsector > 0 || LPCtypes[IspEnvironment->DetectedDevice].SectorTable[0] >= IspEnvironment->BinaryLength) { - Sector = 0; - SectorStart = 0; + Sector = beginsector; + offset = beginsector * LPCtypes[IspEnvironment->DetectedDevice].SectorTable[0]; } else { - SectorStart = LPCtypes[IspEnvironment->DetectedDevice].SectorTable[0]; Sector = 1; } + SectorStart = Sector * LPCtypes[IspEnvironment->DetectedDevice].SectorTable[0]; if (IspEnvironment->WipeDevice == 1) { @@ -1105,7 +1111,7 @@ int NxpDownload(ISP_ENVIRONMENT *IspEnvironment) DebugPrintf(2, "ATTENTION: Only bank A was wiped!!!\n"); } } - else{ + else if (beginsector == 0) { //no wiping requested: erasing sector 0 first DebugPrintf(2, "Erasing sector 0 first, to invalidate checksum. "); @@ -1202,9 +1208,9 @@ int NxpDownload(ISP_ENVIRONMENT *IspEnvironment) } SectorLength = LPCtypes[IspEnvironment->DetectedDevice].SectorTable[Sector]; - if (SectorLength > IspEnvironment->BinaryLength - SectorStart) + if (SectorLength > IspEnvironment->BinaryLength - SectorStart + offset) { - SectorLength = IspEnvironment->BinaryLength - SectorStart; + SectorLength = IspEnvironment->BinaryLength - SectorStart + offset; } for (SectorOffset = 0; SectorOffset < SectorLength; SectorOffset += SectorChunk) @@ -1213,7 +1219,7 @@ int NxpDownload(ISP_ENVIRONMENT *IspEnvironment) if (SectorOffset == 0) { for (SectorOffset = 0; SectorOffset < SectorLength; ++SectorOffset) { - if (IspEnvironment->BinaryContent[SectorStart + SectorOffset] != 0xFF) + if (IspEnvironment->BinaryContent[SectorStart + SectorOffset - offset] != 0xFF) break; } if (SectorOffset == SectorLength) // all data contents were 0xFFs @@ -1285,7 +1291,7 @@ int NxpDownload(ISP_ENVIRONMENT *IspEnvironment) Line = 0; // Transfer blocks of 45 * 4 bytes to RAM - for (Pos = SectorStart + SectorOffset; (Pos < SectorStart + SectorOffset + CopyLength) && (Pos < IspEnvironment->BinaryLength); Pos += (45 * 4)) + for (Pos = SectorStart + SectorOffset; (Pos < SectorStart + SectorOffset + CopyLength) && (Pos < IspEnvironment->BinaryLength + offset); Pos += (45 * 4)) { for (Block = 0; Block < 4; Block++) // Each block 45 bytes { @@ -1311,11 +1317,11 @@ int NxpDownload(ISP_ENVIRONMENT *IspEnvironment) if ( (IspEnvironment->BinaryOffset < ReturnValueLpcRamStart(IspEnvironment)) ||(IspEnvironment->BinaryOffset >= ReturnValueLpcRamStart(IspEnvironment)+(LPCtypes[IspEnvironment->DetectedDevice].RAMSize*1024))) { // Flash: use full memory - c = IspEnvironment->BinaryContent[Pos + Block * 45 + BlockOffset]; + c = IspEnvironment->BinaryContent[Pos + Block * 45 + BlockOffset - offset]; } else { // RAM: Skip first 0x200 bytes, these are used by the download program in LPC21xx - c = IspEnvironment->BinaryContent[Pos + Block * 45 + BlockOffset + 0x200]; + c = IspEnvironment->BinaryContent[Pos + Block * 45 + BlockOffset + 0x200 - offset]; } block_CRC += c; @@ -1499,14 +1505,14 @@ int NxpDownload(ISP_ENVIRONMENT *IspEnvironment) CopyLengthPartialRemainingBytes = 256; } - SendComPortBlock(IspEnvironment, &IspEnvironment->BinaryContent[SectorStart + SectorOffset + CopyLengthPartialOffset], CopyLengthPartialRemainingBytes); + SendComPortBlock(IspEnvironment, &IspEnvironment->BinaryContent[SectorStart + SectorOffset + CopyLengthPartialOffset - offset], CopyLengthPartialRemainingBytes); if (ReceiveComPortBlockComplete(IspEnvironment, &BigAnswer, CopyLengthPartialRemainingBytes, 10000) != 0) { return (ERROR_WRITE_DATA); } - if(memcmp(&IspEnvironment->BinaryContent[SectorStart + SectorOffset + CopyLengthPartialOffset], BigAnswer, CopyLengthPartialRemainingBytes)) + if(memcmp(&IspEnvironment->BinaryContent[SectorStart + SectorOffset + CopyLengthPartialOffset - offset], BigAnswer, CopyLengthPartialRemainingBytes)) { return (ERROR_WRITE_DATA); } @@ -1595,7 +1601,10 @@ int NxpDownload(ISP_ENVIRONMENT *IspEnvironment) DebugPrintf(2, "\n"); fflush(stdout); - if ((SectorStart + SectorLength) >= IspEnvironment->BinaryLength && Sector!=0) + if (beginsector > 0 && SectorStart + SectorLength >= IspEnvironment->BinaryLength + offset) { + break; + } + if (beginsector == 0 && SectorStart + SectorLength >= IspEnvironment->BinaryLength + offset && Sector != 0) { Sector = 0; SectorStart = 0;