diff options
| author | Brad Luyster <BradLuyster@gmail.com> | 2012-09-07 21:39:43 -0400 |
|---|---|---|
| committer | Brad Luyster <BradLuyster@gmail.com> | 2012-09-07 21:39:43 -0400 |
| commit | 0a326d6219945b5e55f0c0ff6f3abb9e63dbaaa5 (patch) | |
| tree | 98004704a66cf7c5a546e39f8e3264d4e8a705c8 | |
Initial Commit
| -rw-r--r-- | Makefile | 33 | ||||
| -rw-r--r-- | Makefile.vc | 26 | ||||
| -rw-r--r-- | README | 45 | ||||
| -rw-r--r-- | StdAfx.h | 0 | ||||
| -rw-r--r-- | adprog.c | 325 | ||||
| -rw-r--r-- | adprog.h | 47 | ||||
| -rwxr-xr-x | debugout.bin | bin | 0 -> 940 bytes | |||
| -rw-r--r-- | gpl.txt | 674 | ||||
| -rw-r--r-- | lgpl-3.0.txt | 165 | ||||
| -rw-r--r-- | lpc21isp.c | 2190 | ||||
| -rw-r--r-- | lpc21isp.cbp | 57 | ||||
| -rw-r--r-- | lpc21isp.h | 289 | ||||
| -rw-r--r-- | lpc21isp.layout | 16 | ||||
| -rw-r--r-- | lpcprog.c | 1273 | ||||
| -rw-r--r-- | lpcprog.dsp | 100 | ||||
| -rw-r--r-- | lpcprog.dsw | 29 | ||||
| -rw-r--r-- | lpcprog.h | 127 | ||||
| -rw-r--r-- | lpcterm.c | 138 | ||||
| -rw-r--r-- | lpcterm.h | 43 | ||||
| -rw-r--r-- | out.txt | 817 |
20 files changed, 6394 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6f8bc7d --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +all: lpc21isp + +GLOBAL_DEP = adprog.h lpc21isp.h lpcprog.h lpcterm.h +CC = gcc + +ifneq ($(findstring(freebsd, $(OSTYPE))),) +CFLAGS+=-D__FREEBSD__ +endif + +ifeq ($(OSTYPE),) +OSTYPE = $(shell uname) +endif + +ifneq ($(findstring Darwin,$(OSTYPE)),) +CFLAGS+=-D__APPLE__ +endif + +CFLAGS += -Wall -static + +adprog.o: adprog.c $(GLOBAL_DEP) + $(CC) $(CDEBUG) $(CFLAGS) -c -o adprog.o adprog.c + +lpcprog.o: lpcprog.c $(GLOBAL_DEP) + $(CC) $(CDEBUG) $(CFLAGS) -c -o lpcprog.o lpcprog.c + +lpcterm.o: lpcterm.c $(GLOBAL_DEP) + $(CC) $(CDEBUG) $(CFLAGS) -c -o lpcterm.o lpcterm.c + +lpc21isp: lpc21isp.c adprog.o lpcprog.o lpcterm.o $(GLOBAL_DEP) + $(CC) $(CDEBUG) $(CFLAGS) -o lpc21isp lpc21isp.c adprog.o lpcprog.o lpcterm.o + +clean: + $(RM) adprog.o lpcprog.o lpcterm.o lpc21isp diff --git a/Makefile.vc b/Makefile.vc new file mode 100644 index 0000000..3ca4935 --- /dev/null +++ b/Makefile.vc @@ -0,0 +1,26 @@ +all: lpc21isp.exe
+
+GLOBAL_DEP = lpc21isp.h adprog.h lpcprog.h lpcterm.h
+RM = del
+CC = cl
+
+# CFLAGS = -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS
+CFLAGS =
+
+adprog.obj: adprog.c $(GLOBAL_DEP)
+ $(CC) -c $(CFLAGS) adprog.c
+
+lpcprog.obj: lpcprog.c $(GLOBAL_DEP)
+ $(CC) -c $(CFLAGS) lpcprog.c
+
+lpcterm.obj: lpcterm.c $(GLOBAL_DEP)
+ $(CC) -c $(CFLAGS) lpcterm.c
+
+lpc21isp.obj: lpc21isp.c $(GLOBAL_DEP)
+ $(CC) -c $(CFLAGS) lpc21isp.c
+
+lpc21isp.exe: lpc21isp.obj adprog.obj lpcprog.obj lpcterm.obj
+ $(CC) /Felpc21isp.exe lpc21isp.obj adprog.obj lpcprog.obj lpcterm.obj
+
+clean:
+ $(RM) adprog.obj lpcprog.obj lpcterm.obj lpc21isp.obj lpc21isp.exe vc*.pdb
@@ -0,0 +1,45 @@ +/******************************************************************************
+
+Project: Portable command line ISP for Philips LPC2000 family
+ and Analog Devices ADUC70xx
+
+Filename: README
+
+Compiler: Microsoft VC 6/7, GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author: Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright: (c) Martin Maurer 2003-2008, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+ This file is part of lpc21isp.
+
+ lpc21isp is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ any later version.
+
+ lpc21isp is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ and GNU General Public License along with lpc21isp.
+ If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+To compile with microsoft visual studio:
+- Open console. Execute bat file from your installation, e.g.
+ "c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat"
+- Go to directory where you unpacked the source.
+- Run
+ nmake /f Makefile.vc clean all
+
+To compile with gcc (linux, cygwin, ...)
+- Open shell / terminal windows
+- Run (if you want to use make and gcc)
+ make -f Makefile.gnu clean all
+- Run (if you want to use gmake and gcc)
+ gmake -f Makefile.gnu clean all
diff --git a/StdAfx.h b/StdAfx.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/StdAfx.h diff --git a/adprog.c b/adprog.c new file mode 100644 index 0000000..c6b99b7 --- /dev/null +++ b/adprog.c @@ -0,0 +1,325 @@ +/******************************************************************************
+
+Project: Portable command line ISP for NXP LPC1000 / LPC2000 family
+ and Analog Devices ADUC70xx
+
+Filename: adprog.c
+
+Compiler: Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
+ GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author: Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright: (c) Martin Maurer 2003-2011, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+ This file is part of lpc21isp.
+
+ lpc21isp is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ any later version.
+
+ lpc21isp is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ and GNU General Public License along with lpc21isp.
+ If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#if defined(_WIN32)
+#if !defined __BORLANDC__
+#include "StdAfx.h"
+#endif
+#endif // defined(_WIN32)
+#include "lpc21isp.h"
+
+#ifdef AD_SUPPORT
+#include "adprog.h"
+
+/***************************** 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;
+
+/***************************** AnalogDevicesFormPacket ******************/
+/** Create an Analog Devices communication packet from the constituent
+elements.
+\param [in] cmd The command being sent, one of 'E' for erase, 'W' for
+write, 'V' for verify or 'R' for run..
+\param [in] no_bytes the number of data bytes to send with the command in
+the packet.
+\param [in] address the address to apply the command to.
+\param [in] data the data to send with the packet, may be null if no_bytes
+is zero.
+\param[out] packet that will be filled.
+*/
+static void AnalogDevicesFormPacket(ISP_ENVIRONMENT *IspEnvironment,
+ char cmd, int no_bytes, unsigned int address,
+ const void *data, AD_PACKET *packet)
+{
+ BINARY checksum;
+ const BINARY *data_in;
+ int i;
+
+ (void)IspEnvironment; /* never used in this function */
+
+ /* Some sanity checking on the arguments. These should only */
+ /* fail if there is a bug in the caller. */
+ /* Check 1) that the number of data bytes is in an acceptable */
+ /* range, 2) that we have a non-null pointer if data is being */
+ /* put in the packet and 3) that we have a non-null pointer to */
+ /* the packet to be filled. We just exit with an error message */
+ /* if any of these tests fail. */
+ if ((no_bytes < 0) || (no_bytes > 250))
+ {
+ DebugPrintf(1,
+ "The number of bytes (%d) passed to FormPacket is invalid.\n",
+ no_bytes);
+ exit(-1);
+ }
+ if ((data == 0) && (no_bytes != 0))
+ {
+ DebugPrintf(1,
+ "A null pointer to data paased to FormPacket when data was expected.\n");
+ exit(-1);
+ }
+ if (packet == 0)
+ {
+ DebugPrintf(1,
+ "A null packet pointer was passed to FormPacket.\n");
+ exit(-1);
+ }
+
+ checksum = 0; /* Checksum starts at zero. */
+
+ data_in = (BINARY*) data; /* Pointer pun so we can walk through */
+ /* the data. */
+
+ packet->start1 = 0x7; /* The start of the packet is constant.*/
+ packet->start2 = 0xE;
+
+ /* Fill in the rest of the packet and calculate the checksum */
+ /* as we go. */
+
+ /* The number of bytes is the number of data bytes + the */
+ /* address bytes + the command byte. */
+ packet->bytes = (BINARY)(no_bytes + 5);
+
+ checksum += packet->bytes;
+
+ /* The command for the packet being sent. No error checking */
+ /* done on this. */
+ packet->cmd = cmd;
+
+ checksum += cmd;
+
+ /* Now break up the address and place in the proper packet */
+ /* locations. */
+ packet->address_l = (BINARY)(address & 0xFF);
+ packet->address_m = (BINARY)((address >> 8) & 0xFF);
+ packet->address_u = (BINARY)((address >> 16) & 0xFF);
+ packet->address_h = (BINARY)((address >> 24) & 0xFF);
+
+ checksum += packet->address_l;
+ checksum += packet->address_m;
+ checksum += packet->address_u;
+ checksum += packet->address_h;
+
+ /* Copy the data bytes into the packet. We could use memcpy */
+ /* but we have to calculate the checksum anyway. */
+ for (i = 0; i < no_bytes; i++)
+ {
+ packet->data[i] = data_in[i];
+ checksum += data_in[i];
+ }
+
+ /* Finally, add the checksum to the end of the packet. */
+ packet->data[i] = (BINARY)-checksum;
+}
+
+/***************************** AnalogDevicesSendPacket ******************/
+/** Send a previously form Analog Devices communication. Retry a
+couple of times if needed but fail by exiting the program if no ACK is
+forthcoming.
+\param [in] packet the packet to send.
+*/
+static void AnalogDevicesSendPacket(ISP_ENVIRONMENT *IspEnvironment,
+ const AD_PACKET * packet)
+{
+ BINARY response;
+ int retry = 0;
+
+ do {
+ retry++;
+
+ /* Make sure we don't read garbage later instead of */
+ /* the response we expect from the micro. */
+ ClearSerialPortBuffers(IspEnvironment);
+
+ /* Send the packet, the size is the number of data */
+ /* bytes in the packet plus 3 bytes worth of header */
+ /* plus checksum. */
+ SendComPortBlock(IspEnvironment, packet, packet->bytes + 4);
+
+ /* Receive the response and check, return to caller */
+ /* if successful. */
+ if (ReceiveComPortBlockComplete(IspEnvironment, &response, 1, 5000) == 0)
+ {
+ if (response == ANALOG_DEVICES_ACK)
+ {
+ DebugPrintf(3, "Packet Sent\n");
+ return;
+ }
+ if (response != ANALOG_DEVICES_NAK)
+ {
+ DebugPrintf(3, "Unexpected response to packet (%x)\n", (int)response);
+ }
+ DebugPrintf(2, "*");
+ }
+ } while (retry < 3);
+
+ DebugPrintf(1, "Send packet failed\n");
+ exit(-1);
+}
+
+/***************************** AnalogDevicesErase ***********************/
+/** Erase the Analog Devices micro. We take the simple way out and
+just erase the whole thing.
+*/
+static void AnalogDevicesErase(ISP_ENVIRONMENT *IspEnvironment)
+{
+ BINARY pages;
+ AD_PACKET packet;
+
+ pages = 0;
+ DebugPrintf(2, "Erasing .. ");
+ AnalogDevicesFormPacket(IspEnvironment, 'E', 1, 0, &pages, &packet);
+ AnalogDevicesSendPacket(IspEnvironment, &packet);
+ DebugPrintf(2, "Erased\n");
+}
+
+#define AD_PACKET_SIZE (250)
+
+/***************************** AnalogDevicesWrite ***********************/
+/** Write the program.
+\param [in] data the program to download to the micro.
+\param [in] address where to start placing the program.
+\param [in] bytes the size of the progrm to download.
+*/
+static void AnalogDevicesWrite(ISP_ENVIRONMENT *IspEnvironment,
+ const void *data, long address, size_t bytes)
+{
+ AD_PACKET packet;
+ const BINARY *prog_data;
+
+ DebugPrintf(2, "Writing %d bytes ", bytes);
+ prog_data = (const BINARY*) data;
+ while (bytes > AD_PACKET_SIZE)
+ {
+ AnalogDevicesFormPacket(IspEnvironment, 'W', AD_PACKET_SIZE, address, prog_data, &packet);
+ AnalogDevicesSendPacket(IspEnvironment, &packet);
+ address += AD_PACKET_SIZE;
+ prog_data += AD_PACKET_SIZE;
+ bytes -= AD_PACKET_SIZE;
+ DebugPrintf(2, ".");
+ }
+ if (bytes > 0)
+ {
+ AnalogDevicesFormPacket(IspEnvironment, 'W', bytes, address, prog_data, &packet);
+ AnalogDevicesSendPacket(IspEnvironment, &packet);
+ DebugPrintf(2, ".");
+ }
+}
+
+/***************************** AnalogDevicesDownload ********************/
+/** Perform the download into an Analog Devices micro. As a quick and
+* dirty hack against flash relocations at 0x80000
+* \return 0 if ok, error code else
+* \ToDo: possible to implement the return value instead of calling
+* exit() in sub-functions
+*/
+int AnalogDevicesDownload(ISP_ENVIRONMENT *IspEnvironment)
+{
+ AnalogDevicesSync(IspEnvironment);
+ AnalogDevicesErase(IspEnvironment);
+ if (IspEnvironment->BinaryLength > 0x80000)
+ {
+ DebugPrintf(2, "Note: Flash remapped 0x80000 to 0.\n");
+ AnalogDevicesWrite(IspEnvironment, IspEnvironment->BinaryContent + 0x80000, 0, IspEnvironment->BinaryLength-0x80000);
+ }
+ else
+ {
+ AnalogDevicesWrite(IspEnvironment, IspEnvironment->BinaryContent, 0, IspEnvironment->BinaryLength);
+ }
+ return (0);
+}
+#endif // AD_SUPPORT
diff --git a/adprog.h b/adprog.h new file mode 100644 index 0000000..efd296c --- /dev/null +++ b/adprog.h @@ -0,0 +1,47 @@ +/******************************************************************************
+
+Project: Portable command line ISP for NXP LPC1000 / LPC2000 family
+ and Analog Devices ADUC70xx
+
+Filename: adprog.h
+
+Compiler: Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
+ GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author: Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright: (c) Martin Maurer 2003-2011, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+ This file is part of lpc21isp.
+
+ lpc21isp is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ any later version.
+
+ lpc21isp is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ and GNU General Public License along with lpc21isp.
+ If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define ANALOG_DEVICES_SYNC_CHAR ((BINARY)0x08)
+#define ANALOG_DEVICES_SYNC_RESPONSE ("ADuC")
+#define ANALOG_DEVICES_SYNC_SIZE (strlen(ANALOG_DEVICES_SYNC_RESPONSE))
+#define ANALOG_DEVICES_ACK 0x6
+#define ANALOG_DEVICES_NAK 0x7
+
+typedef struct
+{
+ BINARY product_id[15];
+ BINARY version[3];
+ BINARY reserved[4];
+ BINARY terminator[2];
+} AD_SYNC_RESPONSE;
+
+int AnalogDevicesDownload(ISP_ENVIRONMENT *IspEnvironment);
diff --git a/debugout.bin b/debugout.bin Binary files differnew file mode 100755 index 0000000..fb849ea --- /dev/null +++ b/debugout.bin @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/lgpl-3.0.txt b/lgpl-3.0.txt new file mode 100644 index 0000000..fc8a5de --- /dev/null +++ b/lgpl-3.0.txt @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/lpc21isp.c b/lpc21isp.c new file mode 100644 index 0000000..3040275 --- /dev/null +++ b/lpc21isp.c @@ -0,0 +1,2190 @@ +/******************************************************************************
+
+Project: Portable command line ISP for NXP LPC1000 / LPC2000 family
+ and Analog Devices ADUC70xx
+
+Filename: lpc21isp.c
+
+Compiler: Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
+ GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author: Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright: (c) Martin Maurer 2003-2011, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+ This file is part of lpc21isp.
+
+ lpc21isp is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ any later version.
+
+ lpc21isp is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ and GNU General Public License along with lpc21isp.
+ If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#if defined(_WIN32)
+#if !defined __BORLANDC__
+#include "StdAfx.h" // Precompiled Header for WIN32
+#endif
+#endif // defined(_WIN32)
+#include "lpc21isp.h" // if using propriatory serial port communication (customize attached lpc21isp.h)
+#include "adprog.h"
+#include "lpcprog.h"
+#include "lpcterm.h"
+
+/*
+Change-History:
+
+1.00 2004-01-08 Initial Version, tested for MSVC6/7 and GCC under Cygwin
+1.01 2004-01-10 Porting to Linux (at least compiling must work)
+1.02 2004-01-10 Implemented conversion intel hex format -> binary
+1.03 2004-01-25 Preparation to upload to public website
+1.04 2004-02-12 Merged in bugfixes by Soeren Gust
+1.05 2004-03-14 Implement printing of error codes as text / strings
+1.06 2004-03-09 Merged in bugfixes by Charles Manning:
+ The '?' sychronisation does not reliably respond to the first '?'.
+ I added some retries.
+ The LPC2106 sometimes responds to the '?' by echoing them back.
+ This sometimes causes an attempt to match "?Synchonized".
+ Added code to strip off any leading '?'s.
+ Timeouts were too long.
+ Change from RTS/CTS to no flow control.
+ Done because many/most people will use only 3-wire comms.
+ Added some progress tracing.
+1.07 2004-03-14 Implement handling of control lines for easier booting
+1.08 2004-04-01 Bugfix for upload problem
+1.09 2004-04-03 Redesign of upload routine
+ Now always 180 byte blocks are uploaded, to prevent
+ small junks in uuencoding
+1.10 2004-04-03 Clear buffers before sending commands to LPC21xx,
+ this prevents synchronizing errors when previously loaded
+ program does a lot of output, so FIFO of PC runs full
+1.11 2004-04-03 Small optimization for controlling reset line
+ otherwise termonly starts LPC twice, free PC buffers
+1.12 2004-04-04 Add switch to enable logging terminal output to lpc21isp.log
+1.13 2004-05-19 Merged in improvement by Charles Manning:
+ Instead of exiting the wrong hex file size is corrected
+1.14 2004-07-07 Merged in improvement by Alex Holden:
+ Remove little/big endian dependancy
+1.15 2004-09-27 Temporary improvement by Cyril Holweck:
+ Removed test (data echoed = data transmited) on the main
+ data transfert, since this was the biggest failure
+ reason and is covered by checksome anyway.
+ Added COMPILE_FOR_LPC21, to have target dump it's own
+ memory to stdout.
+1.16 2004-10-09 Merged in bugfix / improvement by Sinelnikov Evgeny
+ I found out that Linux and Windows serial port initialization
+ are different with pinouts states. My board don't get
+ reset signal at first cycle of DTR pinout moving.
+ And I add this moving to initalization cycle.
+1.17 2004-10-21 Changes by Cyril Holweck
+ Divide main, take out the real programming function, that can
+ also be used by a target to copy its own code to another.
+1.18 2004-10-26 Changes by Cyril Holweck
+ Added a "G 0 A\r\n" at end of programming to run code.
+1.19 2004-11-03 Changes by Robert Adsett
+ Add support for Analog Devices.
+ Separate file load from programming.
+ Change from a debug on/off flag to debug level
+ Remove if (debug) tests and replace with DebugPrintf
+ statements.
+ Change serial I/O and timing so that the system
+ dependancies are isolated to a few portability functions.
+ Add support for binary serial I/O.
+ Add doxygen support.
+1.20 2004-11-07 Preparation for multiport booting (factory support)
+1.21 2004-11-08 Bugfix from Robert Adsett
+ BinaryLength was not initialized
+1.22 2004-11-08 Changes from Cyril Holweck / Evgeny Sinelnikov
+ Forgotten IspEnvironment-> and bugfixes if COMPILE_FOR_LINUX
+ If COMPILE_FOR_LPC21, PhilipsDownload() 'acts as' main():
+ - it should not be static and should return int.
+ - no sub-function can use exit() but only return ()
+ Use 'char' instead of 'byte' ;)
+1.23 2005-01-16 Build in automatic detection of LPC chiptype
+ (needed for 256 KByte support)
+1.24B 2005-06-02 Changes by Thiadmer Riemersma: completed support for other
+ chip types (LPC213x series and others).
+1.24C 2005-06-11 Changes by Thiadmer Riemersma: added the device ID codes for
+ chip types LPC2131 and LPC2132.
+1.25 2005-06-19 Martin Maurer: Setup more parameters in DCB,
+ otherwise wrong code is downloaded (only Windows and Cygwin)
+ when a previous program has changed these parameters
+ Check exact string of "G 0 A\r\n0\r\n" instead of whole received buffer,
+ to prevent checking of already received by program start
+ (error on running program, but reports CMD_SUCCESS)
+ Add ifdefs for all baudrates (needed only for high baudrate,
+ which seem to be not available on Macs...)
+1.26 2005-06-26 Martin Maurer:
+ Correct check again: "G 0 A\r\n0\r\n" is cutted, because of reboot
+ (error on running program, but reports CMD_SUCCESS)
+1.27 2005-06-29 Martin Maurer:
+ Add LPC chip ID's (thanks to Robert from Philips) for
+ missing LPC213x and upcoming new LPC214x chips
+ (currently untested, because i don't have access to these chips,
+ please give me feedback !)
+1.28 2005-07-27 Anders Rosvall / Embedded Artists AB:
+ Changed the reset timeout to 500 ms when entering the bootloader.
+ Some external reset controllers have quite long timeout periods,
+ so extening the timeout delay would be a good thing.
+1.29 2005-09-14 Rob Jansen:
+ Added functionality to download to RAM and run from there.
+ In LoadFile() added record types 04 (Extended Linear Address Record)
+ and 05 (Start Linear Address Record), added address offset
+ (IspEnvironment->BinaryOffset) and start address (...->StartAddress).
+ Changed PhilipsDownload to skip all Flash prepare/erase/copy commands.
+ Note: Tested with VC7 only
+1.30 2005-10-04 Rob Jansen:
+ - forgot to change the version string in 1.29
+ - Wrong text in LoadFile corrected (printed text mentions record type 05,
+ this should be 04
+ - Changed LoadFile to accept multiple record types 04
+ - Changed LoadFile to check on memory size, will not load more than x MB
+ if linear extended address records are used
+1.31 2005-11-13 Martin Maurer: Thanks to Frank Gutmann
+ Updated number of sectors in device table
+ for LPC2194, LPC2292 and LPC2294
+1.32 2005-12-02 Martin Maurer: Corrected missing control of RTS/DTR
+ in case user selected -termonly and -control
+ Small correction (typo in debug)
+1.33 2006-10-01 Jean-Marc Koller:
+ Added support for MacOS X (difference on how to set termios baudrate).
+1.34 2006-10-01 Cyril Holweck:
+ Made it compile again for lpc21isp
+ Added const keyword to constant variables to make it better
+ code for embeded target. (decrease RAM usage)
+ Replaced all regular call to printf() by DebugPrintf()
+ Removed call to scanf() (not much usefull and cost a lot to my target)
+1.35 2006-22-01 Cyril Holweck
+ Added feature for LPC21: will start downloading at Sector 1 and upward,
+ to finish with Sector 0, the one containing the checksum controling BSL entry
+1.36 2006-25-01 Cyril Holweck
+ PhilipsDownload() will now return a unique error code for each error
+1.37 2006-10-03 Jeroen Domburg
+ Added LPC2103 (and only the 2103, I can't find the IDs for 2101/2102)
+ Corrected a loop which occured if the program completely fits in sector 0
+1.38 2007-01-05 Ray Molenkamp
+ Added feature for LPC21: Wipe entire device before programming to enable
+ reflashing of chips with the lpc codeprotection feature enabled.
+1.39 2007-01-12 Martin Maurer
+ Added initial support for new processors LPC23xx and LPC24xx
+1.40 2007-01-22 Martin Maurer
+ Correction of chip id of LPC2458
+1.41 2007-01-28 Jean-Marc Koller
+ Modified Terminal() to disable ECHO with termios only once, instead of
+ modifying and restoring termios in each getch and kbhit call (which caused
+ a strange echo behaviour in MacOS X).
+1.42 2007-01-28 Rob Probin
+ Added -localecho command to allow local echoing in terminal mode for use
+ where target does not echo back keystrokes.
+1.43 2007-01-29 Martin Maurer
+ Moved keyboard handling routines to own subroutines,
+ so they can be used during aborting synchronisation.
+ Newest cygwin made problems, StringOscillator always contained '\0x0d'
+ at the end, when calling lpc21isp from batch file
+1.44 2007-02-23 Yang Yang
+ Added feature for LPC21: Verify the data in Flash after every writes
+ to sector. To detect errors in writing to Flash ROM.
+1.45 2007-02-25 Martin Maurer
+ Replace printf syntax of DumpString by a simple pointer to a string
+ printf syntax is a nice thing, but it is not working :-(
+ and therefore makes debugging much more difficult...
+ Moved VERSION_STR to top of file to avoid possible cosmetical errors
+1.46 2007-02-25 Martin Maurer
+ Again corrected debug output: should solve output of
+ (FFFFFFB5) instead of (B5)
+1.47 2007-02-27 Robert Adsett
+ Raised timeout on AD send packet function.
+1.48 2007-04-20 Martin Maurer
+ Thanks to Josef Wolf for preventing to overwrite over end of array
+1.49 2007-10-16 New Option -halfduplex allow single wire using.
+ Implemented and tested only for Windows. Data Resend implemented.
+1.50 2007-10-31 Changes by Simon Ellwood
+ Formated the code for readablity
+ Fixed some c++ compiler issues
+1.51 2007-11-20 Changes by Simon Ellwood
+ Split into seperate files
+ Made more modular so when used in an embedded mode only the required code is built
+1.52 2008-01-22 Changes by Manuel Koeppen
+ Made compileable again for linux and windows
+ Fixed bug in ClearSerialPortBuffers (linux)
+1.53 2008-02-25 Changes by Michael Roth
+ Get priority of debug messages wih -control right
+1.54 2008-03-03 Martin Maurer
+ Try to bring lpc21isp back to a useable state in Windows, Cygwin, Linux and Mac OS.
+ Merged in changes by Erika Stefanini, which were done only for old version 1.49:
+ Added device ids for revision B chips
+1.55 2008-03-03 Martin Maurer
+ Thanks to Fausto Marzoli, bugfix for compiling latest version under Linux
+1.56 2008-04-01 Steve Franks
+ Integrate FreeBSD patch.
+ Add support for swapping and/or inverting RTS & DTR
+1.57 2008-04-06 Mauricio Scaff
+ Changed OpenSerialPort to work with MacOS
+ Corrected the number of sectors in some 512K devices (28 instead of 27)
+ Added support for LPC2387 and LPC2388
+ Defined BL error 19 (Code Protected)
+1.58 2008-05-10 Herbert Demmel dh2@demmel.com
+ I had the special requirement to integrate the program into my own Windows
+ software compiled with Borland C++ Builder 5. I had to do some minor changes
+ for Borland (see defined __BORLANDC__) and modified to code slightly to have
+ some simple callbacks for screen i/o (see define INTEGRATED_IN_WIN_APP).
+ Please notet that I don *not* check / modify the part for AnalogDevices !!
+ Besides that I fixed some minor issues:
+ added dcb.fOutxCtsFlow = FALSE and dcb.fOutxDsrFlow = FALSE (sometimes required)
+ Now comparing one character less of answer to "Now launching ... code" command
+1.59 2008-07-07 Peter Hayward
+ Fixed freeze under Windows XP SP2 by removing redundant call to SetCommMask.
+1.60 2008-07-21 Martin Maurer
+ Added uptodate part ids for LPC2458, LPC2468 and LPC2478
+ Add comment "obsolete" for older part ids for LPC2458 and LPC2468
+ Add ", " between compile date and time
+1.61 2008-10-21 Fausto Marzoli (thanks to Geoffrey Wossum for the patches)
+ Fix for compiling latest version under Linux and "ControlLinesSwapped" issue
+1.62 2008-11-19 Martin Maurer
+ Added (untested) support for LPC2109
+ Added (untested) support for LPC2361 / LPC2362
+ Heavy update of part identification number of LPC23xx and LPC24xx
+ Correct bug, that hex file must exist, when "-detectonly" is used
+ Correct Makefile.vc: use /Fe instead of -o
+1.63 2008-11-23 Martin Maurer
+ Changed to GNU Lesser General Public License
+1.64 2009-01-19 Steve Franks
+ __FREEBSD__ changed to __FreeBSD__ at some point, plus other com port fixes
+1.65 2009-03-26 Vito Marolda
+ Added pre-erasure of sector 0 to invalidate checksum before starting
+ modification of the other sectors, so that the bootloader restarts
+ if programming gets aborted while writing on a non-empty part.
+1.66 2009-03-26 Vito Marolda
+ Corrected interpretation of intel hex record 03 which is execution start address
+ and not data segment address
+1.67 2009-04-19 SASANO Takayoshi
+ Add OpenBSD support
+1.68 2009-05-17 Martin Maurer
+ Merge in changes done by Bruno Quoitin (baudrate problem when __APPLE__ is used)
+ Remove TABs from source code and replaced them with spaces
+1.69 2009-06-18 Martin Maurer
+ Add support for LPC17xx devices
+1.70 2009-06-29 Martin Maurer
+ Further improvement of LPC17xx support
+ Workaround for booter (4.1) of LPC17xx, which does not echo all sent characters (0D,0A,...)
+ ISP command GO seems to be broken:
+ Sending 'G 196 T(0A)'
+ Answer(Length=15): 'G 196 T(0A)0(0D)(0A)'
+ leads to 'prefetch_abort_exception(0D)(0A)1FFF07A5'
+ No solution known...need your help here...
+ Manual workaround: Use DTR and RTS toggling to start application (e.g. 2 batch files)
+1.71 2009-07-19 Martin Maurer
+ Added LPC17xx with CPUID starting with 0x26 (not according user manual)
+1.72 2009-09-14 Martin Maurer
+ Add support for LPC13xx devices
+1.73 2009-09-14 Martin Maurer
+ Correct again (hopefully the last time) the CPUIDs for some LPC17xx devices
+ (Now according to User Manual LPC17xx Version 00.07 (31 July 2009))
+1.74 2009-09-14 Mario Ivancic
+ Added support for multiple HEX files, besed on internal version 1.37B.
+ NOTE: this feature is used in production in 1.37B but is not tested in this version.
+ Added numeric debug level command line switch -debugn, n=[0-5]
+ Added command line scitch -try n to specify nQuestionMarks limit. Defaul: 100
+ Merged in DoNotStart patch from cgommel_new
+ Static functions declarations moved from lpc21isp.h to this file
+ Modified LoadFile() to return error_code instead exit(1)
+ Removed IspEnvironment.debug_level, all code uses global debug_level
+1.75 2010-01-05 Martin Maurer
+ Added support for LPC11xx devices (not tested at all)
+ Changed Product in LPC_DEVICE_TYPE from number to string to distinguish new LPC11 devices
+ Changed "unsigned" to "unsigned int" in LPC_DEVICE_TYPE
+1.76 2010-02-01 Published test version without source code
+1.77 2010-02-01 Martin Maurer
+ Corrected chip id of LPC1342 and LPC1343
+ Added a new chip type for LPC11xx and LPC13xx microcontrollers
+ Use higher area of RAM with LPC11xx and LPC13xx, because lower RAM is occupied by ISP
+ Add code to lpcprog.c to read unique id, but not yet activate.
+ Adapt block sizes for copying for each model of LPC11xx and LPC13xx
+1.78 2010-02-16 Martin Maurer
+ Corrected chip id of LPC1751
+ Added support for LPC1759, LPC1767 and LPC1769
+1.79 2010-02-19 Andrew Pines
+ Added __APPLE__ flag to CFLAGS in Makefile to detect and handle OS X
+ Added -Wall to Makefile to report warnings more comprehensively
+ Added #define in lpc21isp.h to substitute strnicmp with strncasecmp (needed for Unix)
+ Fixed a few format specifiers in lpcprog.c to eliminate some warnings
+1.80 2010-03-04 Philip Munts
+ Added entries to LPCtypes[] in lpcprog.c for obsolete revisions of LPC2364/6/8/78.
+ Added entry to LPCtypes[] in lpcprog.c for new LPC2387.
+1.81 2011-03-30 Mario Ivancic
+ As per message #517 from Thiadmer Riemersma, removed WaitForWatchDog and WatchDogSeconds
+ in PhilipsDownload(). +1.82 2011-06-25 Moses McKnight + Corrected MaxCopySize for a number of the LPC11xx series + Added support for several more LPC11xx and LPC11Cxx series
+1.83 2011-08-02 Martin Maurer
+ Thanks to Conurus for detecting and fixing a bug with patching checksum
+ (patching was too early, chip id was not yet available)
+ (Re-)Added code to start downloaded via "G 0 T", when using LPC1xxx
+ (Starting code at position 0 seems to work, compare to comment of version 1.70)
+ Changed some occurances of Philips to NXP
+ Added -static to Makefile (thanks to Camilo)
+ Added support for LPC1311/01 and LPC1313/01 (they have separate identifiers)
+ Correct flash size of LPC1342 to 16 KByte (thanks to Decio)
+ Abort programming when unknown NXP chip id is detected
+*/
+
+// Please don't use TABs in the source code !!!
+
+// Don't forget to update the version string that is on the next line
+#define VERSION_STR "1.83"
+
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+static char RxTmpBuf[256]; // save received data to this buffer for half-duplex
+char * pRxTmpBuf = RxTmpBuf;
+#endif
+
+#if !defined COMPILE_FOR_LPC21
+int debug_level = 2;
+#endif
+
+static void ControlModemLines(ISP_ENVIRONMENT *IspEnvironment, unsigned char DTR, unsigned char RTS);
+static unsigned char Ascii2Hex(unsigned char c);
+
+#ifdef COMPILE_FOR_WINDOWS
+static void SerialTimeoutSet(ISP_ENVIRONMENT *IspEnvironment, unsigned timeout_milliseconds);
+static int SerialTimeoutCheck(ISP_ENVIRONMENT *IspEnvironment);
+#endif // COMPILE_FOR_WINDOWS
+
+static int AddFileHex(ISP_ENVIRONMENT *IspEnvironment, const char *arg);
+static int AddFileBinary(ISP_ENVIRONMENT *IspEnvironment, const char *arg);
+static int LoadFile(ISP_ENVIRONMENT *IspEnvironment, const char *filename, int FileFormat);
+
+#define ERR_RECORD_TYPE_LOADFILE 55 /** File record type not yet implemented. */
+#define ERR_ALLOC_FILE_LIST 60
+#define ERR_FILE_OPEN_HEX 61 /**< Couldn't open hex file. */
+#define ERR_FILE_SIZE_HEX 62 /**< Unexpected hex file size. */
+#define ERR_FILE_ALLOC_HEX 63 /**< Couldn't allocate enough memory for hex file. */
+#define ERR_FILE_ALLOC_BIN 64 /**< Couldn't allocate enough memory for bin file. */
+#define ERR_FILE_RECST_HEX 65 /**< Can't find start of record indicator for Intel Hex file.*/
+#define ERR_FILE_OPEN_BIN 66 /**< Couldn't open binary file. */
+#define ERR_FILE_SIZE_BIN 67 /**< Unexpected binary file size. */
+#define ERR_FILE_WRITE_BIN 68 /**< Couldn't write debug binary file to disk. How's that for ironic? */
+#define ERR_MEMORY_RANGE 69 /**< Out of memory range. */
+
+/************* Portability layer. Serial and console I/O differences */
+/* are taken care of here. */
+
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+static void OpenSerialPort(ISP_ENVIRONMENT *IspEnvironment)
+{
+ DCB dcb;
+ COMMTIMEOUTS commtimeouts;
+
+ IspEnvironment->hCom = CreateFile(IspEnvironment->serial_port, GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
+
+ if (IspEnvironment->hCom == INVALID_HANDLE_VALUE)
+ {
+ DebugPrintf(1, "Can't open COM-Port %s ! - Error: %ld\n", IspEnvironment->serial_port, GetLastError());
+ exit(2);
+ }
+
+ DebugPrintf(3, "COM-Port %s opened...\n", IspEnvironment->serial_port);
+
+ GetCommState(IspEnvironment->hCom, &dcb);
+ dcb.BaudRate = atol(IspEnvironment->baud_rate);
+ dcb.ByteSize = 8;
+ dcb.StopBits = ONESTOPBIT;
+ dcb.Parity = NOPARITY;
+ dcb.fDtrControl = DTR_CONTROL_DISABLE;
+ dcb.fOutX = FALSE;
+ dcb.fInX = FALSE;
+ dcb.fNull = FALSE;
+ dcb.fRtsControl = RTS_CONTROL_DISABLE;
+
+ // added by Herbert Demmel - iF CTS line has the wrong state, we would never send anything!
+ dcb.fOutxCtsFlow = FALSE;
+ dcb.fOutxDsrFlow = FALSE;
+
+ if (SetCommState(IspEnvironment->hCom, &dcb) == 0)
+ {
+ DebugPrintf(1, "Can't set baudrate %s ! - Error: %ld", IspEnvironment->baud_rate, GetLastError());
+ exit(3);
+ }
+
+ /*
+ * Peter Hayward 02 July 2008
+ *
+ * The following call is only needed if the WaitCommEvent
+ * or possibly the GetCommMask functions are used. They are
+ * *not* in this implimentation. However, under Windows XP SP2
+ * on my laptop the use of this call causes XP to freeze (crash) while
+ * this program is running, e.g. in section 5/6/7 ... of a largish
+ * download. Removing this *unnecessary* call fixed the problem.
+ * At the same time I've added a call to SetupComm to request
+ * (not necessarity honoured) the operating system to provide
+ * large I/O buffers for high speed I/O without handshaking.
+ *
+ * SetCommMask(IspEnvironment->hCom,EV_RXCHAR | EV_TXEMPTY);
+ */
+ SetupComm(IspEnvironment->hCom, 32000, 32000);
+
+ SetCommMask(IspEnvironment->hCom, EV_RXCHAR | EV_TXEMPTY);
+
+ commtimeouts.ReadIntervalTimeout = MAXDWORD;
+ commtimeouts.ReadTotalTimeoutMultiplier = 0;
+ commtimeouts.ReadTotalTimeoutConstant = 1;
+ commtimeouts.WriteTotalTimeoutMultiplier = 0;
+ commtimeouts.WriteTotalTimeoutConstant = 0;
+ SetCommTimeouts(IspEnvironment->hCom, &commtimeouts);
+}
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+#if defined COMPILE_FOR_LINUX
+static void OpenSerialPort(ISP_ENVIRONMENT *IspEnvironment)
+{
+ IspEnvironment->fdCom = open(IspEnvironment->serial_port, O_RDWR | O_NOCTTY | O_NONBLOCK);
+
+ if (IspEnvironment->fdCom < 0)
+ {
+ int err = errno;
+ DebugPrintf(1, "Can't open COM-Port %s ! (Error: %dd (0x%X))\n", IspEnvironment->serial_port, err, err);
+ exit(2);
+ }
+
+ DebugPrintf(3, "COM-Port %s opened...\n", IspEnvironment->serial_port);
+
+ /* clear input & output buffers, then switch to "blocking mode" */
+ tcflush(IspEnvironment->fdCom, TCOFLUSH);
+ tcflush(IspEnvironment->fdCom, TCIFLUSH);
+ fcntl(IspEnvironment->fdCom, F_SETFL, fcntl(IspEnvironment->fdCom, F_GETFL) & ~O_NONBLOCK);
+
+ tcgetattr(IspEnvironment->fdCom, &IspEnvironment->oldtio); /* save current port settings */
+
+ bzero(&IspEnvironment->newtio, sizeof(IspEnvironment->newtio));
+ IspEnvironment->newtio.c_cflag = CS8 | CLOCAL | CREAD;
+
+#if defined(__FreeBSD__) || defined(__OpenBSD__)
+
+ if(cfsetspeed(&IspEnvironment->newtio,(speed_t) strtol(IspEnvironment->baud_rate,NULL,10))) {
+ DebugPrintf(1, "baudrate %s not supported\n", IspEnvironment->baud_rate);
+ exit(3);
+ };
+#else
+
+#ifdef __APPLE__
+#define NEWTERMIOS_SETBAUDARTE(bps) IspEnvironment->newtio.c_ispeed = IspEnvironment->newtio.c_ospeed = bps;
+#else
+#define NEWTERMIOS_SETBAUDARTE(bps) IspEnvironment->newtio.c_cflag |= bps;
+#endif
+
+ switch (atol(IspEnvironment->baud_rate))
+ {
+#ifdef B1152000
+ case 1152000: NEWTERMIOS_SETBAUDARTE(B1152000); break;
+#endif // B1152000
+#ifdef B576000
+ case 576000: NEWTERMIOS_SETBAUDARTE(B576000); break;
+#endif // B576000
+#ifdef B230400
+ case 230400: NEWTERMIOS_SETBAUDARTE(B230400); break;
+#endif // B230400
+#ifdef B115200
+ case 115200: NEWTERMIOS_SETBAUDARTE(B115200); break;
+#endif // B115200
+#ifdef B57600
+ case 57600: NEWTERMIOS_SETBAUDARTE(B57600); break;
+#endif // B57600
+#ifdef B38400
+ case 38400: NEWTERMIOS_SETBAUDARTE(B38400); break;
+#endif // B38400
+#ifdef B19200
+ case 19200: NEWTERMIOS_SETBAUDARTE(B19200); break;
+#endif // B19200
+#ifdef B9600
+ case 9600: NEWTERMIOS_SETBAUDARTE(B9600); break;
+#endif // B9600
+
+ // Special value
+ // case 32000: NEWTERMIOS_SETBAUDARTE(32000); break;
+
+ default:
+ {
+ DebugPrintf(1, "unknown baudrate %s\n", IspEnvironment->baud_rate);
+ exit(3);
+ }
+ }
+
+#endif
+
+ IspEnvironment->newtio.c_iflag = IGNPAR | IGNBRK | IXON | IXOFF;
+ IspEnvironment->newtio.c_oflag = 0;
+
+ /* set input mode (non-canonical, no echo,...) */
+ IspEnvironment->newtio.c_lflag = 0;
+
+ cfmakeraw(&IspEnvironment->newtio);
+ IspEnvironment->newtio.c_cc[VTIME] = 1; /* inter-character timer used */
+ IspEnvironment->newtio.c_cc[VMIN] = 0; /* blocking read until 0 chars received */
+
+ tcflush(IspEnvironment->fdCom, TCIFLUSH);
+ if(tcsetattr(IspEnvironment->fdCom, TCSANOW, &IspEnvironment->newtio))
+ {
+ DebugPrintf(1, "Could not change serial port behaviour (wrong baudrate?)\n");
+ exit(3);
+ }
+
+}
+#endif // defined COMPILE_FOR_LINUX
+
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+static void CloseSerialPort(ISP_ENVIRONMENT *IspEnvironment)
+{
+ CloseHandle(IspEnvironment->hCom);
+}
+
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+#if defined COMPILE_FOR_LINUX
+static void CloseSerialPort(ISP_ENVIRONMENT *IspEnvironment)
+{
+ tcflush(IspEnvironment->fdCom, TCOFLUSH);
+ tcflush(IspEnvironment->fdCom, TCIFLUSH);
+ tcsetattr(IspEnvironment->fdCom, TCSANOW, &IspEnvironment->oldtio);
+
+ close(IspEnvironment->fdCom);
+}
+#endif // defined COMPILE_FOR_LINUX
+
+
+/***************************** SendComPortBlock *************************/
+/** Sends a block of bytes out the opened com port.
+\param [in] s block to send.
+\param [in] n size of the block.
+*/
+void SendComPortBlock(ISP_ENVIRONMENT *IspEnvironment, const void *s, size_t n)
+{
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+ unsigned long realsize;
+ size_t m;
+ unsigned long rxsize;
+ char * pch;
+ char * rxpch;
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+ DumpString(4, s, n, "Sending ");
+
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+ if (IspEnvironment->HalfDuplex == 0)
+ {
+ WriteFile(IspEnvironment->hCom, s, n, &realsize, NULL);
+ }
+ else
+ {
+ pch = (char *)s;
+ rxpch = RxTmpBuf;
+ pRxTmpBuf = RxTmpBuf;
+
+ // avoid buffer otherflow
+ if (n > sizeof (RxTmpBuf))
+ n = sizeof (RxTmpBuf);
+
+ for (m = 0; m < n; m++)
+ {
+ WriteFile(IspEnvironment->hCom, pch, 1, &realsize, NULL);
+
+ if ((*pch != '?') || (n != 1))
+ {
+ do
+ {
+ ReadFile(IspEnvironment->hCom, rxpch, 1, &rxsize, NULL);
+ }while (rxsize == 0);
+ }
+ pch++;
+ rxpch++;
+ }
+ *rxpch = 0; // terminate echo string
+ }
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21
+
+ write(IspEnvironment->fdCom, s, n);
+
+#endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21
+}
+
+/***************************** SendComPort ******************************/
+/** Sends a string out the opened com port.
+\param [in] s string to send.
+*/
+void SendComPort(ISP_ENVIRONMENT *IspEnvironment, const char *s)
+{
+ SendComPortBlock(IspEnvironment, s, strlen(s));
+}
+
+/***************************** SerialTimeoutTick ************************/
+/** Performs a timer tick. In this simple case all we do is count down
+with protection against underflow and wrapping at the low end.
+*/
+static void SerialTimeoutTick(ISP_ENVIRONMENT *IspEnvironment)
+{
+ if (IspEnvironment->serial_timeout_count <= 1)
+ {
+ IspEnvironment->serial_timeout_count = 0;
+ }
+ else
+ {
+ IspEnvironment->serial_timeout_count--;
+ }
+}
+
+
+/***************************** ReceiveComPortBlock **********************/
+/** Receives a buffer from the open com port. Returns all the characters
+ready (waits for up to 'n' milliseconds before accepting that no more
+characters are ready) or when the buffer is full. 'n' is system dependant,
+see SerialTimeout routines.
+\param [out] answer buffer to hold the bytes read from the serial port.
+\param [in] max_size the size of buffer pointed to by answer.
+\param [out] real_size pointer to a long that returns the amout of the
+buffer that is actually used.
+*/
+static void ReceiveComPortBlock(ISP_ENVIRONMENT *IspEnvironment,
+ void *answer, unsigned long max_size,
+ unsigned long *real_size)
+{
+ char tmp_string[32];
+
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+ if (IspEnvironment->HalfDuplex == 0)
+ ReadFile(IspEnvironment->hCom, answer, max_size, real_size, NULL);
+ else
+ {
+ *real_size = strlen (pRxTmpBuf);
+ if (*real_size)
+ {
+ if (max_size >= *real_size)
+ {
+ strncpy((char*) answer, pRxTmpBuf, *real_size);
+ RxTmpBuf[0] = 0;
+ pRxTmpBuf = RxTmpBuf;
+ }
+ else
+ {
+ strncpy((char*) answer, pRxTmpBuf, max_size);
+ *real_size = max_size;
+ pRxTmpBuf += max_size;
+ }
+ }
+ else
+ ReadFile(IspEnvironment->hCom, answer, max_size, real_size, NULL);
+ }
+
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21
+
+ *real_size = read(IspEnvironment->fdCom, answer, max_size);
+
+#endif // defined COMPILE_FOR_LINUX
+
+ sprintf(tmp_string, "Read(Length=%ld): ", (*real_size));
+ DumpString(5, answer, (*real_size), tmp_string);
+
+ if (*real_size == 0)
+ {
+ SerialTimeoutTick(IspEnvironment);
+ }
+}
+
+
+/***************************** SerialTimeoutSet *************************/
+/** Sets (or resets) the timeout to the timout period requested. Starts
+counting to this period. This timeout support is a little odd in that the
+timeout specifies the accumulated deadtime waiting to read not the total
+time waiting to read. They should be close enought to the same for this
+use. Used by the serial input routines, the actual counting takes place in
+ReceiveComPortBlock.
+\param [in] timeout_milliseconds the time in milliseconds to use for
+timeout. Note that just because it is set in milliseconds doesn't mean
+that the granularity is that fine. In many cases (particularly Linux) it
+will be coarser.
+*/
+static void SerialTimeoutSet(ISP_ENVIRONMENT *IspEnvironment, unsigned timeout_milliseconds)
+{
+#if defined COMPILE_FOR_LINUX
+ IspEnvironment->serial_timeout_count = timeout_milliseconds / 100;
+#elif defined COMPILE_FOR_LPC21
+ IspEnvironment->serial_timeout_count = timeout_milliseconds * 200;
+#else
+ IspEnvironment->serial_timeout_count = timeout_milliseconds;
+#endif
+}
+
+
+
+/***************************** SerialTimeoutCheck ***********************/
+/** Check to see if the serial timeout timer has run down.
+\retval 1 if timer has run out.
+\retval 0 if timer still has time left.
+*/
+static int SerialTimeoutCheck(ISP_ENVIRONMENT *IspEnvironment)
+{
+ if (IspEnvironment->serial_timeout_count == 0)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+
+#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
+/***************************** getch ************************************/
+/** Replacement for the common dos function of the same name. Reads a
+single unbuffered character from the 'keyboard'.
+\return The character read from the keyboard.
+*/
+int getch(void)
+{
+ char ch;
+
+ /* Read in one character */
+ read(0,&ch,1);
+
+ return ch;
+}
+#endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
+
+#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
+/***************************** kbhit ************************************/
+/** Replacement for the common dos function of the same name. Indicates if
+there are characters to be read from the console.
+\retval 0 No characters ready.
+\retval 1 Characters from the console ready to be read.
+*/
+int kbhit(void)
+{
+ /* return 0 for no key pressed, 1 for key pressed */
+ int return_value = 0;
+
+ /* time struct for the select() function, to only wait a little while */
+ struct timeval select_time;
+ /* file descriptor variable for the select() call */
+ fd_set readset;
+
+ /* we're only interested in STDIN */
+ FD_ZERO(&readset);
+ FD_SET(STDIN_FILENO, &readset);
+
+ /* how long to block for - this must be > 0.0, but could be changed
+ to some other setting. 10-18msec seems to work well and only
+ minimally load the system (0% CPU loading) */
+ select_time.tv_sec = 0;
+ select_time.tv_usec = 10;
+
+ /* is there a keystroke there? */
+ if (select(1, &readset, NULL, NULL, &select_time))
+ {
+ /* yes, remember it */
+ return_value = 1;
+ }
+
+
+ /* return with what we found out */
+ return return_value;
+}
+struct termios keyboard_origtty;
+#endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
+
+
+/***************************** PrepareKeyboardTtySettings ***************/
+/** Set the keyboard tty to be able to check for new characters via kbhit
+getting them via getch
+*/
+
+void PrepareKeyboardTtySettings(void)
+{
+#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
+ /* store the current tty settings */
+ if (!tcgetattr(0, &keyboard_origtty))
+ {
+ struct termios tty;
+ /* start with the current settings */
+ tty = keyboard_origtty;
+ /* make modifications to put it in raw mode, turn off echo */
+ tty.c_lflag &= ~ICANON;
+ tty.c_lflag &= ~ECHO;
+ tty.c_lflag &= ~ISIG;
+ tty.c_cc[VMIN] = 1;
+ tty.c_cc[VTIME] = 0;
+
+ /* put the settings into effect */
+ tcsetattr(0, TCSADRAIN, &tty);
+ }
+#endif
+}
+
+
+/***************************** ResetKeyboardTtySettings *****************/
+/** Reset the keyboard tty to original settings
+*/
+void ResetKeyboardTtySettings(void)
+{
+#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
+ /* reset the tty to its original settings */
+ tcsetattr(0, TCSADRAIN, &keyboard_origtty);
+#endif
+}
+
+
+#if !defined COMPILE_FOR_LPC21
+/***************************** ControlModemLines ************************/
+/** Controls the modem lines to place the microcontroller into various
+states during the programming process.
+error rather abruptly terminates the program.
+\param [in] DTR the state to set the DTR line to.
+\param [in] RTS the state to set the RTS line to.
+*/
+static void ControlModemLines(ISP_ENVIRONMENT *IspEnvironment, unsigned char DTR, unsigned char RTS)
+{
+ //handle wether to invert the control lines:
+ DTR ^= IspEnvironment->ControlLinesInverted;
+ RTS ^= IspEnvironment->ControlLinesInverted;
+
+ //handle wether to swap the control lines
+ if (IspEnvironment->ControlLinesSwapped)
+ {
+ unsigned char tempRTS;
+ tempRTS = RTS;
+ RTS = DTR;
+ DTR = tempRTS;
+ }
+
+#if defined COMPILE_FOR_LINUX
+ int status;
+
+ if (ioctl(IspEnvironment->fdCom, TIOCMGET, &status) == 0)
+ {
+ DebugPrintf(3, "ioctl get ok, status = %X\n",status);
+ }
+ else
+ {
+ DebugPrintf(1, "ioctl get failed\n");
+ }
+
+ if (DTR) status |= TIOCM_DTR;
+ else status &= ~TIOCM_DTR;
+
+ if (RTS) status |= TIOCM_RTS;
+ else status &= ~TIOCM_RTS;
+
+ if (ioctl(IspEnvironment->fdCom, TIOCMSET, &status) == 0)
+ {
+ DebugPrintf(3, "ioctl set ok, status = %X\n",status);
+ }
+ else
+ {
+ DebugPrintf(1, "ioctl set failed\n");
+ }
+
+ if (ioctl(IspEnvironment->fdCom, TIOCMGET, &status) == 0)
+ {
+ DebugPrintf(3, "ioctl get ok, status = %X\n",status);
+ }
+ else
+ {
+ DebugPrintf(1, "ioctl get failed\n");
+ }
+
+#endif // defined COMPILE_FOR_LINUX
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+ if (DTR) EscapeCommFunction(IspEnvironment->hCom, SETDTR);
+ else EscapeCommFunction(IspEnvironment->hCom, CLRDTR);
+
+ if (RTS) EscapeCommFunction(IspEnvironment->hCom, SETRTS);
+ else EscapeCommFunction(IspEnvironment->hCom, CLRRTS);
+
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+#if defined COMPILE_FOR_LPC21
+ LPC_RESET(DTR);
+ LPC_BSL(RTS);
+#endif
+
+ DebugPrintf(3, "DTR (%d), RTS (%d)\n", DTR, RTS);
+}
+
+
+/***************************** ClearSerialPortBuffers********************/
+/** Empty the serial port buffers. Cleans things to a known state.
+*/
+void ClearSerialPortBuffers(ISP_ENVIRONMENT *IspEnvironment)
+{
+#if defined COMPILE_FOR_LINUX
+ /* variables to store the current tty state, create a new one */
+ struct termios origtty, tty;
+
+ /* store the current tty settings */
+ tcgetattr(IspEnvironment->fdCom, &origtty);
+
+ // Flush input and output buffers
+ tty=origtty;
+ tcsetattr(IspEnvironment->fdCom, TCSAFLUSH, &tty);
+
+ /* reset the tty to its original settings */
+ tcsetattr(IspEnvironment->fdCom, TCSADRAIN, &origtty);
+#endif // defined COMPILE_FOR_LINUX
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+ PurgeComm(IspEnvironment->hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+}
+#endif // !defined COMPILE_FOR_LPC21
+
+
+#if defined COMPILE_FOR_LINUX
+/***************************** Sleep ************************************/
+/** Provide linux replacement for windows function.
+\param [in] Milliseconds the time to wait for in milliseconds.
+*/
+void Sleep(unsigned long MilliSeconds)
+{
+ usleep(MilliSeconds*1000); //convert to microseconds
+}
+#endif // defined COMPILE_FOR_LINUX
+
+
+#if defined COMPILE_FOR_LPC21
+/** Provide linux replacement for windows function.
+\note I implement that one in my private header file today...
+\param [in] Milliseconds the time to wait for in milliseconds.
+*/
+/*static void Sleep(unsigned long MilliSeconds)
+{
+# warning Sleep function not implemented
+}
+*/
+#endif // defined COMPILE_FOR_LPC21
+
+
+
+/************* Applicationlayer. */
+
+#if !defined COMPILE_FOR_LPC21
+/***************************** DebugPrintf ******************************/
+/** Prints a debug string depending the current debug level. The higher
+the debug level the more detail that will be printed. Each print
+has an associated level, the higher the level the more detailed the
+debugging information being sent.
+\param [in] level the debug level of the print statement, if the level
+is less than or equal to the current debug level it will be printed.
+\param [in] fmt a standard printf style format string.
+\param [in] ... the usual printf parameters.
+*/
+#if !defined INTEGRATED_IN_WIN_APP
+void DebugPrintf(int level, const char *fmt, ...)
+{
+ va_list ap;
+
+ if (level <= debug_level)
+ {
+ char pTemp[2000];
+ va_start(ap, fmt);
+ //vprintf(fmt, ap);
+ vsprintf(pTemp, fmt, ap);
+ TRACE(pTemp);
+ va_end(ap);
+ fflush(stdout);
+ }
+}
+#endif
+#endif // !defined COMPILE_FOR_LPC21
+
+
+/***************************** ReceiveComPort ***************************/
+/** Receives a buffer from the open com port. Returns when the buffer is
+filled, the numer of requested linefeeds has been received or the timeout
+period has passed
+\param [in] ISPEnvironment.
+\param [out] Answer buffer to hold the bytes read from the serial port.
+\param [in] MaxSize the size of buffer pointed to by Answer.
+\param [out] RealSize pointer to a long that returns the amout of the
+buffer that is actually used.
+\param [in] WantedNr0x0A the maximum number of linefeeds to accept before
+returning.
+\param [in] timeOutMilliseconds the maximum amount of time to wait before
+reading with an incomplete buffer.
+*/
+void ReceiveComPort(ISP_ENVIRONMENT *IspEnvironment,
+ const char *Ans, unsigned long MaxSize,
+ unsigned long *RealSize, unsigned long WantedNr0x0A,
+ unsigned timeOutMilliseconds)
+{
+ unsigned long tmp_realsize;
+ unsigned long nr_of_0x0A = 0;
+ unsigned long nr_of_0x0D = 0;
+ int eof = 0;
+ unsigned long p;
+ unsigned char *Answer;
+ char tmp_string[32];
+
+ Answer = (unsigned char*) Ans;
+
+ SerialTimeoutSet(IspEnvironment, timeOutMilliseconds);
+
+ (*RealSize) = 0;
+
+ do
+ {
+ ReceiveComPortBlock(IspEnvironment, Answer + (*RealSize), MaxSize - 1 - (*RealSize), &tmp_realsize);
+
+ if (tmp_realsize != 0)
+ {
+ for (p = (*RealSize); p < (*RealSize) + tmp_realsize; p++)
+ {
+ if (Answer[p] == 0x0a)
+ {
+ nr_of_0x0A++;
+ }
+ else if (Answer[p] == 0x0d)
+ {
+ nr_of_0x0D++;
+ }
+ else if (((signed char) Answer[p]) < 0)
+ {
+ eof = 1;
+ }
+ }
+ }
+
+ (*RealSize) += tmp_realsize;
+
+ } while (((*RealSize) < MaxSize) && (SerialTimeoutCheck(IspEnvironment) == 0) && (nr_of_0x0A < WantedNr0x0A) && (nr_of_0x0D < WantedNr0x0A) && !eof);
+
+ Answer[(*RealSize)] = 0;
+
+ sprintf(tmp_string, "Answer(Length=%ld): ", (*RealSize));
+ DumpString(3, Answer, (*RealSize), tmp_string);
+}
+
+
+#if !defined COMPILE_FOR_LPC21
+
+/***************************** ReceiveComPortBlockComplete **************/
+/** Receives a fixed block from the open com port. Returns when the
+block is completely filled or the timeout period has passed
+\param [out] block buffer to hold the bytes read from the serial port.
+\param [in] size the size of the buffer pointed to by block.
+\param [in] timeOut the maximum amount of time to wait before guvung up on
+completing the read.
+\return 0 if successful, non-zero otherwise.
+*/
+int ReceiveComPortBlockComplete(ISP_ENVIRONMENT *IspEnvironment,
+ void *block, size_t size, unsigned timeout)
+{
+ unsigned long realsize = 0, read;
+ char *result;
+ char tmp_string[32];
+
+ result = (char*) block;
+
+ SerialTimeoutSet(IspEnvironment, timeout);
+
+ do
+ {
+ ReceiveComPortBlock(IspEnvironment, result + realsize, size - realsize, &read);
+
+ realsize += read;
+
+ } while ((realsize < size) && (SerialTimeoutCheck(IspEnvironment) == 0));
+
+ sprintf(tmp_string, "Answer(Length=%ld): ", realsize);
+ DumpString(3, result, realsize, tmp_string);
+
+ if (realsize != size)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/***************************** ReadArguments ****************************/
+/** Reads the command line arguments and parses it for the various
+options. Uses the same arguments as main. Used to separate the command
+line parsing from main and improve its readability. This should also make
+it easier to modify the command line parsing in the future.
+\param [in] argc the number of arguments.
+\param [in] argv an array of pointers to the arguments.
+*/
+static void ReadArguments(ISP_ENVIRONMENT *IspEnvironment, unsigned int argc, char *argv[])
+{
+ unsigned int i;
+
+ if (argc >= 5)
+ {
+ for (i = 1; i < argc - 3; i++)
+ {
+ if (stricmp(argv[i], "-wipe") == 0)
+ {
+ IspEnvironment->WipeDevice = 1;
+ DebugPrintf(3, "Wipe entire device before writing.\n");
+ continue;
+ }
+
+ if (stricmp(argv[i], "-bin") == 0)
+ {
+ IspEnvironment->FileFormat = FORMAT_BINARY;
+ DebugPrintf(3, "Binary format file input.\n");
+ continue;
+ }
+
+ if (stricmp(argv[i], "-hex") == 0)
+ {
+ IspEnvironment->FileFormat = FORMAT_HEX;
+ DebugPrintf(3, "Hex format file input.\n");
+ continue;
+ }
+
+ if (stricmp(argv[i], "-logfile") == 0)
+ {
+ IspEnvironment->LogFile = 1;
+ DebugPrintf(3, "Log terminal output.\n");
+ continue;
+ }
+
+ if (stricmp(argv[i], "-detectonly") == 0)
+ {
+ IspEnvironment->DetectOnly = 1;
+ IspEnvironment->ProgramChip = 0;
+ DebugPrintf(3, "Only detect LPC chip part id.\n");
+ continue;
+ }
+
+ if(strnicmp(argv[i],"-debug", 6) == 0)
+ {
+ char* num;
+ num = argv[i] + 6;
+ while(*num && isdigit(*num) == 0) num++;
+ if(isdigit(*num) != 0) debug_level = atoi( num);
+ else debug_level = 4;
+ DebugPrintf(3, "Turn on debug, level: %d.\n", debug_level);
+ continue;
+ }
+
+ if (stricmp(argv[i], "-DoNotStart") == 0)
+ {
+ IspEnvironment->DoNotStart = 1;
+ DebugPrintf(3, "Do NOT start MCU after programming.\n");
+ continue;
+ }
+
+ if (stricmp(argv[i], "-control") == 0)
+ {
+ IspEnvironment->ControlLines = 1;
+ DebugPrintf(3, "Use RTS/DTR to control target state.\n");
+ continue;
+ }
+
+ if (stricmp(argv[i], "-controlswap") == 0)
+ {
+ IspEnvironment->ControlLinesSwapped = 1;
+ DebugPrintf(3, "Use RTS to control reset, and DTR to control P0.14(ISP).\n");
+ continue;
+ }
+
+ if (stricmp(argv[i], "-controlinv") == 0)
+ {
+ IspEnvironment->ControlLinesInverted = 1;
+ DebugPrintf(3, "Invert state of RTS & DTR (0=true/assert/set, 1=false/deassert/clear).\n");
+ continue;
+ }
+
+ if (stricmp(argv[i], "-halfduplex") == 0)
+ {
+ IspEnvironment->HalfDuplex = 1;
+ DebugPrintf(3, "halfduplex serial communication.\n");
+ continue;
+ }
+
+ if (stricmp(argv[i], "-ADARM") == 0)
+ {
+ IspEnvironment->micro = ANALOG_DEVICES_ARM;
+ DebugPrintf(2, "Target: Analog Devices.\n");
+ continue;
+ }
+
+ if (stricmp(argv[i], "-NXPARM") == 0 || stricmp(argv[i], "-PHILIPSARM") == 0)
+ {
+ IspEnvironment->micro = NXP_ARM;
+ DebugPrintf(2, "Target: NXP.\n");
+ continue;
+ }
+
+ if (stricmp(argv[i], "-Verify") == 0)
+ {
+ IspEnvironment->Verify = 1;
+ DebugPrintf(2, "Verify after copy RAM to Flash.\n");
+ continue;
+ }
+
+#ifdef INTEGRATED_IN_WIN_APP
+ if (stricmp(argv[i], "-nosync") == 0)
+ {
+ IspEnvironment->NoSync = 1;
+ DebugPrintf(2, "Performing no syncing, already done.\n");
+ continue;
+ }
+#endif
+
+#ifdef TERMINAL_SUPPORT
+ if (CheckTerminalParameters(IspEnvironment, argv[i]))
+ {
+ continue;
+ }
+#endif
+
+ if(*argv[i] == '-') DebugPrintf( 2, "Unknown command line option: \"%s\"\n", argv[i]);
+ else
+ {
+ int ret_val;
+ if(IspEnvironment->FileFormat == FORMAT_HEX)
+ {
+ ret_val = AddFileHex(IspEnvironment, argv[i]);
+ }
+ else
+ {
+ ret_val = AddFileBinary(IspEnvironment, argv[i]);
+ }
+ if( ret_val != 0)
+ {
+ DebugPrintf( 2, "Unknown command line option: \"%s\"\n", argv[i]);
+ }
+ }
+ }
+
+ // Newest cygwin delivers a '\x0d' at the end of argument
+ // when calling lpc21isp from batch file
+ for (i = 0; i < strlen(argv[argc - 1]) && i < (sizeof(IspEnvironment->StringOscillator) - 1) &&
+ argv[argc - 1][i] >= '0' && argv[argc - 1][i] <= '9'; i++)
+ {
+ IspEnvironment->StringOscillator[i] = argv[argc - 1][i];
+ }
+ IspEnvironment->StringOscillator[i] = 0;
+
+ IspEnvironment->serial_port = argv[argc - 3];
+ IspEnvironment->baud_rate = argv[argc - 2];
+ }
+
+ if (argc < 5)
+ {
+ debug_level = (debug_level < 2) ? 2 : debug_level;
+ }
+
+ if (argc < 5)
+ {
+ DebugPrintf(2, "\n"
+ "Portable command line ISP\n"
+ "for NXP LPC1000 / LPC2000 family and Analog Devices ADUC 70xx\n"
+ "Version " VERSION_STR " compiled for " COMPILED_FOR ": " __DATE__ ", " __TIME__ "\n"
+ "Copyright (c) by Martin Maurer, 2003-2011, Email: Martin.Maurer@clibb.de\n"
+ "Portions Copyright (c) by Aeolus Development 2004, www.aeolusdevelopment.com\n"
+ "\n");
+
+ DebugPrintf(1, "Syntax: lpc21isp [Options] file[ file[ ...]] comport baudrate Oscillator_in_kHz\n\n"
+ "Example: lpc21isp test.hex com1 115200 14746\n\n"
+ "Options: -bin for uploading binary file\n"
+ " -hex for uploading file in intel hex format (default)\n"
+ " -term for starting terminal after upload\n"
+ " -termonly for starting terminal without an upload\n"
+ " -localecho for local echo in terminal\n"
+ " -detectonly detect only used LPC chiptype (NXPARM only)\n"
+ " -debug0 for no debug\n"
+ " -debug3 for progress info only\n"
+ " -debug5 for full debug\n"
+ " -donotstart do not start MCU after download\n"
+ " -try<n> try n times to synchronise\n"
+ " -wipe Erase entire device before upload\n"
+ " -control for controlling RS232 lines for easier booting\n"
+ " (Reset = DTR, EnableBootLoader = RTS)\n"
+#ifdef INTEGRATED_IN_WIN_APP
+ " -nosync Do not synchronize device via '?'\n"
+#endif
+ " -controlswap swap RS232 control lines\n"
+ " (Reset = RTS, EnableBootLoader = DTR)\n"
+ " -controlinv Invert state of RTS & DTR \n"
+ " (0=true/assert/set, 1=false/deassert/clear).\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"
+ " -halfduplex use halfduplex serial communication (i.e. with K-Line)\n"
+ " -ADARM for downloading to an Analog Devices\n"
+ " ARM microcontroller ADUC70xx\n"
+ " -NXPARM for downloading to a NXP LPC1xxx/LPC2xxx (default)\n");
+
+ exit(1);
+ }
+
+ if (IspEnvironment->micro == NXP_ARM)
+ {
+ // If StringOscillator is bigger than 100 MHz, there seems to be something wrong
+ if (strlen(IspEnvironment->StringOscillator) > 5)
+ {
+ DebugPrintf(1, "Invalid crystal frequency %s\n", IspEnvironment->StringOscillator);
+ exit(1);
+ }
+ }
+}
+
+/***************************** ResetTarget ******************************/
+/** Resets the target leaving it in either download (program) mode or
+run mode.
+\param [in] mode the mode to leave the target in.
+*/
+void ResetTarget(ISP_ENVIRONMENT *IspEnvironment, TARGET_MODE mode)
+{
+ if (IspEnvironment->ControlLines)
+ {
+ switch (mode)
+ {
+ /* Reset and jump to boot loader. */
+ case PROGRAM_MODE:
+ ControlModemLines(IspEnvironment, 1, 1);
+ 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);
+ // Clear the RTS line after having reset the micro
+ // Needed for the "GO <Address> <Mode>" ISP command to work */
+ ControlModemLines(IspEnvironment, 0, 0);
+ break;
+
+ /* Reset and start uploaded program */
+ case RUN_MODE:
+ ControlModemLines(IspEnvironment, 1, 0);
+ Sleep(100);
+ ClearSerialPortBuffers(IspEnvironment);
+ Sleep(100);
+ ControlModemLines(IspEnvironment, 0, 0);
+ Sleep(100);
+ break;
+ }
+ }
+}
+
+
+/***************************** Ascii2Hex ********************************/
+/** Converts a hex character to its equivalent number value. In case of an
+error rather abruptly terminates the program.
+\param [in] c the hex digit to convert.
+\return the value of the hex digit.
+*/
+static unsigned char Ascii2Hex(unsigned char c)
+{
+ if (c >= '0' && c <= '9')
+ {
+ return (unsigned char)(c - '0');
+ }
+
+ if (c >= 'A' && c <= 'F')
+ {
+ return (unsigned char)(c - 'A' + 10);
+ }
+
+ if (c >= 'a' && c <= 'f')
+ {
+ return (unsigned char)(c - 'a' + 10);
+ }
+
+ DebugPrintf(1, "Wrong Hex-Nibble %c (%02X)\n", c, c);
+ exit(1);
+
+ return 0; // this "return" will never be reached, but some compilers give a warning if it is not present
+}
+
+
+/***************************** AddFileHex *******************************/
+/** Add a file to the list of files to read in, flag it as hex format.
+\param [in] IspEnvironment Programming environment.
+\param [in] arg The argument that was passed to the program as a file name.
+\return 0 on success, an error code otherwise.
+*/
+static int AddFileHex(ISP_ENVIRONMENT *IspEnvironment, const char *arg)
+{
+ FILE_LIST *entry;
+
+ // Add file to list. If cannot allocate storage for node return an error.
+ entry = malloc(sizeof(FILE_LIST));
+ if( entry == 0)
+ {
+ DebugPrintf(1, "Error %d Could not allocated memory for file node %s\n", ERR_ALLOC_FILE_LIST, arg);
+ return ERR_ALLOC_FILE_LIST;
+ }
+
+ // Build up entry and insert it at the start of the list.
+ entry->name = arg;
+ entry->prev = IspEnvironment->f_list;
+ entry->hex_flag = 1;
+ IspEnvironment->f_list = entry;
+
+ return 0; // Success.
+}
+
+
+/***************************** AddFileBinary ****************************/
+/** Add a file to the list of files to read in, flag it as binary format.
+\param [in] IspEnvironment Programming environment.
+\param [in] arg The argument that was passed to the program as a file name.
+\return 0 on success, an error code otherwise.
+*/
+static int AddFileBinary(ISP_ENVIRONMENT *IspEnvironment, const char *arg)
+{
+ FILE_LIST *entry;
+
+ // Add file to list. If cannot allocate storage for node return an error.
+ entry = malloc(sizeof(FILE_LIST));
+ if( entry == 0)
+ {
+ DebugPrintf( 1, "Error %d Could not allocated memory for file node %s\n", ERR_ALLOC_FILE_LIST, arg);
+ return ERR_ALLOC_FILE_LIST;
+ }
+
+ // Build up entry and insert it at the start of the list.
+ entry->name = arg;
+ entry->prev = IspEnvironment->f_list;
+ entry->hex_flag = 0;
+ IspEnvironment->f_list = entry;
+
+ return 0; // Success.
+}
+
+#if 0
+void ReadHexFile(ISP_ENVIRONMENT *IspEnvironment)
+{
+ LoadFile(IspEnvironment);
+
+ if (IspEnvironment->BinaryLength)
+ {
+ BINARY* FileContent = IspEnvironment->FileContent;
+
+ unsigned long Pos;
+ unsigned char RecordLength;
+ unsigned short RecordAddress;
+ unsigned long RealAddress = 0;
+ unsigned char RecordType;
+ unsigned char Hexvalue;
+ unsigned long StartAddress;
+ int BinaryOffsetDefined = 0;
+ unsigned char i;
+
+
+ DebugPrintf(3, "Converting file %s to binary format...\n", IspEnvironment->input_file);
+
+ Pos = 0;
+ while (Pos < IspEnvironment->BinaryLength)
+ {
+ 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) > IspEnvironment->BinaryMemSize)
+ {
+ IspEnvironment->BinaryMemSize <<= 1; // Double the size allocated !!!
+ IspEnvironment->BinaryContent = (BINARY*) realloc(IspEnvironment->BinaryContent, IspEnvironment->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"
+ "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%08X\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);
+ }
+ }
+}
+#endif // #if 0
+
+
+/***************************** LoadFile *********************************/
+/** Loads the requested file to download into memory.
+\param [in] IspEnvironment structure containing input filename
+\param [in] filename the name of the file to read in.
+\param [in] FileFormat the format of the file to read in (FORMAT_HEX or FORMAT_BINARY)
+\return 0 if successful, otherwise an error code.
+*/
+static int LoadFile(ISP_ENVIRONMENT *IspEnvironment, const char *filename, int FileFormat)
+{
+ int fd;
+ int i;
+ int BinaryOffsetDefined;
+ unsigned long Pos;
+ unsigned long FileLength;
+ BINARY *FileContent; /**< Used to store the content of a hex */
+ /* file before converting to binary. */
+ unsigned long BinaryMemSize;
+
+ fd = open(filename, O_RDONLY | O_BINARY);
+ if (fd == -1)
+ {
+ DebugPrintf(1, "Can't open file %s\n", filename);
+ return ERR_FILE_OPEN_HEX;
+ }
+
+ FileLength = lseek(fd, 0L, 2); // Get file size
+
+ if (FileLength == (size_t)-1)
+ {
+ DebugPrintf(1, "\nFileLength = -1 !?!\n");
+ return ERR_FILE_SIZE_HEX;
+ }
+
+ lseek(fd, 0L, 0);
+
+ // Just read the entire file into memory to parse.
+ FileContent = (BINARY*) malloc(FileLength);
+
+ if( FileContent == 0)
+ {
+ DebugPrintf( 1, "\nCouldn't allocate enough memory for file.\n");
+ return ERR_FILE_ALLOC_HEX;
+ }
+
+ BinaryOffsetDefined = 0;
+
+ BinaryMemSize = IspEnvironment->BinaryLength;
+
+ read(fd, FileContent, FileLength);
+
+ close(fd);
+
+ DebugPrintf(2, "File %s:\n\tloaded...\n", filename);
+
+ // Intel-Hex -> Binary Conversion
+
+ if (FileFormat == FORMAT_HEX)
+ {
+ 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", filename);
+
+ 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)
+ {
+ if(!BinaryMemSize) BinaryMemSize = FileLength * 2;
+ else 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
+ {
+ unsigned long cs,ip;
+ 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++]);
+ }
+ }
+ cs = StartAddress >> 16; //high part
+ ip = StartAddress & 0xffff; //low part
+ StartAddress = cs*16+ip; //segmented 20-bit space
+ DebugPrintf(1,"Start Address = 0x%08X\n", StartAddress);
+ IspEnvironment->StartAddress = StartAddress;
+ }
+ 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);
+ return ERR_MEMORY_RANGE;
+ }
+ }
+ }
+ 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%08X\n", StartAddress);
+ IspEnvironment->StartAddress = StartAddress;
+ }
+ else
+ {
+ free( FileContent);
+ DebugPrintf( 1, "Error %d RecordType %02X not yet implemented\n", ERR_RECORD_TYPE_LOADFILE, RecordType);
+ return( ERR_RECORD_TYPE_LOADFILE);
+ }
+
+ 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);
+ }
+
+ free( FileContent); // Done with file contents
+ }
+ else // FORMAT_BINARY
+ {
+ IspEnvironment->BinaryContent = FileContent;
+ IspEnvironment->BinaryLength = FileLength;
+ }
+
+ DebugPrintf(2, "\timage size : %ld\n", IspEnvironment->BinaryLength);
+
+ return 0;
+}
+
+/***************************** LoadFiles1 ********************************/
+/** Loads the requested files to download into memory.
+\param [in] IspEnvironment structure containing input filename(s).
+\param [in] file simple linked list of files to read
+\return 0 if successful, otherwise an error code.
+*/
+static int LoadFiles1(ISP_ENVIRONMENT *IspEnvironment, const FILE_LIST *file)
+{
+ int ret_val;
+
+ if( file->prev != 0)
+ {
+ DebugPrintf( 3, "Follow file list %s\n", file->name);
+
+ ret_val = LoadFiles1( IspEnvironment, file->prev);
+ if( ret_val != 0)
+ {
+ return ret_val;
+ }
+ }
+
+ DebugPrintf( 3, "Attempt to read File %s\n", file->name);
+ if(file->hex_flag != 0)
+ {
+ ret_val = LoadFile(IspEnvironment, file->name, FORMAT_HEX);
+ }
+ else
+ {
+ ret_val = LoadFile(IspEnvironment, file->name, FORMAT_BINARY);
+ }
+ if( ret_val != 0)
+ {
+ return ret_val;
+ }
+
+ return 0;
+}
+
+/***************************** LoadFiles ********************************/
+/** Loads the requested files to download into memory.
+\param [in] IspEnvironment structure containing input filename(s).
+\param [in] file simple linked list of files to read
+\return 0 if successful, otherwise an error code.
+*/
+static int LoadFiles(ISP_ENVIRONMENT *IspEnvironment)
+{
+ int ret_val;
+
+ ret_val = LoadFiles1(IspEnvironment, IspEnvironment->f_list);
+ if( ret_val != 0)
+ {
+ exit(1); // return ret_val;
+ }
+
+ DebugPrintf( 2, "Image 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;
+ }
+
+ // When debugging is switched on, output result of conversion to file debugout.bin
+ if(debug_level >= 4)
+ {
+ int fdout;
+ DebugPrintf( 1, "Dumping image file.\n");
+ fdout = open("debugout.bin", O_RDWR | O_BINARY | O_CREAT | O_TRUNC, 0777);
+ write(fdout, IspEnvironment->BinaryContent, IspEnvironment->BinaryLength);
+ close(fdout);
+ }
+ return 0;
+}
+#endif // !defined COMPILE_FOR_LPC21
+
+#ifndef COMPILE_FOR_LPC21
+int PerformActions(ISP_ENVIRONMENT *IspEnvironment)
+{
+ int downloadResult = -1;
+
+ DebugPrintf(2, "lpc21isp version " VERSION_STR "\n");
+
+ /* Download requested, read in the input file. */
+ if (IspEnvironment->ProgramChip)
+ {
+ LoadFiles(IspEnvironment);
+ }
+
+ OpenSerialPort(IspEnvironment); /* Open the serial port to the microcontroller. */
+
+ ResetTarget(IspEnvironment, PROGRAM_MODE);
+
+ ClearSerialPortBuffers(IspEnvironment);
+
+ /* Perform the requested download. */
+ if (IspEnvironment->ProgramChip || IspEnvironment->DetectOnly)
+ {
+ switch (IspEnvironment->micro)
+ {
+#ifdef LPC_SUPPORT
+ case NXP_ARM:
+ downloadResult = NxpDownload(IspEnvironment);
+ break;
+#endif
+
+#ifdef AD_SUPPORT
+ case ANALOG_DEVICES_ARM:
+ downloadResult = AnalogDevicesDownload(IspEnvironment);
+ break;
+#endif
+ }
+
+ if (downloadResult != 0)
+ {
+ CloseSerialPort(IspEnvironment);
+ exit(downloadResult);
+ }
+ }
+
+ if (IspEnvironment->StartAddress == 0 || IspEnvironment->TerminalOnly)
+ {
+ /* Only reset target if startaddress = 0
+ * Otherwise stay with the running program as started in Download()
+ */
+ ResetTarget(IspEnvironment, RUN_MODE);
+ }
+
+ debug_level = 1; /* From now on there is no more debug output !! */
+ /* Therefore switch it off... */
+
+#ifdef TERMINAL_SUPPORT
+ // Pass control to Terminal which will provide a terminal if one was asked for
+ // User asked for terminal emulation, provide a really dumb terminal.
+ Terminal(IspEnvironment);
+#endif
+
+ CloseSerialPort(IspEnvironment); /* All done, close the serial port to the */
+
+ return 0;
+}
+#endif
+
+/***************************** main *************************************/
+/** main. Everything starts from here.
+\param [in] argc the number of arguments.
+\param [in] argv an array of pointers to the arguments.
+*/
+
+#if !defined COMPILE_FOR_LPC21
+
+#if defined INTEGRATED_IN_WIN_APP
+int AppDoProgram(int argc, char *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ ISP_ENVIRONMENT IspEnvironment;
+
+ // Initialize debug level
+ debug_level = 2;
+
+ // Initialize ISP Environment
+ memset(&IspEnvironment, 0, sizeof(IspEnvironment)); // Clear the IspEnviroment to a known value
+ IspEnvironment.micro = NXP_ARM; // Default Micro
+ IspEnvironment.FileFormat = FORMAT_HEX; // Default File Format
+ IspEnvironment.ProgramChip = TRUE; // Default to Programming the chip
+ IspEnvironment.nQuestionMarks = 100;
+ IspEnvironment.DoNotStart = 0;
+ ReadArguments(&IspEnvironment, argc, argv); // Read and parse the command line
+
+ return PerformActions(&IspEnvironment); // Do as requested !
+}
+
+#endif // !defined COMPILE_FOR_LPC21
+
+/***************************** DumpString ******************************/
+/** Prints an area of memory to stdout. Converts non-printables to hex.
+\param [in] level the debug level of the block to be dumped. If this is
+less than or equal to the current debug level than the dump will happen
+otherwise this just returns.
+\param [in] b pointer to an area of memory.
+\param [in] size the length of the memory block to print.
+\param [in] prefix string is a pointer to a prefix string.
+*/
+void DumpString(int level, const void *b, size_t size, const char *prefix_string)
+{
+ size_t i;
+ const char * s = (const char*) b;
+ unsigned char c;
+
+ DebugPrintf(level, prefix_string);
+
+ DebugPrintf(level, "'");
+ for (i = 0; i < size; i++)
+ {
+ c = s[i];
+ if (c >= 0x20 && c <= 0x7e) /*isprint?*/
+ {
+ DebugPrintf(level, "%c", c);
+ }
+ else
+ {
+ DebugPrintf(level, "(%02X)", c);
+ }
+ }
+ DebugPrintf(level, "'\n");
+}
+
+#if !defined COMPILE_FOR_LPC21
+int lpctest(char* FileName)
+{
+ ISP_ENVIRONMENT IspEnvironment;
+
+ // Initialize debug level
+ debug_level = 2;
+
+ // Initialize ISP Environment
+ memset(&IspEnvironment, 0, sizeof(IspEnvironment)); // Clear the IspEnviroment to a known value
+ IspEnvironment.micro = NXP_ARM; // Default Micro
+ IspEnvironment.FileFormat = FORMAT_HEX; // Default File Format
+ IspEnvironment.ProgramChip = TRUE; // Default to Programming the chip
+ // IspEnvironment.input_file = FileName;
+ IspEnvironment.ControlLines = TRUE;
+ IspEnvironment.serial_port = "COM2";
+ IspEnvironment.baud_rate = "19200";
+ IspEnvironment.nQuestionMarks = 100;
+ IspEnvironment.DoNotStart = 0;
+ strcpy(IspEnvironment.StringOscillator, "25000");
+
+ return PerformActions(&IspEnvironment); // Do as requested !
+}
+#endif
diff --git a/lpc21isp.cbp b/lpc21isp.cbp new file mode 100644 index 0000000..0069e37 --- /dev/null +++ b/lpc21isp.cbp @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<CodeBlocks_project_file> + <FileVersion major="1" minor="6" /> + <Project> + <Option title="lpc21isp" /> + <Option pch_mode="2" /> + <Option compiler="gcc" /> + <Build> + <Target title="Debug"> + <Option output="bin\Debug\lpc21isp" prefix_auto="1" extension_auto="1" /> + <Option object_output="obj\Debug\" /> + <Option type="1" /> + <Option compiler="gcc" /> + <Compiler> + <Add option="-g" /> + </Compiler> + </Target> + <Target title="Release"> + <Option output="bin\Release\lpc21isp" prefix_auto="1" extension_auto="1" /> + <Option object_output="obj\Release\" /> + <Option type="1" /> + <Option compiler="gcc" /> + <Compiler> + <Add option="-O2" /> + </Compiler> + <Linker> + <Add option="-s" /> + </Linker> + </Target> + </Build> + <Compiler> + <Add option="-Wall" /> + </Compiler> + <Unit filename="adprog.c"> + <Option compilerVar="CC" /> + </Unit> + <Unit filename="adprog.h" /> + <Unit filename="lpc21isp.c"> + <Option compilerVar="CC" /> + </Unit> + <Unit filename="lpc21isp.h" /> + <Unit filename="lpcprog.c"> + <Option compilerVar="CC" /> + </Unit> + <Unit filename="lpcprog.h" /> + <Unit filename="lpcterm.c"> + <Option compilerVar="CC" /> + </Unit> + <Unit filename="lpcterm.h" /> + <Extensions> + <code_completion /> + <envvars /> + <debugger /> + <lib_finder disable_auto="1" /> + </Extensions> + </Project> +</CodeBlocks_project_file> diff --git a/lpc21isp.h b/lpc21isp.h new file mode 100644 index 0000000..13c26f4 --- /dev/null +++ b/lpc21isp.h @@ -0,0 +1,289 @@ +/******************************************************************************
+
+Project: Portable command line ISP for NXP LPC1000 / LPC2000 family
+ and Analog Devices ADUC70xx
+
+Filename: lsp21isp.h
+
+Compiler: Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
+ GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author: Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright: (c) Martin Maurer 2003-2011, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+ This file is part of lpc21isp.
+
+ lpc21isp is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ any later version.
+
+ lpc21isp is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ and GNU General Public License along with lpc21isp.
+ If not, see <http://www.gnu.org/licenses/>.
+*/
+
+// #define INTEGRATED_IN_WIN_APP
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define COMPILE_FOR_WINDOWS
+#define COMPILED_FOR "Windows"
+#elif defined(__CYGWIN__)
+#define COMPILE_FOR_CYGWIN
+#define COMPILED_FOR "Cygwin"
+#elif defined(__arm__) || defined(__thumb__)
+#define COMPILE_FOR_LPC21
+#define COMPILED_FOR "ARM"
+#define printf iprintf
+#elif defined(__APPLE__)
+#define COMPILE_FOR_LINUX
+#define COMPILED_FOR "Apple MacOS X"
+#elif defined(__FreeBSD__)
+#define COMPILE_FOR_LINUX
+#define COMPILED_FOR "FreeBSD"
+#elif defined(__OpenBSD__)
+#define COMPILE_FOR_LINUX
+#define COMPILED_FOR "OpenBSD"
+#else
+#define COMPILE_FOR_LINUX
+#define COMPILED_FOR "Linux"
+#endif
+
+// The Required features can be enabled / disabled here
+#define LPC_SUPPORT
+
+#ifndef COMPILE_FOR_LPC21
+#define AD_SUPPORT
+#define TERMINAL_SUPPORT
+#endif
+
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+#include <windows.h>
+#include <io.h>
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+#if defined COMPILE_FOR_WINDOWS
+#include <conio.h>
+//#define TRACE(x) OutputDebugString(x)
+#define TRACE(x) printf("%s",x)
+#endif // defined COMPILE_FOR_WINDOWS
+
+#if defined COMPILE_FOR_CYGWIN
+//#define TRACE(x) OutputDebugString(x)
+#define TRACE(x) printf("%s",x)
+#endif // defined COMPILE_FOR_WINDOWS
+
+#if defined COMPILE_FOR_LINUX
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/ioctl.h>
+extern void Sleep(unsigned long MilliSeconds);
+#define TRACE(x) printf("%s",x)
+#endif // defined COMPILE_FOR_LINUX
+
+#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
+#include <termios.h>
+#include <unistd.h> // for read and return value of lseek
+#include <sys/time.h> // for select_time
+extern int kbhit(void);
+extern int getch(void);
+extern struct termios keyboard_origtty;
+#endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
+
+#include <ctype.h> // isdigit()
+#include <stdio.h> // stdout
+#include <stdarg.h>
+#include <time.h>
+#if defined (COMPILE_FOR_LINUX)
+#if defined(__OpenBSD__)
+#include <errno.h>
+#else
+#include <sys/errno.h>
+#endif
+#endif
+
+#if defined COMPILE_FOR_LPC21
+#include <stdlib.h>
+#include <string.h>
+//#include <lpc_ioctl.h> // if using libc serial port communication
+#else
+#include <fcntl.h>
+#endif
+
+typedef enum
+{
+ NXP_ARM,
+ ANALOG_DEVICES_ARM
+} TARGET;
+
+typedef enum
+{
+ PROGRAM_MODE,
+ RUN_MODE
+} TARGET_MODE;
+
+typedef enum
+{
+ FORMAT_BINARY,
+ FORMAT_HEX
+} FILE_FORMAT_TYPE;
+
+typedef unsigned char BINARY; // Data type used for microcontroller
+
+/** Used to create list of files to read in. */
+typedef struct file_list FILE_LIST;
+
+/** Structure used to build list of input files. */
+struct file_list
+{
+ const char *name; /**< The name of the input file. */
+ FILE_LIST *prev; /**< The previous file name in the list.*/
+ char hex_flag; /**< True if the input file is hex. */
+};
+
+typedef struct
+{
+#if !defined COMPILE_FOR_LPC21
+ TARGET micro; // The type of micro that will be programmed.
+ FILE_FORMAT_TYPE FileFormat;
+ unsigned char ProgramChip; // Normally set
+
+ unsigned char ControlLines;
+ unsigned char ControlLinesSwapped;
+ unsigned char ControlLinesInverted;
+ unsigned char LogFile;
+ FILE_LIST *f_list; // List of files to read in.
+ int nQuestionMarks; // how many times to try to synchronise
+ int DoNotStart;
+ char *serial_port; // Name of the serial port to use to
+ // communicate with the microcontroller.
+ // Read from the command line.
+#endif // !defined COMPILE_FOR_LPC21
+
+ unsigned char TerminalOnly; // Declared here for lazyness saves ifdef's
+#ifdef TERMINAL_SUPPORT
+ unsigned char TerminalAfterUpload;
+ unsigned char LocalEcho;
+#endif
+
+ unsigned char HalfDuplex; // Only used for LPC Programming
+ unsigned char DetectOnly;
+ unsigned char WipeDevice;
+ unsigned char Verify;
+ int DetectedDevice; /* index in LPCtypes[] array */
+ char *baud_rate; /**< Baud rate to use on the serial
+ * port communicating with the
+ * microcontroller. Read from the
+ * command line. */
+
+ char StringOscillator[6]; /**< Holds representation of oscillator
+ * speed from the command line. */
+
+ BINARY *FileContent;
+ BINARY *BinaryContent; /**< Binary image of the */
+ /* microcontroller's memory. */
+ unsigned long BinaryLength;
+ unsigned long BinaryOffset;
+ unsigned long StartAddress;
+ unsigned long BinaryMemSize;
+
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+ HANDLE hCom;
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21
+ int fdCom;
+#endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21
+
+#if defined COMPILE_FOR_LINUX
+ struct termios oldtio, newtio;
+#endif // defined COMPILE_FOR_LINUX
+
+#ifdef INTEGRATED_IN_WIN_APP
+ unsigned char NoSync;
+#endif
+
+ unsigned serial_timeout_count; /**< Local used to track timeouts on serial port read. */
+
+} ISP_ENVIRONMENT;
+
+#if defined COMPILE_FOR_LPC21
+
+#define DebugPrintf(in, ...)
+
+#else
+extern int debug_level;
+
+#if defined INTEGRATED_IN_WIN_APP
+
+#define DebugPrintf AppDebugPrintf
+void AppDebugPrintf(int level, const char *fmt, ...);
+
+#define exit(val) AppException(val)
+void AppException(int exception_level);
+
+int AppDoProgram(int argc, char *argv[]);
+
+#define Exclude_kbhit 1
+int AppSyncing(int trials);
+void AppWritten(int size);
+
+#else
+void DebugPrintf(int level, const char *fmt, ...);
+//#define DebugPrintf(level, ...) if (level <= debug_level) { TRACE( __VA_ARGS__ ); }
+#endif
+
+void ClearSerialPortBuffers(ISP_ENVIRONMENT *IspEnvironment);
+
+#endif
+
+
+#if defined COMPILE_FOR_LINUX
+#define stricmp strcasecmp
+#define strnicmp strncasecmp
+#endif // defined COMPILE_FOR_LINUX
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif // O_BINARY
+
+#ifndef DWORD
+#define DWORD unsigned long
+#endif // DWORD
+
+/*
+debug levels
+0 - very quiet - Nothing gets printed at this level
+1 - quiet - Only error messages should be printed
+2 - indicate progress - Add progress messages
+3 - first level debug - Major level tracing
+4 - second level debug - Add detailed debugging
+5 - log comm's - log serial I/O
+*/
+
+
+void ReceiveComPort(ISP_ENVIRONMENT *IspEnvironment,
+ const char *Ans, unsigned long MaxSize,
+ unsigned long *RealSize, unsigned long WantedNr0x0A,
+ unsigned timeOutMilliseconds);
+void PrepareKeyboardTtySettings(void);
+void ResetKeyboardTtySettings(void);
+void ResetTarget(ISP_ENVIRONMENT *IspEnvironment, TARGET_MODE mode);
+
+void DumpString(int level, const void *s, size_t size, const char *prefix_string);
+void SendComPort(ISP_ENVIRONMENT *IspEnvironment, const char *s);
+void SendComPortBlock(ISP_ENVIRONMENT *IspEnvironment, const void *s, size_t n);
+int ReceiveComPortBlockComplete(ISP_ENVIRONMENT *IspEnvironment, void *block, size_t size, unsigned timeout);
+void ClearSerialPortBuffers(ISP_ENVIRONMENT *IspEnvironment);
+
+int lpctest(char* FileName);
diff --git a/lpc21isp.layout b/lpc21isp.layout new file mode 100644 index 0000000..d6bec77 --- /dev/null +++ b/lpc21isp.layout @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<CodeBlocks_layout_file> + <ActiveTarget name="Release" /> + <File name="lpc21isp.c" open="1" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor1 position="20180" topLine="309" /> + </File> + <File name="lpc21isp.h" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor1 position="566" topLine="226" /> + </File> + <File name="lpcprog.c" open="1" top="1" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor1 position="4072" topLine="74" /> + </File> + <File name="lpcprog.h" open="1" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor1 position="0" topLine="63" /> + </File> +</CodeBlocks_layout_file> diff --git a/lpcprog.c b/lpcprog.c new file mode 100644 index 0000000..9773a6d --- /dev/null +++ b/lpcprog.c @@ -0,0 +1,1273 @@ +/******************************************************************************
+
+Project: Portable command line ISP for NXP LPC1000 / LPC2000 family
+ and Analog Devices ADUC70xx
+
+Filename: lpcprog.c
+
+Compiler: Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
+ GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author: Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright: (c) Martin Maurer 2003-2011, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+ This file is part of lpc21isp.
+
+ lpc21isp is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ any later version.
+
+ lpc21isp is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ and GNU General Public License along with lpc21isp.
+ If not, see <http://www.gnu.org/licenses/>.
+*/
+
+// This file is for the Actual Programming of the LPC Chips
+
+#if defined(_WIN32)
+#if !defined __BORLANDC__
+#include "StdAfx.h"
+#endif
+#endif // defined(_WIN32)
+#include "lpc21isp.h"
+
+#ifdef LPC_SUPPORT
+#include "lpcprog.h"
+
+static const unsigned int SectorTable_210x[] =
+{
+ 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
+ 8192, 8192, 8192, 8192, 8192, 8192, 8192
+};
+
+static const unsigned int SectorTable_2103[] =
+{
+ 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096
+};
+
+static const unsigned int SectorTable_2109[] =
+{
+ 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192
+};
+
+static const unsigned int SectorTable_211x[] =
+{
+ 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
+ 8192, 8192, 8192, 8192, 8192, 8192, 8192,
+};
+
+static const unsigned int SectorTable_212x[] =
+{
+ 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
+ 65536, 65536, 8192, 8192, 8192, 8192, 8192, 8192, 8192
+};
+
+// Used for devices with 500K (LPC2138 and LPC2148) and
+// for devices with 504K (1 extra 4k block at the end)
+static const unsigned int SectorTable_213x[] =
+{
+ 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096,
+ 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
+ 32768, 32768, 32768, 32768, 32768, 32768, 4096, 4096,
+ 4096, 4096, 4096, 4096
+};
+
+// Used for LPC17xx devices
+static const unsigned int SectorTable_17xx[] =
+{
+ 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096,
+ 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096,
+ 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
+ 32768, 32768, 32768, 32768, 32768, 32768
+};
+
+static int unsigned SectorTable_RAM[] = { 65000 };
+
+static LPC_DEVICE_TYPE LPCtypes[] =
+{
+ { 0, 0, 0, 0, 0, 0, 0, CHIP_VARIANT_NONE }, /* unknown */
+
+ // id, name of product, flash size, ram size, total number of sector, max copy size, sector table, chip variant
+
+ { 0x2500102B, "1102", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+
+ { 0x041E502B, "1111.../101", 8, 2, 2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x2516D02B, "1111.../102", 8, 2, 2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x0416502B, "1111.../201", 8, 4, 2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x2516902B, "1111.../202", 8, 4, 2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x042D502B, "1112.../101", 16, 2, 4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x2524D02B, "1112.../102", 16, 2, 4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x0425502B, "1112.../201", 16, 4, 4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x2524902B, "1112.../202", 16, 4, 4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x0434502B, "1113.../201", 24, 4, 6, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x2532902B, "1113.../202", 24, 4, 6, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x0434102B, "1113.../301", 24, 8, 6, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x2532102B, "1113.../302", 24, 8, 6, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x0444502B, "1114.../201", 32, 4, 8, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x2540902B, "1114.../202", 32, 4, 8, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x1A40902B, "1114FN.../102", 32, 4, 8, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x0444102B, "1114.../301", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x2540102B, "1114.../302", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+
+ { 0x1421102B, "11C12.../301", 16, 8, 4, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x1440102B, "11C14.../301", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x1431102B, "11C22.../301", 16, 8, 4, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x1430102B, "11C24.../301", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+
+ { 0x0364002B, "1224.../101", 32, 8, 4, 2048, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x0364202B, "1224.../121", 48, 12, 32, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x0365002B, "1225.../301", 64, 16, 32, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x0365202B, "1225.../321", 80, 20, 32, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x0366002B, "1226", 96, 24, 32, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+ { 0x0367002B, "1227", 128, 32, 32, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+
+ { 0x2C42502B, "1311", 8, 4, 2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
+ { 0x1816902B, "1311/01", 8, 4, 2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
+ { 0x2C40102B, "1313", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
+ { 0x1830102B, "1313/01", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
+ { 0x3D01402B, "1342", 16, 4, 4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
+ { 0x3D00002B, "1343", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
+
+ { 0x25001118, "1751", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x25001121, "1752", 64, 16, 16, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x25011722, "1754", 128, 32, 18, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x25011723, "1756", 256, 32, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x25013F37, "1758", 512, 64, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x25113737, "1759", 512, 64, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x26011922, "1764", 128, 32, 18, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x26013733, "1765", 256, 64, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x26013F33, "1766", 256, 64, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x26012837, "1767", 512, 64, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x26013F37, "1768", 512, 64, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x26113F37, "1769", 512, 64, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+
+ { 0x27011132, "1774", 128, 40, 18, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x27191F43, "1776", 256, 80, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x27193747, "1777", 512, 96, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x27193F47, "1778", 512, 96, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x281D1743, "1785", 256, 80, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x281D1F43, "1786", 256, 80, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x281D3747, "1787", 512, 96, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+ { 0x281D3F47, "1788", 512, 96, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+
+ { 0x0004FF11, "2103", 32, 8, 8, 4096, SectorTable_2103, CHIP_VARIANT_LPC2XXX },
+ { 0xFFF0FF12, "2104", 128, 16, 15, 8192, SectorTable_210x, CHIP_VARIANT_LPC2XXX },
+ { 0xFFF0FF22, "2105", 128, 32, 15, 8192, SectorTable_210x, CHIP_VARIANT_LPC2XXX },
+ { 0xFFF0FF32, "2106", 128, 64, 15, 8192, SectorTable_210x, CHIP_VARIANT_LPC2XXX },
+ { 0x0201FF01, "2109", 64, 8, 8, 4096, SectorTable_2109, CHIP_VARIANT_LPC2XXX },
+ { 0x0101FF12, "2114", 128, 16, 15, 8192, SectorTable_211x, CHIP_VARIANT_LPC2XXX },
+ { 0x0201FF12, "2119", 128, 16, 15, 8192, SectorTable_211x, CHIP_VARIANT_LPC2XXX },
+ { 0x0101FF13, "2124", 256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
+ { 0x0201FF13, "2129", 256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
+ { 0x0002FF01, "2131", 32, 8, 8, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x0002FF11, "2132", 64, 16, 9, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x0002FF12, "2134", 128, 16, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x0002FF23, "2136", 256, 32, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x0002FF25, "2138", 512, 32, 27, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x0402FF01, "2141", 32, 8, 8, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x0402FF11, "2142", 64, 16, 9, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x0402FF12, "2144", 128, 16, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x0402FF23, "2146", 256, 40, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x0402FF25, "2148", 512, 40, 27, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x0301FF13, "2194", 256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
+ { 0x0301FF12, "2210", 0, 16, 0, 8192, SectorTable_211x, CHIP_VARIANT_LPC2XXX }, /* table is a "don't care" */
+ { 0x0401FF12, "2212", 128, 16, 15, 8192, SectorTable_211x, CHIP_VARIANT_LPC2XXX },
+ { 0x0601FF13, "2214", 256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
+ /* "2290"; same id as the LPC2210 */
+ { 0x0401FF13, "2292", 256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
+ { 0x0501FF13, "2294", 256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
+ { 0x00000000, "2361", 128, 34, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x00000000, "2362", 128, 34, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x0603FB02, "2364", 128, 34, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 01 -- 6 July 2007 */
+ { 0x1600F902, "2364", 128, 34, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x1600E823, "2365", 256, 58, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x0603FB23, "2366", 256, 58, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 01 -- 6 July 2007 */
+ { 0x1600F923, "2366", 256, 58, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x1600E825, "2367", 512, 58, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x0603FB25, "2368", 512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 01 -- 6 July 2007 */
+ { 0x1600F925, "2368", 512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x1700E825, "2377", 512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x0703FF25, "2378", 512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 01 -- 6 July 2007 */
+ { 0x1600FD25, "2378", 512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 01 -- 29 October 2007 */
+ { 0x1700FD25, "2378", 512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x1700FF35, "2387", 512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 03 -- 25 August 2008 */
+ { 0x1800F935, "2387", 512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x1800FF35, "2388", 512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x1500FF35, "2458", 512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x1600FF30, "2460", 0, 98, 0, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x1600FF35, "2468", 512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x1701FF30, "2470", 0, 98, 0, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+ { 0x1701FF35, "2478", 512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }
+};
+
+/***************************** NXP Download *********************************/
+/** Download the file from the internal memory image to the NXP microcontroller.
+* This function is visible from outside if COMPILE_FOR_LPC21
+*/
+
+static int SendAndVerify(ISP_ENVIRONMENT *IspEnvironment, const char *Command,
+ char *AnswerBuffer, int AnswerLength)
+{
+ unsigned long realsize;
+ int cmdlen;
+
+ SendComPort(IspEnvironment, Command);
+ ReceiveComPort(IspEnvironment, AnswerBuffer, AnswerLength - 1, &realsize, 2, 5000);
+ cmdlen = strlen(Command);
+ return (strncmp(AnswerBuffer, Command, cmdlen) == 0
+ && strcmp(AnswerBuffer + cmdlen, "0\r\n") == 0);
+}
+
+
+
+/***************************** NxpOutputErrorMessage ***********************/
+/** Given an error number find and print the appropriate error message.
+\param [in] ErrorNumber The number of the error.
+*/
+#if defined COMPILE_FOR_LPC21
+
+#define NxpOutputErrorMessage(in) // Cleanly remove this feature from the embedded version !!
+
+#else
+
+static void NxpOutputErrorMessage(unsigned char ErrorNumber)
+{
+ switch (ErrorNumber)
+ {
+ case 0:
+ DebugPrintf(1, "CMD_SUCCESS\n");
+ break;
+
+ case 1:
+ DebugPrintf(1, "INVALID_COMMAND\n");
+ break;
+
+ case 2:
+ DebugPrintf(1, "SRC_ADDR_ERROR: Source address is not on word boundary.\n");
+ break;
+ case 3:
+ DebugPrintf(1, "DST_ADDR_ERROR: Destination address is not on a correct boundary.\n");
+ break;
+
+ case 4:
+ DebugPrintf(1, "SRC_ADDR_NOT_MAPPED: Source address is not mapped in the memory map.\n"
+ " Count value is taken into consideration where applicable.\n");
+ break;
+
+ case 5:
+ DebugPrintf(1, "DST_ADDR_NOT_MAPPED: Destination address is not mapped in the memory map.\n"
+ " Count value is taken into consideration where applicable.\n");
+ break;
+
+ case 6:
+ DebugPrintf(1, "COUNT_ERROR: Byte count is not multiple of 4 or is not a permitted value.\n");
+ break;
+
+ case 7:
+ DebugPrintf(1, "INVALID_SECTOR: Sector number is invalid or end sector number is\n"
+ " greater than start sector number.\n");
+ break;
+
+ case 8:
+ DebugPrintf(1, "SECTOR_NOT_BLANK\n");
+ break;
+
+ case 9:
+ DebugPrintf(1, "SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION:\n"
+ "Command to prepare sector for write operation was not executed.\n");
+ break;
+
+ case 10:
+ DebugPrintf(1, "COMPARE_ERROR: Source and destination data not equal.\n");
+ break;
+
+ case 11:
+ DebugPrintf(1, "BUSY: Flash programming hardware interface is busy.\n");
+ break;
+
+ case 12:
+ DebugPrintf(1, "PARAM_ERROR: Insufficient number of parameters or invalid parameter.\n");
+ break;
+
+ case 13:
+ DebugPrintf(1, "ADDR_ERROR: Address is not on word boundary.\n");
+ break;
+
+ case 14:
+ DebugPrintf(1, "ADDR_NOT_MAPPED: Address is not mapped in the memory map.\n"
+ " Count value is taken in to consideration where applicable.\n");
+ break;
+
+ case 15:
+ DebugPrintf(1, "CMD_LOCKED\n");
+ break;
+
+ case 16:
+ DebugPrintf(1, "INVALID_CODE: Unlock code is invalid.\n");
+ break;
+
+ case 17:
+ DebugPrintf(1, "INVALID_BAUD_RATE: Invalid baud rate setting.\n");
+ break;
+
+ case 18:
+ DebugPrintf(1, "INVALID_STOP_BIT: Invalid stop bit setting.\n");
+ break;
+
+ case 19:
+ DebugPrintf( 1, "CODE READ PROTECTION ENABLED\n");
+ break;
+
+ case 255:
+ break;
+
+ default:
+ DebugPrintf(1, "unknown error %u\n", ErrorNumber);
+ break;
+ }
+
+ //DebugPrintf(1, "error (%u), see NxpOutputErrorMessage() in lpc21isp.c for help \n\r", ErrorNumber);
+}
+#endif // !defined COMPILE_FOR_LPC21
+
+/***************************** GetAndReportErrorNumber ***************************/
+/** Find error number in string. This will normally be the string
+returned from the microcontroller.
+\param [in] Answer the buffer to search for the error number.
+\return the error number found, if no linefeed found before the end of the
+string an error value of 255 is returned. If a non-numeric value is found
+then it is printed to stdout and an error value of 255 is returned.
+*/
+static unsigned char GetAndReportErrorNumber(const char *Answer)
+{
+ unsigned char Result = 0xFF; // Error !!!
+ unsigned int i = 0;
+
+ while (1)
+ {
+ if (Answer[i] == 0x00)
+ {
+ break;
+ }
+
+ if (Answer[i] == 0x0a)
+ {
+ i++;
+
+ if (Answer[i] < '0' || Answer[i] > '9')
+ {
+ DebugPrintf(1, "ErrorString: %s", &Answer[i]);
+ break;
+ }
+
+ Result = (unsigned char) (atoi(&Answer[i]));
+ break;
+ }
+
+ i++;
+ }
+
+ NxpOutputErrorMessage(Result);
+
+ return Result;
+}
+
+
+int NxpDownload(ISP_ENVIRONMENT *IspEnvironment)
+{
+ unsigned long realsize;
+ char Answer[128];
+ char ExpectedAnswer[128];
+ char temp[128];
+ /*const*/ char *strippedAnswer, *endPtr;
+ int strippedsize;
+ int nQuestionMarks;
+ int found;
+ unsigned long Sector;
+ unsigned long SectorLength;
+ unsigned long SectorStart, SectorOffset, SectorChunk;
+ char tmpString[128];
+ char uuencode_table[64];
+ int Line;
+ unsigned long tmpStringPos;
+ unsigned long BlockOffset;
+ unsigned long Block;
+ unsigned long Pos;
+ unsigned long CopyLength;
+ int c,k=0,i;
+ unsigned long ivt_CRC; // CRC over interrupt vector table
+ unsigned long block_CRC;
+ time_t tStartUpload=0, tDoneUpload=0;
+ char tmp_string[64];
+ char * cmdstr;
+
+#if !defined COMPILE_FOR_LPC21
+
+#if defined __BORLANDC__
+#define local_static static
+#else
+#define local_static
+#endif
+
+// char * cmdstr;
+ int repeat = 0;
+ // Puffer for data to resend after "RESEND\r\n" Target responce
+ local_static char sendbuf0[128];
+ local_static char sendbuf1[128];
+ local_static char sendbuf2[128];
+ local_static char sendbuf3[128];
+ local_static char sendbuf4[128];
+ local_static char sendbuf5[128];
+ local_static char sendbuf6[128];
+ local_static char sendbuf7[128];
+ local_static char sendbuf8[128];
+ local_static char sendbuf9[128];
+ local_static char sendbuf10[128];
+ local_static char sendbuf11[128];
+ local_static char sendbuf12[128];
+ local_static char sendbuf13[128];
+ local_static char sendbuf14[128];
+ local_static char sendbuf15[128];
+ local_static char sendbuf16[128];
+ local_static char sendbuf17[128];
+ local_static char sendbuf18[128];
+ local_static char sendbuf19[128];
+
+ char * sendbuf[20] = { sendbuf0, sendbuf1, sendbuf2, sendbuf3, sendbuf4,
+ sendbuf5, sendbuf6, sendbuf7, sendbuf8, sendbuf9,
+ sendbuf10, sendbuf11, sendbuf12, sendbuf13, sendbuf14,
+ sendbuf15, sendbuf16, sendbuf17, sendbuf18, sendbuf19};
+#endif
+
+ DebugPrintf(2, "Synchronizing (ESC to abort)");
+
+ PrepareKeyboardTtySettings();
+
+#if defined INTEGRATED_IN_WIN_APP
+ if (IspEnvironment->NoSync)
+ {
+ found = 1;
+ }
+ else
+#endif
+ {
+ for (nQuestionMarks = found = 0; !found && nQuestionMarks < IspEnvironment->nQuestionMarks; nQuestionMarks++)
+ {
+#if defined INTEGRATED_IN_WIN_APP
+ // allow calling application to abort when syncing takes too long
+
+ if (!AppSyncing(nQuestionMarks))
+ {
+ return (USER_ABORT_SYNC);
+ }
+#else
+#ifndef Exclude_kbhit
+ if (kbhit())
+ {
+ if (getch() == 0x1b)
+ {
+ ResetKeyboardTtySettings();
+ DebugPrintf(2, "\nUser aborted during synchronisation\n");
+ return (USER_ABORT_SYNC);
+ }
+ }
+#endif
+#endif
+
+ DebugPrintf(2, ".");
+ SendComPort(IspEnvironment, "?");
+
+ memset(Answer,0,sizeof(Answer));
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,100);
+
+ strippedAnswer = Answer;
+ strippedsize = realsize;
+ while ((strippedsize > 0) && ((*strippedAnswer == '?') || (*strippedAnswer == 0)))
+ {
+ strippedAnswer++;
+ strippedsize--;
+ }
+
+ sprintf(tmp_string, "StrippedAnswer(Length=%d): '", strippedsize);
+ DumpString(3, strippedAnswer, strippedsize, tmp_string);
+
+ tStartUpload = time(NULL);
+
+ if (strcmp(strippedAnswer, "Synchronized\r\n") == 0)
+ {
+ found = 1;
+ }
+#if !defined COMPILE_FOR_LPC21
+ else
+ {
+ ResetTarget(IspEnvironment, PROGRAM_MODE);
+ }
+#endif
+ }
+ }
+
+ ResetKeyboardTtySettings();
+
+ if (!found)
+ {
+ DebugPrintf(1, " no answer on '?'\n");
+ return (NO_ANSWER_QM);
+ }
+
+#if defined INTEGRATED_IN_WIN_APP
+ AppSyncing(-1); // flag syncing done
+#endif
+
+ DebugPrintf(2, " OK\n");
+
+ SendComPort(IspEnvironment, "Synchronized\n");
+
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer) - 1, &realsize, 2, 1000);
+
+ if ((strcmp(Answer, "Synchronized\r\nOK\r\n") != 0) && (strcmp(Answer, "Synchronized\rOK\r\n") != 0) &&
+ (strcmp(Answer, "Synchronized\nOK\r\n") != 0))
+ {
+ DebugPrintf(1, "No answer on 'Synchronized'\n");
+ return (NO_ANSWER_SYNC);
+ }
+
+ DebugPrintf(3, "Synchronized 1\n");
+
+ DebugPrintf(3, "Setting oscillator\n");
+
+ sprintf(temp, "%s\n", IspEnvironment->StringOscillator);
+
+ SendComPort(IspEnvironment, temp);
+
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2, 1000);
+
+ sprintf(temp, "%s\nOK\r\n", IspEnvironment->StringOscillator);
+
+ if (strcmp(Answer, temp) != 0)
+ {
+ DebugPrintf(1, "No answer on Oscillator-Command\n");
+ return (NO_ANSWER_OSC);
+ }
+
+ DebugPrintf(3, "Unlock\n");
+
+ cmdstr = "U 23130\n";
+
+ if (!SendAndVerify(IspEnvironment, cmdstr, Answer, sizeof Answer))
+ {
+ DebugPrintf(1, "Unlock-Command:\n");
+ return (UNLOCK_ERROR + GetAndReportErrorNumber(Answer));
+ }
+
+ DebugPrintf(2, "Read bootcode version: ");
+
+ cmdstr = "K\n";
+
+ SendComPort(IspEnvironment, cmdstr);
+
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 4,5000);
+
+ if (strncmp(Answer, cmdstr, strlen(cmdstr)) != 0)
+ {
+ DebugPrintf(1, "no answer on Read Boot Code Version\n");
+ return (NO_ANSWER_RBV);
+ }
+
+ if (strncmp(Answer + strlen(cmdstr), "0\r\n", 3) == 0)
+ {
+ strippedAnswer = Answer + strlen(cmdstr) + 3;
+ /*
+ int maj, min, build;
+ if (sscanf(strippedAnswer, "%d %d %d", &build, &min, &maj) == 2) {
+ maj = min;
+ min = build;
+ build = 0;
+ } // if
+ DebugPrintf(2, "%d.%d.%d\n", maj, min, build);
+ */
+ DebugPrintf(2, strippedAnswer);
+ }
+ else
+ {
+ DebugPrintf(2, "unknown\n");
+ }
+
+ DebugPrintf(2, "Read part ID: ");
+
+ cmdstr = "J\n";
+
+ SendComPort(IspEnvironment, cmdstr);
+
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 3,5000);
+
+ if (strncmp(Answer, cmdstr, strlen(cmdstr)) != 0)
+ {
+ DebugPrintf(1, "no answer on Read Part Id\n");
+ return (NO_ANSWER_RPID);
+ }
+
+ strippedAnswer = (strncmp(Answer, "J\n0\r\n", 5) == 0) ? Answer + 5 : Answer;
+
+ Pos = strtoul(strippedAnswer, &endPtr, 10);
+ *endPtr = '\0'; /* delete \r\n */
+ for (i = sizeof LPCtypes / sizeof LPCtypes[0] - 1; i > 0 && LPCtypes[i].id != Pos; i--)
+ /* nothing */;
+ IspEnvironment->DetectedDevice = i;
+ if (IspEnvironment->DetectedDevice == 0) {
+ DebugPrintf(2, "unknown");
+ }
+ else {
+ DebugPrintf(2, "LPC%s, %d kiB ROM / %d kiB SRAM",
+ LPCtypes[IspEnvironment->DetectedDevice].Product,
+ LPCtypes[IspEnvironment->DetectedDevice].FlashSize,
+ LPCtypes[IspEnvironment->DetectedDevice].RAMSize);
+ }
+ DebugPrintf(2, " (0x%X)\n", Pos);//strippedAnswer);
+
+ if (!IspEnvironment->DetectOnly)
+ {
+ // Build up uuencode table
+ uuencode_table[0] = 0x60; // 0x20 is translated to 0x60 !
+
+ for (i = 1; i < 64; i++)
+ {
+ 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
+
+ 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;
+ }
+
+ // 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));
+ }
+
+ DebugPrintf(3, "Position 0x14 patched: ivt_CRC = 0x%08lX\n", ivt_CRC);
+ }
+ else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX ||
+ LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX ||
+ LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX)
+ {
+ // Patch 0x1C, otherwise it is not running and jumps to boot mode
+
+ 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;
+ }
+
+ // 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));
+ }
+
+ 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);
+ }
+ }
+
+#if 0
+ DebugPrintf(2, "Read Unique ID:\n");
+
+ cmdstr = "N\n";
+
+ SendComPort(IspEnvironment, cmdstr);
+
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 5,5000);
+
+ if (strncmp(Answer, cmdstr, strlen(cmdstr)) != 0)
+ {
+ DebugPrintf(1, "no answer on Read Unique ID\n");
+ return (NO_ANSWER_RBV);
+ }
+
+ if (strncmp(Answer + strlen(cmdstr), "0\r\n", 3) == 0)
+ {
+ strippedAnswer = Answer + strlen(cmdstr) + 3;
+ DebugPrintf(2, strippedAnswer);
+ }
+ else
+ {
+ DebugPrintf(2, "unknown\n");
+ }
+#endif // 0
+
+ /* In case of a download to RAM, use full RAM for downloading
+ * set the flash parameters to full RAM also.
+ * This makes sure that all code is downloaded as one big sector
+ */
+
+ if (IspEnvironment->BinaryOffset >= ReturnValueLpcRamStart(IspEnvironment))
+ {
+ LPCtypes[IspEnvironment->DetectedDevice].FlashSectors = 1;
+ LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize = LPCtypes[IspEnvironment->DetectedDevice].RAMSize*1024 - (ReturnValueLpcRamBase(IspEnvironment) - ReturnValueLpcRamStart(IspEnvironment));
+ LPCtypes[IspEnvironment->DetectedDevice].SectorTable = SectorTable_RAM;
+ SectorTable_RAM[0] = LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize;
+ }
+ if (IspEnvironment->DetectOnly)
+ return (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)
+ {
+ Sector = 0;
+ SectorStart = 0;
+ }
+ else
+ {
+ SectorStart = LPCtypes[IspEnvironment->DetectedDevice].SectorTable[0];
+ Sector = 1;
+ }
+
+ if (IspEnvironment->WipeDevice == 1)
+ {
+ DebugPrintf(2, "Wiping Device. ");
+
+ sprintf(tmpString, "P %d %d\n", 0, LPCtypes[IspEnvironment->DetectedDevice].FlashSectors-1);
+
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+ {
+ DebugPrintf(1, "Wrong answer on Prepare-Command\n");
+ return (WRONG_ANSWER_PREP + GetAndReportErrorNumber(Answer));
+ }
+
+ sprintf(tmpString, "E %d %d\n", 0, LPCtypes[IspEnvironment->DetectedDevice].FlashSectors-1);
+
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+ {
+ DebugPrintf(1, "Wrong answer on Erase-Command\n");
+ return (WRONG_ANSWER_ERAS + GetAndReportErrorNumber(Answer));
+ }
+ DebugPrintf(2, "OK \n");
+ }
+ else{
+ //no wiping requested: erasing sector 0 first
+ DebugPrintf(2, "Erasing sector 0 first, to invalidate checksum. ");
+
+ sprintf(tmpString, "P %d %d\n", 0, 0);
+
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+ {
+ DebugPrintf(1, "Wrong answer on Prepare-Command\n");
+ return (WRONG_ANSWER_PREP + GetAndReportErrorNumber(Answer));
+ }
+
+ sprintf(tmpString, "E %d %d\n", 0, 0);
+
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+ {
+ DebugPrintf(1, "Wrong answer on Erase-Command\n");
+ return (WRONG_ANSWER_ERAS + GetAndReportErrorNumber(Answer));
+ }
+ DebugPrintf(2, "OK \n");
+ }
+ while (1)
+ {
+ if (Sector >= LPCtypes[IspEnvironment->DetectedDevice].FlashSectors)
+ {
+ DebugPrintf(1, "Program too large; running out of Flash sectors.\n");
+ return (PROGRAM_TOO_LARGE);
+ }
+
+ DebugPrintf(2, "Sector %ld: ", Sector);
+ fflush(stdout);
+
+ if (IspEnvironment->BinaryOffset < ReturnValueLpcRamStart(IspEnvironment)) // Skip Erase when running from RAM
+ {
+ sprintf(tmpString, "P %ld %ld\n", Sector, Sector);
+
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+ {
+ DebugPrintf(1, "Wrong answer on Prepare-Command (1) (Sector %ld)\n", Sector);
+ return (WRONG_ANSWER_PREP + GetAndReportErrorNumber(Answer));
+ }
+
+ DebugPrintf(2, ".");
+ fflush(stdout);
+ if (IspEnvironment->WipeDevice == 0 && (Sector!=0)) //Sector 0 already erased
+ {
+ sprintf(tmpString, "E %ld %ld\n", Sector, Sector);
+
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+ {
+ DebugPrintf(1, "Wrong answer on Erase-Command (Sector %ld)\n", Sector);
+ return (WRONG_ANSWER_ERAS + GetAndReportErrorNumber(Answer));
+ }
+
+ DebugPrintf(2, ".");
+ fflush(stdout);
+ }
+ }
+
+ SectorLength = LPCtypes[IspEnvironment->DetectedDevice].SectorTable[Sector];
+ if (SectorLength > IspEnvironment->BinaryLength - SectorStart)
+ {
+ SectorLength = IspEnvironment->BinaryLength - SectorStart;
+ }
+
+ for (SectorOffset = 0; SectorOffset < SectorLength; SectorOffset += SectorChunk)
+ {
+ if (SectorOffset > 0)
+ {
+ // Add a visible marker between segments in a sector
+ DebugPrintf(2, "|"); /* means: partial segment copied */
+ fflush(stdout);
+ }
+
+ // If the Flash ROM sector size is bigger than the number of bytes
+ // we can copy from RAM to Flash, we must "chop up" the sector and
+ // copy these individually.
+ // This is especially needed in the case where a Flash sector is
+ // bigger than the amount of SRAM.
+ SectorChunk = SectorLength - SectorOffset;
+ if (SectorChunk > (unsigned)LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize)
+ {
+ SectorChunk = LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize;
+ }
+
+ // Write multiple of 45 * 4 Byte blocks to RAM, but copy maximum of on sector to Flash
+ // In worst case we transfer up to 180 byte to much to RAM
+ // but then we can always use full 45 byte blocks and length is multiple of 4
+ CopyLength = SectorChunk;
+ if ((CopyLength % (45 * 4)) != 0)
+ {
+ CopyLength += ((45 * 4) - (CopyLength % (45 * 4)));
+ }
+
+ sprintf(tmpString, "W %ld %ld\n", ReturnValueLpcRamBase(IspEnvironment), CopyLength);
+
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+ {
+ DebugPrintf(1, "Wrong answer on Write-Command\n");
+ return (WRONG_ANSWER_WRIT + GetAndReportErrorNumber(Answer));
+ }
+
+ DebugPrintf(2, ".");
+ fflush(stdout);
+
+ block_CRC = 0;
+ 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 (Block = 0; Block < 4; Block++) // Each block 45 bytes
+ {
+ DebugPrintf(2, ".");
+ fflush(stdout);
+
+#if defined INTEGRATED_IN_WIN_APP
+ // inform the calling application about having written another chuck of data
+ AppWritten(45);
+#endif
+
+ // Uuencode one 45 byte block
+ tmpStringPos = 0;
+
+#if !defined COMPILE_FOR_LPC21
+ sendbuf[Line][tmpStringPos++] = (char)(' ' + 45); // Encode Length of block
+#else
+ tmpString[tmpStringPos++] = (char)(' ' + 45); // Encode Length of block
+#endif
+
+ for (BlockOffset = 0; BlockOffset < 45; BlockOffset++)
+ {
+ if (IspEnvironment->BinaryOffset < ReturnValueLpcRamStart(IspEnvironment))
+ { // Flash: use full memory
+ c = IspEnvironment->BinaryContent[Pos + Block * 45 + BlockOffset];
+ }
+ else
+ { // RAM: Skip first 0x200 bytes, these are used by the download program in LPC21xx
+ c = IspEnvironment->BinaryContent[Pos + Block * 45 + BlockOffset + 0x200];
+ }
+
+ block_CRC += c;
+
+ k = (k << 8) + (c & 255);
+
+ if ((BlockOffset % 3) == 2) // Collecting always 3 Bytes, then do processing in 4 Bytes
+ {
+#if !defined COMPILE_FOR_LPC21
+ sendbuf[Line][tmpStringPos++] = uuencode_table[(k >> 18) & 63];
+ sendbuf[Line][tmpStringPos++] = uuencode_table[(k >> 12) & 63];
+ sendbuf[Line][tmpStringPos++] = uuencode_table[(k >> 6) & 63];
+ sendbuf[Line][tmpStringPos++] = uuencode_table[ k & 63];
+#else
+ tmpString[tmpStringPos++] = uuencode_table[(k >> 18) & 63];
+ tmpString[tmpStringPos++] = uuencode_table[(k >> 12) & 63];
+ tmpString[tmpStringPos++] = uuencode_table[(k >> 6) & 63];
+ tmpString[tmpStringPos++] = uuencode_table[ k & 63];
+#endif
+ }
+ }
+
+
+#if !defined COMPILE_FOR_LPC21
+ sendbuf[Line][tmpStringPos++] = '\n';
+ sendbuf[Line][tmpStringPos++] = 0;
+
+ SendComPort(IspEnvironment, sendbuf[Line]);
+ // receive only for debug proposes
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,5000);
+#else
+ tmpString[tmpStringPos++] = '\n';
+ tmpString[tmpStringPos++] = 0;
+
+ SendComPort(IspEnvironment, tmpString);
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,5000);
+ if (strncmp(Answer, tmpString, tmpStringPos) != 0)
+ {
+ DebugPrintf(1, "Error on writing data (1)\n");
+ return (ERROR_WRITE_DATA);
+ }
+#endif
+
+ Line++;
+
+ DebugPrintf(3, "Line = %d\n", Line);
+
+ if (Line == 20)
+ {
+#if !defined COMPILE_FOR_LPC21
+ for (repeat = 0; repeat < 3; repeat++)
+ {
+
+ // printf("block_CRC = %ld\n", block_CRC);
+
+ sprintf(tmpString, "%ld\n", block_CRC);
+
+ SendComPort(IspEnvironment, tmpString);
+
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000);
+
+ sprintf(tmpString, "%ld\nOK\r\n", block_CRC);
+
+ if (strcmp(Answer, tmpString) != 0)
+ {
+ for (i = 0; i < Line; i++)
+ {
+ SendComPort(IspEnvironment, sendbuf[i]);
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,5000);
+ }
+ }
+ else
+ break;
+ }
+
+ if (repeat >= 3)
+ {
+ DebugPrintf(1, "Error on writing block_CRC (1)\n");
+ return (ERROR_WRITE_CRC);
+ }
+#else
+ // printf("block_CRC = %ld\n", block_CRC);
+ sprintf(tmpString, "%ld\r\n", block_CRC);
+ SendComPort(IspEnvironment, tmpString);
+
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000);
+
+ sprintf(tmpString, "%ld\r\nOK\r\n", block_CRC);
+ if (strcmp(Answer, tmpString) != 0)
+ {
+ DebugPrintf(1, "Error on writing block_CRC (2)\n");
+ return (ERROR_WRITE_CRC);
+ }
+#endif
+ Line = 0;
+ block_CRC = 0;
+ }
+ }
+ }
+
+ if (Line != 0)
+ {
+#if !defined COMPILE_FOR_LPC21
+ for (repeat = 0; repeat < 3; repeat++)
+ {
+ sprintf(tmpString, "%ld\n", block_CRC);
+
+ SendComPort(IspEnvironment, tmpString);
+
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000);
+
+ sprintf(tmpString, "%ld\nOK\r\n", block_CRC);
+
+ if (strcmp(Answer, tmpString) != 0)
+ {
+ for (i = 0; i < Line; i++)
+ {
+ SendComPort(IspEnvironment, sendbuf[i]);
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,5000);
+ }
+ }
+ else
+ break;
+ }
+
+ if (repeat >= 3)
+ {
+ DebugPrintf(1, "Error on writing block_CRC (3)\n");
+ return (ERROR_WRITE_CRC2);
+ }
+#else
+ sprintf(tmpString, "%ld\r\n", block_CRC);
+ SendComPort(IspEnvironment, tmpString);
+
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000);
+
+ sprintf(tmpString, "%ld\r\nOK\r\n", block_CRC);
+ if (strcmp(Answer, tmpString) != 0)
+ {
+ DebugPrintf(1, "Error on writing block_CRC (4)\n");
+ return (ERROR_WRITE_CRC2);
+ }
+#endif
+ }
+
+ if (IspEnvironment->BinaryOffset < ReturnValueLpcRamStart(IspEnvironment))
+ {
+ // Prepare command must be repeated before every write
+ sprintf(tmpString, "P %ld %ld\n", Sector, Sector);
+
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+ {
+ DebugPrintf(1, "Wrong answer on Prepare-Command (2) (Sector %ld)\n", Sector);
+ return (WRONG_ANSWER_PREP2 + GetAndReportErrorNumber(Answer));
+ }
+
+ // Round CopyLength up to one of the following values: 512, 1024,
+ // 4096, 8192; but do not exceed the maximum copy size (usually
+ // 8192, but chip-dependent)
+ if (CopyLength < 512)
+ {
+ CopyLength = 512;
+ }
+ else if (SectorLength < 1024)
+ {
+ CopyLength = 1024;
+ }
+ else if (SectorLength < 4096)
+ {
+ CopyLength = 4096;
+ }
+ else
+ {
+ CopyLength = 8192;
+ }
+ if (CopyLength > (unsigned)LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize)
+ {
+ CopyLength = LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize;
+ }
+
+ sprintf(tmpString, "C %ld %ld %ld\n", SectorStart + SectorOffset, ReturnValueLpcRamBase(IspEnvironment), CopyLength);
+
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+ {
+ DebugPrintf(1, "Wrong answer on Copy-Command\n");
+ return (WRONG_ANSWER_COPY + GetAndReportErrorNumber(Answer));
+ }
+
+ if (IspEnvironment->Verify)
+ {
+
+ //Avoid compare first 64 bytes.
+ //Because first 64 bytes are re-mapped to flash boot sector,
+ //and the compare result may not be correct.
+ if (SectorStart + SectorOffset<64)
+ {
+ sprintf(tmpString, "M %d %ld %ld\n", 64, ReturnValueLpcRamBase(IspEnvironment) + (64 - SectorStart - SectorOffset), CopyLength-(64 - SectorStart - SectorOffset));
+ }
+ else
+ {
+ sprintf(tmpString, "M %ld %ld %ld\n", SectorStart + SectorOffset, ReturnValueLpcRamBase(IspEnvironment), CopyLength);
+ }
+
+ if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+ {
+ DebugPrintf(1, "Wrong answer on Compare-Command\n");
+ return (WRONG_ANSWER_COPY + GetAndReportErrorNumber(Answer));
+ }
+ }
+ }
+ }
+
+ DebugPrintf(2, "\n");
+ fflush(stdout);
+
+ if ((SectorStart + SectorLength) >= IspEnvironment->BinaryLength && Sector!=0)
+ {
+ Sector = 0;
+ SectorStart = 0;
+ }
+ else if (Sector == 0) {
+ break;
+ }
+ else {
+ SectorStart += LPCtypes[IspEnvironment->DetectedDevice].SectorTable[Sector];
+ Sector++;
+ }
+ }
+
+ tDoneUpload = time(NULL);
+ if (IspEnvironment->Verify)
+ DebugPrintf(2, "Download Finished and Verified correct... taking %d seconds\n", tDoneUpload - tStartUpload);
+ else
+ DebugPrintf(2, "Download Finished... taking %d seconds\n", tDoneUpload - tStartUpload);
+
+ if(IspEnvironment->DoNotStart == 0)
+ {
+ DebugPrintf(2, "Now launching the brand new code\n");
+ fflush(stdout);
+
+ if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX)
+ {
+ sprintf(tmpString, "G %ld A\n", IspEnvironment->StartAddress);
+ }
+ else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX ||
+ LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX ||
+ LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX)
+ {
+ sprintf(tmpString, "G %ld T\n", IspEnvironment->StartAddress & ~1);
+ }
+ else
+ {
+ printf("Internal Error %s %d\n", __FILE__, __LINE__);
+ exit(1);
+ }
+
+ SendComPort(IspEnvironment, tmpString); //goto 0 : run this fresh new downloaded code code
+ if (IspEnvironment->BinaryOffset < ReturnValueLpcRamStart(IspEnvironment))
+ { // Skip response on G command - show response on Terminal instead
+ ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2, 5000);
+ /* the reply string is frequently terminated with a -1 (EOF) because the
+ * connection gets broken; zero-terminate the string ourselves
+ */
+ while (realsize > 0 && ((signed char) Answer[(int)realsize - 1]) < 0)
+ realsize--;
+ Answer[(int)realsize] = '\0';
+ /* Better to check only the first 9 chars instead of complete receive buffer,
+ * because the answer can contain the output by the started programm
+ */
+ if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX)
+ {
+ sprintf(ExpectedAnswer, "G %ld A\n0", IspEnvironment->StartAddress);
+ }
+ else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX ||
+ LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX ||
+ LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX)
+ {
+ sprintf(ExpectedAnswer, "G %ld T\n0", IspEnvironment->StartAddress & ~1);
+ }
+ else
+ {
+ printf("Internal Error %s %d\n", __FILE__, __LINE__);
+ exit(1);
+ }
+
+ if (realsize == 0 || strncmp((const char *)Answer, /*cmdstr*/ExpectedAnswer, strlen(/*cmdstr*/ExpectedAnswer)) != 0)
+ {
+ DebugPrintf(2, "Failed to run the new downloaded code: ");
+ return (FAILED_RUN + GetAndReportErrorNumber(Answer));
+ }
+ }
+
+ fflush(stdout);
+ }
+ return (0);
+}
+#endif // LPC_SUPPORT
+
+
+unsigned long ReturnValueLpcRamStart(ISP_ENVIRONMENT *IspEnvironment)
+{
+ if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX)
+ {
+ return LPC_RAMSTART_LPC2XXX;
+ }
+ else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX)
+ {
+ return LPC_RAMSTART_LPC17XX;
+ }
+ else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX)
+ {
+ return LPC_RAMSTART_LPC13XX;
+ }
+ else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX)
+ {
+ return LPC_RAMSTART_LPC11XX;
+ }
+ printf("Error in ReturnValueLpcRamStart (%d)\n", LPCtypes[IspEnvironment->DetectedDevice].ChipVariant);
+ exit(1);
+}
+
+
+unsigned long ReturnValueLpcRamBase(ISP_ENVIRONMENT *IspEnvironment)
+{
+ if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX)
+ {
+ return LPC_RAMBASE_LPC2XXX;
+ }
+ else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX)
+ {
+ return LPC_RAMBASE_LPC17XX;
+ }
+ else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX)
+ {
+ return LPC_RAMBASE_LPC13XX;
+ }
+ else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX)
+ {
+ return LPC_RAMBASE_LPC11XX;
+ }
+ printf("Error in ReturnValueLpcRamBase (%d)\n", LPCtypes[IspEnvironment->DetectedDevice].ChipVariant);
+ exit(1);
+}
diff --git a/lpcprog.dsp b/lpcprog.dsp new file mode 100644 index 0000000..8590d66 --- /dev/null +++ b/lpcprog.dsp @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Project File - Name="lpcprog" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=lpcprog - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "lpcprog.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "lpcprog.mak" CFG="lpcprog - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "lpcprog - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "lpcprog - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "lpcprog - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "lpcprog - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "lpcprog - Win32 Release"
+# Name "lpcprog - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\adprog.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lpc21isp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lpcprog.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lpcterm.c
+# End Source File
+# End Target
+# End Project
diff --git a/lpcprog.dsw b/lpcprog.dsw new file mode 100644 index 0000000..50aa31a --- /dev/null +++ b/lpcprog.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "lpcprog"=.\lpcprog.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/lpcprog.h b/lpcprog.h new file mode 100644 index 0000000..eaa2588 --- /dev/null +++ b/lpcprog.h @@ -0,0 +1,127 @@ +/******************************************************************************
+
+Project: Portable command line ISP for NXP LPC1000 / LPC2000 family
+ and Analog Devices ADUC70xx
+
+Filename: lpcprog.h
+
+Compiler: Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
+ GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author: Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright: (c) Martin Maurer 2003-2011, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+ This file is part of lpc21isp.
+
+ lpc21isp is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ any later version.
+
+ lpc21isp is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ and GNU General Public License along with lpc21isp.
+ If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* LPC_RAMSTART, LPC_RAMBASE
+*
+* Used in NxpDownload() to decide whether to Flash code or just place in in RAM
+* (works for .hex files only)
+*
+* LPC_RAMSTART - the Physical start address of the SRAM
+* LPC_RAMBASE - the base address where downloading starts.
+* Note that any code in the .hex file that resides in 0x4000,0000 ~ 0x4000,0200
+* will _not_ be written to the LPCs SRAM.
+* This is due to the fact that 0x4000,0040 - 0x4000,0200 is used by the bootrom.
+* Any interrupt vectors must be copied to 0x4000,0000 and remapped to 0x0000,0000
+* by the startup code.
+*/
+#define LPC_RAMSTART_LPC2XXX 0x40000000L
+#define LPC_RAMBASE_LPC2XXX 0x40000200L
+
+#define LPC_RAMSTART_LPC17XX 0x10000000L
+#define LPC_RAMBASE_LPC17XX 0x10000200L
+
+#define LPC_RAMSTART_LPC13XX 0x10000000L
+#define LPC_RAMBASE_LPC13XX 0x10000300L
+
+#define LPC_RAMSTART_LPC11XX 0x10000000L
+#define LPC_RAMBASE_LPC11XX 0x10000300L
+
+/* Return values used by NxpDownload(): reserving all values from 0x1000 to 0x1FFF */
+
+#define NO_ANSWER_WDT 0x1000
+#define NO_ANSWER_QM 0x1001
+#define NO_ANSWER_SYNC 0x1002
+#define NO_ANSWER_OSC 0x1003
+#define NO_ANSWER_RBV 0x1004
+#define NO_ANSWER_RPID 0x1005
+#define ERROR_WRITE_DATA 0x1006
+#define ERROR_WRITE_CRC 0x1007
+#define ERROR_WRITE_CRC2 0x1008
+#define PROGRAM_TOO_LARGE 0x1009
+
+#define USER_ABORT_SYNC 0x100A /* User aborted synchronisation process */
+
+#define UNLOCK_ERROR 0x1100 /* return value is 0x1100 + NXP ISP returned value (0 to 255) */
+#define WRONG_ANSWER_PREP 0x1200 /* return value is 0x1200 + NXP ISP returned value (0 to 255) */
+#define WRONG_ANSWER_ERAS 0x1300 /* return value is 0x1300 + NXP ISP returned value (0 to 255) */
+#define WRONG_ANSWER_WRIT 0x1400 /* return value is 0x1400 + NXP ISP returned value (0 to 255) */
+#define WRONG_ANSWER_PREP2 0x1500 /* return value is 0x1500 + NXP ISP returned value (0 to 255) */
+#define WRONG_ANSWER_COPY 0x1600 /* return value is 0x1600 + NXP ISP returned value (0 to 255) */
+#define FAILED_RUN 0x1700 /* return value is 0x1700 + NXP ISP returned value (0 to 255) */
+
+#if defined COMPILE_FOR_LPC21
+#ifndef WIN32
+#define LPC_BSL_PIN 13
+#define LPC_RESET_PIN 47
+#define LPC_RESET(in) NAsetGPIOpin(LPC_RESET_PIN, (in))
+#define LPC_BSL(in) NAsetGPIOpin(LPC_BSL_PIN, (in))
+#endif // WIN32
+#endif // COMPILE_FOR_LPC21
+
+
+/* LPC_FLASHMASK
+*
+* LPC_FLASHMASK - bitmask to define the maximum size of the Filesize to download.
+* LoadFile() will check any new segment address record (03) or extended linear
+* address record (04) to see if the addressed 64 kByte data block still falls
+* in the max. flash size.
+* LoadFile() will not load any files that are larger than this size.
+*/
+#define LPC_FLASHMASK 0xFFC00000 /* 22 bits = 4 MB */
+
+typedef enum
+ {
+ CHIP_VARIANT_NONE,
+ CHIP_VARIANT_LPC2XXX,
+ CHIP_VARIANT_LPC17XX,
+ CHIP_VARIANT_LPC13XX,
+ CHIP_VARIANT_LPC11XX
+ } CHIP_VARIANT;
+
+typedef struct
+{
+ const unsigned long id;
+ const char *Product;
+ const unsigned int FlashSize; /* in kiB, for informational purposes only */
+ const unsigned int RAMSize; /* in kiB, for informational purposes only */
+ unsigned int FlashSectors; /* total number of sectors */
+ unsigned int MaxCopySize; /* maximum size that can be copied to Flash in a single command */
+ const unsigned int *SectorTable; /* pointer to a sector table with constant the sector sizes */
+ const CHIP_VARIANT ChipVariant;
+} LPC_DEVICE_TYPE;
+
+int NxpDownload(ISP_ENVIRONMENT *IspEnvironment);
+
+unsigned long ReturnValueLpcRamStart(ISP_ENVIRONMENT *IspEnvironment);
+
+unsigned long ReturnValueLpcRamBase(ISP_ENVIRONMENT *IspEnvironment);
+
diff --git a/lpcterm.c b/lpcterm.c new file mode 100644 index 0000000..e176a6d --- /dev/null +++ b/lpcterm.c @@ -0,0 +1,138 @@ +/******************************************************************************
+
+Project: Portable command line ISP for NXP LPC1000 / LPC2000 family
+ and Analog Devices ADUC70xx
+
+Filename: lpcterm.c
+
+Compiler: Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
+ GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author: Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright: (c) Martin Maurer 2003-2011, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+ This file is part of lpc21isp.
+
+ lpc21isp is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ any later version.
+
+ lpc21isp is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ and GNU General Public License along with lpc21isp.
+ If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#if defined(_WIN32)
+#if !defined __BORLANDC__
+#include "StdAfx.h"
+#endif
+#endif // defined(_WIN32)
+#include "lpc21isp.h"
+#include "lpcterm.h"
+
+#ifdef TERMINAL_SUPPORT
+/***************************** Terminal *********************************/
+/** Acts as a simple dumb terminal. Press 'ESC' to exit.
+*/
+BOOL CheckTerminalParameters(ISP_ENVIRONMENT *IspEnvironment, char* pstr)
+{
+ if (stricmp(pstr, "-localecho") == 0)
+ {
+ IspEnvironment->LocalEcho = 1;
+ DebugPrintf(3, "Local echo in terminal mode.\n");
+ return TRUE;
+ }
+
+ if (stricmp(pstr, "-term") == 0)
+ {
+ IspEnvironment->TerminalAfterUpload = 1;
+ DebugPrintf(3, "Invoke terminal after upload.\n");
+ return TRUE;
+ }
+
+ if (stricmp(pstr, "-termonly") == 0)
+ {
+ IspEnvironment->TerminalOnly = 1;
+ IspEnvironment->ProgramChip = 0;
+ DebugPrintf(3, "Only provide terminal.\n");
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void Terminal(ISP_ENVIRONMENT *IspEnvironment)
+{
+ if (IspEnvironment->TerminalAfterUpload || IspEnvironment->TerminalOnly)
+ {
+ int ch = 0;
+ char buffer[128];
+ int fdlogfile = -1;
+ unsigned long realsize;
+
+ // When logging is switched on, output terminal output to lpc21isp.log
+ if (IspEnvironment->LogFile)
+ {
+ fdlogfile = open("lpc21isp.log", O_RDWR | O_BINARY | O_CREAT | O_TRUNC, 0777);
+ }
+
+ PrepareKeyboardTtySettings();
+
+ DebugPrintf(1, "Terminal started (press Escape to abort)\n\n");
+ fflush(stdout);
+
+ do
+ {
+ ReceiveComPort(IspEnvironment, buffer, sizeof(buffer) - 1, &realsize, 0,200); // Check for received characters
+
+ if (realsize)
+ {
+ write(1, buffer, realsize);
+ fflush(stdout);
+ if (IspEnvironment->LogFile) // When logging is turned on, then copy output to logfile
+ {
+ write(fdlogfile, buffer, realsize);
+ }
+ }
+
+ // check for keypress, and write any out the port.
+ if (kbhit())
+ {
+ ch = getch();
+ if (ch == 0x1b)
+ {
+ break;
+ }
+ buffer[0] = (unsigned char)ch;
+ buffer[1] = 0;
+
+ if (IspEnvironment->LocalEcho)
+ {
+ write(1, buffer, 1);
+ }
+
+ SendComPort(IspEnvironment, buffer);
+ }
+ }
+ while (ch != 0x1b);
+
+ DebugPrintf(1, "\n\nTerminal stopped\n\n");
+ fflush(stdout);
+
+ ResetKeyboardTtySettings();
+
+ if (IspEnvironment->LogFile)
+ {
+ close(fdlogfile);
+ }
+ }
+}
+#endif
diff --git a/lpcterm.h b/lpcterm.h new file mode 100644 index 0000000..3fda95d --- /dev/null +++ b/lpcterm.h @@ -0,0 +1,43 @@ +/******************************************************************************
+
+Project: Portable command line ISP for NXP LPC1000 / LPC2000 family
+ and Analog Devices ADUC70xx
+
+Filename: lpcterm.h
+
+Compiler: Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
+ GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author: Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright: (c) Martin Maurer 2003-2011, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+ This file is part of lpc21isp.
+
+ lpc21isp is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ any later version.
+
+ lpc21isp is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ and GNU General Public License along with lpc21isp.
+ If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+typedef int BOOL;
+
+void Terminal(ISP_ENVIRONMENT *IspEnvironment);
+BOOL CheckTerminalParameters(ISP_ENVIRONMENT *IspEnvironment, char* pstr);
@@ -0,0 +1,817 @@ +Turn on debug, level: 5. +lpc21isp version 1.83 +Attempt to read File /home/brad/Dropbox/Dev/lpc1114_blink_led-1.2.1-120108/out/lpc1114_blink_led.hex +File /home/brad/Dropbox/Dev/lpc1114_blink_led-1.2.1-120108/out/lpc1114_blink_led.hex: + loaded... +Converting file /home/brad/Dropbox/Dev/lpc1114_blink_led-1.2.1-120108/out/lpc1114_blink_led.hex to binary format... +RecordLength = 10 +RecordAddress = 0000 +RealAddress = 00000000 +RecordType = 00 +Image size now: 16 +RecordLength = 10 +RecordAddress = 0010 +RealAddress = 00000010 +RecordType = 00 +Image size now: 32 +RecordLength = 10 +RecordAddress = 0020 +RealAddress = 00000020 +RecordType = 00 +Image size now: 48 +RecordLength = 10 +RecordAddress = 0030 +RealAddress = 00000030 +RecordType = 00 +Image size now: 64 +RecordLength = 10 +RecordAddress = 0040 +RealAddress = 00000040 +RecordType = 00 +Image size now: 80 +RecordLength = 10 +RecordAddress = 0050 +RealAddress = 00000050 +RecordType = 00 +Image size now: 96 +RecordLength = 10 +RecordAddress = 0060 +RealAddress = 00000060 +RecordType = 00 +Image size now: 112 +RecordLength = 10 +RecordAddress = 0070 +RealAddress = 00000070 +RecordType = 00 +Image size now: 128 +RecordLength = 10 +RecordAddress = 0080 +RealAddress = 00000080 +RecordType = 00 +Image size now: 144 +RecordLength = 10 +RecordAddress = 0090 +RealAddress = 00000090 +RecordType = 00 +Image size now: 160 +RecordLength = 10 +RecordAddress = 00A0 +RealAddress = 000000A0 +RecordType = 00 +Image size now: 176 +RecordLength = 10 +RecordAddress = 00B0 +RealAddress = 000000B0 +RecordType = 00 +Image size now: 192 +RecordLength = 10 +RecordAddress = 00C0 +RealAddress = 000000C0 +RecordType = 00 +Image size now: 208 +RecordLength = 10 +RecordAddress = 00D0 +RealAddress = 000000D0 +RecordType = 00 +Image size now: 224 +RecordLength = 10 +RecordAddress = 00E0 +RealAddress = 000000E0 +RecordType = 00 +Image size now: 240 +RecordLength = 10 +RecordAddress = 00F0 +RealAddress = 000000F0 +RecordType = 00 +Image size now: 256 +RecordLength = 10 +RecordAddress = 0100 +RealAddress = 00000100 +RecordType = 00 +Image size now: 272 +RecordLength = 10 +RecordAddress = 0110 +RealAddress = 00000110 +RecordType = 00 +Image size now: 288 +RecordLength = 10 +RecordAddress = 0120 +RealAddress = 00000120 +RecordType = 00 +Image size now: 304 +RecordLength = 10 +RecordAddress = 0130 +RealAddress = 00000130 +RecordType = 00 +Image size now: 320 +RecordLength = 10 +RecordAddress = 0140 +RealAddress = 00000140 +RecordType = 00 +Image size now: 336 +RecordLength = 10 +RecordAddress = 0150 +RealAddress = 00000150 +RecordType = 00 +Image size now: 352 +RecordLength = 10 +RecordAddress = 0160 +RealAddress = 00000160 +RecordType = 00 +Image size now: 368 +RecordLength = 10 +RecordAddress = 0170 +RealAddress = 00000170 +RecordType = 00 +Image size now: 384 +RecordLength = 10 +RecordAddress = 0180 +RealAddress = 00000180 +RecordType = 00 +Image size now: 400 +RecordLength = 10 +RecordAddress = 0190 +RealAddress = 00000190 +RecordType = 00 +Image size now: 416 +RecordLength = 10 +RecordAddress = 01A0 +RealAddress = 000001A0 +RecordType = 00 +Image size now: 432 +RecordLength = 10 +RecordAddress = 01B0 +RealAddress = 000001B0 +RecordType = 00 +Image size now: 448 +RecordLength = 10 +RecordAddress = 01C0 +RealAddress = 000001C0 +RecordType = 00 +Image size now: 464 +RecordLength = 10 +RecordAddress = 01D0 +RealAddress = 000001D0 +RecordType = 00 +Image size now: 480 +RecordLength = 10 +RecordAddress = 01E0 +RealAddress = 000001E0 +RecordType = 00 +Image size now: 496 +RecordLength = 10 +RecordAddress = 01F0 +RealAddress = 000001F0 +RecordType = 00 +Image size now: 512 +RecordLength = 10 +RecordAddress = 0200 +RealAddress = 00000200 +RecordType = 00 +Image size now: 528 +RecordLength = 10 +RecordAddress = 0210 +RealAddress = 00000210 +RecordType = 00 +Image size now: 544 +RecordLength = 10 +RecordAddress = 0220 +RealAddress = 00000220 +RecordType = 00 +Image size now: 560 +RecordLength = 10 +RecordAddress = 0230 +RealAddress = 00000230 +RecordType = 00 +Image size now: 576 +RecordLength = 10 +RecordAddress = 0240 +RealAddress = 00000240 +RecordType = 00 +Image size now: 592 +RecordLength = 10 +RecordAddress = 0250 +RealAddress = 00000250 +RecordType = 00 +Image size now: 608 +RecordLength = 10 +RecordAddress = 0260 +RealAddress = 00000260 +RecordType = 00 +Image size now: 624 +RecordLength = 10 +RecordAddress = 0270 +RealAddress = 00000270 +RecordType = 00 +Image size now: 640 +RecordLength = 10 +RecordAddress = 0280 +RealAddress = 00000280 +RecordType = 00 +Image size now: 656 +RecordLength = 10 +RecordAddress = 0290 +RealAddress = 00000290 +RecordType = 00 +Image size now: 672 +RecordLength = 10 +RecordAddress = 02A0 +RealAddress = 000002A0 +RecordType = 00 +Image size now: 688 +RecordLength = 10 +RecordAddress = 02B0 +RealAddress = 000002B0 +RecordType = 00 +Image size now: 704 +RecordLength = 10 +RecordAddress = 02C0 +RealAddress = 000002C0 +RecordType = 00 +Image size now: 720 +RecordLength = 10 +RecordAddress = 02D0 +RealAddress = 000002D0 +RecordType = 00 +Image size now: 736 +RecordLength = 10 +RecordAddress = 02E0 +RealAddress = 000002E0 +RecordType = 00 +Image size now: 752 +RecordLength = 10 +RecordAddress = 02F0 +RealAddress = 000002F0 +RecordType = 00 +Image size now: 768 +RecordLength = 10 +RecordAddress = 0300 +RealAddress = 00000300 +RecordType = 00 +Image size now: 784 +RecordLength = 10 +RecordAddress = 0310 +RealAddress = 00000310 +RecordType = 00 +Image size now: 800 +RecordLength = 10 +RecordAddress = 0320 +RealAddress = 00000320 +RecordType = 00 +Image size now: 816 +RecordLength = 10 +RecordAddress = 0330 +RealAddress = 00000330 +RecordType = 00 +Image size now: 832 +RecordLength = 10 +RecordAddress = 0340 +RealAddress = 00000340 +RecordType = 00 +Image size now: 848 +RecordLength = 10 +RecordAddress = 0350 +RealAddress = 00000350 +RecordType = 00 +Image size now: 864 +RecordLength = 10 +RecordAddress = 0360 +RealAddress = 00000360 +RecordType = 00 +Image size now: 880 +RecordLength = 10 +RecordAddress = 0370 +RealAddress = 00000370 +RecordType = 00 +Image size now: 896 +RecordLength = 10 +RecordAddress = 0380 +RealAddress = 00000380 +RecordType = 00 +Image size now: 912 +RecordLength = 10 +RecordAddress = 0390 +RealAddress = 00000390 +RecordType = 00 +Image size now: 928 +RecordLength = 0C +RecordAddress = 03A0 +RealAddress = 000003A0 +RecordType = 00 +Image size now: 940 +RecordLength = 04 +RecordAddress = 0000 +RealAddress = 00000000 +RecordType = 03 +Start Address = 0x000000C1 +RecordLength = 00 +RecordAddress = 0000 +RealAddress = 00000000 +RecordType = 01 + converted to binary format... + image size : 940 +Image size : 940 +Dumping image file. +COM-Port /dev/ttyUSB0 opened... +Synchronizing (ESC to abort).Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=1): '1' +Read(Length=1): '(0D)' +Answer(Length=3): '?1(0D)' +StrippedAnswer(Length=2): ''1(0D)' +.Sending '?' +Read(Length=1): '(0A)' +Answer(Length=1): '(0A)' +StrippedAnswer(Length=1): ''(0A)' +.Sending '?' +Read(Length=1): '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=2): '??' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' +.Sending '?' +Read(Length=1): '?' +Read(Length=0): '' +Answer(Length=1): '?' +StrippedAnswer(Length=0): ''' + no answer on '?' |
