--- /dev/null
+/******************************************************************************\r
+\r
+Project: Portable command line ISP for Philips LPC2000 family\r
+ and Analog Devices ADUC70xx\r
+\r
+Filename: lpcprog.c\r
+\r
+Compiler: Microsoft VC 6/7, GCC Cygwin, GCC Linux, GCC ARM ELF\r
+\r
+Author: Martin Maurer (Martin.Maurer@clibb.de)\r
+\r
+Copyright: (c) Martin Maurer 2003-2008, All rights reserved\r
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com\r
+\r
+ This file is part of lpc21isp.\r
+\r
+ lpc21isp is free software: you can redistribute it and/or modify\r
+ it under the terms of the GNU Lesser General Public License as published by\r
+ the Free Software Foundation, either version 3 of the License, or\r
+ any later version.\r
+\r
+ lpc21isp is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU Lesser General Public License for more details.\r
+\r
+ You should have received a copy of the GNU Lesser General Public License\r
+ and GNU General Public License along with lpc21isp.\r
+ If not, see <http://www.gnu.org/licenses/>.\r
+*/\r
+\r
+// This file is for the Actual Programming of the LPC Chips\r
+\r
+#if defined(_WIN32)\r
+#if !defined __BORLANDC__\r
+#include "StdAfx.h"\r
+#endif\r
+#endif // defined(_WIN32)\r
+#include "lpc21isp.h"\r
+\r
+#ifdef LPC_SUPPORT\r
+#include "lpcprog.h"\r
+\r
+static const unsigned int SectorTable_210x[] =\r
+{\r
+ 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\r
+ 8192, 8192, 8192, 8192, 8192, 8192, 8192\r
+};\r
+\r
+static const unsigned int SectorTable_2103[] =\r
+{\r
+ 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096\r
+};\r
+\r
+static const unsigned int SectorTable_2109[] =\r
+{\r
+ 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192\r
+};\r
+\r
+static const unsigned int SectorTable_211x[] =\r
+{\r
+ 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\r
+ 8192, 8192, 8192, 8192, 8192, 8192, 8192,\r
+};\r
+\r
+static const unsigned int SectorTable_212x[] =\r
+{\r
+ 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,\r
+ 65536, 65536, 8192, 8192, 8192, 8192, 8192, 8192, 8192\r
+};\r
+\r
+// Used for devices with 500K (LPC2138 and LPC2148) and\r
+// for devices with 504K (1 extra 4k block at the end)\r
+static const unsigned int SectorTable_213x[] =\r
+{\r
+ 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096,\r
+ 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,\r
+ 32768, 32768, 32768, 32768, 32768, 32768, 4096, 4096,\r
+ 4096, 4096, 4096, 4096\r
+};\r
+\r
+static int unsigned SectorTable_RAM[] = { 65000 };\r
+\r
+static LPC_DEVICE_TYPE LPCtypes[] =\r
+{\r
+ { 0, 0, 0 }, /* unknown */\r
+ { 0x0004FF11, 2103, 32, 8, 8, 4096, SectorTable_2103 },\r
+ { 0xFFF0FF12, 2104, 128, 16, 15, 8192, SectorTable_210x },\r
+ { 0xFFF0FF22, 2105, 128, 32, 15, 8192, SectorTable_210x },\r
+ { 0xFFF0FF32, 2106, 128, 64, 15, 8192, SectorTable_210x },\r
+ { 0x0201FF01, 2109, 64, 8, 8, 4096, SectorTable_2109 },\r
+ { 0x0101FF12, 2114, 128, 16, 15, 8192, SectorTable_211x },\r
+ { 0x0201FF12, 2119, 128, 16, 15, 8192, SectorTable_211x },\r
+ { 0x0101FF13, 2124, 256, 16, 17, 8192, SectorTable_212x },\r
+ { 0x0201FF13, 2129, 256, 16, 17, 8192, SectorTable_212x },\r
+ { 0x0002FF01, 2131, 32, 8, 8, 4096, SectorTable_213x },\r
+ { 0x0002FF11, 2132, 64, 16, 9, 4096, SectorTable_213x },\r
+ { 0x0002FF12, 2134, 128, 16, 11, 4096, SectorTable_213x },\r
+ { 0x0002FF23, 2136, 256, 32, 15, 4096, SectorTable_213x },\r
+ { 0x0002FF25, 2138, 512, 32, 27, 4096, SectorTable_213x },\r
+ { 0x0402FF01, 2141, 32, 8, 8, 4096, SectorTable_213x },\r
+ { 0x0402FF11, 2142, 64, 16, 9, 4096, SectorTable_213x },\r
+ { 0x0402FF12, 2144, 128, 16, 11, 4096, SectorTable_213x },\r
+ { 0x0402FF23, 2146, 256, 40, 15, 4096, SectorTable_213x },\r
+ { 0x0402FF25, 2148, 512, 40, 27, 4096, SectorTable_213x },\r
+ { 0x0301FF13, 2194, 256, 16, 17, 8192, SectorTable_212x },\r
+ { 0x0301FF12, 2210, 0, 16, 0, 8192, SectorTable_211x }, /* table is a "don't care" */\r
+ { 0x0401FF12, 2212, 128, 16, 15, 8192, SectorTable_211x },\r
+ { 0x0601FF13, 2214, 256, 16, 17, 8192, SectorTable_212x },\r
+ /* 2290; same id as the LPC2210 */\r
+ { 0x0401FF13, 2292, 256, 16, 17, 8192, SectorTable_212x },\r
+ { 0x0501FF13, 2294, 256, 16, 17, 8192, SectorTable_212x },\r
+ { 0x00000000, 2361, 128, 34, 11, 4096, SectorTable_213x },\r
+ { 0x00000000, 2362, 128, 34, 11, 4096, SectorTable_213x },\r
+ { 0x1600F902, 2364, 128, 34, 11, 4096, SectorTable_213x },\r
+ { 0x1600E823, 2365, 256, 58, 15, 4096, SectorTable_213x },\r
+ { 0x1600F923, 2366, 256, 58, 15, 4096, SectorTable_213x },\r
+ { 0x1600E825, 2367, 512, 58, 15, 4096, SectorTable_213x },\r
+ { 0x1600F925, 2368, 512, 58, 28, 4096, SectorTable_213x },\r
+ { 0x1700E825, 2377, 512, 58, 28, 4096, SectorTable_213x },\r
+ { 0x1700FD25, 2378, 512, 58, 28, 4096, SectorTable_213x },\r
+ { 0x1800F935, 2387, 512, 98, 28, 4096, SectorTable_213x },\r
+ { 0x1800FF35, 2388, 512, 98, 28, 4096, SectorTable_213x },\r
+ { 0x1500FF35, 2458, 512, 98, 28, 4096, SectorTable_213x },\r
+ { 0x1600FF30, 2460, 0, 98, 0, 4096, SectorTable_213x },\r
+ { 0x1600FF35, 2468, 512, 98, 28, 4096, SectorTable_213x },\r
+ { 0x1701FF30, 2470, 0, 98, 0, 4096, SectorTable_213x },\r
+ { 0x1701FF35, 2478, 512, 98, 28, 4096, SectorTable_213x }\r
+};\r
+\r
+/***************************** PHILIPS Download *********************************/\r
+/** Download the file from the internal memory image to the philips microcontroller.\r
+* This function is visible from outside if COMPILE_FOR_LPC21\r
+*/\r
+\r
+static int SendAndVerify(ISP_ENVIRONMENT *IspEnvironment, const char *Command,\r
+ char *AnswerBuffer, int AnswerLength)\r
+{\r
+ unsigned long realsize;\r
+ int cmdlen;\r
+\r
+ SendComPort(IspEnvironment, Command);\r
+ ReceiveComPort(IspEnvironment, AnswerBuffer, AnswerLength - 1, &realsize, 2, 5000);\r
+ cmdlen = strlen(Command);\r
+ return (strncmp(AnswerBuffer, Command, cmdlen) == 0\r
+ && strcmp(AnswerBuffer + cmdlen, "0\r\n") == 0);\r
+}\r
+\r
+\r
+\r
+/***************************** PhilipsOutputErrorMessage ***********************/\r
+/** Given an error number find and print the appropriate error message.\r
+\param [in] ErrorNumber The number of the error.\r
+*/\r
+#if defined COMPILE_FOR_LPC21\r
+\r
+#define PhilipsOutputErrorMessage(in) // Cleanly remove this feature from the embedded version !!\r
+\r
+#else\r
+\r
+static void PhilipsOutputErrorMessage(unsigned char ErrorNumber)\r
+{\r
+ switch (ErrorNumber)\r
+ {\r
+ case 0:\r
+ DebugPrintf(1, "CMD_SUCCESS\n");\r
+ break;\r
+\r
+ case 1:\r
+ DebugPrintf(1, "INVALID_COMMAND\n");\r
+ break;\r
+\r
+ case 2:\r
+ DebugPrintf(1, "SRC_ADDR_ERROR: Source address is not on word boundary.\n");\r
+ break;\r
+ case 3:\r
+ DebugPrintf(1, "DST_ADDR_ERROR: Destination address is not on a correct boundary.\n");\r
+ break;\r
+\r
+ case 4:\r
+ DebugPrintf(1, "SRC_ADDR_NOT_MAPPED: Source address is not mapped in the memory map.\n"\r
+ " Count value is taken into consideration where applicable.\n");\r
+ break;\r
+\r
+ case 5:\r
+ DebugPrintf(1, "DST_ADDR_NOT_MAPPED: Destination address is not mapped in the memory map.\n"\r
+ " Count value is taken into consideration where applicable.\n");\r
+ break;\r
+\r
+ case 6:\r
+ DebugPrintf(1, "COUNT_ERROR: Byte count is not multiple of 4 or is not a permitted value.\n");\r
+ break;\r
+\r
+ case 7:\r
+ DebugPrintf(1, "INVALID_SECTOR: Sector number is invalid or end sector number is\n"\r
+ " greater than start sector number.\n");\r
+ break;\r
+\r
+ case 8:\r
+ DebugPrintf(1, "SECTOR_NOT_BLANK\n");\r
+ break;\r
+\r
+ case 9:\r
+ DebugPrintf(1, "SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION:\n"\r
+ "Command to prepare sector for write operation was not executed.\n");\r
+ break;\r
+\r
+ case 10:\r
+ DebugPrintf(1, "COMPARE_ERROR: Source and destination data not equal.\n");\r
+ break;\r
+\r
+ case 11:\r
+ DebugPrintf(1, "BUSY: Flash programming hardware interface is busy.\n");\r
+ break;\r
+\r
+ case 12:\r
+ DebugPrintf(1, "PARAM_ERROR: Insufficient number of parameters or invalid parameter.\n");\r
+ break;\r
+\r
+ case 13:\r
+ DebugPrintf(1, "ADDR_ERROR: Address is not on word boundary.\n");\r
+ break;\r
+\r
+ case 14:\r
+ DebugPrintf(1, "ADDR_NOT_MAPPED: Address is not mapped in the memory map.\n"\r
+ " Count value is taken in to consideration where applicable.\n");\r
+ break;\r
+\r
+ case 15:\r
+ DebugPrintf(1, "CMD_LOCKED\n");\r
+ break;\r
+\r
+ case 16:\r
+ DebugPrintf(1, "INVALID_CODE: Unlock code is invalid.\n");\r
+ break;\r
+\r
+ case 17:\r
+ DebugPrintf(1, "INVALID_BAUD_RATE: Invalid baud rate setting.\n");\r
+ break;\r
+\r
+ case 18:\r
+ DebugPrintf(1, "INVALID_STOP_BIT: Invalid stop bit setting.\n");\r
+ break;\r
+\r
+ case 19:\r
+ DebugPrintf( 1, "CODE READ PROTECTION ENABLED\n");\r
+ break;\r
+\r
+ case 255:\r
+ break;\r
+\r
+ default:\r
+ DebugPrintf(1, "unknown error %u\n", ErrorNumber);\r
+ break;\r
+ }\r
+\r
+ //DebugPrintf(1, "error (%u), see PhilipsOutputErrorMessage() in lpc21isp.c for help \n\r", ErrorNumber);\r
+}\r
+#endif // !defined COMPILE_FOR_LPC21\r
+\r
+/***************************** GetAndReportErrorNumber ***************************/\r
+/** Find error number in string. This will normally be the string\r
+returned from the microcontroller.\r
+\param [in] Answer the buffer to search for the error number.\r
+\return the error number found, if no linefeed found before the end of the\r
+string an error value of 255 is returned. If a non-numeric value is found\r
+then it is printed to stdout and an error value of 255 is returned.\r
+*/\r
+static unsigned char GetAndReportErrorNumber(const char *Answer)\r
+{\r
+ unsigned char Result = 0xFF; // Error !!!\r
+ unsigned int i = 0;\r
+\r
+ while (1)\r
+ {\r
+ if (Answer[i] == 0x00)\r
+ {\r
+ break;\r
+ }\r
+\r
+ if (Answer[i] == 0x0a)\r
+ {\r
+ i++;\r
+\r
+ if (Answer[i] < '0' || Answer[i] > '9')\r
+ {\r
+ DebugPrintf(1, "ErrorString: %s", &Answer[i]);\r
+ break;\r
+ }\r
+\r
+ Result = (unsigned char) (atoi(&Answer[i]));\r
+ break;\r
+ }\r
+\r
+ i++;\r
+ }\r
+\r
+ PhilipsOutputErrorMessage(Result);\r
+\r
+ return Result;\r
+}\r
+\r
+\r
+int PhilipsDownload(ISP_ENVIRONMENT *IspEnvironment)\r
+{\r
+ unsigned long realsize;\r
+ char Answer[128];\r
+ char temp[128];\r
+ /*const*/ char *strippedAnswer, *endPtr;\r
+ int strippedsize;\r
+ int nQuestionMarks;\r
+ int found;\r
+ unsigned long Sector;\r
+ unsigned long SectorLength;\r
+ unsigned long SectorStart, SectorOffset, SectorChunk;\r
+ char tmpString[128];\r
+ char uuencode_table[64];\r
+ int Line;\r
+ unsigned long tmpStringPos;\r
+ unsigned long BlockOffset;\r
+ unsigned long Block;\r
+ unsigned long Pos;\r
+ unsigned long CopyLength;\r
+ int c,k=0,i;\r
+ unsigned long ivt_CRC; // CRC over interrupt vector table\r
+ unsigned long block_CRC;\r
+ time_t tStartUpload=0, tDoneUpload=0;\r
+ long WatchDogSeconds = 0;\r
+ int WaitForWatchDog = 0;\r
+ char tmp_string[64];\r
+ char * cmdstr;\r
+\r
+#if !defined COMPILE_FOR_LPC21\r
+\r
+#if defined __BORLANDC__\r
+#define local_static static\r
+#else\r
+#define local_static\r
+#endif\r
+\r
+// char * cmdstr;\r
+ int repeat = 0;\r
+ // Puffer for data to resend after "RESEND\r\n" Target responce\r
+ local_static char sendbuf0[128];\r
+ local_static char sendbuf1[128];\r
+ local_static char sendbuf2[128];\r
+ local_static char sendbuf3[128];\r
+ local_static char sendbuf4[128];\r
+ local_static char sendbuf5[128];\r
+ local_static char sendbuf6[128];\r
+ local_static char sendbuf7[128];\r
+ local_static char sendbuf8[128];\r
+ local_static char sendbuf9[128];\r
+ local_static char sendbuf10[128];\r
+ local_static char sendbuf11[128];\r
+ local_static char sendbuf12[128];\r
+ local_static char sendbuf13[128];\r
+ local_static char sendbuf14[128];\r
+ local_static char sendbuf15[128];\r
+ local_static char sendbuf16[128];\r
+ local_static char sendbuf17[128];\r
+ local_static char sendbuf18[128];\r
+ local_static char sendbuf19[128];\r
+\r
+ char * sendbuf[20] = { sendbuf0, sendbuf1, sendbuf2, sendbuf3, sendbuf4,\r
+ sendbuf5, sendbuf6, sendbuf7, sendbuf8, sendbuf9,\r
+ sendbuf10, sendbuf11, sendbuf12, sendbuf13, sendbuf14,\r
+ sendbuf15, sendbuf16, sendbuf17, sendbuf18, sendbuf19};\r
+#endif\r
+\r
+ if (!IspEnvironment->DetectOnly)\r
+ {\r
+ // Build up uuencode table\r
+ uuencode_table[0] = 0x60; // 0x20 is translated to 0x60 !\r
+\r
+ for (i = 1; i < 64; i++)\r
+ {\r
+ uuencode_table[i] = (char)(0x20 + i);\r
+ }\r
+\r
+ // Patch 0x14, otherwise it is not running and jumps to boot mode\r
+\r
+ ivt_CRC = 0;\r
+\r
+ // Clear the vector at 0x14 so it doesn't affect the checksum:\r
+ for (i = 0; i < 4; i++)\r
+ {\r
+ IspEnvironment->BinaryContent[i + 0x14] = 0;\r
+ }\r
+\r
+ // Calculate a native checksum of the little endian vector table:\r
+ for (i = 0; i < (4 * 8);) {\r
+ ivt_CRC += IspEnvironment->BinaryContent[i++];\r
+ ivt_CRC += IspEnvironment->BinaryContent[i++] << 8;\r
+ ivt_CRC += IspEnvironment->BinaryContent[i++] << 16;\r
+ ivt_CRC += IspEnvironment->BinaryContent[i++] << 24;\r
+ }\r
+\r
+ /* Negate the result and place in the vector at 0x14 as little endian\r
+ * again. The resulting vector table should checksum to 0. */\r
+ ivt_CRC = (unsigned long) (0 - ivt_CRC);\r
+ for (i = 0; i < 4; i++)\r
+ {\r
+ IspEnvironment->BinaryContent[i + 0x14] = (unsigned char)(ivt_CRC >> (8 * i));\r
+ }\r
+\r
+ DebugPrintf(3, "Position 0x14 patched: ivt_CRC = 0x%08lX\n", ivt_CRC);\r
+ }\r
+\r
+ DebugPrintf(2, "Synchronizing (ESC to abort)");\r
+\r
+ PrepareKeyboardTtySettings();\r
+\r
+#if defined INTEGRATED_IN_WIN_APP\r
+ if (IspEnvironment->NoSync)\r
+ {\r
+ found = 1;\r
+ }\r
+ else\r
+#endif\r
+ {\r
+ for (nQuestionMarks = found = 0; !found && nQuestionMarks < 100; nQuestionMarks++)\r
+ {\r
+#if defined INTEGRATED_IN_WIN_APP\r
+ // allow calling application to abort when syncing takes too long\r
+\r
+ if (!AppSyncing(nQuestionMarks))\r
+ {\r
+ return (USER_ABORT_SYNC);\r
+ }\r
+#else\r
+#ifndef Exclude_kbhit\r
+ if (kbhit())\r
+ {\r
+ if (getch() == 0x1b)\r
+ {\r
+ ResetKeyboardTtySettings();\r
+ DebugPrintf(2, "\nUser aborted during synchronisation\n");\r
+ return (USER_ABORT_SYNC);\r
+ }\r
+ }\r
+#endif\r
+#endif\r
+\r
+ DebugPrintf(2, ".");\r
+ SendComPort(IspEnvironment, "?");\r
+\r
+ memset(Answer,0,sizeof(Answer));\r
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,100);\r
+\r
+ strippedAnswer = Answer;\r
+ strippedsize = realsize;\r
+ while ((strippedsize > 0) && ((*strippedAnswer == '?') || (*strippedAnswer == 0)))\r
+ {\r
+ strippedAnswer++;\r
+ strippedsize--;\r
+ }\r
+\r
+ sprintf(tmp_string, "StrippedAnswer(Length=%ld): '", strippedsize);\r
+ DumpString(3, strippedAnswer, strippedsize, tmp_string);\r
+\r
+ if (strcmp(strippedAnswer, "Bootloader\r\n") == 0 && IspEnvironment->TerminalOnly == 0)\r
+ {\r
+ long chars, xtal;\r
+ unsigned long ticks;\r
+ chars = (17 * IspEnvironment->BinaryLength + 1) / 10;\r
+ WatchDogSeconds = (10 * chars + 5) / atol(IspEnvironment->baud_rate) + 10;\r
+ xtal = atol(IspEnvironment->StringOscillator) * 1000;\r
+ ticks = (unsigned long)WatchDogSeconds * ((xtal + 15) / 16);\r
+ DebugPrintf(2, "Entering ISP; re-synchronizing (watchdog = %ld seconds)\n", WatchDogSeconds);\r
+ sprintf(temp, "T %lu\r\n", ticks);\r
+ SendComPort(IspEnvironment, temp);\r
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,100);\r
+ if (strcmp(Answer, "OK\r\n") != 0)\r
+ {\r
+ ResetKeyboardTtySettings();\r
+ DebugPrintf(2, "No answer on 'watchdog timer set'\n");\r
+ return (NO_ANSWER_WDT);\r
+ }\r
+ SendComPort(IspEnvironment, "G 10356\r\n");\r
+ Sleep(200);\r
+ nQuestionMarks = 0;\r
+ WaitForWatchDog = 1;\r
+ continue;\r
+ }\r
+\r
+ tStartUpload = time(NULL);\r
+\r
+ if (strcmp(strippedAnswer, "Synchronized\r\n") == 0)\r
+ {\r
+ found = 1;\r
+ }\r
+#if !defined COMPILE_FOR_LPC21\r
+ else\r
+ {\r
+ ResetTarget(IspEnvironment, PROGRAM_MODE);\r
+ }\r
+#endif\r
+ }\r
+ }\r
+\r
+ ResetKeyboardTtySettings();\r
+\r
+ if (!found)\r
+ {\r
+ DebugPrintf(1, " no answer on '?'\n");\r
+ return (NO_ANSWER_QM);\r
+ }\r
+\r
+#if defined INTEGRATED_IN_WIN_APP\r
+ AppSyncing(-1); // flag syncing done\r
+#endif\r
+\r
+ DebugPrintf(2, " OK\n");\r
+\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ {\r
+ SendComPort(IspEnvironment, "Synchronized\r\n");\r
+ }\r
+ else\r
+ {\r
+ SendComPort(IspEnvironment, "Synchronized\n");\r
+ }\r
+\r
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer) - 1, &realsize, 2, 1000);\r
+\r
+ if ((strcmp(Answer, "Synchronized\r\nOK\r\n") != 0) && (strcmp(Answer, "Synchronized\rOK\r\n") != 0) &&\r
+ (strcmp(Answer, "Synchronized\nOK\r\n") != 0))\r
+ {\r
+ DebugPrintf(1, "No answer on 'Synchronized'\n");\r
+ return (NO_ANSWER_SYNC);\r
+ }\r
+\r
+ DebugPrintf(3, "Synchronized 1\n");\r
+\r
+ DebugPrintf(3, "Setting oscillator\n");\r
+\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ sprintf(temp, "%s\r\n", IspEnvironment->StringOscillator);\r
+ else\r
+ sprintf(temp, "%s\n", IspEnvironment->StringOscillator);\r
+\r
+ SendComPort(IspEnvironment, temp);\r
+\r
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2, 1000);\r
+\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ sprintf(temp, "%s\r\nOK\r\n", IspEnvironment->StringOscillator);\r
+ else\r
+ sprintf(temp, "%s\nOK\r\n", IspEnvironment->StringOscillator);\r
+\r
+ if (strcmp(Answer, temp) != 0)\r
+ {\r
+ DebugPrintf(1, "No answer on Oscillator-Command\n");\r
+ return (NO_ANSWER_OSC);\r
+ }\r
+\r
+ DebugPrintf(3, "Unlock\n");\r
+\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ cmdstr = "U 23130\r\n";\r
+ else\r
+ cmdstr = "U 23130\n";\r
+\r
+ //if (!SendAndVerify(IspEnvironment, "U 23130\n", Answer, sizeof Answer))//if (!SendAndVerify(IspEnvironment, "U 23130\r\n", Answer, sizeof Answer))\r
+ if (!SendAndVerify(IspEnvironment, cmdstr, Answer, sizeof Answer))\r
+ {\r
+ DebugPrintf(1, "Unlock-Command:\n");\r
+ return (UNLOCK_ERROR + GetAndReportErrorNumber(Answer));\r
+ }\r
+\r
+ DebugPrintf(2, "Read bootcode version: ");\r
+\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ cmdstr = "K\r\n";\r
+ else\r
+ cmdstr = "K\n";\r
+\r
+ SendComPort(IspEnvironment, cmdstr);\r
+\r
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 4,5000);\r
+\r
+\r
+ //if (strncmp(Answer, "K\n", 2) != 0)//if (strncmp(Answer, "K\r\n", 3) != 0)\r
+ if (strncmp(Answer, cmdstr, strlen(cmdstr)) != 0)\r
+ {\r
+ DebugPrintf(1, "no answer on Read Boot Code Version\n");\r
+ return (NO_ANSWER_RBV);\r
+ }\r
+\r
+ //if (strncmp(Answer, "K\n0\r\n", 5) == 0)//if (strncmp(Answer, "K\r\n0\r\n", 6) == 0)\r
+ if (strncmp(Answer + strlen(cmdstr), "0\r\n", 3) == 0)\r
+ {\r
+ strippedAnswer = Answer + strlen(cmdstr) + 3;\r
+ /*\r
+ int maj, min, build;\r
+ if (sscanf(strippedAnswer, "%d %d %d", &build, &min, &maj) == 2) {\r
+ maj = min;\r
+ min = build;\r
+ build = 0;\r
+ } // if\r
+ DebugPrintf(2, "%d.%d.%d\n", maj, min, build);\r
+ */\r
+ DebugPrintf(2, strippedAnswer);\r
+ }\r
+ else\r
+ {\r
+ DebugPrintf(2, "unknown\n");\r
+ }\r
+\r
+ DebugPrintf(2, "Read part ID: ");\r
+\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ cmdstr = "J\r\n";\r
+ else\r
+ cmdstr = "J\n";\r
+\r
+ SendComPort(IspEnvironment, cmdstr);\r
+\r
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 3,5000);\r
+\r
+\r
+\r
+ //if (strncmp(Answer, "J\n", 2) != 0)//if (strncmp(Answer, "J\r\n", 3) != 0)\r
+ if (strncmp(Answer, cmdstr, strlen(cmdstr)) != 0)\r
+ {\r
+ DebugPrintf(1, "no answer on Read Part Id\n");\r
+ return (NO_ANSWER_RPID);\r
+ }\r
+\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ strippedAnswer = (strncmp(Answer, "J\r\n0\r\n", 6) == 0) ? Answer + 6 : Answer;\r
+ else\r
+ strippedAnswer = (strncmp(Answer, "J\n0\r\n", 5) == 0) ? Answer + 5 : Answer;\r
+\r
+ Pos = strtoul(strippedAnswer, &endPtr, 10);\r
+ *endPtr = '\0'; /* delete \r\n */\r
+ for (i = sizeof LPCtypes / sizeof LPCtypes[0] - 1; i > 0 && LPCtypes[i].id != Pos; i--)\r
+ /* nothing */;\r
+ IspEnvironment->DetectedDevice = i;\r
+ if (IspEnvironment->DetectedDevice == 0) {\r
+ DebugPrintf(2, "unknown");\r
+ }\r
+ else {\r
+ DebugPrintf(2, "LPC%d, %d kiB ROM / %d kiB SRAM",\r
+ LPCtypes[IspEnvironment->DetectedDevice].Product,\r
+ LPCtypes[IspEnvironment->DetectedDevice].FlashSize,\r
+ LPCtypes[IspEnvironment->DetectedDevice].RAMSize);\r
+ }\r
+ DebugPrintf(2, " (0x%X)\n", Pos);//strippedAnswer);\r
+\r
+ /* In case of a download to RAM, use full RAM for downloading\r
+ * set the flash parameters to full RAM also.\r
+ * This makes sure that all code is downloaded as one big sector\r
+ */\r
+\r
+ if (IspEnvironment->BinaryOffset >= LPC_RAMSTART)\r
+ {\r
+ LPCtypes[IspEnvironment->DetectedDevice].FlashSectors = 1;\r
+ LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize = LPCtypes[IspEnvironment->DetectedDevice].RAMSize*1024 - (LPC_RAMBASE - LPC_RAMSTART);\r
+ LPCtypes[IspEnvironment->DetectedDevice].SectorTable = SectorTable_RAM;\r
+ SectorTable_RAM[0] = LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize;\r
+ }\r
+ if (IspEnvironment->DetectOnly)\r
+ return (0);\r
+\r
+\r
+ // Start with sector 1 and go upward... Sector 0 containing the interrupt vectors\r
+ // will be loaded last, since it contains a checksum and device will re-enter\r
+ // bootloader mode as long as this checksum is invalid.\r
+ DebugPrintf(2, "Will start programming at Sector 1 if possible, and conclude with Sector 0 to ensure that checksum is written last.\n");\r
+ if (LPCtypes[IspEnvironment->DetectedDevice].SectorTable[0] >= IspEnvironment->BinaryLength)\r
+ {\r
+ Sector = 0;\r
+ SectorStart = 0;\r
+ }\r
+ else\r
+ {\r
+ SectorStart = LPCtypes[IspEnvironment->DetectedDevice].SectorTable[0];\r
+ Sector = 1;\r
+ }\r
+\r
+ if (IspEnvironment->WipeDevice == 1)\r
+ {\r
+ DebugPrintf(2, "Wiping Device. ");\r
+\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ sprintf(tmpString, "P %ld %ld\r\n", 0, LPCtypes[IspEnvironment->DetectedDevice].FlashSectors-1);\r
+ else\r
+ sprintf(tmpString, "P %ld %ld\n", 0, LPCtypes[IspEnvironment->DetectedDevice].FlashSectors-1);\r
+\r
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))\r
+ {\r
+ DebugPrintf(1, "Wrong answer on Prepare-Command\n");\r
+ return (WRONG_ANSWER_PREP + GetAndReportErrorNumber(Answer));\r
+ }\r
+\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ sprintf(tmpString, "E %ld %ld\r\n", 0, LPCtypes[IspEnvironment->DetectedDevice].FlashSectors-1);\r
+ else\r
+ sprintf(tmpString, "E %ld %ld\n", 0, LPCtypes[IspEnvironment->DetectedDevice].FlashSectors-1);\r
+\r
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))\r
+ {\r
+ DebugPrintf(1, "Wrong answer on Erase-Command\n");\r
+ return (WRONG_ANSWER_ERAS + GetAndReportErrorNumber(Answer));\r
+ }\r
+ DebugPrintf(2, "OK \n");\r
+ }\r
+ while (1)\r
+ {\r
+ if (Sector >= LPCtypes[IspEnvironment->DetectedDevice].FlashSectors)\r
+ {\r
+ DebugPrintf(1, "Program too large; running out of Flash sectors.\n");\r
+ return (PROGRAM_TOO_LARGE);\r
+ }\r
+\r
+ DebugPrintf(2, "Sector %ld: ", Sector);\r
+ fflush(stdout);\r
+\r
+ if (IspEnvironment->BinaryOffset < LPC_RAMSTART) // Skip Erase when running from RAM\r
+ {\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ sprintf(tmpString, "P %ld %ld\r\n", Sector, Sector);\r
+ else\r
+ sprintf(tmpString, "P %ld %ld\n", Sector, Sector);\r
+\r
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))\r
+ {\r
+ DebugPrintf(1, "Wrong answer on Prepare-Command (1) (Sector %ld)\n", Sector);\r
+ return (WRONG_ANSWER_PREP + GetAndReportErrorNumber(Answer));\r
+ }\r
+\r
+ DebugPrintf(2, ".");\r
+ fflush(stdout);\r
+ if (IspEnvironment->WipeDevice == 0)\r
+ {\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ sprintf(tmpString, "E %ld %ld\r\n", Sector, Sector);\r
+ else\r
+ sprintf(tmpString, "E %ld %ld\n", Sector, Sector);\r
+\r
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))\r
+ {\r
+ DebugPrintf(1, "Wrong answer on Erase-Command (Sector %ld)\n", Sector);\r
+ return (WRONG_ANSWER_ERAS + GetAndReportErrorNumber(Answer));\r
+ }\r
+\r
+ DebugPrintf(2, ".");\r
+ fflush(stdout);\r
+ }\r
+ }\r
+\r
+ SectorLength = LPCtypes[IspEnvironment->DetectedDevice].SectorTable[Sector];\r
+ if (SectorLength > IspEnvironment->BinaryLength - SectorStart)\r
+ {\r
+ SectorLength = IspEnvironment->BinaryLength - SectorStart;\r
+ }\r
+\r
+ for (SectorOffset = 0; SectorOffset < SectorLength; SectorOffset += SectorChunk)\r
+ {\r
+ if (SectorOffset > 0)\r
+ {\r
+ // Add a visible marker between segments in a sector\r
+ DebugPrintf(2, "|"); /* means: partial segment copied */\r
+ fflush(stdout);\r
+ }\r
+\r
+ // If the Flash ROM sector size is bigger than the number of bytes\r
+ // we can copy from RAM to Flash, we must "chop up" the sector and\r
+ // copy these individually.\r
+ // This is especially needed in the case where a Flash sector is\r
+ // bigger than the amount of SRAM.\r
+ SectorChunk = SectorLength - SectorOffset;\r
+ if (SectorChunk > (unsigned)LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize)\r
+ {\r
+ SectorChunk = LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize;\r
+ }\r
+\r
+ // Write multiple of 45 * 4 Byte blocks to RAM, but copy maximum of on sector to Flash\r
+ // In worst case we transfer up to 180 byte to much to RAM\r
+ // but then we can always use full 45 byte blocks and length is multiple of 4\r
+ CopyLength = SectorChunk;\r
+ if ((CopyLength % (45 * 4)) != 0)\r
+ {\r
+ CopyLength += ((45 * 4) - (CopyLength % (45 * 4)));\r
+ }\r
+\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ sprintf(tmpString, "W %ld %ld\r\n", LPC_RAMBASE, CopyLength);\r
+ else\r
+ sprintf(tmpString, "W %ld %ld\n", LPC_RAMBASE, CopyLength);\r
+\r
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))\r
+ {\r
+ DebugPrintf(1, "Wrong answer on Write-Command\n");\r
+ return (WRONG_ANSWER_WRIT + GetAndReportErrorNumber(Answer));\r
+ }\r
+\r
+ DebugPrintf(2, ".");\r
+ fflush(stdout);\r
+\r
+ block_CRC = 0;\r
+ Line = 0;\r
+\r
+ // Transfer blocks of 45 * 4 bytes to RAM\r
+ for (Pos = SectorStart + SectorOffset; (Pos < SectorStart + SectorOffset + CopyLength) && (Pos < IspEnvironment->BinaryLength); Pos += (45 * 4))\r
+ {\r
+ for (Block = 0; Block < 4; Block++) // Each block 45 bytes\r
+ {\r
+ DebugPrintf(2, ".");\r
+ fflush(stdout);\r
+\r
+#if defined INTEGRATED_IN_WIN_APP\r
+ // inform the calling application about having written another chuck of data\r
+ AppWritten(45);\r
+#endif\r
+\r
+ // Uuencode one 45 byte block\r
+ tmpStringPos = 0;\r
+\r
+#if !defined COMPILE_FOR_LPC21\r
+ sendbuf[Line][tmpStringPos++] = (char)(' ' + 45); // Encode Length of block\r
+#else\r
+ tmpString[tmpStringPos++] = (char)(' ' + 45); // Encode Length of block\r
+#endif\r
+\r
+ for (BlockOffset = 0; BlockOffset < 45; BlockOffset++)\r
+ {\r
+ if (IspEnvironment->BinaryOffset < LPC_RAMSTART)\r
+ { // Flash: use full memory\r
+ c = IspEnvironment->BinaryContent[Pos + Block * 45 + BlockOffset];\r
+ }\r
+ else\r
+ { // RAM: Skip first 0x200 bytes, these are used by the download program in LPC21xx\r
+ c = IspEnvironment->BinaryContent[Pos + Block * 45 + BlockOffset + 0x200];\r
+ }\r
+\r
+ block_CRC += c;\r
+\r
+ k = (k << 8) + (c & 255);\r
+\r
+ if ((BlockOffset % 3) == 2) // Collecting always 3 Bytes, then do processing in 4 Bytes\r
+ {\r
+#if !defined COMPILE_FOR_LPC21\r
+ sendbuf[Line][tmpStringPos++] = uuencode_table[(k >> 18) & 63];\r
+ sendbuf[Line][tmpStringPos++] = uuencode_table[(k >> 12) & 63];\r
+ sendbuf[Line][tmpStringPos++] = uuencode_table[(k >> 6) & 63];\r
+ sendbuf[Line][tmpStringPos++] = uuencode_table[ k & 63];\r
+#else\r
+ tmpString[tmpStringPos++] = uuencode_table[(k >> 18) & 63];\r
+ tmpString[tmpStringPos++] = uuencode_table[(k >> 12) & 63];\r
+ tmpString[tmpStringPos++] = uuencode_table[(k >> 6) & 63];\r
+ tmpString[tmpStringPos++] = uuencode_table[ k & 63];\r
+#endif\r
+ }\r
+ }\r
+\r
+\r
+#if !defined COMPILE_FOR_LPC21\r
+ sendbuf[Line][tmpStringPos++] = '\r';\r
+ sendbuf[Line][tmpStringPos++] = '\n';\r
+ sendbuf[Line][tmpStringPos++] = 0;\r
+\r
+ SendComPort(IspEnvironment, sendbuf[Line]);\r
+ // receive only for debug proposes\r
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,5000);\r
+#else\r
+ tmpString[tmpStringPos++] = '\r';\r
+ tmpString[tmpStringPos++] = '\n';\r
+ tmpString[tmpStringPos++] = 0;\r
+\r
+ SendComPort(IspEnvironment, tmpString);\r
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,5000);\r
+ if (strncmp(Answer, tmpString, tmpStringPos) != 0)\r
+ {\r
+ DebugPrintf(1, "Error on writing data (1)\n");\r
+ return (ERROR_WRITE_DATA);\r
+ }\r
+#endif\r
+\r
+ Line++;\r
+\r
+ DebugPrintf(3, "Line = %d\n", Line);\r
+\r
+ if (Line == 20)\r
+ {\r
+#if !defined COMPILE_FOR_LPC21\r
+ for (repeat = 0; repeat < 3; repeat++)\r
+ {\r
+\r
+ // printf("block_CRC = %ld\n", block_CRC);\r
+\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ sprintf(tmpString, "%ld\r\n", block_CRC);\r
+ else\r
+ sprintf(tmpString, "%ld\n", block_CRC);\r
+\r
+ SendComPort(IspEnvironment, tmpString);\r
+\r
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000);\r
+\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ sprintf(tmpString, "%ld\r\nOK\r\n", block_CRC);\r
+ else\r
+ sprintf(tmpString, "%ld\nOK\r\n", block_CRC);\r
+\r
+ if (strcmp(Answer, tmpString) != 0)\r
+ {\r
+ for (i = 0; i < Line; i++)\r
+ {\r
+ SendComPort(IspEnvironment, sendbuf[i]);\r
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,5000);\r
+ }\r
+ }\r
+ else\r
+ break;\r
+ }\r
+\r
+ if (repeat >= 3)\r
+ {\r
+ DebugPrintf(1, "Error on writing block_CRC (1)\n");\r
+ return (ERROR_WRITE_CRC);\r
+ }\r
+#else\r
+ // printf("block_CRC = %ld\n", block_CRC);\r
+ sprintf(tmpString, "%ld\r\n", block_CRC);\r
+ SendComPort(IspEnvironment, tmpString);\r
+\r
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000);\r
+\r
+ sprintf(tmpString, "%ld\r\nOK\r\n", block_CRC);\r
+ if (strcmp(Answer, tmpString) != 0)\r
+ {\r
+ DebugPrintf(1, "Error on writing block_CRC (1)\n");\r
+ return (ERROR_WRITE_CRC);\r
+ }\r
+#endif\r
+ Line = 0;\r
+ block_CRC = 0;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (Line != 0)\r
+ {\r
+#if !defined COMPILE_FOR_LPC21\r
+ for (repeat = 0; repeat < 3; repeat++)\r
+ {\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ sprintf(tmpString, "%ld\r\n", block_CRC);\r
+ else\r
+ sprintf(tmpString, "%ld\n", block_CRC);\r
+\r
+ SendComPort(IspEnvironment, tmpString);\r
+\r
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000);\r
+\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ sprintf(tmpString, "%ld\r\nOK\r\n", block_CRC);\r
+ else\r
+ sprintf(tmpString, "%ld\nOK\r\n", block_CRC);\r
+\r
+ if (strcmp(Answer, tmpString) != 0)\r
+ {\r
+ for (i = 0; i < Line; i++)\r
+ {\r
+ SendComPort(IspEnvironment, sendbuf[i]);\r
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,5000);\r
+ }\r
+ }\r
+ else\r
+ break;\r
+ }\r
+\r
+ if (repeat >= 3)\r
+ {\r
+ DebugPrintf(1, "Error on writing block_CRC (2)\n");\r
+ return (ERROR_WRITE_CRC2);\r
+ }\r
+#else\r
+ sprintf(tmpString, "%ld\r\n", block_CRC);\r
+ SendComPort(IspEnvironment, tmpString);\r
+\r
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000);\r
+\r
+ sprintf(tmpString, "%ld\r\nOK\r\n", block_CRC);\r
+ if (strcmp(Answer, tmpString) != 0)\r
+ {\r
+ DebugPrintf(1, "Error on writing block_CRC (2)\n");\r
+ return (ERROR_WRITE_CRC2);\r
+ }\r
+#endif\r
+ }\r
+\r
+ if (IspEnvironment->BinaryOffset < LPC_RAMSTART)\r
+ {\r
+ // Prepare command must be repeated before every write\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ sprintf(tmpString, "P %ld %ld\r\n", Sector, Sector);\r
+ else\r
+ sprintf(tmpString, "P %ld %ld\n", Sector, Sector);\r
+\r
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))\r
+ {\r
+ DebugPrintf(1, "Wrong answer on Prepare-Command (2) (Sector %ld)\n", Sector);\r
+ return (WRONG_ANSWER_PREP2 + GetAndReportErrorNumber(Answer));\r
+ }\r
+\r
+ // Round CopyLength up to one of the following values: 512, 1024,\r
+ // 4096, 8192; but do not exceed the maximum copy size (usually\r
+ // 8192, but chip-dependent)\r
+ if (CopyLength < 512)\r
+ {\r
+ CopyLength = 512;\r
+ }\r
+ else if (SectorLength < 1024)\r
+ {\r
+ CopyLength = 1024;\r
+ }\r
+ else if (SectorLength < 4096)\r
+ {\r
+ CopyLength = 4096;\r
+ }\r
+ else\r
+ {\r
+ CopyLength = 8192;\r
+ }\r
+ if (CopyLength > (unsigned)LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize)\r
+ {\r
+ CopyLength = LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize;\r
+ }\r
+\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ sprintf(tmpString, "C %ld %ld %ld\r\n", SectorStart + SectorOffset, LPC_RAMBASE, CopyLength);\r
+ else\r
+ sprintf(tmpString, "C %ld %ld %ld\n", SectorStart + SectorOffset, LPC_RAMBASE, CopyLength);\r
+\r
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))\r
+ {\r
+ DebugPrintf(1, "Wrong answer on Copy-Command\n");\r
+ return (WRONG_ANSWER_COPY + GetAndReportErrorNumber(Answer));\r
+ }\r
+\r
+ if (IspEnvironment->Verify)\r
+ {\r
+\r
+ //Avoid compare first 64 bytes.\r
+ //Because first 64 bytes are re-mapped to flash boot sector,\r
+ //and the compare result may not be correct.\r
+ if (SectorStart + SectorOffset<64)\r
+ {\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ sprintf(tmpString, "M %ld %ld %ld\r\n", 64, LPC_RAMBASE + (64 - SectorStart - SectorOffset), CopyLength-(64 - SectorStart - SectorOffset));\r
+ else\r
+ sprintf(tmpString, "M %ld %ld %ld\n", 64, LPC_RAMBASE + (64 - SectorStart - SectorOffset), CopyLength-(64 - SectorStart - SectorOffset));\r
+ }\r
+ else\r
+ {\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ sprintf(tmpString, "M %ld %ld %ld\r\n", SectorStart + SectorOffset, LPC_RAMBASE, CopyLength);\r
+ else\r
+ sprintf(tmpString, "M %ld %ld %ld\n", SectorStart + SectorOffset, LPC_RAMBASE, CopyLength);\r
+ }\r
+\r
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))\r
+ {\r
+ DebugPrintf(1, "Wrong answer on Compare-Command\n");\r
+ return (WRONG_ANSWER_COPY + GetAndReportErrorNumber(Answer));\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ DebugPrintf(2, "\n");\r
+ fflush(stdout);\r
+\r
+ if ((SectorStart + SectorLength) >= IspEnvironment->BinaryLength && Sector!=0)\r
+ {\r
+ Sector = 0;\r
+ SectorStart = 0;\r
+ }\r
+ else if (Sector == 0) {\r
+ break;\r
+ }\r
+ else {\r
+ SectorStart += LPCtypes[IspEnvironment->DetectedDevice].SectorTable[Sector];\r
+ Sector++;\r
+ }\r
+ }\r
+\r
+ tDoneUpload = time(NULL);\r
+ if (IspEnvironment->Verify)\r
+ DebugPrintf(2, "Download Finished and Verified correct... taking %d seconds\n", tDoneUpload - tStartUpload);\r
+ else\r
+ DebugPrintf(2, "Download Finished... taking %d seconds\n", tDoneUpload - tStartUpload);\r
+\r
+ if (WaitForWatchDog)\r
+ {\r
+ DebugPrintf(2, "Wait for restart, in %d seconds from now\n", WatchDogSeconds - (tDoneUpload - tStartUpload));\r
+ }\r
+ else\r
+ {\r
+ DebugPrintf(2, "Now launching the brand new code\n");\r
+ fflush(stdout);\r
+\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ sprintf(tmpString, "G %ld A\r\n", IspEnvironment->StartAddress);\r
+ else\r
+ sprintf(tmpString, "G %ld A\n", IspEnvironment->StartAddress);\r
+\r
+ SendComPort(IspEnvironment, tmpString); //goto 0 : run this fresh new downloaded code code\r
+ if (IspEnvironment->BinaryOffset < LPC_RAMSTART)\r
+ { // Skip response on G command - show response on Terminal instead\r
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2, 5000);\r
+ /* the reply string is frequently terminated with a -1 (EOF) because the\r
+ * connection gets broken; zero-terminate the string ourselves\r
+ */\r
+ while (realsize > 0 && ((signed char) Answer[(int)realsize - 1]) < 0)\r
+ realsize--;\r
+ Answer[(int)realsize] = '\0';\r
+ /* Better to check only the first 9 chars instead of complete receive buffer,\r
+ * because the answer can contain the output by the started programm\r
+ */\r
+ if (IspEnvironment->HalfDuplex == 0)\r
+ {\r
+ // This was not working with my LPC2214 most of the time - Herbert Demmel\r
+ // was: cmdstr = "G 0 A\r\n0\r";\r
+ cmdstr = "G 0 A\r\n0";\r
+ }\r
+ else\r
+ {\r
+ cmdstr = "G 0 A\n0\r";\r
+ }\r
+\r
+ //if (realsize == 0 || strncmp((const char *)Answer, "G 0 A\n0\r", 8) != 0)//if (realsize == 0 || strncmp((const char *)Answer, "G 0 A\r\n0\r", 9) != 0)\r
+ if (realsize == 0 || strncmp((const char *)Answer, cmdstr, strlen(cmdstr)) != 0)\r
+ {\r
+ DebugPrintf(2, "Failed to run the new downloaded code: ");\r
+ return (FAILED_RUN + GetAndReportErrorNumber(Answer));\r
+ }\r
+ }\r
+\r
+ fflush(stdout);\r
+ }\r
+ return (0);\r
+}\r
+#endif // LPC_SUPPORT\r