Changeset 566 for trunk/tools/lpc21isp

Show
Ignore:
Timestamp:
11/23/09 01:30:28 (4 months ago)
Author:
goodea
Message:

Update lpc21isp

Location:
trunk/tools/lpc21isp
Files:
13 added
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/tools/lpc21isp/Makefile

    r411 r566  
    1 CC=gcc 
    2 OBJS=lpc21isp.o 
    3 CFLAGS=-O2 -Wall -g 
    4 INSTALLDIR=/usr/local/bin/ 
     1all:      lpc21isp 
    52 
    6 all: lpc21isp 
     3GLOBAL_DEP  = adprog.h lpc21isp.h lpcprog.h lpcterm.h 
     4CC = gcc 
    75 
    8 .c.o: 
    9         $(CC) $(CFLAGS) -c $< -o $@ 
     6ifneq ($(findstring(freebsd, $(OSTYPE))),) 
     7CFLAGS+=-D__FREEBSD__ 
     8endif 
    109 
    11 lpc21isp: $(OBJS) 
    12         $(CC) -o $@ $(OBJS) 
     10adprog.o: adprog.c $(GLOBAL_DEP) 
     11        $(CC) $(CDEBUG) $(CFLAGS) -c -o adprog.o adprog.c 
     12 
     13lpcprog.o: lpcprog.c $(GLOBAL_DEP) 
     14        $(CC) $(CDEBUG) $(CFLAGS) -c -o lpcprog.o lpcprog.c 
     15 
     16lpcterm.o: lpcterm.c $(GLOBAL_DEP) 
     17        $(CC) $(CDEBUG) $(CFLAGS) -c -o lpcterm.o lpcterm.c 
     18 
     19lpc21isp: lpc21isp.c adprog.o lpcprog.o lpcterm.o $(GLOBAL_DEP) 
     20        $(CC) $(CDEBUG) $(CFLAGS) -o lpc21isp lpc21isp.c adprog.o lpcprog.o lpcterm.o 
    1321 
    1422clean: 
    15         rm -f $(OBJS) lpc21isp 
    16  
    17 install: 
    18         install -m 755 lpc21isp /usr/local/bin/lpc21isp 
    19  
    20 .PHONY: clean 
     23        $(RM) adprog.o lpcprog.o lpcterm.o lpc21isp 
  • trunk/tools/lpc21isp/lpc21isp.c

    r306 r566  
    66Filename:          lpc21isp.c 
    77 
    8 Compiler:          Microsoft VC 6/7, GCC Cygwin, GCC Linux 
    9  
    10 Autor:             Martin Maurer (Martin.Maurer@clibb.de) 
    11  
    12 Copyright:         (c) Martin Maurer 2003-2007, All rights reserved 
     8Compiler:          Microsoft VC 6/7, GCC Cygwin, GCC Linux, GCC ARM ELF 
     9 
     10Author:            Martin Maurer (Martin.Maurer@clibb.de) 
     11 
     12Copyright:         (c) Martin Maurer 2003-2008, All rights reserved 
    1313Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com 
    1414 
    15 Version:           1.39 
    16  
     15    This file is part of lpc21isp. 
     16 
     17    lpc21isp is free software: you can redistribute it and/or modify 
     18    it under the terms of the GNU Lesser General Public License as published by 
     19    the Free Software Foundation, either version 3 of the License, or 
     20    any later version. 
     21 
     22    lpc21isp is distributed in the hope that it will be useful, 
     23    but WITHOUT ANY WARRANTY; without even the implied warranty of 
     24    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     25    GNU Lesser General Public License for more details. 
     26 
     27    You should have received a copy of the GNU Lesser General Public License 
     28    and GNU General Public License along with lpc21isp. 
     29    If not, see <http://www.gnu.org/licenses/>. 
     30*/ 
     31 
     32#if defined(_WIN32) 
     33#if !defined __BORLANDC__ 
     34#include "StdAfx.h"        // Precompiled Header for WIN32 
     35#endif 
     36#endif // defined(_WIN32) 
     37#include "lpc21isp.h"   // if using propriatory serial port communication (customize attached lpc21isp.h) 
     38#include "adprog.h" 
     39#include "lpcprog.h" 
     40#include "lpcterm.h" 
     41 
     42/* 
    1743Change-History: 
    1844 
    19  1.00  2004-01-08  Initial Version, tested for MSVC6/7 and GCC under Cygwin 
    20  1.01  2004-01-10  Porting to Linux (at least compiling must work) 
    21  1.02  2004-01-10  Implemented conversion intel hex format -> binary 
    22  1.03  2004-01-25  Preparation to upload to public website 
    23  1.04  2004-02-12  Merged in bugfixes by Soeren Gust 
    24  1.05  2004-03-14  Implement printing of error codes as text / strings 
    25  1.06  2004-03-09  Merged in bugfixes by Charles Manning: 
    26                    The '?' sychronisation does not reliably respond to the first '?'. 
    27                    I added some retries. 
    28                    The LPC2106 sometimes responds to the '?' by echoing them back. 
    29                    This sometimes causes an attempt to match "?Synchonized". 
    30                    Added code to strip off any leading '?'s. 
    31                    Timeouts were too long. 
    32                    Change from RTS/CTS to no flow control. 
    33                    Done because many/most people will use only 3-wire comms. 
    34                    Added some progress tracing. 
    35  1.07  2004-03-14  Implement handling of control lines for easier booting 
    36  1.08  2004-04-01  Bugfix for upload problem 
    37  1.09  2004-04-03  Redesign of upload routine 
    38                    Now always 180 byte blocks are uploaded, to prevent 
    39                    small junks in uuencoding 
    40  1.10  2004-04-03  Clear buffers before sending commands to LPC21xx, 
    41                    this prevents synchronizing errors when previously loaded 
    42                    program does a lot of output, so FIFO of PC runs full 
    43  1.11  2004-04-03  Small optimization for controlling reset line 
    44                    otherwise termonly starts LPC twice, free PC buffers 
    45  1.12  2004-04-04  Add switch to enable logging terminal output to lpc21isp.log 
    46  1.13  2004-05-19  Merged in improvement by Charles Manning: 
    47                    Instead of exiting the wrong hex file size is corrected 
    48  1.14  2004-07-07  Merged in improvement by Alex Holden: 
    49                    Remove little/big endian dependancy 
    50  1.15  2004-09-27  Temporary improvement by Cyril Holweck: 
    51                    Removed test (data echoed = data transmited) on the main 
    52                    data transfert, since this was the biggest failure 
    53                    reason and is covered by checksome anyway. 
    54                    Added COMPILE_FOR_LPC21, to have target dump it's own 
    55                    memory to stdout. 
    56  1.16  2004-10-09  Merged in bugfix / improvement by Sinelnikov Evgeny 
    57                    I found out that Linux and Windows serial port initialization 
    58                    are different with pinouts states. My board don't get 
    59                    reset signal at first cycle of DTR pinout moving. 
    60                    And I add this moving to initalization cycle. 
    61  1.17  2004-10-21  Changes by Cyril Holweck 
    62                    Divide main, take out the real programming function, that can 
    63                    also be used by a target to copy its own code to another. 
    64  1.18  2004-10-26  Changes by Cyril Holweck 
    65                    Added a "G 0 A\r\n" at end of programming to run code. 
    66  1.19  2004-11-03  Changes by Robert Adsett 
    67                    Add support for Analog Devices. 
    68                    Separate file load from programming. 
    69                    Change from a debug on/off flag to debug level 
    70                    Remove if(debug) tests and replace with DebugPrintf 
    71                    statements. 
    72                    Change serial I/O and timing so that the system 
    73                    dependancies are isolated to a few portability functions. 
    74                    Add support for binary serial I/O. 
    75                    Add doxygen support. 
    76  1.20  2004-11-07  Preparation for multiport booting (factory support) 
    77  1.21  2004-11-08  Bugfix from Robert Adsett 
    78                    BinaryLength was not initialized 
    79  1.22  2004-11-08  Changes from Cyril Holweck / Evgeny Sinelnikov 
    80                    Forgotten IspEnvironment-> and bugfixes if COMPILE_FOR_LINUX 
    81                    If COMPILE_FOR_LPC21, PhilipsDownload() 'acts as' main(): 
    82                    - it should not be static and should return int. 
    83                    - no sub-function can use exit() but only return() 
    84                    Use 'char' instead of 'byte' ;) 
    85  1.23  2005-01-16  Build in automatic detection of LPC chiptype 
    86                    (needed for 256 KByte support) 
    87  1.24B 2005-06-02  Changes by Thiadmer Riemersma: completed support for other 
    88                    chip types (LPC213x series and others). 
    89  1.24C 2005-06-11  Changes by Thiadmer Riemersma: added the device ID codes for 
    90                    chip types LPC2131 and LPC2132. 
    91  1.25  2005-06-19  Martin Maurer: Setup more parameters in DCB, 
    92                    otherwise wrong code is downloaded (only Windows and Cygwin) 
    93                    when a previous program has changed these parameters 
    94                    Check exact string of "G 0 A\r\n0\r\n" instead of whole received buffer, 
    95                    to prevent checking of already received by program start 
    96                    (error on running program, but reports CMD_SUCCESS) 
    97                    Add ifdefs for all baudrates (needed only for high baudrate, 
    98                    which seem to be not available on Macs...) 
    99  1.26  2005-06-26  Martin Maurer: 
    100                    Correct check again: "G 0 A\r\n0\r\n" is cutted, because of reboot 
    101                    (error on running program, but reports CMD_SUCCESS) 
    102  1.27  2005-06-29  Martin Maurer: 
    103                    Add LPC chip ID's (thanks to Robert from Philips) for 
    104                    missing LPC213x and upcoming new LPC214x chips 
    105                    (currently untested, because i don't have access to these chips, 
    106                     please give me feedback !) 
    107  1.28  2005-07-27  Anders Rosvall / Embedded Artists AB: 
    108                    Changed the reset timeout to 500 ms when entering the bootloader. 
    109                    Some external reset controllers have quite long timeout periods, 
    110                    so extening the timeout delay would be a good thing. 
    111  1.29  2005-09-14  Rob Jansen: 
    112                    Added functionality to download to RAM and run from there. 
    113                    In LoadFile() added record types 04 (Extended Linear Address Record) 
    114                    and 05 (Start Linear Address Record), added address offset 
    115                    (IspEnvironment->BinaryOffset) and start address (...->StartAddress). 
    116                    Changed PhilipsDownload to skip all Flash prepare/erase/copy commands. 
    117                                    Note: Tested with VC7 only 
    118 1.30   2005-10-04  Rob Jansen: 
    119                    - forgot to change the version string in 1.29 
    120                                    - Wrong text in LoadFile corrected (printed text mentions record type 05, 
    121                                      this should be 04 
    122                                    - Changed LoadFile to accept multiple record types 04 
    123                                    - Changed LoadFile to check on memory size, will not load more than x MB 
    124                                      if linear extended address records are used 
    125 1.31   2005-11-13  Martin Maurer: Thanks to Frank Gutmann 
    126                    Updated number of sectors in device table 
    127                                    for LPC2194, LPC2292 and LPC2294 
    128 1.32   2005-12-02  Martin Maurer: Corrected missing control of RTS/DTR 
    129                    in case user selected -termonly and -control 
    130                    Small correction (typo in debug) 
    131 1.33   2006-10-01  Jean-Marc Koller: 
    132                    Added support for MacOS X (difference on how to set termios baudrate). 
     451.00  2004-01-08  Initial Version, tested for MSVC6/7 and GCC under Cygwin 
     461.01  2004-01-10  Porting to Linux (at least compiling must work) 
     471.02  2004-01-10  Implemented conversion intel hex format -> binary 
     481.03  2004-01-25  Preparation to upload to public website 
     491.04  2004-02-12  Merged in bugfixes by Soeren Gust 
     501.05  2004-03-14  Implement printing of error codes as text / strings 
     511.06  2004-03-09  Merged in bugfixes by Charles Manning: 
     52                  The '?' sychronisation does not reliably respond to the first '?'. 
     53                  I added some retries. 
     54                  The LPC2106 sometimes responds to the '?' by echoing them back. 
     55                  This sometimes causes an attempt to match "?Synchonized". 
     56                  Added code to strip off any leading '?'s. 
     57                  Timeouts were too long. 
     58                  Change from RTS/CTS to no flow control. 
     59                  Done because many/most people will use only 3-wire comms. 
     60                  Added some progress tracing. 
     611.07  2004-03-14  Implement handling of control lines for easier booting 
     621.08  2004-04-01  Bugfix for upload problem 
     631.09  2004-04-03  Redesign of upload routine 
     64                  Now always 180 byte blocks are uploaded, to prevent 
     65                  small junks in uuencoding 
     661.10  2004-04-03  Clear buffers before sending commands to LPC21xx, 
     67                  this prevents synchronizing errors when previously loaded 
     68                  program does a lot of output, so FIFO of PC runs full 
     691.11  2004-04-03  Small optimization for controlling reset line 
     70                  otherwise termonly starts LPC twice, free PC buffers 
     711.12  2004-04-04  Add switch to enable logging terminal output to lpc21isp.log 
     721.13  2004-05-19  Merged in improvement by Charles Manning: 
     73                  Instead of exiting the wrong hex file size is corrected 
     741.14  2004-07-07  Merged in improvement by Alex Holden: 
     75                  Remove little/big endian dependancy 
     761.15  2004-09-27  Temporary improvement by Cyril Holweck: 
     77                  Removed test (data echoed = data transmited) on the main 
     78                  data transfert, since this was the biggest failure 
     79                  reason and is covered by checksome anyway. 
     80                  Added COMPILE_FOR_LPC21, to have target dump it's own 
     81                  memory to stdout. 
     821.16  2004-10-09  Merged in bugfix / improvement by Sinelnikov Evgeny 
     83                  I found out that Linux and Windows serial port initialization 
     84                  are different with pinouts states. My board don't get 
     85                  reset signal at first cycle of DTR pinout moving. 
     86                  And I add this moving to initalization cycle. 
     871.17  2004-10-21  Changes by Cyril Holweck 
     88                  Divide main, take out the real programming function, that can 
     89                  also be used by a target to copy its own code to another. 
     901.18  2004-10-26  Changes by Cyril Holweck 
     91                  Added a "G 0 A\r\n" at end of programming to run code. 
     921.19  2004-11-03  Changes by Robert Adsett 
     93                  Add support for Analog Devices. 
     94                  Separate file load from programming. 
     95                  Change from a debug on/off flag to debug level 
     96                  Remove if (debug) tests and replace with DebugPrintf 
     97                  statements. 
     98                  Change serial I/O and timing so that the system 
     99                  dependancies are isolated to a few portability functions. 
     100                  Add support for binary serial I/O. 
     101                  Add doxygen support. 
     1021.20  2004-11-07  Preparation for multiport booting (factory support) 
     1031.21  2004-11-08  Bugfix from Robert Adsett 
     104                  BinaryLength was not initialized 
     1051.22  2004-11-08  Changes from Cyril Holweck / Evgeny Sinelnikov 
     106                  Forgotten IspEnvironment-> and bugfixes if COMPILE_FOR_LINUX 
     107                  If COMPILE_FOR_LPC21, PhilipsDownload() 'acts as' main(): 
     108                  - it should not be static and should return int. 
     109                  - no sub-function can use exit() but only return () 
     110                  Use 'char' instead of 'byte' ;) 
     1111.23  2005-01-16  Build in automatic detection of LPC chiptype 
     112                  (needed for 256 KByte support) 
     1131.24B 2005-06-02  Changes by Thiadmer Riemersma: completed support for other 
     114                  chip types (LPC213x series and others). 
     1151.24C 2005-06-11  Changes by Thiadmer Riemersma: added the device ID codes for 
     116                  chip types LPC2131 and LPC2132. 
     1171.25  2005-06-19  Martin Maurer: Setup more parameters in DCB, 
     118                  otherwise wrong code is downloaded (only Windows and Cygwin) 
     119                  when a previous program has changed these parameters 
     120                  Check exact string of "G 0 A\r\n0\r\n" instead of whole received buffer, 
     121                  to prevent checking of already received by program start 
     122                  (error on running program, but reports CMD_SUCCESS) 
     123                  Add ifdefs for all baudrates (needed only for high baudrate, 
     124                  which seem to be not available on Macs...) 
     1251.26  2005-06-26  Martin Maurer: 
     126                  Correct check again: "G 0 A\r\n0\r\n" is cutted, because of reboot 
     127                  (error on running program, but reports CMD_SUCCESS) 
     1281.27  2005-06-29  Martin Maurer: 
     129                  Add LPC chip ID's (thanks to Robert from Philips) for 
     130                  missing LPC213x and upcoming new LPC214x chips 
     131                  (currently untested, because i don't have access to these chips, 
     132                  please give me feedback !) 
     1331.28  2005-07-27  Anders Rosvall / Embedded Artists AB: 
     134                  Changed the reset timeout to 500 ms when entering the bootloader. 
     135                  Some external reset controllers have quite long timeout periods, 
     136                  so extening the timeout delay would be a good thing. 
     1371.29  2005-09-14  Rob Jansen: 
     138                  Added functionality to download to RAM and run from there. 
     139                  In LoadFile() added record types 04 (Extended Linear Address Record) 
     140                  and 05 (Start Linear Address Record), added address offset 
     141                  (IspEnvironment->BinaryOffset) and start address (...->StartAddress). 
     142                  Changed PhilipsDownload to skip all Flash prepare/erase/copy commands. 
     143                  Note: Tested with VC7 only 
     1441.30   2005-10-04 Rob Jansen: 
     145                  - forgot to change the version string in 1.29 
     146                  - Wrong text in LoadFile corrected (printed text mentions record type 05, 
     147                    this should be 04 
     148                  - Changed LoadFile to accept multiple record types 04 
     149                  - Changed LoadFile to check on memory size, will not load more than x MB 
     150                    if linear extended address records are used 
     1511.31   2005-11-13 Martin Maurer: Thanks to Frank Gutmann 
     152                  Updated number of sectors in device table 
     153                  for LPC2194, LPC2292 and LPC2294 
     1541.32   2005-12-02 Martin Maurer: Corrected missing control of RTS/DTR 
     155                  in case user selected -termonly and -control 
     156                  Small correction (typo in debug) 
     1571.33   2006-10-01 Jean-Marc Koller: 
     158                  Added support for MacOS X (difference on how to set termios baudrate). 
    1331591.34   2006-10-01  Cyril Holweck: 
    134                    Made it compile again for lpc21isp 
    135                    Added const keyword to constant variables to make it better 
    136                    code for embeded target. (decrease RAM usage) 
    137                    Replaced all regular call to printf() by DebugPrintf() 
    138                    Removed call to scanf() (not much usefull and cost a lot to my target) 
    139 1.35   2006-22-01  Cyril Holweck 
    140                    Added feature for LPC21: will start downloading at Sector 1 and upward, 
    141                    to finish with Sector 0, the one containing the checksum controling BSL entry 
    142 1.36   2006-25-01  Cyril Holweck 
    143                    PhilipsDownload() will now return a unique error code for each error 
    144 1.37   2006-10-03  Jeroen Domburg 
    145                    Added LPC2103 (and only the 2103, I can't find the IDs for 2101/2102) 
    146                            Corrected a loop which occured if the program completely fits in sector 0 
    147 1.38   2007-01-05  Ray Molenkamp 
    148                    Added feature for LPC21: Wipe entire device before programming to enable 
    149                    reflashing of chips with the lpc codeprotection feature enabled. 
    150 1.39   2007-01-12  Martin Maurer 
    151                    Added initial support for new processors LPC23xx and LPC24xx 
    152  
    153 ******************************************************************************/ 
    154  
    155 #define VERSION_STR     "1.39" 
    156  
    157 /* LPC_RAMSTART, LPC_RAMBASE 
    158  * 
    159  * Used in PhilipsDownload() to decide whether to Flash code or just place in in RAM 
    160  * (works for .hex files only) 
    161  * 
    162  * LPC_RAMSTART - the Physical start address of the SRAM 
    163  * LPC_RAMBASE  - the base address where downloading starts. 
    164  *                Note that any code in the .hex file that resides in 0x4000,0000 ~ 0x4000,0200 
    165  *                will _not_ be written to the LPCs SRAM. 
    166  *                This is due to the fact that 0x4000,0040 - 0x4000,0200 is used by the bootrom. 
    167  *                Any interrupt vectors must be copied to 0x4000,0000 and remapped to 0x0000,0000 
    168  *                by the startup code. 
    169  */ 
    170 #define LPC_RAMSTART    0x40000000L 
    171 #define LPC_RAMBASE     0x40000200L 
    172  
    173 /* LPC_FLASHMASK 
    174  * 
    175  * LPC_FLASHMASK - bitmask to define the maximum size of the Filesize to download. 
    176  *                 LoadFile() will check any new segment address record (03) or extended linear 
    177  *                 address record (04) to see if the addressed 64 kByte data block still falls 
    178  *                 in the max. flash size. 
    179  *                 LoadFile() will not load any files that are larger than this size. 
    180  */ 
    181 #define LPC_FLASHMASK  0xFFC00000 /* 22 bits = 4 MB */ 
    182  
    183  
    184 #if defined(_WIN32) && !defined(__CYGWIN__) 
    185     #define COMPILE_FOR_WINDOWS 
    186     #define COMPILED_FOR ("Windows") 
    187 #elif defined(__CYGWIN__) 
    188     #define COMPILE_FOR_CYGWIN 
    189     #define COMPILED_FOR ("Cygwin") 
    190 #elif defined(__arm__) || defined(__thumb__) 
    191     #define COMPILE_FOR_LPC21 
    192     #define COMPILED_FOR ("ARM") 
    193     #define printf iprintf 
    194 #elif defined(__APPLE__) 
    195     #define COMPILE_FOR_LINUX 
    196     #define COMPILED_FOR ("Apple MacOS X") 
    197 #else 
    198     #define COMPILE_FOR_LINUX 
    199     #define COMPILED_FOR ("Linux") 
     160                  Made it compile again for lpc21isp 
     161                  Added const keyword to constant variables to make it better 
     162                  code for embeded target. (decrease RAM usage) 
     163                  Replaced all regular call to printf() by DebugPrintf() 
     164                  Removed call to scanf() (not much usefull and cost a lot to my target) 
     1651.35   2006-22-01 Cyril Holweck 
     166                  Added feature for LPC21: will start downloading at Sector 1 and upward, 
     167                  to finish with Sector 0, the one containing the checksum controling BSL entry 
     1681.36   2006-25-01 Cyril Holweck 
     169                  PhilipsDownload() will now return a unique error code for each error 
     1701.37   2006-10-03 Jeroen Domburg 
     171                  Added LPC2103 (and only the 2103, I can't find the IDs for 2101/2102) 
     172                  Corrected a loop which occured if the program completely fits in sector 0 
     1731.38   2007-01-05 Ray Molenkamp 
     174                  Added feature for LPC21: Wipe entire device before programming to enable 
     175                  reflashing of chips with the lpc codeprotection feature enabled. 
     1761.39   2007-01-12 Martin Maurer 
     177                  Added initial support for new processors LPC23xx and LPC24xx 
     1781.40   2007-01-22 Martin Maurer 
     179                  Correction of chip id of LPC2458 
     1801.41   2007-01-28 Jean-Marc Koller 
     181                  Modified Terminal() to disable ECHO with termios only once, instead of 
     182                  modifying and restoring termios in each getch and kbhit call (which caused 
     183                  a strange echo behaviour in MacOS X). 
     1841.42   2007-01-28 Rob Probin 
     185                  Added -localecho command to allow local echoing in terminal mode for use 
     186                  where target does not echo back keystrokes. 
     1871.43   2007-01-29 Martin Maurer 
     188                  Moved keyboard handling routines to own subroutines, 
     189                  so they can be used during aborting synchronisation. 
     190                  Newest cygwin made problems, StringOscillator always contained '\0x0d' 
     191                  at the end, when calling lpc21isp from batch file 
     1921.44   2007-02-23 Yang Yang 
     193                  Added feature for LPC21: Verify the data in Flash after every writes 
     194                  to sector. To detect errors in writing to Flash ROM. 
     1951.45   2007-02-25 Martin Maurer 
     196                  Replace printf syntax of DumpString by a simple pointer to a string 
     197                  printf syntax is a nice thing, but it is not working :-( 
     198                  and therefore makes debugging much more difficult... 
     199                  Moved VERSION_STR to top of file to avoid possible cosmetical errors 
     2001.46   2007-02-25 Martin Maurer 
     201                  Again corrected debug output: should solve output of 
     202                  (FFFFFFB5) instead of (B5) 
     2031.47   2007-02-27 Robert Adsett 
     204                  Raised timeout on AD send packet function. 
     2051.48   2007-04-20 Martin Maurer 
     206                  Thanks to Josef Wolf for preventing to overwrite over end of array 
     2071.49   2007-10-16 New Option -halfduplex allow single wire using. 
     208                  Implemented and tested only for Windows. Data Resend implemented. 
     2091.50   2007-10-31 Changes by Simon Ellwood 
     210                  Formated the code for readablity 
     211                  Fixed some c++ compiler issues 
     2121.51   2007-11-20 Changes by Simon Ellwood 
     213                  Split into seperate files 
     214                  Made more modular so when used in an embedded mode only the required code is built 
     2151.52   2008-01-22 Changes by Manuel Koeppen 
     216                  Made compileable again for linux and windows 
     217                  Fixed bug in ClearSerialPortBuffers (linux) 
     2181.53   2008-02-25 Changes by Michael Roth 
     219                  Get priority of debug messages wih -control right 
     2201.54   2008-03-03 Martin Maurer 
     221                  Try to bring lpc21isp back to a useable state in Windows, Cygwin, Linux and Mac OS. 
     222                  Merged in changes by Erika Stefanini, which were done only for old version 1.49: 
     223                  Added device ids for revision B chips 
     2241.55   2008-03-03 Martin Maurer 
     225                  Thanks to Fausto Marzoli, bugfix for compiling latest version under Linux 
     2261.56   2008-04-01 Steve Franks 
     227                  Integrate FreeBSD patch. 
     228                  Add support for swapping and/or inverting RTS & DTR 
     2291.57   2008-04-06 Mauricio Scaff 
     230                  Changed OpenSerialPort to work with MacOS 
     231                  Corrected the number of sectors in some 512K devices (28 instead of 27) 
     232                  Added support for LPC2387 and LPC2388 
     233                  Defined BL error 19 (Code Protected) 
     2341.58   2008-05-10 Herbert Demmel dh2@demmel.com 
     235                  I had the special requirement to integrate the program into my own Windows 
     236                  software compiled with Borland C++ Builder 5. I had to do some minor changes 
     237                  for Borland (see defined __BORLANDC__) and modified to code slightly to have 
     238                  some simple callbacks for screen i/o (see define INTEGRATED_IN_WIN_APP). 
     239                  Please notet that I don *not* check / modify the part for AnalogDevices !! 
     240                  Besides that I fixed some minor issues: 
     241                  added dcb.fOutxCtsFlow = FALSE and dcb.fOutxDsrFlow = FALSE (sometimes required) 
     242                  Now comparing one character less of answer to "Now launching ... code" command 
     2431.59   2008-07-07 Peter Hayward 
     244                  Fixed freeze under Windows XP SP2 by removing redundant call to SetCommMask. 
     2451.60   2008-07-21 Martin Maurer 
     246                  Added uptodate part ids for LPC2458, LPC2468 and LPC2478 
     247                  Add comment "obsolete" for older part ids for LPC2458 and LPC2468 
     248                  Add ", " between compile date and time 
     2491.61   2008-10-21 Fausto Marzoli (thanks to Geoffrey Wossum for the patches) 
     250                  Fix for compiling latest version under Linux and "ControlLinesSwapped" issue 
     2511.62   2008-11-19 Martin Maurer 
     252                  Added (untested) support for LPC2109 
     253                  Added (untested) support for LPC2361 / LPC2362 
     254                  Heavy update of part identification number of LPC23xx and LPC24xx 
     255                  Correct bug, that hex file must exist, when "-detectonly" is used 
     256                  Correct Makefile.vc: use /Fe instead of -o 
     2571.63   2008-11-23 Martin Maurer 
     258                  Changed to GNU Lesser General Public License 
     2591.64   2009-01-19 Steve Franks 
     260                __FREEBSD__ changed to __FreeBSD__ at some point, plus other com port fixes 
     261*/ 
     262 
     263// Don't forget to update the version string that is on the next line 
     264#define VERSION_STR "1.64" 
     265 
     266#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
     267static char RxTmpBuf[256];        // save received data to this buffer for half-duplex 
     268char * pRxTmpBuf = RxTmpBuf; 
    200269#endif 
    201270 
    202 #if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    203 #include <windows.h> 
    204 #include <io.h> 
    205 #endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    206  
    207 #if defined COMPILE_FOR_WINDOWS 
    208 #include <conio.h> 
    209 #endif // defined COMPILE_FOR_WINDOWS 
    210  
    211 #if defined COMPILE_FOR_LINUX 
    212 #include <sys/types.h> 
    213 #include <sys/stat.h> 
    214 #include <stdlib.h> 
    215 #include <string.h> 
    216 #include <strings.h> 
    217 #include <sys/ioctl.h> 
    218 #endif // defined COMPILE_FOR_LINUX 
    219  
    220 #if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN 
    221 #include <termios.h> 
    222 #include <unistd.h>     // for read and return value of lseek 
    223 #include <sys/time.h>   // for select_time 
    224 #endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN 
    225  
    226 #include <ctype.h>      // isdigit() 
    227 #include <stdio.h>      // stdout 
    228 #include <stdarg.h> 
    229 #include <time.h> 
    230  
    231 #if defined COMPILE_FOR_LPC21 
    232 #include <stdlib.h> 
    233 #include <string.h> 
    234 //#include <lpc_ioctl.h>  // if using libc serial port communication 
    235 #include "lpc21isp.h"   // if using propriatory serial port communication (customize attached lpc21isp.h) 
     271#if !defined COMPILE_FOR_LPC21 
     272int debug_level = 2; 
    236273#endif 
    237  
    238 #if !defined COMPILE_FOR_LPC21 
    239 #include <fcntl.h> 
    240 #endif 
    241  
    242 #ifndef O_BINARY 
    243 #define O_BINARY 0 
    244 #endif // O_BINARY 
    245  
    246 #ifndef DWORD 
    247 #define DWORD unsigned long 
    248 #endif // DWORD 
    249  
    250 #if defined COMPILE_FOR_LINUX 
    251 #define stricmp strcasecmp 
    252 #endif // defined COMPILE_FOR_LINUX 
    253  
    254  
    255 /* Return values used by PhilipsDownload(): reserving all values from 0x1000 to 0x1FFF */ 
    256  
    257 #define NO_ANSWER_WDT       0x1000 
    258 #define NO_ANSWER_QM        0x1001 
    259 #define NO_ANSWER_SYNC      0x1002 
    260 #define NO_ANSWER_OSC       0x1003 
    261 #define NO_ANSWER_RBV       0x1004 
    262 #define NO_ANSWER_RPID      0x1005 
    263 #define ERROR_WRITE_DATA    0x1006 
    264 #define ERROR_WRITE_CRC     0x1007 
    265 #define ERROR_WRITE_CRC2    0x1008 
    266 #define PROGRAM_TOO_LARGE   0x1009 
    267  
    268 #define UNLOCK_ERROR        0x1100   /* return value is 0x1100 + philips ISP returned value (0 to 255) */ 
    269 #define WRONG_ANSWER_PREP   0x1200   /* return value is 0x1200 + philips ISP returned value (0 to 255) */ 
    270 #define WRONG_ANSWER_ERAS   0x1300   /* return value is 0x1300 + philips ISP returned value (0 to 255) */ 
    271 #define WRONG_ANSWER_WRIT   0x1400   /* return value is 0x1400 + philips ISP returned value (0 to 255) */ 
    272 #define WRONG_ANSWER_PREP2  0x1500   /* return value is 0x1500 + philips ISP returned value (0 to 255) */ 
    273 #define WRONG_ANSWER_COPY   0x1600   /* return value is 0x1600 + philips ISP returned value (0 to 255) */ 
    274 #define FAILED_RUN          0x1700   /* return value is 0x1700 + philips ISP returned value (0 to 255) */ 
    275  
    276  
    277  
    278  
    279  
    280 typedef unsigned char BINARY;   /**< data type used for microcontroller 
    281                                 *  memory image.                        */ 
    282  
    283 /* 
    284 debug levels 
    285 0 - very quiet          - Nothing gets printed at this level 
    286 1 - quiet               - Only error messages should be printed 
    287 2 - indicate progress   - Add progress messages 
    288 3 - first level debug   - Major level tracing 
    289 4 - second level debug  - Add detailed debugging 
    290 5 - log comm's          - log serial I/O 
    291 */ 
    292  
    293 typedef enum 
    294 { 
    295     PHILIPS_ARM, 
    296     ANALOG_DEVICES_ARM 
    297 } TARGET; 
    298  
    299 typedef struct 
    300 { 
    301     unsigned long id; 
    302     unsigned Product; 
    303     unsigned FlashSize;     /* in kiB, for informational purposes only */ 
    304     unsigned RAMSize;       /* in kiB, for informational purposes only */ 
    305     unsigned FlashSectors;  /* total number of sectors */ 
    306     unsigned MaxCopySize;   /* maximum size that can be copied to Flash in a single command */ 
    307     const int *SectorTable; /* pointer to a sector table with constant the sector sizes */ 
    308 } LPC_DEVICE_TYPE; 
    309  
    310 typedef struct 
    311 { 
    312  
    313 #if !defined COMPILE_FOR_LPC21 
    314     TARGET micro;                      /**< The type of micro that will be 
    315                                          * programmed.                           */ 
    316     int debug_level; 
    317     unsigned char TerminalAfterUpload; 
    318     unsigned char FormatHex; 
    319     unsigned char ControlLines; 
    320     unsigned char LogFile; 
    321     char *input_file;                   /**< Name of the file to get input from. */ 
    322     char *serial_port;                  /**< Name of the serial port to use to 
    323                                          * communicate with the microcontroller. 
    324                                          * Read from the command line.          */ 
    325  
    326 #endif // !defined COMPILE_FOR_LPC21 
    327     unsigned char TerminalOnly; 
    328     unsigned char DetectOnly; 
    329     unsigned char WipeDevice; 
    330     int           DetectedDevice;       /* index in LPCtypes[] array */ 
    331     char *baud_rate;                    /**< Baud rate to use on the serial 
    332                                          * port communicating with the 
    333                                          * microcontroller. Read from the 
    334                                          * command line.                        */ 
    335  
    336     char *StringOscillator;             /**< Holds representation of oscillator 
    337                                           * speed from the command line.         */ 
    338     BINARY *BinaryContent;              /**< Binary image of the                 */ 
    339                                         /* microcontroller's memory.             */ 
    340     unsigned long BinaryLength; 
    341         unsigned long BinaryOffset; 
    342         unsigned long StartAddress; 
    343  
    344 #if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    345     HANDLE hCom; 
    346 #endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    347  
    348 #if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21 
    349     int fdCom; 
    350 #endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21 
    351  
    352 #if defined COMPILE_FOR_LINUX 
    353     struct termios oldtio, newtio; 
    354 #endif // defined COMPILE_FOR_LINUX 
    355  
    356     unsigned serial_timeout_count;   /**< Local used to track 
    357                                       * timeouts on serial port read. */ 
    358  
    359 } ISP_ENVIRONMENT; 
    360  
    361  
    362 static void DumpString(int level, const void *s, size_t size, const char *fmt, ...); 
    363 static void SendComPort(ISP_ENVIRONMENT *IspEnvironment, const char *s); 
    364 static void ReceiveComPort(ISP_ENVIRONMENT *IspEnvironment, void *Answer, unsigned long MaxSize, unsigned long *RealSize, unsigned long WantedNr0x0A,unsigned timeOutMilliseconds); 
    365 static void PhilipsOutputErrorMessage(unsigned char ErrorNumber); 
    366 static unsigned char GetErrorNumber(const char *Answer); 
    367 static void SerialTimeoutSet(ISP_ENVIRONMENT *IspEnvironment, unsigned timeout_milliseconds); 
    368 static void SerialTimeoutTick(ISP_ENVIRONMENT *IspEnvironment); 
    369 static int SerialTimeoutCheck(ISP_ENVIRONMENT *IspEnvironment); 
    370  
    371 #if !defined COMPILE_FOR_LPC21 
    372  
    373 static int debug_level = 2; 
    374  
    375 static void DebugPrintf( int level, const char *fmt, ...); 
    376 static void ClearSerialPortBuffers(ISP_ENVIRONMENT *IspEnvironment); 
    377 static void ControlModemLines(ISP_ENVIRONMENT *IspEnvironment, unsigned char DTR, unsigned char RTS); 
    378 static unsigned char Ascii2Hex(unsigned char c); 
    379 #endif 
    380  
    381 static const int SectorTable_210x[] = { 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 
    382                                         8192, 8192, 8192, 8192, 8192, 8192, 8192 }; 
    383 static const int SectorTable_2103[] = { 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096 }; 
    384 static const int SectorTable_211x[] = { 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 
    385                                         8192, 8192, 8192, 8192, 8192, 8192, 8192, }; 
    386 static const int SectorTable_212x[] = { 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 
    387                                         65536, 65536, 8192, 8192, 8192, 8192, 8192, 8192, 
    388                                         8192 }; 
    389 static const int SectorTable_213x[] = { 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 
    390                                         32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 
    391                                         32768, 32768, 32768, 32768, 32768, 32768, 4096, 4096, 
    392                                         4096, 4096, 4096 }; 
    393 static int SectorTable_RAM[]  = { 65000 }; 
    394  
    395 static LPC_DEVICE_TYPE LPCtypes[] = 
    396 { 
    397   { 0, 0, 0 },  /* unknown */ 
    398   { 0x0004FF11, 2103,  32,  8,  8, 4096, SectorTable_2103 }, 
    399   { 0xFFF0FF12, 2104, 128, 16, 15, 8192, SectorTable_210x }, 
    400   { 0xFFF0FF22, 2105, 128, 32, 15, 8192, SectorTable_210x }, 
    401   { 0xFFF0FF32, 2106, 128, 64, 15, 8192, SectorTable_210x }, 
    402   { 0x0101FF12, 2114, 128, 16, 15, 8192, SectorTable_211x }, 
    403   { 0x0201FF12, 2119, 128, 16, 15, 8192, SectorTable_211x }, 
    404   { 0x0101FF13, 2124, 256, 16, 17, 8192, SectorTable_212x }, 
    405   { 0x0201FF13, 2129, 256, 16, 17, 8192, SectorTable_212x }, 
    406   { 0x0002FF01, 2131,  32,  8,  8, 4096, SectorTable_213x }, 
    407   { 0x0002FF11, 2132,  64, 16,  9, 4096, SectorTable_213x }, 
    408   { 0x0002FF12, 2134, 128, 16, 11, 4096, SectorTable_213x }, 
    409   { 0x0002FF23, 2136, 256, 32, 15, 4096, SectorTable_213x }, 
    410   { 0x0002FF25, 2138, 512, 32, 27, 4096, SectorTable_213x }, 
    411   { 0x0402FF01, 2141,  32,  8,  8, 4096, SectorTable_213x }, 
    412   { 0x0402FF11, 2142,  64, 16,  9, 4096, SectorTable_213x }, 
    413   { 0x0402FF12, 2144, 128, 16, 11, 4096, SectorTable_213x }, 
    414   { 0x0402FF23, 2146, 256, 40, 15, 4096, SectorTable_213x }, 
    415   { 0x0402FF25, 2148, 512, 40, 27, 4096, SectorTable_213x }, 
    416   { 0x0301FF13, 2194, 256, 16, 17, 8192, SectorTable_212x }, 
    417   { 0x0301FF12, 2210,   0, 16,  0, 8192, SectorTable_211x }, /* table is a "don't care" */ 
    418   { 0x0401FF12, 2212, 128, 16, 15, 8192, SectorTable_211x }, 
    419   { 0x0601FF13, 2214, 256, 16, 17, 8192, SectorTable_212x }, 
    420   /*            2290; same id as the LPC2210 */ 
    421   { 0x0401FF13, 2292, 256, 16, 17, 8192, SectorTable_212x }, 
    422   { 0x0501FF13, 2294, 256, 16, 17, 8192, SectorTable_212x }, 
    423   { 0x0603FB02, 2364, 128, 34, 11, 4096, SectorTable_213x }, 
    424   { 0x0603FB23, 2366, 256, 58, 15, 4096, SectorTable_213x }, 
    425   { 0x0603FB25, 2368, 512, 58, 27, 4096, SectorTable_213x }, 
    426   { 0x0703FF25, 2378, 512, 58, 27, 4096, SectorTable_213x }, 
    427   /* { 0x0603FF35, 2458, 512, 98, 27, 4096, SectorTable_213x }, same id as 2468 ? */ 
    428   { 0x0603FF35, 2468, 512, 98, 27, 4096, SectorTable_213x } 
    429 }; 
    430274 
    431275/************* Portability layer. Serial and console I/O differences    */ 
    432276/* are taken care of here.                                              */ 
    433277 
    434 #if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN 
    435 static int kbhit( void); 
    436 static int getch( void); 
    437 #endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN 
    438  
    439 #if defined COMPILE_FOR_LINUX 
    440 static void Sleep(unsigned long MilliSeconds); 
    441 #endif // defined COMPILE_FOR_LINUX 
    442  
    443  
    444  
    445 #if !defined COMPILE_FOR_LPC21 
     278#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    446279static void OpenSerialPort(ISP_ENVIRONMENT *IspEnvironment) 
    447280{ 
    448     // Open COM-Port (different between Windows and Linux) 
    449  
    450 #if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    451281    DCB    dcb; 
    452282    COMMTIMEOUTS commtimeouts; 
     
    454284    IspEnvironment->hCom = CreateFile(IspEnvironment->serial_port, GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); 
    455285 
    456     if(IspEnvironment->hCom == INVALID_HANDLE_VALUE) 
    457     { 
    458         DebugPrintf( 1, "Can't open COM-Port %s ! - Error: %ld\n", IspEnvironment->serial_port, GetLastError()); 
     286    if (IspEnvironment->hCom == INVALID_HANDLE_VALUE) 
     287    { 
     288        DebugPrintf(1, "Can't open COM-Port %s ! - Error: %ld\n", IspEnvironment->serial_port, GetLastError()); 
    459289        exit(2); 
    460290    } 
    461291 
    462     DebugPrintf( 3, "COM-Port %s opened...\n", IspEnvironment->serial_port); 
     292    DebugPrintf(3, "COM-Port %s opened...\n", IspEnvironment->serial_port); 
    463293 
    464294    GetCommState(IspEnvironment->hCom, &dcb); 
     
    472302    dcb.fNull       = FALSE; 
    473303    dcb.fRtsControl = RTS_CONTROL_DISABLE; 
    474     if(SetCommState(IspEnvironment->hCom, &dcb) == 0) 
    475     { 
    476         DebugPrintf( 1, "Can't set baudrate %s ! - Error: %ld", IspEnvironment->baud_rate, GetLastError()); 
     304 
     305    // added by Herbert Demmel - iF CTS line has the wrong state, we would never send anything! 
     306    dcb.fOutxCtsFlow = FALSE; 
     307    dcb.fOutxDsrFlow = FALSE; 
     308 
     309    if (SetCommState(IspEnvironment->hCom, &dcb) == 0) 
     310    { 
     311        DebugPrintf(1, "Can't set baudrate %s ! - Error: %ld", IspEnvironment->baud_rate, GetLastError()); 
    477312        exit(3); 
    478313    } 
    479314 
    480     SetCommMask(IspEnvironment->hCom,EV_RXCHAR | EV_TXEMPTY); 
     315   /* 
     316    *  Peter Hayward 02 July 2008 
     317    * 
     318    *  The following call is only needed if the WaitCommEvent 
     319    *  or possibly the GetCommMask functions are used.  They are 
     320    *  *not* in this implimentation.  However, under Windows XP SP2 
     321    *  on my laptop the use of this call causes XP to freeze (crash) while 
     322    *  this program is running, e.g. in section 5/6/7 ... of a largish 
     323    *  download.  Removing this *unnecessary* call fixed the problem. 
     324    *  At the same time I've added a call to SetupComm to request 
     325    *  (not necessarity honoured) the operating system to provide 
     326    *  large I/O buffers for high speed I/O without handshaking. 
     327    * 
     328    *   SetCommMask(IspEnvironment->hCom,EV_RXCHAR | EV_TXEMPTY); 
     329    */ 
     330    SetupComm(IspEnvironment->hCom, 32000, 32000); 
     331 
     332    SetCommMask(IspEnvironment->hCom, EV_RXCHAR | EV_TXEMPTY); 
    481333 
    482334    commtimeouts.ReadIntervalTimeout         = MAXDWORD; 
     
    486338    commtimeouts.WriteTotalTimeoutConstant   =    0; 
    487339    SetCommTimeouts(IspEnvironment->hCom, &commtimeouts); 
    488  
     340} 
    489341#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    490342 
    491343#if defined COMPILE_FOR_LINUX 
    492  
    493     IspEnvironment->fdCom = open(IspEnvironment->serial_port, O_RDWR | O_NOCTTY | O_NONBLOCK ); 
    494  
    495     if(IspEnvironment->fdCom < 0) 
    496     { 
    497         DebugPrintf( 1, "Can't open COM-Port %s !\n", IspEnvironment->serial_port); 
     344static void OpenSerialPort(ISP_ENVIRONMENT *IspEnvironment) 
     345{ 
     346    IspEnvironment->fdCom = open(IspEnvironment->serial_port, O_RDWR | O_NOCTTY | O_NONBLOCK); 
     347 
     348    if (IspEnvironment->fdCom < 0) 
     349    { 
     350        int err = errno; 
     351        DebugPrintf(1, "Can't open COM-Port %s ! (Error: %dd (0x%X))\n", IspEnvironment->serial_port, err, err); 
    498352        exit(2); 
    499353    } 
    500354 
    501     DebugPrintf( 3, "COM-Port %s opened...\n", IspEnvironment->serial_port); 
    502  
    503         /* clear input & output buffers, then switch to "blocking mode" */ 
    504         tcflush(IspEnvironment->fdCom, TCOFLUSH); 
    505         tcflush(IspEnvironment->fdCom, TCIFLUSH); 
    506         fcntl(IspEnvironment->fdCom, F_SETFL, fcntl(IspEnvironment->fdCom, F_GETFL) & ~O_NONBLOCK); 
     355    DebugPrintf(3, "COM-Port %s opened...\n", IspEnvironment->serial_port); 
     356 
     357    /* clear input & output buffers, then switch to "blocking mode" */ 
     358    tcflush(IspEnvironment->fdCom, TCOFLUSH); 
     359    tcflush(IspEnvironment->fdCom, TCIFLUSH); 
     360    fcntl(IspEnvironment->fdCom, F_SETFL, fcntl(IspEnvironment->fdCom, F_GETFL) & ~O_NONBLOCK); 
    507361 
    508362    tcgetattr(IspEnvironment->fdCom, &IspEnvironment->oldtio); /* save current port settings */ 
     
    512366 
    513367#ifdef __APPLE__ 
    514 #define NEWTERMIOS_SETBAUDARTE(bps)     IspEnvironment->newtio.c_ispeed = IspEnvironment->newtio.c_ospeed = bps; 
     368#define NEWTERMIOS_SETBAUDARTE(bps) IspEnvironment->newtio.c_ispeed = IspEnvironment->newtio.c_ospeed = bps; 
     369 
     370#elif __FreeBSD__ 
     371 
     372        if(cfsetspeed(&IspEnvironment->newtio,(speed_t) strtol(IspEnvironment->baud_rate,NULL,10))) { 
     373                  DebugPrintf(1, "baudrate %s not supported\n", IspEnvironment->baud_rate); 
     374                  exit(3); 
     375              }; 
    515376#else 
    516 #define NEWTERMIOS_SETBAUDARTE(bps)     IspEnvironment->newtio.c_cflag |= bps; 
    517 #endif 
    518  
    519     switch(atol(IspEnvironment->baud_rate)) 
     377#define NEWTERMIOS_SETBAUDARTE(bps) IspEnvironment->newtio.c_cflag |= bps; 
     378 
     379    switch (atol(IspEnvironment->baud_rate)) 
    520380    { 
    521381#ifdef B1152000 
    522         case 1152000: NEWTERMIOS_SETBAUDARTE( B1152000 ); break; 
     382          case 1152000: NEWTERMIOS_SETBAUDARTE(B1152000); break; 
    523383#endif // B1152000 
    524384#ifdef B576000 
    525         case  576000: NEWTERMIOS_SETBAUDARTE( B576000 ); break; 
     385          case  576000: NEWTERMIOS_SETBAUDARTE(B576000); break; 
    526386#endif // B576000 
    527387#ifdef B230400 
    528         case  230400: NEWTERMIOS_SETBAUDARTE( B230400 ); break; 
     388          case  230400: NEWTERMIOS_SETBAUDARTE(B230400); break; 
    529389#endif // B230400 
    530390#ifdef B115200 
    531         case  115200: NEWTERMIOS_SETBAUDARTE( B115200 ); break; 
     391          case  115200: NEWTERMIOS_SETBAUDARTE(B115200); break; 
    532392#endif // B115200 
    533393#ifdef B57600 
    534         case   57600: NEWTERMIOS_SETBAUDARTE( B57600 ); break; 
     394          case   57600: NEWTERMIOS_SETBAUDARTE(B57600); break; 
    535395#endif // B57600 
    536396#ifdef B38400 
    537         case   38400: NEWTERMIOS_SETBAUDARTE( B38400 ); break; 
     397          case   38400: NEWTERMIOS_SETBAUDARTE(B38400); break; 
    538398#endif // B38400 
    539399#ifdef B19200 
    540         case   19200: NEWTERMIOS_SETBAUDARTE( B19200 ); break; 
     400          case   19200: NEWTERMIOS_SETBAUDARTE(B19200); break; 
    541401#endif // B19200 
    542402#ifdef B9600 
    543         case    9600: NEWTERMIOS_SETBAUDARTE( B9600 ); break; 
     403          case    9600: NEWTERMIOS_SETBAUDARTE(B9600); break; 
    544404#endif // B9600 
    545         default: 
    546         { 
    547             DebugPrintf( 1, "unknown baudrate %s\n", IspEnvironment->baud_rate); 
    548             exit(3); 
    549         } 
    550     } 
     405          default: 
     406              { 
     407                  DebugPrintf(1, "unknown baudrate %s\n", IspEnvironment->baud_rate); 
     408                  exit(3); 
     409              } 
     410    } 
     411 
     412#endif 
    551413 
    552414    IspEnvironment->newtio.c_iflag = IGNPAR | IGNBRK | IXON | IXOFF; 
     
    561423 
    562424    tcflush(IspEnvironment->fdCom, TCIFLUSH); 
    563     tcsetattr(IspEnvironment->fdCom, TCSANOW, &IspEnvironment->newtio); 
    564  
     425    if(tcsetattr(IspEnvironment->fdCom, TCSANOW, &IspEnvironment->newtio)) 
     426    { 
     427       DebugPrintf(1, "Could not change serial port behaviour (wrong baudrate?)\n"); 
     428       exit(3); 
     429    } 
     430 
     431} 
    565432#endif // defined COMPILE_FOR_LINUX 
    566 } 
    567  
     433 
     434#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    568435static void CloseSerialPort(ISP_ENVIRONMENT *IspEnvironment) 
    569436{ 
    570 #if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    571  
    572437    CloseHandle(IspEnvironment->hCom); 
     438} 
    573439 
    574440#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    575441 
    576442#if defined COMPILE_FOR_LINUX 
    577  
    578         tcflush(IspEnvironment->fdCom, TCOFLUSH); 
    579         tcflush(IspEnvironment->fdCom, TCIFLUSH); 
     443static void CloseSerialPort(ISP_ENVIRONMENT *IspEnvironment) 
     444{ 
     445    tcflush(IspEnvironment->fdCom, TCOFLUSH); 
     446    tcflush(IspEnvironment->fdCom, TCIFLUSH); 
    580447    tcsetattr(IspEnvironment->fdCom, TCSANOW, &IspEnvironment->oldtio); 
    581448 
    582449    close(IspEnvironment->fdCom); 
    583  
     450} 
    584451#endif // defined COMPILE_FOR_LINUX 
    585 } 
    586  
    587 #endif // !defined COMPILE_FOR_LPC21 
     452 
    588453 
    589454/***************************** SendComPortBlock *************************/ 
     
    592457\param [in] n size of the block. 
    593458*/ 
    594 static void SendComPortBlock(ISP_ENVIRONMENT *IspEnvironment, const void *s, size_t n) 
     459void SendComPortBlock(ISP_ENVIRONMENT *IspEnvironment, const void *s, size_t n) 
    595460{ 
    596461#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    597462 
    598463    unsigned long realsize; 
    599  
     464    size_t m; 
     465    unsigned long rxsize; 
     466    char * pch; 
     467    char * rxpch; 
    600468#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    601469 
    602     DumpString( 4, s, n, "Sending "); 
     470    DumpString(4, s, n, "Sending "); 
    603471 
    604472#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    605473 
    606     WriteFile(IspEnvironment->hCom, s, n, &realsize, NULL); 
    607  
     474    if (IspEnvironment->HalfDuplex == 0) 
     475        WriteFile(IspEnvironment->hCom, s, n, &realsize, NULL); 
     476    else 
     477    { 
     478        pch = (char *)s; 
     479        rxpch = RxTmpBuf; 
     480        pRxTmpBuf = RxTmpBuf; 
     481 
     482        // avoid buffer otherflow 
     483        if (n > sizeof (RxTmpBuf)) 
     484            n = sizeof (RxTmpBuf); 
     485 
     486        for (m = 0; m < n; m++) 
     487        { 
     488            WriteFile(IspEnvironment->hCom, pch, 1, &realsize, NULL); 
     489 
     490            if ((*pch != '?') || (n != 1)) 
     491            { 
     492                do 
     493                { 
     494                    ReadFile(IspEnvironment->hCom, rxpch, 1, &rxsize, NULL); 
     495                }while (rxsize == 0); 
     496            } 
     497            pch++; 
     498            rxpch++; 
     499        } 
     500        *rxpch = 0;        // terminate echo string 
     501    } 
    608502#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    609503 
     
    619513\param [in] s string to send. 
    620514*/ 
    621 static void SendComPort(ISP_ENVIRONMENT *IspEnvironment, const char *s) 
    622 { 
    623     SendComPortBlock( IspEnvironment, s, strlen(s)); 
     515void SendComPort(ISP_ENVIRONMENT *IspEnvironment, const char *s) 
     516{ 
     517    SendComPortBlock(IspEnvironment, s, strlen(s)); 
     518} 
     519 
     520/***************************** SerialTimeoutTick ************************/ 
     521/**  Performs a timer tick.  In this simple case all we do is count down 
     522with protection against underflow and wrapping at the low end. 
     523*/ 
     524static void SerialTimeoutTick(ISP_ENVIRONMENT *IspEnvironment) 
     525{ 
     526    if (IspEnvironment->serial_timeout_count <= 1) 
     527    { 
     528        IspEnvironment->serial_timeout_count = 0; 
     529    } 
     530    else 
     531    { 
     532        IspEnvironment->serial_timeout_count--; 
     533    } 
    624534} 
    625535 
     
    635545buffer that is actually used. 
    636546*/ 
    637 static void ReceiveComPortBlock( ISP_ENVIRONMENT *IspEnvironment, 
    638                                  void *answer, unsigned long max_size, 
    639                                  unsigned long *real_size) 
    640 { 
     547static void ReceiveComPortBlock(ISP_ENVIRONMENT *IspEnvironment, 
     548                                          void *answer, unsigned long max_size, 
     549                                          unsigned long *real_size) 
     550{ 
     551    char tmp_string[32]; 
    641552 
    642553#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    643554 
    644     ReadFile(IspEnvironment->hCom, answer, max_size, real_size, NULL); 
     555    if (IspEnvironment->HalfDuplex == 0) 
     556        ReadFile(IspEnvironment->hCom, answer, max_size, real_size, NULL); 
     557    else 
     558    { 
     559        *real_size = strlen (pRxTmpBuf); 
     560        if (*real_size) 
     561        { 
     562            if (max_size >= *real_size) 
     563            { 
     564                strncpy((char*) answer, pRxTmpBuf, *real_size); 
     565                RxTmpBuf[0] = 0; 
     566                pRxTmpBuf = RxTmpBuf; 
     567            } 
     568            else 
     569            { 
     570                strncpy((char*) answer, pRxTmpBuf, max_size); 
     571                *real_size = max_size; 
     572                pRxTmpBuf += max_size; 
     573            } 
     574        } 
     575        else 
     576            ReadFile(IspEnvironment->hCom, answer, max_size, real_size, NULL); 
     577    } 
    645578 
    646579#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
     
    652585#endif // defined COMPILE_FOR_LINUX 
    653586 
    654  
    655     DumpString( 5, answer, (*real_size), "Read(Length=%ld): ", (*real_size)); 
    656  
    657     if( *real_size == 0) 
    658     { 
    659         SerialTimeoutTick( IspEnvironment ); 
     587    sprintf(tmp_string, "Read(Length=%ld): ", (*real_size)); 
     588    DumpString(5, answer, (*real_size), tmp_string); 
     589 
     590    if (*real_size == 0) 
     591    { 
     592        SerialTimeoutTick(IspEnvironment); 
    660593    } 
    661594} 
     
    676609static void SerialTimeoutSet(ISP_ENVIRONMENT *IspEnvironment, unsigned timeout_milliseconds) 
    677610{ 
    678  
    679611#if defined COMPILE_FOR_LINUX 
    680     IspEnvironment->serial_timeout_count = timeout_milliseconds/100; 
     612    IspEnvironment->serial_timeout_count = timeout_milliseconds / 100; 
    681613#elif defined COMPILE_FOR_LPC21 
    682     IspEnvironment->serial_timeout_count = timeout_milliseconds*200; 
     614    IspEnvironment->serial_timeout_count = timeout_milliseconds * 200; 
    683615#else 
    684616    IspEnvironment->serial_timeout_count = timeout_milliseconds; 
     
    686618} 
    687619 
    688 /***************************** SerialTimeoutTick ************************/ 
    689 /**  Performs a timer tick.  In this simple case all we do is count down 
    690 with protection against underflow and wrapping at the low end. 
    691 */ 
    692 static void SerialTimeoutTick(ISP_ENVIRONMENT *IspEnvironment) 
    693 { 
    694     if( IspEnvironment->serial_timeout_count <= 1) 
    695     { 
    696         IspEnvironment->serial_timeout_count = 0; 
    697     } 
    698     else 
    699     { 
    700         IspEnvironment->serial_timeout_count--; 
    701     } 
    702 } 
     620 
    703621 
    704622/***************************** SerialTimeoutCheck ***********************/ 
     
    709627static int SerialTimeoutCheck(ISP_ENVIRONMENT *IspEnvironment) 
    710628{ 
    711     if( IspEnvironment->serial_timeout_count == 0) 
     629    if (IspEnvironment->serial_timeout_count == 0) 
    712630    { 
    713631        return 1; 
     
    723641\return The character read from the keyboard. 
    724642*/ 
    725 static int getch(void) 
     643int getch(void) 
    726644{ 
    727645    char ch; 
    728     struct termios origtty, tty; 
    729  
    730     /* store the current tty settings */ 
    731     tcgetattr(0, &origtty); 
    732  
    733     /* start with the current settings */ 
    734     tty = origtty; 
    735     /* make modifications to put it in raw mode, turn off echo */ 
    736     tty.c_lflag &= ~ICANON; 
    737     tty.c_lflag &= ~ECHO; 
    738     tty.c_lflag &= ~ISIG; 
    739     tty.c_cc[VMIN] = 1; 
    740     tty.c_cc[VTIME] = 0; 
    741  
    742     /* put the settings into effect */ 
    743     tcsetattr(0, TCSADRAIN, &tty); 
    744646 
    745647    /* Read in one character */ 
    746648    read(0,&ch,1); 
    747  
    748     /* reset the tty to its original settings */ 
    749     tcsetattr(0, TCSADRAIN, &origtty); 
    750649 
    751650    return ch; 
     
    760659\retval 1 Characters from the console ready to be read. 
    761660*/ 
    762 static int kbhit(void) 
     661int kbhit(void) 
    763662{ 
    764663    /* return 0 for no key pressed, 1 for key pressed */ 
    765664    int return_value = 0; 
    766665 
    767     /* variables to store the current tty state, create a new one */ 
    768     struct termios origtty, tty; 
    769666    /* time struct for the select() function, to only wait a little while */ 
    770667    struct timeval select_time; 
     
    776673    FD_SET(STDIN_FILENO, &readset); 
    777674 
    778     /* store the current tty settings */ 
    779     tcgetattr(0, &origtty); 
    780  
    781     /* start with the current settings */ 
    782     tty = origtty; 
    783     /* make modifications to put it in raw mode, turn off echo */ 
    784     tty.c_lflag &= ~ICANON; 
    785     tty.c_lflag &= ~ECHO; 
    786     tty.c_lflag &= ~ISIG; 
    787     tty.c_cc[VMIN] = 1; 
    788     tty.c_cc[VTIME] = 0; 
    789  
    790     /* put the settings into effect */ 
    791     tcsetattr(0, TCSADRAIN, &tty); 
    792  
    793675    /* how long to block for - this must be > 0.0, but could be changed 
    794        to some other setting. 10-18msec seems to work well and only 
    795        minimally load the system (0% CPU loading) */ 
     676    to some other setting. 10-18msec seems to work well and only 
     677    minimally load the system (0% CPU loading) */ 
    796678    select_time.tv_sec = 0; 
    797679    select_time.tv_usec = 10; 
     
    804686    } 
    805687 
    806     /* reset the tty to its original settings */ 
    807     tcsetattr(0, TCSADRAIN, &origtty); 
    808688 
    809689    /* return with what we found out */ 
    810690    return return_value; 
    811691} 
     692struct termios keyboard_origtty; 
    812693#endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN 
     694 
     695 
     696/***************************** PrepareKeyboardTtySettings ***************/ 
     697/** Set the keyboard tty to be able to check for new characters via kbhit 
     698getting them via getch 
     699*/ 
     700 
     701void PrepareKeyboardTtySettings(void) 
     702{ 
     703#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN 
     704    /* store the current tty settings */ 
     705    if (!tcgetattr(0, &keyboard_origtty)) 
     706    { 
     707        struct termios tty; 
     708        /* start with the current settings */ 
     709        tty = keyboard_origtty; 
     710        /* make modifications to put it in raw mode, turn off echo */ 
     711        tty.c_lflag &= ~ICANON; 
     712        tty.c_lflag &= ~ECHO; 
     713        tty.c_lflag &= ~ISIG; 
     714        tty.c_cc[VMIN] = 1; 
     715        tty.c_cc[VTIME] = 0; 
     716 
     717        /* put the settings into effect */ 
     718        tcsetattr(0, TCSADRAIN, &tty); 
     719    } 
     720#endif 
     721} 
     722 
     723 
     724/***************************** ResetKeyboardTtySettings *****************/ 
     725/** Reset the keyboard tty to original settings 
     726*/ 
     727void ResetKeyboardTtySettings(void) 
     728{ 
     729#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN 
     730    /* reset the tty to its original settings */ 
     731    tcsetattr(0, TCSADRAIN, &keyboard_origtty); 
     732#endif 
     733} 
    813734 
    814735 
     
    823744static void ControlModemLines(ISP_ENVIRONMENT *IspEnvironment, unsigned char DTR, unsigned char RTS) 
    824745{ 
     746    //handle wether to invert the control lines: 
     747    DTR ^= IspEnvironment->ControlLinesInverted; 
     748    RTS ^= IspEnvironment->ControlLinesInverted; 
     749 
     750    //handle wether to swap the control lines 
     751    if (IspEnvironment->ControlLinesSwapped) 
     752    { 
     753        unsigned char tempRTS; 
     754        tempRTS = RTS; 
     755        RTS = DTR; 
     756        DTR = tempRTS; 
     757    } 
     758 
    825759#if defined COMPILE_FOR_LINUX 
    826760    int status; 
    827761 
    828     if(ioctl(IspEnvironment->fdCom, TIOCMGET, &status) == 0) 
    829     { 
    830         DebugPrintf( 1, "ioctl get ok, status = %X\n",status); 
     762    if (ioctl(IspEnvironment->fdCom, TIOCMGET, &status) == 0) 
     763    { 
     764        DebugPrintf(3, "ioctl get ok, status = %X\n",status); 
    831765    } 
    832766    else 
    833767    { 
    834         DebugPrintf( 1, "ioctl get failed\n"); 
    835     } 
    836  
    837     if(DTR) status |=  TIOCM_DTR; 
     768        DebugPrintf(1, "ioctl get failed\n"); 
     769    } 
     770 
     771    if (DTR) status |=  TIOCM_DTR; 
    838772    else    status &= ~TIOCM_DTR; 
    839773 
    840     if(RTS) status |=  TIOCM_RTS; 
     774    if (RTS) status |=  TIOCM_RTS; 
    841775    else    status &= ~TIOCM_RTS; 
    842776 
    843     if(ioctl(IspEnvironment->fdCom, TIOCMSET, &status) == 0) 
    844     { 
    845         DebugPrintf( 1, "ioctl set ok, status = %X\n",status); 
     777    if (ioctl(IspEnvironment->fdCom, TIOCMSET, &status) == 0) 
     778    { 
     779        DebugPrintf(3, "ioctl set ok, status = %X\n",status); 
    846780    } 
    847781    else 
    848782    { 
    849         DebugPrintf( 1, "ioctl set failed\n"); 
    850     } 
    851  
    852     if(ioctl(IspEnvironment->fdCom, TIOCMGET, &status) == 0) 
    853     { 
    854         DebugPrintf( 1, "ioctl get ok, status = %X\n",status); 
     783        DebugPrintf(1, "ioctl set failed\n"); 
     784    } 
     785 
     786    if (ioctl(IspEnvironment->fdCom, TIOCMGET, &status) == 0) 
     787    { 
     788        DebugPrintf(3, "ioctl get ok, status = %X\n",status); 
    855789    } 
    856790    else 
    857791    { 
    858         DebugPrintf( 1, "ioctl get failed\n"); 
     792        DebugPrintf(1, "ioctl get failed\n"); 
    859793    } 
    860794 
     
    862796#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    863797 
    864     if(DTR) EscapeCommFunction(IspEnvironment->hCom, SETDTR); 
     798    if (DTR) EscapeCommFunction(IspEnvironment->hCom, SETDTR); 
    865799    else    EscapeCommFunction(IspEnvironment->hCom, CLRDTR); 
    866800 
    867     if(RTS) EscapeCommFunction(IspEnvironment->hCom, SETRTS); 
     801    if (RTS) EscapeCommFunction(IspEnvironment->hCom, SETRTS); 
    868802    else    EscapeCommFunction(IspEnvironment->hCom, CLRRTS); 
    869803 
    870804#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 
    871805 
    872     DebugPrintf( 3, "DTR (%d), RTS (%d)\n", DTR, RTS); 
     806#if defined COMPILE_FOR_LPC21 
     807    LPC_RESET(DTR); 
     808    LPC_BSL(RTS); 
     809#endif 
     810 
     811    DebugPrintf(3, "DTR (%d), RTS (%d)\n", DTR, RTS); 
    873812} 
    874813 
     
    877816/**  Empty the serial port buffers.  Cleans things to a known state. 
    878817*/ 
    879 static void ClearSerialPortBuffers(ISP_ENVIRONMENT *IspEnvironment) 
     818void ClearSerialPortBuffers(ISP_ENVIRONMENT *IspEnvironment) 
    880819{ 
    881820#if defined COMPILE_FOR_LINUX 
     
    887826 
    888827    // Flush input and output buffers 
     828    tty=origtty; 
    889829    tcsetattr(IspEnvironment->fdCom, TCSAFLUSH, &tty); 
    890830 
     
    904844\param [in] Milliseconds the time to wait for in milliseconds. 
    905845*/ 
    906 static void Sleep(unsigned long MilliSeconds) 
     846void Sleep(unsigned long MilliSeconds) 
    907847{ 
    908848    usleep(MilliSeconds*1000); //convert to microseconds 
     
    934874debugging information being sent. 
    935875\param [in] level the debug level of the print statement, if the level 
    936  is less than or equal to the current debug level it will be printed. 
     876is less than or equal to the current debug level it will be printed. 
    937877\param [in] fmt a standard printf style format string. 
    938878\param [in] ... the usual printf parameters. 
    939879*/ 
    940 static void DebugPrintf( int level, const char *fmt, ...) 
     880#if !defined INTEGRATED_IN_WIN_APP 
     881void DebugPrintf(int level, const char *fmt, ...) 
    941882{ 
    942883    va_list ap; 
    943884 
    944     if( level <= debug_level) 
    945     { 
    946         va_start( ap, fmt); 
    947         vprintf( fmt, ap); 
    948         va_end( ap); 
    949         fflush( stdout); 
    950     } 
    951 } 
     885    if (level <= debug_level) 
     886    { 
     887        char pTemp[2000]; 
     888        va_start(ap, fmt); 
     889        //vprintf(fmt, ap); 
     890        vsprintf(pTemp, fmt, ap); 
     891        TRACE(pTemp); 
     892        va_end(ap); 
     893        fflush(stdout); 
     894    } 
     895} 
     896#endif 
    952897#endif // !defined COMPILE_FOR_LPC21 
    953898 
     
    967912reading with an incomplete buffer. 
    968913*/ 
    969 static void ReceiveComPort( ISP_ENVIRONMENT *IspEnvironment, 
    970                             void *Ans, unsigned long MaxSize, 
    971                             unsigned long *RealSize, unsigned long WantedNr0x0A, 
    972                             unsigned timeOutMilliseconds) 
     914void ReceiveComPort(ISP_ENVIRONMENT *IspEnvironment, 
     915                                    const char *Ans, unsigned long MaxSize, 
     916                                    unsigned long *RealSize, unsigned long WantedNr0x0A, 
     917                                    unsigned timeOutMilliseconds) 
    973918{ 
    974919    unsigned long tmp_realsize; 
     
    976921    int eof = 0; 
    977922    unsigned long p; 
    978     signed char *Answer; 
    979  
    980     Answer = Ans; 
    981  
    982     SerialTimeoutSet( IspEnvironment, timeOutMilliseconds); 
     923    unsigned char *Answer; 
     924    char tmp_string[32]; 
     925 
     926    Answer = (unsigned char*) Ans; 
     927 
     928    SerialTimeoutSet(IspEnvironment, timeOutMilliseconds); 
    983929 
    984930    (*RealSize) = 0; 
     
    986932    do 
    987933    { 
    988         ReceiveComPortBlock( IspEnvironment, Answer + (*RealSize), MaxSize - 1 - (*RealSize), &tmp_realsize); 
    989  
    990         if(tmp_realsize != 0) 
     934        ReceiveComPortBlock(IspEnvironment, Answer + (*RealSize), MaxSize - 1 - (*RealSize), &tmp_realsize); 
     935 
     936        if (tmp_realsize != 0) 
    991937        { 
    992             for(p = (*RealSize); p < (*RealSize) + tmp_realsize; p++) 
    993             { 
    994                 if(Answer[p] == 0x0a) 
     938            for (p = (*RealSize); p < (*RealSize) + tmp_realsize; p++) 
     939            { 
     940                if (Answer[p] == 0x0a) 
    995941                { 
    996942                    nr_of_0x0A++; 
    997943                } 
    998                 else if( Answer[p] < 0 ) 
     944                else if (((signed char) Answer[p]) < 0) 
    999945                { 
    1000946                    eof = 1; 
     
    1005951        (*RealSize) += tmp_realsize; 
    1006952 
    1007     } while(((*RealSize) < MaxSize) && (SerialTimeoutCheck(IspEnvironment) == 0) && (nr_of_0x0A < WantedNr0x0A) && !eof); 
     953    } while (((*RealSize) < MaxSize) && (SerialTimeoutCheck(IspEnvironment) == 0) && (nr_of_0x0A < WantedNr0x0A) && !eof); 
    1008954 
    1009955    Answer[(*RealSize)] = 0; 
    1010956 
    1011     DumpString( 3, Answer, (*RealSize), "Answer(Length=%ld): ", (*RealSize)); 
     957    sprintf(tmp_string, "Answer(Length=%ld): ", (*RealSize)); 
     958    DumpString(3, Answer, (*RealSize), tmp_string); 
    1012959} 
    1013960 
     
    1024971\return 0 if successful, non-zero otherwise. 
    1025972*/ 
    1026 static int ReceiveComPortBlockComplete( ISP_ENVIRONMENT *IspEnvironment, 
    1027                                         void *block, size_t size, unsigned timeout) 
     973int ReceiveComPortBlockComplete(ISP_ENVIRONMENT *IspEnvironment, 
     974                                                    void *block, size_t size, unsigned timeout) 
    1028975{ 
    1029976    unsigned long realsize = 0, read; 
    1030977    char *result; 
    1031  
    1032     result = block; 
    1033  
    1034     SerialTimeoutSet( IspEnvironment, timeout); 
     978    char tmp_string[32]; 
     979 
     980    result = (char*) block; 
     981 
     982    SerialTimeoutSet(IspEnvironment, timeout); 
    1035983 
    1036984    do 
    1037985    { 
    1038         ReceiveComPortBlock( IspEnvironment, result + realsize, size - realsize, &read); 
     986        ReceiveComPortBlock(IspEnvironment, result + realsize, size - realsize, &read); 
    1039987 
    1040988        realsize += read; 
    1041989 
    1042     } while((realsize < size) && (SerialTimeoutCheck(IspEnvironment) == 0)); 
    1043  
    1044     DumpString( 3, result, realsize, "Answer(Length=%ld): ", realsize); 
    1045  
    1046     if( realsize != size) 
     990    } while ((realsize < size) && (SerialTimeoutCheck(IspEnvironment) == 0)); 
     991 
     992    sprintf(tmp_string, "Answer(Length=%ld): ", realsize); 
     993    DumpString(3, result, realsize, tmp_string); 
     994 
     995    if (realsize != size) 
    1047996    { 
    1048997        return 1; 
     
    10591008\param [in] argv an array of pointers to the arguments. 
    10601009*/ 
    1061 static void ReadArguments(ISP_ENVIRONMENT *IspEnvironment, int argc, char *argv[]) 
    1062 { 
    1063     int i; 
    1064  
    1065     if(argc >= 5) 
    1066     { 
    1067         for(i = 1; i < argc - 4; i++) 
     1010static void ReadArguments(ISP_ENVIRONMENT *IspEnvironment, unsigned int argc, char *argv[]) 
     1011{ 
     1012    unsigned int i; 
     1013 
     1014    if (argc >= 5) 
     1015    { 
     1016        for (i = 1; i < argc - 4; i++) 
    10681017        { 
    1069             if(stricmp(argv[i], "-wipe") == 0) 
    1070             { 
    1071                  IspEnvironment->WipeDevice = 1; 
    1072                  DebugPrintf( 3, "Wipe entire device before writing.\n"); 
    1073             } 
    1074             if(stricmp(argv[i], "-bin") == 0) 
    1075             { 
    1076                  IspEnvironment->FormatHex = 0; 
    1077                  DebugPrintf( 3, "Binary format file input.\n"); 
    1078             } 
    1079             else if(stricmp(argv[i], "-hex") == 0) 
    1080             { 
    1081                  IspEnvironment->FormatHex = 1; 
    1082                  DebugPrintf( 3, "Hex format file input.\n"); 
    1083             } 
    1084             else if(stricmp(argv[i], "-term") == 0) 
    1085             { 
    1086                  IspEnvironment->TerminalAfterUpload = 1; 
    1087                  DebugPrintf( 3, "Invoke terminal after upload.\n"); 
    1088             } 
    1089             else if(stricmp(argv[i], "-termonly") == 0) 
    1090             { 
    1091                  IspEnvironment->TerminalOnly = 1; 
    1092                  DebugPrintf( 3, "Only provide terminal.\n"); 
    1093             } 
    1094             else if(stricmp(argv[i], "-detectonly") == 0) 
    1095             { 
    1096                  IspEnvironment->DetectOnly = 1; 
    1097                  DebugPrintf( 3, "Only detect LPC chip part id.\n"); 
    1098             } 
    1099             else if(stricmp(argv[i], "-debug") == 0) 
    1100             { 
    1101                  debug_level = 4; 
    1102                  DebugPrintf( 3, "Turn on debug.\n"); 
    1103             } 
    1104             else if(stricmp(argv[i], "-control") == 0) 
    1105             { 
    1106                  IspEnvironment->ControlLines = 1; 
    1107                  DebugPrintf( 3, "Use RTS/DTR to control target state.\n"); 
    1108             } 
    1109             else if(stricmp(argv[i], "-logfile") == 0) 
    1110             { 
    1111                  IspEnvironment->LogFile = 1; 
    1112                  DebugPrintf( 3, "Log terminal output.\n"); 
    1113             } 
    1114             else if( stricmp( argv[i], "-ADARM") == 0) 
     1018            if (stricmp(argv[i], "-wipe") == 0) 
     1019            { 
     1020                IspEnvironment->WipeDevice = 1; 
     1021                DebugPrintf(3, "Wipe entire device before writing.\n"); 
     1022                continue; 
     1023            } 
     1024 
     1025            if (stricmp(argv[i], "-bin") == 0) 
     1026            { 
     1027                IspEnvironment->FileFormat = FORMAT_BINARY; 
     1028                DebugPrintf(3, "Binary format file input.\n"); 
     1029                continue; 
     1030            } 
     1031 
     1032            if (stricmp(argv[i], "-hex") == 0) 
     1033            { 
     1034                IspEnvironment->FileFormat = FORMAT_HEX; 
     1035                DebugPrintf(3, "Hex format file input.\n"); 
     1036                continue; 
     1037            } 
     1038 
     1039            if (stricmp(argv[i], "-logfile") == 0) 
     1040            { 
     1041                IspEnvironment->LogFile = 1; 
     1042                DebugPrintf(3, "Log terminal output.\n"); 
     1043                continue; 
     1044            } 
     1045 
     1046            if (stricmp(argv[i], "-detectonly") == 0) 
     1047            { 
     1048                IspEnvironment->DetectOnly  = 1; 
     1049                IspEnvironment->ProgramChip = 0; 
     1050                DebugPrintf(3, "Only detect LPC chip part id.\n"); 
     1051                continue; 
     1052            } 
     1053 
     1054            if (stricmp(argv[i], "-debug") == 0) 
     1055            { 
     1056                debug_level = 4; 
     1057                DebugPrintf(3, "Turn on debug.\n"); 
     1058                continue; 
     1059            } 
     1060 
     1061            if (stricmp(argv[i], "-control") == 0) 
     1062            { 
     1063                IspEnvironment->ControlLines = 1; 
     1064                DebugPrintf(3, "Use RTS/DTR to control target state.\n"); 
     1065                continue; 
     1066            } 
     1067 
     1068            if (stricmp(argv[i], "-controlswap") == 0) 
     1069            { 
     1070                IspEnvironment->ControlLinesSwapped = 1; 
     1071                DebugPrintf(3, "Use RTS to control reset, and DTR to control P0.14(ISP).\n"); 
     1072                continue; 
     1073            } 
     1074 
     1075            if (stricmp(argv[i], "-controlinv") == 0) 
     1076            { 
     1077                IspEnvironment->ControlLinesInverted = 1; 
     1078                DebugPrintf(3, "Invert state of RTS & DTR (0=true/assert/set, 1=false/deassert/clear).\n"); 
     1079                continue; 
     1080            } 
     1081 
     1082            if (stricmp(argv[i], "-halfduplex") == 0) 
     1083            { 
     1084                IspEnvironment->HalfDuplex = 1; 
     1085                DebugPrintf(3, "halfduplex serial communication.\n"); 
     1086                continue; 
     1087            } 
     1088 
     1089            if (stricmp(argv[i], "-ADARM") == 0) 
    11151090            { 
    11161091                IspEnvironment->micro = ANALOG_DEVICES_ARM; 
    1117                 DebugPrintf( 2, "Target: Analog Devices.\n"); 
    1118             } 
    1119             else if( stricmp( argv[i], "-PHILIPSARM") == 0) 
     1092                DebugPrintf(2, "Target: Analog Devices.\n"); 
     1093                continue; 
     1094            } 
     1095 
     1096            if (stricmp(argv[i], "-PHILIPSARM") == 0) 
    11201097            { 
    11211098                IspEnvironment->micro = PHILIPS_ARM; 
    1122                 DebugPrintf( 2, "Target: Philips.\n"); 
    1123             } 
    1124             else 
    1125             { 
    1126                 DebugPrintf( 2, "Unknown command line option: \"%s\"\n", argv[i]); 
    1127             } 
     1099                DebugPrintf(2, "Target: Philips.\n"); 
     1100                continue; 
     1101            } 
     1102 
     1103            if (stricmp(argv[i], "-Verify") == 0) 
     1104            { 
     1105                IspEnvironment->Verify = 1; 
     1106                DebugPrintf(2, "Verify after copy RAM to Flash.\n"); 
     1107                continue; 
     1108            } 
     1109 
     1110#ifdef INTEGRATED_IN_WIN_APP 
     1111            if (stricmp(argv[i], "-nosync") == 0) 
     1112            { 
     1113                IspEnvironment->NoSync = 1; 
     1114                DebugPrintf(2, "Performing no syncing, already done.\n"); 
     1115                continue; 
     1116            } 
     1117#endif 
     1118 
     1119#ifdef TERMINAL_SUPPORT 
     1120            if (CheckTerminalParameters(IspEnvironment, argv[i])) 
     1121            { 
     1122                continue; 
     1123            } 
     1124#endif 
     1125 
     1126            DebugPrintf(2, "Unknown command line option: \"%s\"\n", argv[i]); 
    11281127        } 
    11291128 
    11301129        IspEnvironment->input_file = argv[argc - 4]; 
    1131         IspEnvironment->StringOscillator = argv[argc - 1]; 
     1130 
     1131        // Newest cygwin delivers a '\x0d' at the end of argument 
     1132        // when calling lpc21isp from batch file 
     1133        for (i = 0; i < strlen(argv[argc - 1]) && i < (sizeof(IspEnvironment->StringOscillator) - 1) && 
     1134            argv[argc - 1][i] >= '0' && argv[argc - 1][i] <= '9'; i++) 
     1135        { 
     1136            IspEnvironment->StringOscillator[i] = argv[argc - 1][i]; 
     1137        } 
     1138        IspEnvironment->StringOscillator[i] = 0; 
     1139 
    11321140        IspEnvironment->serial_port = argv[argc - 3]; 
    11331141        IspEnvironment->baud_rate = argv[argc - 2]; 
    11341142    } 
    11351143 
    1136     if(argc < 5) 
     1144    if (argc < 5) 
    11371145    { 
    11381146        debug_level = (debug_level < 2) ? 2 : debug_level; 
    11391147    } 
    11401148 
    1141     if(argc < 5) 
    1142     { 
    1143         DebugPrintf( 2, "\n"); 
    1144         DebugPrintf( 2, "Portable command line ISP for Philips LPC2000 family and \n"); 
    1145         DebugPrintf( 2, "Version " VERSION_STR "                 Analog Devices ADUC 70xx\n"); 
    1146         DebugPrintf( 2, "Compiled for %s: %s %s\n", COMPILED_FOR, __DATE__, __TIME__); 
    1147         DebugPrintf( 2, "Copyright (c) by Martin Maurer, 2003-2005  Email: Martin.Maurer@clibb.de\n"); 
    1148         DebugPrintf( 2, "Portions Copyright (c) by Aeolus Development 2004\n"); 
    1149         DebugPrintf( 2, "                 http://www.aeolusdevelopment.com\n"); 
    1150         DebugPrintf( 2, "\n"); 
    1151  
    1152         DebugPrintf( 1, "Syntax:  lpc21isp [Options] file comport baudrate Oscillator_in_kHz\n\n"); 
    1153         DebugPrintf( 1, "Example: lpc21isp test.hex com1 115200 14746\n\n"); 
    1154         DebugPrintf( 1, "Options: -bin           for uploading binary file\n"); 
    1155         DebugPrintf( 1, "         -hex           for uploading file in intel hex format (default)\n"); 
    1156         DebugPrintf( 1, "         -term          for starting terminal after upload\n"); 
    1157         DebugPrintf( 1, "         -termonly      for starting terminal without an upload\n"); 
    1158         DebugPrintf( 1, "         -detectonly    detect only used LPC chiptype (PHILIPSARM only)\n"); 
    1159         DebugPrintf( 1, "         -debug         for creating a lot of debug infos\n"); 
    1160         DebugPrintf( 1, "         -wipe          Erase entire device before upload\n"); 
    1161         DebugPrintf( 1, "         -control       for controlling RS232 lines for easier booting\n"); 
    1162         DebugPrintf( 1, "                        (Reset = DTR, EnableBootLoader = RTS)\n"); 
    1163         DebugPrintf( 1, "         -logfile       for enabling logging of terminal output to lpc21isp.log\n"); 
    1164         DebugPrintf( 1, "         -ADARM         for downloading to an Analog Devices\n"); 
    1165         DebugPrintf( 1, "                        ARM microcontroller ADUC70xx\n"); 
    1166         DebugPrintf( 1, "         -PHILIPSARM    for downloading to a microcontroller from\n"); 
    1167         DebugPrintf( 1, "                        Philips LPC2000 family (default)\n"); 
     1149    if (argc < 5) 
     1150    { 
     1151        DebugPrintf(2, "\n" 
     1152                       "Portable command line ISP for NXP LPC2000 family and Analog Devices ADUC 70xx\n" 
     1153                       "Version " VERSION_STR " compiled for " COMPILED_FOR ": " __DATE__ ", " __TIME__ "\n" 
     1154                       "Copyright (c) by Martin Maurer, 2003-2008, Email: Martin.Maurer@clibb.de\n" 
     1155                       "Portions Copyright (c) by Aeolus Development 2004, www.aeolusdevelopment.com\n" 
     1156                       "\n"); 
     1157 
     1158        DebugPrintf(1, "Syntax:  lpc21isp [Options] file comport baudrate Oscillator_in_kHz\n\n" 
     1159                       "Example: lpc21isp test.hex com1 115200 14746\n\n" 
     1160                       "Options: -bin         for uploading binary file\n" 
     1161                       "         -hex         for uploading file in intel hex format (default)\n" 
     1162                       "         -term        for starting terminal after upload\n" 
     1163                       "         -termonly    for starting terminal without an upload\n" 
     1164                       "         -localecho   for local echo in terminal\n" 
     1165                       "         -detectonly  detect only used LPC chiptype (PHILIPSARM only)\n" 
     1166                       "         -debug       for creating a lot of debug infos\n" 
     1167                       "         -wipe        Erase entire device before upload\n" 
     1168                       "         -control     for controlling RS232 lines for easier booting\n" 
     1169                       "                      (Reset = DTR, EnableBootLoader = RTS)\n" 
     1170#ifdef INTEGRATED_IN_WIN_APP 
     1171                       "         -nosync      Do not synchronize device via '?'\n" 
     1172#endif 
     1173                       "         -controlswap swap RS232 control lines\n" 
     1174                       "                      (Reset = RTS, EnableBootLoader = DTR)\n" 
     1175                       "         -controlinv  Invert state of RTS & DTR \n" 
     1176                       "                      (0=true/assert/set, 1=false/deassert/clear).\n" 
     1177                       "         -verify      Verify the data in Flash after every writes to\n" 
     1178                       "                      sector. To detect errors in writing to Flash ROM\n" 
     1179                       "         -logfile     for enabling logging of terminal output to lpc21isp.log\n" 
     1180                       "         -halfduplex  use halfduplex serial communication (i.e. with K-Line)\n" 
     1181                       "         -ADARM       for downloading to an Analog Devices\n" 
     1182                       "                      ARM microcontroller ADUC70xx\n" 
     1183                       "         -PHILIPSARM  for downloading to a microcontroller from\n" 
     1184                       "                      Philips LPC2000 family (default)\n"); 
    11681185 
    11691186        exit(1); 
    11701187    } 
    11711188 
    1172     if(IspEnvironment->micro == PHILIPS_ARM) 
    1173     { 
     1189    if (IspEnvironment->micro == PHILIPS_ARM) 
     1190    { 
     1191        // If StringOscillator is bigger than 100 MHz, there seems to be something wrong 
    11741192        if (strlen(IspEnvironment->StringOscillator) > 5) 
    11751193        { 
    1176             DebugPrintf( 1, "Invalid crystal frequency %s",argv[argc - 1]); 
     1194            DebugPrintf(1, "Invalid crystal frequency %s\n", IspEnvironment->StringOscillator); 
    11771195            exit(1); 
    11781196        } 
    11791197    } 
    11801198} 
    1181  
    1182 typedef enum 
    1183 { 
    1184     PROGRAM_MODE, 
    1185     RUN_MODE 
    1186 } TARGET_MODE; 
    11871199 
    11881200/***************************** ResetTarget ******************************/ 
     
    11911203\param [in] mode the mode to leave the target in. 
    11921204*/ 
    1193 static void ResetTarget( ISP_ENVIRONMENT *IspEnvironment, TARGET_MODE mode) 
    1194 { 
    1195  
    1196     if(IspEnvironment->ControlLines) 
    1197     { 
    1198  
    1199         switch( mode) 
     1205void ResetTarget(ISP_ENVIRONMENT *IspEnvironment, TARGET_MODE mode) 
     1206{ 
     1207    if (IspEnvironment->ControlLines) 
     1208    { 
     1209        switch (mode) 
    12001210        { 
    1201                 /* Reset and jump to boot loader.                       */ 
    1202             case PROGRAM_MODE: 
    1203                 ControlModemLines(IspEnvironment, 1, 1); 
    1204                 Sleep(100); 
    1205                 ClearSerialPortBuffers(IspEnvironment); 
    1206                 Sleep(100); 
    1207                 ControlModemLines(IspEnvironment, 0, 1); 
    1208                 //Longer delay is the Reset signal is conected to an external rest controller 
    1209                 Sleep(500); 
    1210                 // Clear the RTS line after having reset the micro 
    1211                 // Needed for the "GO <Address> <Mode>" ISP command to work */ 
    1212                 ControlModemLines(IspEnvironment, 0, 0); 
    1213                 break; 
    1214  
    1215                 /* Reset and start uploaded program                     */ 
    1216             case RUN_MODE: 
    1217                 ControlModemLines(IspEnvironment, 1, 0); 
    1218                 Sleep(100); 
    1219                 ClearSerialPortBuffers(IspEnvironment); 
    1220                 Sleep(100); 
    1221                 ControlModemLines(IspEnvironment, 0, 0); 
    1222                 Sleep(100); 
    1223                 break; 
     1211        /* Reset and jump to boot loader.                       */ 
     1212        case PROGRAM_MODE: 
     1213            ControlModemLines(IspEnvironment, 1, 1); 
     1214            Sleep(100); 
     1215            ClearSerialPortBuffers(IspEnvironment); 
     1216            Sleep(100); 
     1217            ControlModemLines(IspEnvironment, 0, 1); 
     1218            //Longer delay is the Reset signal is conected to an external rest controller 
     1219            Sleep(500); 
     1220            // Clear the RTS line after having reset the micro 
     1221            // Needed for the "GO <Address> <Mode>" ISP command to work */ 
     1222            ControlModemLines(IspEnvironment, 0, 0); 
     1223            break; 
     1224 
     1225        /* Reset and start uploaded program                     */ 
     1226        case RUN_MODE: 
     1227            ControlModemLines(IspEnvironment, 1, 0); 
     1228            Sleep(100); 
     1229            ClearSerialPortBuffers(IspEnvironment); 
     1230            Sleep(100); 
     1231            ControlModemLines(IspEnvironment, 0, 0); 
     1232            Sleep(100); 
     1233            break; 
    12241234        } 
    12251235    } 
    12261236} 
    12271237 
    1228 /***************************** LoadFile *********************************/ 
    1229 /**  Loads the requested file to download into memory. 
    1230 \param [in] IspEnvironment  structure containing input filename 
    1231 */ 
    1232 static void LoadFile(ISP_ENVIRONMENT *IspEnvironment) 
    1233 { 
    1234     int fd; 
    1235     int i; 
    1236     int BinaryOffsetDefined; 
    1237     unsigned long  Pos; 
    1238     unsigned long  FileLength; 
    1239     BINARY        *FileContent;              /**< Used to store the content of a hex */ 
    1240                                              /* file before converting to binary.    */ 
    1241     unsigned long BinaryMemSize; 
    1242  
    1243     fd = open(IspEnvironment->input_file, O_RDONLY | O_BINARY); 
    1244     if(fd == -1) 
    1245     { 
    1246         DebugPrintf( 1, "Can't open file %s\n", IspEnvironment->input_file); 
    1247         exit(1); 
    1248     } 
    1249  
    1250     FileLength = lseek(fd, 0L, 2);      // Get file size 
    1251  
    1252     if(FileLength == (size_t)-1) 
    1253     { 
    1254         DebugPrintf( 1, "\nFileLength = -1 !?!\n"); 
    1255         exit(1); 
    1256     } 
    1257  
    1258     lseek(fd, 0L, 0); 
    1259  
    1260     FileContent = malloc(FileLength); 
    1261  
    1262     BinaryMemSize = FileLength * 2; 
    1263  
    1264     IspEnvironment->BinaryLength = 0;   /* Increase length as needed.       */ 
    1265         IspEnvironment->BinaryOffset = 0; 
    1266         IspEnvironment->StartAddress = 0; 
    1267         BinaryOffsetDefined = 0; 
    1268  
    1269     IspEnvironment->BinaryContent = malloc(BinaryMemSize); 
    1270  
    1271     read(fd, FileContent, FileLength); 
    1272  
    1273     close(fd); 
    1274  
    1275     DebugPrintf( 2, "File %s:\n\tloaded...\n", IspEnvironment->input_file); 
    1276  
    1277         // Intel-Hex -> Binary Conversion 
    1278  
    1279     if(IspEnvironment->FormatHex != 0) 
    1280     { 
     1238 
     1239/***************************** Ascii2Hex ********************************/ 
     1240/**  Converts a hex character to its equivalent number value. In case of an 
     1241error rather abruptly terminates the program. 
     1242\param [in] c the hex digit to convert. 
     1243\return the value of the hex digit. 
     1244*/ 
     1245static unsigned char Ascii2Hex(unsigned char c) 
     1246{ 
     1247    if (c >= '0' && c <= '9') 
     1248    { 
     1249        return (unsigned char)(c - '0'); 
     1250    } 
     1251 
     1252    if (c >= 'A' && c <= 'F') 
     1253    { 
     1254        return (unsigned char)(c - 'A' + 10); 
     1255    } 
     1256 
     1257    if (c >= 'a' && c <= 'f') 
     1258    { 
     1259        return (unsigned char)(c - 'a' + 10); 
     1260    } 
     1261 
     1262    DebugPrintf(1, "Wrong Hex-Nibble %c (%02X)\n", c, c); 
     1263    exit(1); 
     1264 
     1265    return 0;  // this "return" will never be reached, but some compilers give a warning if it is not present 
     1266} 
     1267 
     1268void ReadHexFile(ISP_ENVIRONMENT *IspEnvironment) 
     1269{ 
     1270    LoadFile(IspEnvironment); 
     1271 
     1272    if (IspEnvironment->BinaryLength) 
     1273    { 
     1274        BINARY* FileContent = IspEnvironment->FileContent; 
     1275 
     1276        unsigned long  Pos; 
    12811277        unsigned char  RecordLength; 
    12821278        unsigned short RecordAddress; 
     
    12841280        unsigned char  RecordType; 
    12851281        unsigned char  Hexvalue; 
    1286                 unsigned long  StartAddress; 
    1287  
    1288         DebugPrintf( 3, "Converting file %s to binary format...\n", IspEnvironment->input_file); 
     1282        unsigned long  StartAddress; 
     1283        int            BinaryOffsetDefined = 0; 
     1284        unsigned char  i; 
     1285 
     1286 
     1287        DebugPrintf(3, "Converting file %s to binary format...\n", IspEnvironment->input_file); 
    12891288 
    12901289        Pos = 0; 
    1291         while(Pos < FileLength) 
     1290        while (Pos < IspEnvironment->BinaryLength) 
    12921291        { 
    1293             if(FileContent[Pos] == '\r') 
     1292            if (FileContent[Pos] == '\r') 
    12941293            { 
    12951294                Pos++; 
     
    12971296            } 
    12981297 
    1299             if(FileContent[Pos] == '\n') 
     1298            if (FileContent[Pos] == '\n') 
    13001299            { 
    13011300                Pos++; 
     
    13031302            } 
    13041303 
    1305             if(FileContent[Pos] != ':') 
    1306             { 
    1307                 DebugPrintf( 1, "Missing start of record (':') wrong byte %c / %02X\n", FileContent[Pos], FileContent[Pos]); 
     1304            if (FileContent[Pos] != ':') 
     1305            { 
     1306                DebugPrintf(1, "Missing start of record (':') wrong byte %c / %02X\n", FileContent[Pos], FileContent[Pos]); 
    13081307                exit(1); 
    13091308            } 
     
    13151314            RecordLength  |= Ascii2Hex(FileContent[Pos++]); 
    13161315 
    1317             DebugPrintf( 4, "RecordLength = %02X\n", RecordLength); 
     1316            DebugPrintf(4, "RecordLength = %02X\n", RecordLength); 
    13181317 
    13191318            RecordAddress   = Ascii2Hex(FileContent[Pos++]); 
     
    13251324            RecordAddress  |= Ascii2Hex(FileContent[Pos++]); 
    13261325 
    1327             DebugPrintf( 4, "RecordAddress = %04X\n", RecordAddress); 
     1326            DebugPrintf(4, "RecordAddress = %04X\n", RecordAddress); 
    13281327 
    13291328            RealAddress = RealAddress - (RealAddress & 0xffff) + RecordAddress; 
    13301329 
    1331             DebugPrintf( 4, "RealAddress = %08lX\n", RealAddress); 
     1330            DebugPrintf(4, "RealAddress = %08lX\n", RealAddress); 
    13321331 
    13331332            RecordType      = Ascii2Hex(FileContent[Pos++]); 
     
    13351334            RecordType     |= Ascii2Hex(FileContent[Pos++]); 
    13361335 
    1337             DebugPrintf( 4, "RecordType = %02X\n", RecordType); 
    1338  
    1339             if(RecordType == 0x00)          // 00 - Data record 
    1340             { 
    1341                                 /* 
    1342                                  * Binary Offset is defined as soon as first data record read 
    1343                                  */ 
    1344                                 BinaryOffsetDefined = 1; 
    1345                                      // Memory for binary file big enough ? 
    1346                 while(RealAddress + RecordLength - IspEnvironment->BinaryOffset > BinaryMemSize) 
    1347                 { 
    1348                     BinaryMemSize <<= 1; 
    1349                     IspEnvironment->BinaryContent = realloc(IspEnvironment->BinaryContent, BinaryMemSize); 
    1350                 } 
    1351  
    1352                     // We need to know, what the highest address is, 
    1353                     // how many bytes / sectors we must flash 
    1354                 if(RealAddress + RecordLength - IspEnvironment->BinaryOffset > IspEnvironment->BinaryLength) 
     1336            DebugPrintf(4, "RecordType = %02X\n", RecordType); 
     1337 
     1338            if (RecordType == 0x00)          // 00 - Data record 
     1339            { 
     1340                /* 
     1341                * Binary Offset is defined as soon as first data record read 
     1342                */ 
     1343 
     1344                //BinaryOffsetDefined = 1; 
     1345 
     1346                // Memory for binary file big enough ? 
     1347                while ((RealAddress + RecordLength - IspEnvironment->BinaryOffset) > IspEnvironment->BinaryMemSize) 
     1348                { 
     1349                    IspEnvironment->BinaryMemSize <<= 1;    // Double the size allocated !!! 
     1350                    IspEnvironment->BinaryContent = (BINARY*) realloc(IspEnvironment->BinaryContent, IspEnvironment->BinaryMemSize); 
     1351                } 
     1352 
     1353                // We need to know, what the highest address is, 
     1354                // how many bytes / sectors we must flash 
     1355                if (RealAddress + RecordLength - IspEnvironment->BinaryOffset > IspEnvironment->BinaryLength) 
    13551356                { 
    13561357                    IspEnvironment->BinaryLength = RealAddress + RecordLength - IspEnvironment->BinaryOffset; 
    1357                     DebugPrintf( 3, "Image size now: %ld\n", IspEnvironment->BinaryLength); 
    1358                 } 
    1359  
    1360                 for(i = 0; i < RecordLength; i++) 
     1358                    DebugPrintf(3, "Image size now: %ld\n", IspEnvironment->BinaryLength); 
     1359                } 
     1360 
     1361                for (i = 0; i < RecordLength; i++) 
    13611362                { 
    13621363                    Hexvalue        = Ascii2Hex(FileContent[Pos++]); 
     
    13661367                } 
    13671368            } 
    1368             else if(RecordType == 0x01)     // 01 - End of file record 
     1369            else if (RecordType == 0x01)     // 01 - End of file record 
    13691370            { 
    13701371                break; 
    13711372            } 
    1372             else if(RecordType == 0x02)     // 02 - Extended segment address record 
    1373             { 
    1374                 for(i = 0; i < RecordLength * 2; i++)   // double amount of nibbles 
     1373            else if (RecordType == 0x02)     // 02 - Extended segment address record 
     1374            { 
     1375                for (i = 0; i < RecordLength * 2; i++)   // double amount of nibbles 
    13751376                { 
    13761377                    RealAddress <<= 4; 
    1377                     if(i == 0) 
     1378                    if (i == 0) 
    13781379                    { 
    13791380                        RealAddress  = Ascii2Hex(FileContent[Pos++]); 
     
    13861387                RealAddress <<= 4; 
    13871388            } 
    1388             else if(RecordType == 0x03)     // 03 - Start segment address record 
    1389             { 
    1390                 for(i = 0; i < RecordLength * 2; i++)   // double amount of nibbles 
     1389            else if (RecordType == 0x03)     // 03 - Start segment address record 
     1390            { 
     1391                for (i = 0; i < RecordLength * 2; i++)   // double amount of nibbles 
    13911392                { 
    13921393                    RealAddress <<= 4; 
    1393                     if(i == 0) 
     1394                    if (i == 0) 
    13941395                    { 
    13951396                        RealAddress  = Ascii2Hex(FileContent[Pos++]); 
     
    14021403                RealAddress <<= 8; 
    14031404            } 
    1404             else if(RecordType == 0x04)     // 04 - Extended linear address record, used by IAR 
    1405             { 
    1406                 for(i = 0; i < RecordLength * 2; i++)   // double amount of nibbles 
     1405            else if (RecordType == 0x04)     // 04 - Extended linear address record, used by IAR 
     1406            { 
     1407                for (i = 0; i < RecordLength * 2; i++)   // double amount of nibbles 
    14071408                { 
    14081409                    RealAddress <<= 4; 
    1409                     if(i == 0) 
     1410                    if (i == 0) 
    14101411                    { 
    14111412                        RealAddress  = Ascii2Hex(FileContent[Pos++]); 
     
    14171418                } 
    14181419                RealAddress <<= 16; 
    1419                                 if(!BinaryOffsetDefined) 
    1420                                 { 
    1421                                         // set startaddress of BinaryContent 
    1422                                         // use of LPC_FLASHMASK to allow a memory range, not taking the first 
    1423                                         // [04] record as actual start-address. 
    1424                                         IspEnvironment->BinaryOffset = RealAddress & LPC_FLASHMASK; 
    1425                                 } 
    1426                                 else 
    1427                                 { 
    1428                                         if((RealAddress & LPC_FLASHMASK) != IspEnvironment->BinaryOffset) 
    1429                                         { 
    1430                                                 DebugPrintf(1, "New Extended Linear Address Record [04] out of memory range\n"); 
    1431                                                 DebugPrintf(1, "Current Memory starts at: 0x%08X, new Address is: 0x%08X", 
    1432                                                                    IspEnvironment->BinaryOffset, RealAddress); 
    1433                                                 exit(1); 
    1434                                         } 
    1435                                 } 
    1436             } 
    1437             else if(RecordType == 0x05)     // 05 - Start linear address record 
    1438             { 
    1439                            StartAddress = 0; 
    1440                for(i = 0; i < RecordLength * 2; i++)   // double amount of nibbles 
     1420                if (!BinaryOffsetDefined) 
     1421                { 
     1422                    // set startaddress of BinaryContent 
     1423                    // use of LPC_FLASHMASK to allow a memory range, not taking the first 
     1424                    // [04] record as actual start-address. 
     1425                    IspEnvironment->BinaryOffset = RealAddress & LPC_FLASHMASK; 
     1426                } 
     1427                else 
     1428                { 
     1429                    if ((RealAddress & LPC_FLASHMASK) != IspEnvironment->BinaryOffset) 
     1430                    { 
     1431                        DebugPrintf(1, "New Extended Linear Address Record [04] out of memory range\n" 
     1432                                      "Current Memory starts at: 0x%08X, new Address is: 0x%08X", 
     1433                                       IspEnvironment->BinaryOffset, RealAddress); 
     1434                        exit(1); 
     1435                    } 
     1436                } 
     1437            } 
     1438            else if (RecordType == 0x05)     // 05 - Start linear address record 
     1439            { 
     1440                StartAddress = 0; 
     1441                for (i = 0; i < RecordLength * 2; i++)   // double amount of nibbles 
    14411442                { 
    14421443                    StartAddress <<= 4; 
    1443                     if(i == 0) 
     1444                    if (i == 0) 
    14441445                    { 
    14451446                        StartAddress  = Ascii2Hex(FileContent[Pos++]); 
     
    14501451                    } 
    14511452                } 
    1452                 DebugPrintf( 1,"Start Address = 0x%8X\n", StartAddress); 
     1453                DebugPrintf(1,"Start Address = 0x%8X\n", StartAddress); 
    14531454                IspEnvironment->StartAddress = StartAddress; 
    1454               } 
    1455  
    1456             while(FileContent[Pos++] != 0x0a)      // Search till line end 
     1455            } 
     1456 
     1457            while (FileContent[Pos++] != 0x0a)      // Search till line end 
    14571458            { 
    14581459            } 
    14591460        } 
    14601461 
    1461         DebugPrintf( 2, "\tconverted to binary format...\n"); 
    1462  
    1463             // When debugging is switched on, output result of conversion to file debugout.bin 
    1464         if(debug_level >= 4) 
     1462        DebugPrintf(2, "\tconverted to binary format...\n"); 
     1463 
     1464        // When debugging is switched on, output result of conversion to file debugout.bin 
     1465        if (debug_level >= 4) 
    14651466        { 
    14661467            int fdout; 
     
    14701471        } 
    14711472    } 
     1473} 
     1474 
     1475 
     1476/***************************** LoadFile *********************************/ 
     1477/**  Loads the requested file to download into memory. 
     1478\param [in] IspEnvironment  structure containing input filename 
     1479*/ 
     1480static void LoadFile(ISP_ENVIRONMENT *IspEnvironment) 
     1481{ 
     1482    int            fd; 
     1483    int            i; 
     1484    int            BinaryOffsetDefined; 
     1485    unsigned long  Pos; 
     1486    unsigned long  FileLength; 
     1487    BINARY        *FileContent;              /**< Used to store the content of a hex */ 
     1488                                             /*   file before converting to binary.  */ 
     1489    unsigned long  BinaryMemSize; 
     1490 
     1491    fd = open(IspEnvironment->input_file, O_RDONLY | O_BINARY); 
     1492    if (fd == -1) 
     1493    { 
     1494        DebugPrintf(1, "Can't open file %s\n", IspEnvironment->input_file); 
     1495        exit(1); 
     1496    } 
     1497 
     1498    FileLength = lseek(fd, 0L, 2);      // Get file size 
     1499 
     1500    if (FileLength == (size_t)-1) 
     1501    { 
     1502        DebugPrintf(1, "\nFileLength = -1 !?!\n"); 
     1503        exit(1); 
     1504    } 
     1505 
     1506    lseek(fd, 0L, 0); 
     1507 
     1508    FileContent = (BINARY*) malloc(FileLength); 
     1509 
     1510    BinaryMemSize = FileLength * 2; 
     1511 
     1512    IspEnvironment->BinaryLength = 0;   /* Increase length as needed.       */ 
     1513    IspEnvironment->BinaryOffset = 0; 
     1514    IspEnvironment->StartAddress = 0; 
     1515    BinaryOffsetDefined = 0; 
     1516 
     1517    IspEnvironment->BinaryContent = (BINARY*) malloc(BinaryMemSize); 
     1518 
     1519    read(fd, FileContent, FileLength); 
     1520 
     1521    close(fd); 
     1522 
     1523    DebugPrintf(2, "File %s:\n\tloaded...\n", IspEnvironment->input_file); 
     1524 
     1525    // Intel-Hex -> Binary Conversion 
     1526 
     1527    if (IspEnvironment->FileFormat == FORMAT_HEX) 
     1528    { 
     1529        unsigned char  RecordLength; 
     1530        unsigned short RecordAddress; 
     1531        unsigned long  RealAddress = 0; 
     1532        unsigned char  RecordType; 
     1533        unsigned char  Hexvalue; 
     1534        unsigned long  StartAddress; 
     1535 
     1536        DebugPrintf(3, "Converting file %s to binary format...\n", IspEnvironment->input_file); 
     1537 
     1538        Pos = 0; 
     1539        while (Pos < FileLength) 
     1540        { 
     1541            if (FileContent[Pos] == '\r') 
     1542            { 
     1543                Pos++; 
     1544                continue; 
     1545            } 
     1546 
     1547            if (FileContent[Pos] == '\n') 
     1548            { 
     1549                Pos++; 
     1550                continue; 
     1551            } 
     1552 
     1553            if (FileContent[Pos] != ':') 
     1554            { 
     1555                DebugPrintf(1, "Missing start of record (':') wrong byte %c / %02X\n", FileContent[Pos], FileContent[Pos]); 
     1556                exit(1); 
     1557            } 
     1558 
     1559            Pos++; 
     1560 
     1561            RecordLength   = Ascii2Hex(FileContent[Pos++]); 
     1562            RecordLength <<= 4; 
     1563            RecordLength  |= Ascii2Hex(FileContent[Pos++]); 
     1564 
     1565            DebugPrintf(4, "RecordLength = %02X\n", RecordLength); 
     1566 
     1567            RecordAddress   = Ascii2Hex(FileContent[Pos++]); 
     1568            RecordAddress <<= 4; 
     1569            RecordAddress  |= Ascii2Hex(FileContent[Pos++]); 
     1570            RecordAddress <<= 4; 
     1571            RecordAddress  |= Ascii2Hex(FileContent[Pos++]); 
     1572            RecordAddress <<= 4; 
     1573            RecordAddress  |= Ascii2Hex(FileContent[Pos++]); 
     1574 
     1575            DebugPrintf(4, "RecordAddress = %04X\n", RecordAddress); 
     1576 
     1577            RealAddress = RealAddress - (RealAddress & 0xffff) + RecordAddress; 
     1578 
     1579            DebugPrintf(4, "RealAddress = %08lX\n", RealAddress); 
     1580 
     1581            RecordType      = Ascii2Hex(FileContent[Pos++]); 
     1582            RecordType    <<= 4; 
     1583            RecordType     |= Ascii2Hex(FileContent[Pos++]); 
     1584 
     1585            DebugPrintf(4, "RecordType = %02X\n", RecordType); 
     1586 
     1587            if (RecordType == 0x00)          // 00 - Data record 
     1588            { 
     1589                /* 
     1590                * Binary Offset is defined as soon as first data record read 
     1591                */ 
     1592                BinaryOffsetDefined = 1; 
     1593                // Memory for binary file big enough ? 
     1594                while (RealAddress + RecordLength - IspEnvironment->BinaryOffset > BinaryMemSize) 
     1595                { 
     1596                    BinaryMemSize <<= 1; 
     1597                    IspEnvironment->BinaryContent = (BINARY*) realloc(IspEnvironment->BinaryContent, BinaryMemSize); 
     1598                } 
     1599 
     1600                // We need to know, what the highest address is, 
     1601                // how many bytes / sectors we must flash 
     1602                if (RealAddress + RecordLength - IspEnvironment->BinaryOffset > IspEnvironment->BinaryLength) 
     1603                { 
     1604                    IspEnvironment->BinaryLength = RealAddress + RecordLength - IspEnvironment->BinaryOffset; 
     1605                    DebugPrintf(3, "Image size now: %ld\n", IspEnvironment->BinaryLength); 
     1606                } 
     1607 
     1608                for (i = 0; i < RecordLength; i++) 
     1609                { 
     1610                    Hexvalue        = Ascii2Hex(FileContent[Pos++]); 
     1611                    Hexvalue      <<= 4; 
     1612                    Hexvalue       |= Ascii2Hex(FileContent[Pos++]); 
     1613                    IspEnvironment->BinaryContent[RealAddress + i - IspEnvironment->BinaryOffset] = Hexvalue; 
     1614                } 
     1615            } 
     1616            else if (RecordType == 0x01)     // 01 - End of file record 
     1617            { 
     1618                break; 
     1619            } 
     1620            else if (RecordType == 0x02)     // 02 - Extended segment address record 
     1621            { 
     1622                for (i = 0; i < RecordLength * 2; i++)   // double amount of nibbles 
     1623                { 
     1624                    RealAddress <<= 4; 
     1625                    if (i == 0) 
     1626                    { 
     1627                        RealAddress  = Ascii2Hex(FileContent[Pos++]); 
     1628                    } 
     1629                    else 
     1630                    { 
     1631                        RealAddress |= Ascii2Hex(FileContent[Pos++]); 
     1632                    } 
     1633                } 
     1634                RealAddress <<= 4; 
     1635            } 
     1636            else if (RecordType == 0x03)     // 03 - Start segment address record 
     1637            { 
     1638                for (i = 0; i < RecordLength * 2; i++)   // double amount of nibbles 
     1639                { 
     1640                    RealAddress <<= 4; 
     1641                    if (i == 0) 
     1642                    { 
     1643                        RealAddress  = Ascii2Hex(FileContent[Pos++]); 
     1644                    } 
     1645                    else 
     1646                    { 
     1647                        RealAddress |= Ascii2Hex(FileContent[Pos++]); 
     1648                    } 
     1649                } 
     1650                RealAddress <<= 8; 
     1651            } 
     1652            else if (RecordType == 0x04)     // 04 - Extended linear address record, used by IAR 
     1653            { 
     1654                for (i = 0; i < RecordLength * 2; i++)   // double amount of nibbles 
     1655                { 
     1656                    RealAddress <<= 4; 
     1657                    if (i == 0) 
     1658                    { 
     1659                        RealAddress  = Ascii2Hex(FileContent[Pos++]); 
     1660                    } 
     1661                    else 
     1662                    { 
     1663                        RealAddress |= Ascii2Hex(FileContent[Pos++]); 
     1664                    } 
     1665                } 
     1666                RealAddress <<= 16; 
     1667                if (!BinaryOffsetDefined) 
     1668                { 
     1669                    // set startaddress of BinaryContent 
     1670                    // use of LPC_FLASHMASK to allow a memory range, not taking the first 
     1671                    // [04] record as actual start-address. 
     1672                    IspEnvironment->BinaryOffset = RealAddress & LPC_FLASHMASK; 
     1673                } 
     1674                else 
     1675                { 
     1676                    if ((RealAddress & LPC_FLASHMASK) != IspEnvironment->BinaryOffset) 
     1677                    { 
     1678                        DebugPrintf(1, "New Extended Linear Address Record [04] out of memory range\n"); 
     1679                        DebugPrintf(1, "Current Memory starts at: 0x%08X, new Address is: 0x%08X", 
     1680                            IspEnvironment->BinaryOffset, RealAddress); 
     1681                        exit(1); 
     1682                    } 
     1683                } 
     1684            } 
     1685            else if (RecordType == 0x05)     // 05 - Start linear address record 
     1686            { 
     1687                StartAddress = 0; 
     1688                for (i = 0; i < RecordLength * 2; i++)   // double amount of nibbles 
     1689                { 
     1690                    StartAddress <<= 4; 
     1691                    if (i == 0) 
     1692                    { 
     1693                        StartAddress  = Ascii2Hex(FileContent[Pos++]); 
     1694                    } 
     1695                    else 
     1696                    { 
     1697                        StartAddress |= Ascii2Hex(FileContent[Pos++]); 
     1698                    } 
     1699                } 
     1700                DebugPrintf(1,"Start Address = 0x%8X\n", StartAddress); 
     1701                IspEnvironment->StartAddress = StartAddress; 
     1702            } 
     1703 
     1704            while (FileContent[Pos++] != 0x0a)      // Search till line end 
     1705            { 
     1706            } 
     1707        } 
     1708 
     1709        DebugPrintf(2, "\tconverted to binary format...\n"); 
     1710 
     1711        // When debugging is switched on, output result of conversion to file debugout.bin 
     1712        if (debug_level >= 4) 
     1713        { 
     1714            int fdout; 
     1715            fdout = open("debugout.bin", O_RDWR | O_BINARY | O_CREAT | O_TRUNC, 0777); 
     1716            write(fdout, IspEnvironment->BinaryContent, IspEnvironment->BinaryLength); 
     1717            close(fdout); 
     1718        } 
     1719    } 
    14721720    else 
    14731721    { 
     
    14771725    } 
    14781726 
    1479     DebugPrintf( 2, "\timage size : %ld\n", IspEnvironment->BinaryLength); 
    1480  
    1481         // check length to flash for correct alignment, can happen with broken ld-scripts 
     1727    DebugPrintf(2, "\timage size : %ld\n", IspEnvironment->BinaryLength); 
     1728 
     1729    // check length to flash for correct alignment, can happen with broken ld-scripts 
    14821730    if (IspEnvironment->BinaryLength % 4 != 0) 
    14831731    { 
    14841732        unsigned long NewBinaryLength = ((IspEnvironment->BinaryLength + 3)/4) * 4; 
    14851733 
    1486         DebugPrintf( 2, "Warning:  data not aligned to 32 bits, padded (length was %lX, now %lX)\n", IspEnvironment->BinaryLength, NewBinaryLength); 
     1734        DebugPrintf(2, "Warning:  data not aligned to 32 bits, padded (length was %lX, now %lX)\n", IspEnvironment->BinaryLength, NewBinaryLength); 
    14871735 
    14881736        IspEnvironment->BinaryLength = NewBinaryLength; 
    14891737    } 
    1490  
    1491 } 
    1492  
    1493  
    1494 #define ANALOG_DEVICES_SYNC_CHAR        ((BINARY)0x08) 
    1495 #define ANALOG_DEVICES_SYNC_RESPONSE    ("ADuC") 
    1496 #define ANALOG_DEVICES_SYNC_SIZE        (strlen( ANALOG_DEVICES_SYNC_RESPONSE)) 
    1497  
    1498 typedef struct { 
    1499     BINARY product_id[15]; 
    1500     BINARY version[3]; 
    1501     BINARY reserved[4]; 
    1502     BINARY terminator[2]; 
    1503     } AD_SYNC_RESPONSE; 
    1504  
    1505 /***************************** AnalogDevicesSync ************************/ 
    1506 /**  Attempt to synchronize with an Analog Device ARM micro.  Sends a 
    1507 backspace and reads back the microcontrollers response.  Performs 
    1508 multiple retries. Exits the program on error, returns to caller in the 
    1509 case of success. 
    1510 */ 
    1511 static void AnalogDevicesSync(ISP_ENVIRONMENT *IspEnvironment) 
    1512 { 
    1513     BINARY sync;                        /* Holds sync command.          */ 
    1514     AD_SYNC_RESPONSE response;          /* Response from micro.         */ 
    1515     int sync_attempts;                  /* Number of retries.           */ 
    1516  
    1517         /*  Make sure we don't read garbage later instead of the        */ 
    1518         /* response we expect from the micro.                           */ 
     1738} 
     1739#endif // !defined COMPILE_FOR_LPC21 
     1740 
     1741#ifndef COMPILE_FOR_LPC21 
     1742int PerformActions(ISP_ENVIRONMENT *IspEnvironment) 
     1743{ 
     1744    int downloadResult = -1; 
     1745 
     1746    DebugPrintf(2, "lpc21isp version " VERSION_STR "\n"); 
     1747 
     1748    /* Download requested, read in the input file.                  */ 
     1749    if (IspEnvironment->ProgramChip) 
     1750    { 
     1751        LoadFile(IspEnvironment); 
     1752    } 
     1753 
     1754    OpenSerialPort(IspEnvironment);   /* Open the serial port to the microcontroller. */ 
     1755 
     1756    ResetTarget(IspEnvironment, PROGRAM_MODE); 
     1757 
    15191758    ClearSerialPortBuffers(IspEnvironment); 
    15201759 
    1521     DebugPrintf( 2, "Synchronizing\n"); /* Progress report.             */ 
    1522  
    1523     sync = ANALOG_DEVICES_SYNC_CHAR;    /* Build up sync command.       */ 
    1524  
    1525         /*  Perform the actual sync attempt.  First send the sync       */ 
    1526         /* character, the attempt to read back the response.  For the   */ 
    1527         /* AD ARM micro this is a fixed length block.  If response is   */ 
    1528         /* received attempt to validate it by comparing the first       */ 
    1529         /* characters to those expected.  If the received block does    */ 
    1530         /* not validate or is incomplete empty the serial buffer and    */ 
    1531         /* retry.                                                       */ 
    1532     for(sync_attempts = 0; sync_attempts < 5; sync_attempts++) 
    1533     { 
    1534         SendComPortBlock( IspEnvironment, &sync, 1); 
    1535  
    1536         if( ReceiveComPortBlockComplete( IspEnvironment, &response, sizeof( response), 
    1537             500) == 0) 
     1760    /* Perform the requested download.                              */ 
     1761    if (IspEnvironment->ProgramChip || IspEnvironment->DetectOnly) 
     1762    { 
     1763        switch (IspEnvironment->micro) 
    15381764        { 
    1539  
    1540             if( memcmp( response.product_id, ANALOG_DEVICES_SYNC_RESPONSE, 
    1541                 ANALOG_DEVICES_SYNC_SIZE) == 0) 
    1542             { 
    1543                 return; 
    1544             } 
    1545             else 
    1546             { 
    1547                 DumpString( 3, &response, sizeof(response), 
    1548                     "Unexpected response to sync attempt "); 
    1549             } 
     1765#ifdef LPC_SUPPORT 
     1766        case PHILIPS_ARM: 
     1767            downloadResult = PhilipsDownload(IspEnvironment); 
     1768            break; 
     1769#endif 
     1770 
     1771#ifdef AD_SUPPORT 
     1772        case ANALOG_DEVICES_ARM: 
     1773            downloadResult = AnalogDevicesDownload(IspEnvironment); 
     1774            break; 
     1775#endif 
    15501776        } 
    1551         else 
     1777 
     1778        if (downloadResult != 0) 
    15521779        { 
    1553             DebugPrintf( 3, "No (or incomplete) answer on sync attempt\n"); 
     1780            CloseSerialPort(IspEnvironment); 
     1781            exit(downloadResult); 
    15541782        } 
    1555  
    1556         ClearSerialPortBuffers(IspEnvironment); 
    1557     } 
    1558  
    1559     DebugPrintf( 1, "No (or unacceptable) answer on sync attempt\n"); 
    1560     exit(4); 
    1561 } 
    1562  
    1563 typedef struct { 
    1564     char start1; 
    1565     char start2; 
    1566     BINARY bytes; 
    1567     char cmd; 
    1568     BINARY address_h; 
    1569     BINARY address_u; 
    1570     BINARY address_m; 
    1571     BINARY address_l; 
    1572     BINARY data[251]; 
    1573     } AD_PACKET; 
    1574  
    1575 /***************************** AnalogDevicesFormPacket ******************/ 
    1576 /**  Create an Analog Devices communication packet from the constituent 
    1577 elements. 
    1578 \param [in] cmd The command being sent, one of 'E' for erase, 'W' for 
    1579 write, 'V' for verify or 'R' for run.. 
    1580 \param [in] no_bytes the number of data bytes to send with the command in 
    1581 the packet. 
    1582 \param [in] address the address to apply the command to. 
    1583 \param [in] data the data to send with the packet, may be null if no_bytes 
    1584 is zero. 
    1585 \param[out] packet that will be filled. 
    1586 */ 
    1587 static void AnalogDevicesFormPacket( ISP_ENVIRONMENT *IspEnvironment, 
    1588                                      char cmd, int no_bytes, unsigned int address, 
    1589                                      const void *data, AD_PACKET *packet) 
    1590 { 
    1591     BINARY checksum; 
    1592     const BINARY *data_in; 
    1593     int i; 
    1594  
    1595     (void)IspEnvironment; /* never used in this function */ 
    1596  
    1597         /*  Some sanity checking on the arguments.  These should only   */ 
    1598         /* fail if there is a bug in the caller.                        */ 
    1599         /*  Check 1) that the number of data bytes is in an acceptable  */ 
    1600         /* range, 2) that we have a non-null pointer if data is being   */ 
    1601         /* put in the packet and 3) that we have a non-null pointer to  */ 
    1602         /* the packet to be filled. We just exit with an error message  */ 
    1603         /* if any of these tests fail.                                  */ 
    1604     if( (no_bytes < 0) || (no_bytes > 250)) 
    1605     { 
    1606         DebugPrintf( 1, 
    1607             "The number of bytes (%d) passed to FormPacket is invalid.\n", 
    1608             no_bytes); 
    1609         exit( -1); 
    1610     } 
    1611     if( (data == 0) && (no_bytes != 0)) 
    1612     { 
    1613         DebugPrintf( 1, 
    1614             "A null pointer to data paased to FormPacket when data was expected.\n"); 
    1615         exit( -1); 
    1616     } 
    1617     if( packet == 0) 
    1618     { 
    1619         DebugPrintf( 1, 
    1620             "A null packet pointer was passed to FormPacket.\n"); 
    1621         exit( -1); 
    1622     } 
    1623  
    1624     checksum = 0;               /*  Checksum starts at zero.            */ 
    1625  
    1626     data_in = data;             /*  Pointer pun so we can walk through  */ 
    1627                                 /* the data.                            */ 
    1628  
    1629     packet->start1 = 0x7;       /*  The start of the packet is constant.*/ 
    1630     packet->start2 = 0xE; 
    1631  
    1632         /*  Fill in the rest of the packet and calculate the checksum   */ 
    1633         /* as we go.                                                    */ 
    1634  
    1635         /* The number of bytes is the number of data bytes + the        */ 
    1636         /* address bytes + the command byte.                            */ 
    1637     packet->bytes = (BINARY)(no_bytes + 5); 
    1638  
    1639     checksum += packet->bytes; 
    1640  
    1641         /*  The command for the packet being sent.  No error checking   */ 
    1642         /* done on this.                                                */ 
    1643     packet->cmd = cmd; 
    1644  
    1645     checksum += cmd; 
    1646  
    1647         /*  Now break up the address and place in the proper packet     */ 
    1648         /* locations.                                                   */ 
    1649     packet->address_l = (BINARY)(address & 0xFF); 
    1650     packet->address_m = (BINARY)((address >> 8) & 0xFF); 
    1651     packet->address_u = (BINARY)((address >> 16) & 0xFF); 
    1652     packet->address_h = (BINARY)((address >> 24) & 0xFF); 
    1653  
    1654     checksum += packet->address_l; 
    1655     checksum += packet->address_m; 
    1656     checksum += packet->address_u; 
    1657     checksum += packet->address_h; 
    1658  
    1659         /*  Copy the data bytes into the packet.  We could use memcpy   */ 
    1660         /* but we have to calculate the checksum anyway.                */ 
    1661     for( i = 0; i < no_bytes; i++) 
    1662     { 
    1663         packet->data[i] = data_in[i]; 
    1664         checksum += data_in[i]; 
    1665     } 
    1666