Changeset 566 for trunk/tools/lpc21isp
- Timestamp:
- 11/23/09 01:30:28 (4 months ago)
- Location:
- trunk/tools/lpc21isp
- Files:
-
- 13 added
- 3 modified
-
Makefile (modified) (1 diff)
-
Makefile.vc (added)
-
README (added)
-
StdAfx.h (added)
-
adprog.c (added)
-
adprog.h (added)
-
gpl.txt (added)
-
lgpl-3.0.txt (added)
-
lpc21isp.c (modified) (45 diffs)
-
lpc21isp.h (modified) (1 diff)
-
lpcprog.c (added)
-
lpcprog.dsp (added)
-
lpcprog.dsw (added)
-
lpcprog.h (added)
-
lpcterm.c (added)
-
lpcterm.h (added)
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/ 1 all: lpc21isp 5 2 6 all: lpc21isp 3 GLOBAL_DEP = adprog.h lpc21isp.h lpcprog.h lpcterm.h 4 CC = gcc 7 5 8 .c.o: 9 $(CC) $(CFLAGS) -c $< -o $@ 6 ifneq ($(findstring(freebsd, $(OSTYPE))),) 7 CFLAGS+=-D__FREEBSD__ 8 endif 10 9 11 lpc21isp: $(OBJS) 12 $(CC) -o $@ $(OBJS) 10 adprog.o: adprog.c $(GLOBAL_DEP) 11 $(CC) $(CDEBUG) $(CFLAGS) -c -o adprog.o adprog.c 12 13 lpcprog.o: lpcprog.c $(GLOBAL_DEP) 14 $(CC) $(CDEBUG) $(CFLAGS) -c -o lpcprog.o lpcprog.c 15 16 lpcterm.o: lpcterm.c $(GLOBAL_DEP) 17 $(CC) $(CDEBUG) $(CFLAGS) -c -o lpcterm.o lpcterm.c 18 19 lpc21isp: lpc21isp.c adprog.o lpcprog.o lpcterm.o $(GLOBAL_DEP) 20 $(CC) $(CDEBUG) $(CFLAGS) -o lpc21isp lpc21isp.c adprog.o lpcprog.o lpcterm.o 13 21 14 22 clean: 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 6 6 Filename: lpc21isp.c 7 7 8 Compiler: Microsoft VC 6/7, GCC Cygwin, GCC Linux 9 10 Aut or:Martin Maurer (Martin.Maurer@clibb.de)11 12 Copyright: (c) Martin Maurer 2003-200 7, All rights reserved8 Compiler: Microsoft VC 6/7, GCC Cygwin, GCC Linux, GCC ARM ELF 9 10 Author: Martin Maurer (Martin.Maurer@clibb.de) 11 12 Copyright: (c) Martin Maurer 2003-2008, All rights reserved 13 13 Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com 14 14 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 /* 17 43 Change-History: 18 44 19 1.00 2004-01-08 Initial Version, tested for MSVC6/7 and GCC under Cygwin20 1.01 2004-01-10 Porting to Linux (at least compiling must work)21 1.02 2004-01-10 Implemented conversion intel hex format -> binary22 1.03 2004-01-25 Preparation to upload to public website23 1.04 2004-02-12 Merged in bugfixes by Soeren Gust24 1.05 2004-03-14 Implement printing of error codes as text / strings25 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 booting36 1.08 2004-04-01 Bugfix for upload problem37 1.09 2004-04-03 Redesign of upload routine38 Now always 180 byte blocks are uploaded, to prevent39 small junks in uuencoding40 1.10 2004-04-03 Clear buffers before sending commands to LPC21xx,41 this prevents synchronizing errors when previously loaded42 program does a lot of output, so FIFO of PC runs full43 1.11 2004-04-03 Small optimization for controlling reset line44 otherwise termonly starts LPC twice, free PC buffers45 1.12 2004-04-04 Add switch to enable logging terminal output to lpc21isp.log46 1.13 2004-05-19 Merged in improvement by Charles Manning:47 Instead of exiting the wrong hex file size is corrected48 1.14 2004-07-07 Merged in improvement by Alex Holden:49 Remove little/big endian dependancy50 1.15 2004-09-27 Temporary improvement by Cyril Holweck:51 Removed test (data echoed = data transmited) on the main52 data transfert, since this was the biggest failure53 reason and is covered by checksome anyway.54 Added COMPILE_FOR_LPC21, to have target dump it's own55 memory to stdout.56 1.16 2004-10-09 Merged in bugfix / improvement by Sinelnikov Evgeny57 I found out that Linux and Windows serial port initialization58 are different with pinouts states. My board don't get59 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 Holweck62 Divide main, take out the real programming function, that can63 also be used by a target to copy its own code to another.64 1.18 2004-10-26 Changes by Cyril Holweck65 Added a "G 0 A\r\n" at end of programming to run code.66 1.19 2004-11-03 Changes by Robert Adsett67 Add support for Analog Devices.68 Separate file load from programming.69 Change from a debug on/off flag to debug level70 Remove if(debug) tests and replace with DebugPrintf71 statements.72 Change serial I/O and timing so that the system73 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 Adsett78 BinaryLength was not initialized79 1.22 2004-11-08 Changes from Cyril Holweck / Evgeny Sinelnikov80 Forgotten IspEnvironment-> and bugfixes if COMPILE_FOR_LINUX81 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 chiptype86 (needed for 256 KByte support)87 1.24B 2005-06-02 Changes by Thiadmer Riemersma: completed support for other88 chip types (LPC213x series and others).89 1.24C 2005-06-11 Changes by Thiadmer Riemersma: added the device ID codes for90 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 parameters94 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 start96 (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 reboot101 (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) for104 missing LPC213x and upcoming new LPC214x chips105 (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 offset115 (IspEnvironment->BinaryOffset) and start address (...->StartAddress).116 Changed PhilipsDownload to skip all Flash prepare/erase/copy commands.117 Note: Tested with VC7 only118 1.30 2005-10-04 Rob Jansen:119 - forgot to change the version string in 1.29120 - Wrong text in LoadFile corrected (printed text mentions record type 05,121 this should be 04122 - Changed LoadFile to accept multiple record types 04123 - Changed LoadFile to check on memory size, will not load more than x MB124 if linear extended address records are used125 1.31 2005-11-13 Martin Maurer: Thanks to Frank Gutmann126 Updated number of sectors in device table127 for LPC2194, LPC2292 and LPC2294128 1.32 2005-12-02 Martin Maurer: Corrected missing control of RTS/DTR129 in case user selected -termonly and -control130 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).45 1.00 2004-01-08 Initial Version, tested for MSVC6/7 and GCC under Cygwin 46 1.01 2004-01-10 Porting to Linux (at least compiling must work) 47 1.02 2004-01-10 Implemented conversion intel hex format -> binary 48 1.03 2004-01-25 Preparation to upload to public website 49 1.04 2004-02-12 Merged in bugfixes by Soeren Gust 50 1.05 2004-03-14 Implement printing of error codes as text / strings 51 1.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. 61 1.07 2004-03-14 Implement handling of control lines for easier booting 62 1.08 2004-04-01 Bugfix for upload problem 63 1.09 2004-04-03 Redesign of upload routine 64 Now always 180 byte blocks are uploaded, to prevent 65 small junks in uuencoding 66 1.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 69 1.11 2004-04-03 Small optimization for controlling reset line 70 otherwise termonly starts LPC twice, free PC buffers 71 1.12 2004-04-04 Add switch to enable logging terminal output to lpc21isp.log 72 1.13 2004-05-19 Merged in improvement by Charles Manning: 73 Instead of exiting the wrong hex file size is corrected 74 1.14 2004-07-07 Merged in improvement by Alex Holden: 75 Remove little/big endian dependancy 76 1.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. 82 1.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. 87 1.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. 90 1.18 2004-10-26 Changes by Cyril Holweck 91 Added a "G 0 A\r\n" at end of programming to run code. 92 1.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. 102 1.20 2004-11-07 Preparation for multiport booting (factory support) 103 1.21 2004-11-08 Bugfix from Robert Adsett 104 BinaryLength was not initialized 105 1.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' ;) 111 1.23 2005-01-16 Build in automatic detection of LPC chiptype 112 (needed for 256 KByte support) 113 1.24B 2005-06-02 Changes by Thiadmer Riemersma: completed support for other 114 chip types (LPC213x series and others). 115 1.24C 2005-06-11 Changes by Thiadmer Riemersma: added the device ID codes for 116 chip types LPC2131 and LPC2132. 117 1.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...) 125 1.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) 128 1.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 !) 133 1.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. 137 1.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 144 1.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 151 1.31 2005-11-13 Martin Maurer: Thanks to Frank Gutmann 152 Updated number of sectors in device table 153 for LPC2194, LPC2292 and LPC2294 154 1.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) 157 1.33 2006-10-01 Jean-Marc Koller: 158 Added support for MacOS X (difference on how to set termios baudrate). 133 159 1.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) 165 1.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 168 1.36 2006-25-01 Cyril Holweck 169 PhilipsDownload() will now return a unique error code for each error 170 1.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 173 1.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. 176 1.39 2007-01-12 Martin Maurer 177 Added initial support for new processors LPC23xx and LPC24xx 178 1.40 2007-01-22 Martin Maurer 179 Correction of chip id of LPC2458 180 1.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). 184 1.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. 187 1.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 192 1.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. 195 1.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 200 1.46 2007-02-25 Martin Maurer 201 Again corrected debug output: should solve output of 202 (FFFFFFB5) instead of (B5) 203 1.47 2007-02-27 Robert Adsett 204 Raised timeout on AD send packet function. 205 1.48 2007-04-20 Martin Maurer 206 Thanks to Josef Wolf for preventing to overwrite over end of array 207 1.49 2007-10-16 New Option -halfduplex allow single wire using. 208 Implemented and tested only for Windows. Data Resend implemented. 209 1.50 2007-10-31 Changes by Simon Ellwood 210 Formated the code for readablity 211 Fixed some c++ compiler issues 212 1.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 215 1.52 2008-01-22 Changes by Manuel Koeppen 216 Made compileable again for linux and windows 217 Fixed bug in ClearSerialPortBuffers (linux) 218 1.53 2008-02-25 Changes by Michael Roth 219 Get priority of debug messages wih -control right 220 1.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 224 1.55 2008-03-03 Martin Maurer 225 Thanks to Fausto Marzoli, bugfix for compiling latest version under Linux 226 1.56 2008-04-01 Steve Franks 227 Integrate FreeBSD patch. 228 Add support for swapping and/or inverting RTS & DTR 229 1.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) 234 1.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 243 1.59 2008-07-07 Peter Hayward 244 Fixed freeze under Windows XP SP2 by removing redundant call to SetCommMask. 245 1.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 249 1.61 2008-10-21 Fausto Marzoli (thanks to Geoffrey Wossum for the patches) 250 Fix for compiling latest version under Linux and "ControlLinesSwapped" issue 251 1.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 257 1.63 2008-11-23 Martin Maurer 258 Changed to GNU Lesser General Public License 259 1.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 267 static char RxTmpBuf[256]; // save received data to this buffer for half-duplex 268 char * pRxTmpBuf = RxTmpBuf; 200 269 #endif 201 270 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 272 int debug_level = 2; 236 273 #endif 237 238 #if !defined COMPILE_FOR_LPC21239 #include <fcntl.h>240 #endif241 242 #ifndef O_BINARY243 #define O_BINARY 0244 #endif // O_BINARY245 246 #ifndef DWORD247 #define DWORD unsigned long248 #endif // DWORD249 250 #if defined COMPILE_FOR_LINUX251 #define stricmp strcasecmp252 #endif // defined COMPILE_FOR_LINUX253 254 255 /* Return values used by PhilipsDownload(): reserving all values from 0x1000 to 0x1FFF */256 257 #define NO_ANSWER_WDT 0x1000258 #define NO_ANSWER_QM 0x1001259 #define NO_ANSWER_SYNC 0x1002260 #define NO_ANSWER_OSC 0x1003261 #define NO_ANSWER_RBV 0x1004262 #define NO_ANSWER_RPID 0x1005263 #define ERROR_WRITE_DATA 0x1006264 #define ERROR_WRITE_CRC 0x1007265 #define ERROR_WRITE_CRC2 0x1008266 #define PROGRAM_TOO_LARGE 0x1009267 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 microcontroller281 * memory image. */282 283 /*284 debug levels285 0 - very quiet - Nothing gets printed at this level286 1 - quiet - Only error messages should be printed287 2 - indicate progress - Add progress messages288 3 - first level debug - Major level tracing289 4 - second level debug - Add detailed debugging290 5 - log comm's - log serial I/O291 */292 293 typedef enum294 {295 PHILIPS_ARM,296 ANALOG_DEVICES_ARM297 } TARGET;298 299 typedef struct300 {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 struct311 {312 313 #if !defined COMPILE_FOR_LPC21314 TARGET micro; /**< The type of micro that will be315 * 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 to323 * communicate with the microcontroller.324 * Read from the command line. */325 326 #endif // !defined COMPILE_FOR_LPC21327 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 serial332 * port communicating with the333 * microcontroller. Read from the334 * command line. */335 336 char *StringOscillator; /**< Holds representation of oscillator337 * 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_CYGWIN345 HANDLE hCom;346 #endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN347 348 #if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21349 int fdCom;350 #endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21351 352 #if defined COMPILE_FOR_LINUX353 struct termios oldtio, newtio;354 #endif // defined COMPILE_FOR_LINUX355 356 unsigned serial_timeout_count; /**< Local used to track357 * 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_LPC21372 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 #endif380 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 };430 274 431 275 /************* Portability layer. Serial and console I/O differences */ 432 276 /* are taken care of here. */ 433 277 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 446 279 static void OpenSerialPort(ISP_ENVIRONMENT *IspEnvironment) 447 280 { 448 // Open COM-Port (different between Windows and Linux)449 450 #if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN451 281 DCB dcb; 452 282 COMMTIMEOUTS commtimeouts; … … 454 284 IspEnvironment->hCom = CreateFile(IspEnvironment->serial_port, GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); 455 285 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()); 459 289 exit(2); 460 290 } 461 291 462 DebugPrintf( 3, "COM-Port %s opened...\n", IspEnvironment->serial_port);292 DebugPrintf(3, "COM-Port %s opened...\n", IspEnvironment->serial_port); 463 293 464 294 GetCommState(IspEnvironment->hCom, &dcb); … … 472 302 dcb.fNull = FALSE; 473 303 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()); 477 312 exit(3); 478 313 } 479 314 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); 481 333 482 334 commtimeouts.ReadIntervalTimeout = MAXDWORD; … … 486 338 commtimeouts.WriteTotalTimeoutConstant = 0; 487 339 SetCommTimeouts(IspEnvironment->hCom, &commtimeouts); 488 340 } 489 341 #endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 490 342 491 343 #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); 344 static 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); 498 352 exit(2); 499 353 } 500 354 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); 507 361 508 362 tcgetattr(IspEnvironment->fdCom, &IspEnvironment->oldtio); /* save current port settings */ … … 512 366 513 367 #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 }; 515 376 #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)) 520 380 { 521 381 #ifdef B1152000 522 case 1152000: NEWTERMIOS_SETBAUDARTE( B1152000); break;382 case 1152000: NEWTERMIOS_SETBAUDARTE(B1152000); break; 523 383 #endif // B1152000 524 384 #ifdef B576000 525 case 576000: NEWTERMIOS_SETBAUDARTE( B576000); break;385 case 576000: NEWTERMIOS_SETBAUDARTE(B576000); break; 526 386 #endif // B576000 527 387 #ifdef B230400 528 case 230400: NEWTERMIOS_SETBAUDARTE( B230400); break;388 case 230400: NEWTERMIOS_SETBAUDARTE(B230400); break; 529 389 #endif // B230400 530 390 #ifdef B115200 531 case 115200: NEWTERMIOS_SETBAUDARTE( B115200); break;391 case 115200: NEWTERMIOS_SETBAUDARTE(B115200); break; 532 392 #endif // B115200 533 393 #ifdef B57600 534 case 57600: NEWTERMIOS_SETBAUDARTE( B57600); break;394 case 57600: NEWTERMIOS_SETBAUDARTE(B57600); break; 535 395 #endif // B57600 536 396 #ifdef B38400 537 case 38400: NEWTERMIOS_SETBAUDARTE( B38400); break;397 case 38400: NEWTERMIOS_SETBAUDARTE(B38400); break; 538 398 #endif // B38400 539 399 #ifdef B19200 540 case 19200: NEWTERMIOS_SETBAUDARTE( B19200); break;400 case 19200: NEWTERMIOS_SETBAUDARTE(B19200); break; 541 401 #endif // B19200 542 402 #ifdef B9600 543 case 9600: NEWTERMIOS_SETBAUDARTE( B9600); break;403 case 9600: NEWTERMIOS_SETBAUDARTE(B9600); break; 544 404 #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 551 413 552 414 IspEnvironment->newtio.c_iflag = IGNPAR | IGNBRK | IXON | IXOFF; … … 561 423 562 424 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 } 565 432 #endif // defined COMPILE_FOR_LINUX 566 } 567 433 434 #if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 568 435 static void CloseSerialPort(ISP_ENVIRONMENT *IspEnvironment) 569 436 { 570 #if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN571 572 437 CloseHandle(IspEnvironment->hCom); 438 } 573 439 574 440 #endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 575 441 576 442 #if defined COMPILE_FOR_LINUX 577 578 tcflush(IspEnvironment->fdCom, TCOFLUSH); 579 tcflush(IspEnvironment->fdCom, TCIFLUSH); 443 static void CloseSerialPort(ISP_ENVIRONMENT *IspEnvironment) 444 { 445 tcflush(IspEnvironment->fdCom, TCOFLUSH); 446 tcflush(IspEnvironment->fdCom, TCIFLUSH); 580 447 tcsetattr(IspEnvironment->fdCom, TCSANOW, &IspEnvironment->oldtio); 581 448 582 449 close(IspEnvironment->fdCom); 583 450 } 584 451 #endif // defined COMPILE_FOR_LINUX 585 } 586 587 #endif // !defined COMPILE_FOR_LPC21 452 588 453 589 454 /***************************** SendComPortBlock *************************/ … … 592 457 \param [in] n size of the block. 593 458 */ 594 staticvoid SendComPortBlock(ISP_ENVIRONMENT *IspEnvironment, const void *s, size_t n)459 void SendComPortBlock(ISP_ENVIRONMENT *IspEnvironment, const void *s, size_t n) 595 460 { 596 461 #if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 597 462 598 463 unsigned long realsize; 599 464 size_t m; 465 unsigned long rxsize; 466 char * pch; 467 char * rxpch; 600 468 #endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 601 469 602 DumpString( 4, s, n, "Sending ");470 DumpString(4, s, n, "Sending "); 603 471 604 472 #if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 605 473 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 } 608 502 #endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 609 503 … … 619 513 \param [in] s string to send. 620 514 */ 621 static void SendComPort(ISP_ENVIRONMENT *IspEnvironment, const char *s) 622 { 623 SendComPortBlock( IspEnvironment, s, strlen(s)); 515 void 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 522 with protection against underflow and wrapping at the low end. 523 */ 524 static 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 } 624 534 } 625 535 … … 635 545 buffer that is actually used. 636 546 */ 637 static void ReceiveComPortBlock( ISP_ENVIRONMENT *IspEnvironment, 638 void *answer, unsigned long max_size, 639 unsigned long *real_size) 640 { 547 static void ReceiveComPortBlock(ISP_ENVIRONMENT *IspEnvironment, 548 void *answer, unsigned long max_size, 549 unsigned long *real_size) 550 { 551 char tmp_string[32]; 641 552 642 553 #if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 643 554 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 } 645 578 646 579 #endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN … … 652 585 #endif // defined COMPILE_FOR_LINUX 653 586 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); 660 593 } 661 594 } … … 676 609 static void SerialTimeoutSet(ISP_ENVIRONMENT *IspEnvironment, unsigned timeout_milliseconds) 677 610 { 678 679 611 #if defined COMPILE_FOR_LINUX 680 IspEnvironment->serial_timeout_count = timeout_milliseconds /100;612 IspEnvironment->serial_timeout_count = timeout_milliseconds / 100; 681 613 #elif defined COMPILE_FOR_LPC21 682 IspEnvironment->serial_timeout_count = timeout_milliseconds *200;614 IspEnvironment->serial_timeout_count = timeout_milliseconds * 200; 683 615 #else 684 616 IspEnvironment->serial_timeout_count = timeout_milliseconds; … … 686 618 } 687 619 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 703 621 704 622 /***************************** SerialTimeoutCheck ***********************/ … … 709 627 static int SerialTimeoutCheck(ISP_ENVIRONMENT *IspEnvironment) 710 628 { 711 if (IspEnvironment->serial_timeout_count == 0)629 if (IspEnvironment->serial_timeout_count == 0) 712 630 { 713 631 return 1; … … 723 641 \return The character read from the keyboard. 724 642 */ 725 staticint getch(void)643 int getch(void) 726 644 { 727 645 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);744 646 745 647 /* Read in one character */ 746 648 read(0,&ch,1); 747 748 /* reset the tty to its original settings */749 tcsetattr(0, TCSADRAIN, &origtty);750 649 751 650 return ch; … … 760 659 \retval 1 Characters from the console ready to be read. 761 660 */ 762 staticint kbhit(void)661 int kbhit(void) 763 662 { 764 663 /* return 0 for no key pressed, 1 for key pressed */ 765 664 int return_value = 0; 766 665 767 /* variables to store the current tty state, create a new one */768 struct termios origtty, tty;769 666 /* time struct for the select() function, to only wait a little while */ 770 667 struct timeval select_time; … … 776 673 FD_SET(STDIN_FILENO, &readset); 777 674 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 793 675 /* 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 only795 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) */ 796 678 select_time.tv_sec = 0; 797 679 select_time.tv_usec = 10; … … 804 686 } 805 687 806 /* reset the tty to its original settings */807 tcsetattr(0, TCSADRAIN, &origtty);808 688 809 689 /* return with what we found out */ 810 690 return return_value; 811 691 } 692 struct termios keyboard_origtty; 812 693 #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 698 getting them via getch 699 */ 700 701 void 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 */ 727 void 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 } 813 734 814 735 … … 823 744 static void ControlModemLines(ISP_ENVIRONMENT *IspEnvironment, unsigned char DTR, unsigned char RTS) 824 745 { 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 825 759 #if defined COMPILE_FOR_LINUX 826 760 int status; 827 761 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); 831 765 } 832 766 else 833 767 { 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; 838 772 else status &= ~TIOCM_DTR; 839 773 840 if (RTS) status |= TIOCM_RTS;774 if (RTS) status |= TIOCM_RTS; 841 775 else status &= ~TIOCM_RTS; 842 776 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); 846 780 } 847 781 else 848 782 { 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); 855 789 } 856 790 else 857 791 { 858 DebugPrintf( 1, "ioctl get failed\n");792 DebugPrintf(1, "ioctl get failed\n"); 859 793 } 860 794 … … 862 796 #if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 863 797 864 if (DTR) EscapeCommFunction(IspEnvironment->hCom, SETDTR);798 if (DTR) EscapeCommFunction(IspEnvironment->hCom, SETDTR); 865 799 else EscapeCommFunction(IspEnvironment->hCom, CLRDTR); 866 800 867 if (RTS) EscapeCommFunction(IspEnvironment->hCom, SETRTS);801 if (RTS) EscapeCommFunction(IspEnvironment->hCom, SETRTS); 868 802 else EscapeCommFunction(IspEnvironment->hCom, CLRRTS); 869 803 870 804 #endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN 871 805 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); 873 812 } 874 813 … … 877 816 /** Empty the serial port buffers. Cleans things to a known state. 878 817 */ 879 staticvoid ClearSerialPortBuffers(ISP_ENVIRONMENT *IspEnvironment)818 void ClearSerialPortBuffers(ISP_ENVIRONMENT *IspEnvironment) 880 819 { 881 820 #if defined COMPILE_FOR_LINUX … … 887 826 888 827 // Flush input and output buffers 828 tty=origtty; 889 829 tcsetattr(IspEnvironment->fdCom, TCSAFLUSH, &tty); 890 830 … … 904 844 \param [in] Milliseconds the time to wait for in milliseconds. 905 845 */ 906 staticvoid Sleep(unsigned long MilliSeconds)846 void Sleep(unsigned long MilliSeconds) 907 847 { 908 848 usleep(MilliSeconds*1000); //convert to microseconds … … 934 874 debugging information being sent. 935 875 \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.876 is less than or equal to the current debug level it will be printed. 937 877 \param [in] fmt a standard printf style format string. 938 878 \param [in] ... the usual printf parameters. 939 879 */ 940 static void DebugPrintf( int level, const char *fmt, ...) 880 #if !defined INTEGRATED_IN_WIN_APP 881 void DebugPrintf(int level, const char *fmt, ...) 941 882 { 942 883 va_list ap; 943 884 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 952 897 #endif // !defined COMPILE_FOR_LPC21 953 898 … … 967 912 reading with an incomplete buffer. 968 913 */ 969 static void ReceiveComPort(ISP_ENVIRONMENT *IspEnvironment,970 void*Ans, unsigned long MaxSize,971 unsigned long *RealSize, unsigned long WantedNr0x0A,972 unsigned timeOutMilliseconds)914 void ReceiveComPort(ISP_ENVIRONMENT *IspEnvironment, 915 const char *Ans, unsigned long MaxSize, 916 unsigned long *RealSize, unsigned long WantedNr0x0A, 917 unsigned timeOutMilliseconds) 973 918 { 974 919 unsigned long tmp_realsize; … … 976 921 int eof = 0; 977 922 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); 983 929 984 930 (*RealSize) = 0; … … 986 932 do 987 933 { 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) 991 937 { 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) 995 941 { 996 942 nr_of_0x0A++; 997 943 } 998 else if ( Answer[p] < 0)944 else if (((signed char) Answer[p]) < 0) 999 945 { 1000 946 eof = 1; … … 1005 951 (*RealSize) += tmp_realsize; 1006 952 1007 } while (((*RealSize) < MaxSize) && (SerialTimeoutCheck(IspEnvironment) == 0) && (nr_of_0x0A < WantedNr0x0A) && !eof);953 } while (((*RealSize) < MaxSize) && (SerialTimeoutCheck(IspEnvironment) == 0) && (nr_of_0x0A < WantedNr0x0A) && !eof); 1008 954 1009 955 Answer[(*RealSize)] = 0; 1010 956 1011 DumpString( 3, Answer, (*RealSize), "Answer(Length=%ld): ", (*RealSize)); 957 sprintf(tmp_string, "Answer(Length=%ld): ", (*RealSize)); 958 DumpString(3, Answer, (*RealSize), tmp_string); 1012 959 } 1013 960 … … 1024 971 \return 0 if successful, non-zero otherwise. 1025 972 */ 1026 static int ReceiveComPortBlockComplete(ISP_ENVIRONMENT *IspEnvironment,1027 void *block, size_t size, unsigned timeout)973 int ReceiveComPortBlockComplete(ISP_ENVIRONMENT *IspEnvironment, 974 void *block, size_t size, unsigned timeout) 1028 975 { 1029 976 unsigned long realsize = 0, read; 1030 977 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); 1035 983 1036 984 do 1037 985 { 1038 ReceiveComPortBlock( IspEnvironment, result + realsize, size - realsize, &read);986 ReceiveComPortBlock(IspEnvironment, result + realsize, size - realsize, &read); 1039 987 1040 988 realsize += read; 1041 989 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) 1047 996 { 1048 997 return 1; … … 1059 1008 \param [in] argv an array of pointers to the arguments. 1060 1009 */ 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++)1010 static 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++) 1068 1017 { 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) 1115 1090 { 1116 1091 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) 1120 1097 { 1121 1098 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]); 1128 1127 } 1129 1128 1130 1129 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 1132 1140 IspEnvironment->serial_port = argv[argc - 3]; 1133 1141 IspEnvironment->baud_rate = argv[argc - 2]; 1134 1142 } 1135 1143 1136 if (argc < 5)1144 if (argc < 5) 1137 1145 { 1138 1146 debug_level = (debug_level < 2) ? 2 : debug_level; 1139 1147 } 1140 1148 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"); 1168 1185 1169 1186 exit(1); 1170 1187 } 1171 1188 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 1174 1192 if (strlen(IspEnvironment->StringOscillator) > 5) 1175 1193 { 1176 DebugPrintf( 1, "Invalid crystal frequency %s",argv[argc - 1]);1194 DebugPrintf(1, "Invalid crystal frequency %s\n", IspEnvironment->StringOscillator); 1177 1195 exit(1); 1178 1196 } 1179 1197 } 1180 1198 } 1181 1182 typedef enum1183 {1184 PROGRAM_MODE,1185 RUN_MODE1186 } TARGET_MODE;1187 1199 1188 1200 /***************************** ResetTarget ******************************/ … … 1191 1203 \param [in] mode the mode to leave the target in. 1192 1204 */ 1193 static void ResetTarget( ISP_ENVIRONMENT *IspEnvironment, TARGET_MODE mode) 1194 { 1195 1196 if(IspEnvironment->ControlLines) 1197 { 1198 1199 switch( mode) 1205 void ResetTarget(ISP_ENVIRONMENT *IspEnvironment, TARGET_MODE mode) 1206 { 1207 if (IspEnvironment->ControlLines) 1208 { 1209 switch (mode) 1200 1210 { 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 controller1209 Sleep(500);1210 // Clear the RTS line after having reset the micro1211 // 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; 1224 1234 } 1225 1235 } 1226 1236 } 1227 1237 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 1241 error rather abruptly terminates the program. 1242 \param [in] c the hex digit to convert. 1243 \return the value of the hex digit. 1244 */ 1245 static 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 1268 void ReadHexFile(ISP_ENVIRONMENT *IspEnvironment) 1269 { 1270 LoadFile(IspEnvironment); 1271 1272 if (IspEnvironment->BinaryLength) 1273 { 1274 BINARY* FileContent = IspEnvironment->FileContent; 1275 1276 unsigned long Pos; 1281 1277 unsigned char RecordLength; 1282 1278 unsigned short RecordAddress; … … 1284 1280 unsigned char RecordType; 1285 1281 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); 1289 1288 1290 1289 Pos = 0; 1291 while (Pos < FileLength)1290 while (Pos < IspEnvironment->BinaryLength) 1292 1291 { 1293 if (FileContent[Pos] == '\r')1292 if (FileContent[Pos] == '\r') 1294 1293 { 1295 1294 Pos++; … … 1297 1296 } 1298 1297 1299 if (FileContent[Pos] == '\n')1298 if (FileContent[Pos] == '\n') 1300 1299 { 1301 1300 Pos++; … … 1303 1302 } 1304 1303 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]); 1308 1307 exit(1); 1309 1308 } … … 1315 1314 RecordLength |= Ascii2Hex(FileContent[Pos++]); 1316 1315 1317 DebugPrintf( 4, "RecordLength = %02X\n", RecordLength);1316 DebugPrintf(4, "RecordLength = %02X\n", RecordLength); 1318 1317 1319 1318 RecordAddress = Ascii2Hex(FileContent[Pos++]); … … 1325 1324 RecordAddress |= Ascii2Hex(FileContent[Pos++]); 1326 1325 1327 DebugPrintf( 4, "RecordAddress = %04X\n", RecordAddress);1326 DebugPrintf(4, "RecordAddress = %04X\n", RecordAddress); 1328 1327 1329 1328 RealAddress = RealAddress - (RealAddress & 0xffff) + RecordAddress; 1330 1329 1331 DebugPrintf( 4, "RealAddress = %08lX\n", RealAddress);1330 DebugPrintf(4, "RealAddress = %08lX\n", RealAddress); 1332 1331 1333 1332 RecordType = Ascii2Hex(FileContent[Pos++]); … … 1335 1334 RecordType |= Ascii2Hex(FileContent[Pos++]); 1336 1335 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) 1355 1356 { 1356 1357 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++) 1361 1362 { 1362 1363 Hexvalue = Ascii2Hex(FileContent[Pos++]); … … 1366 1367 } 1367 1368 } 1368 else if (RecordType == 0x01) // 01 - End of file record1369 else if (RecordType == 0x01) // 01 - End of file record 1369 1370 { 1370 1371 break; 1371 1372 } 1372 else if (RecordType == 0x02) // 02 - Extended segment address record1373 { 1374 for (i = 0; i < RecordLength * 2; i++) // double amount of nibbles1373 else if (RecordType == 0x02) // 02 - Extended segment address record 1374 { 1375 for (i = 0; i < RecordLength * 2; i++) // double amount of nibbles 1375 1376 { 1376 1377 RealAddress <<= 4; 1377 if (i == 0)1378 if (i == 0) 1378 1379 { 1379 1380 RealAddress = Ascii2Hex(FileContent[Pos++]); … … 1386 1387 RealAddress <<= 4; 1387 1388 } 1388 else if (RecordType == 0x03) // 03 - Start segment address record1389 { 1390 for (i = 0; i < RecordLength * 2; i++) // double amount of nibbles1389 else if (RecordType == 0x03) // 03 - Start segment address record 1390 { 1391 for (i = 0; i < RecordLength * 2; i++) // double amount of nibbles 1391 1392 { 1392 1393 RealAddress <<= 4; 1393 if (i == 0)1394 if (i == 0) 1394 1395 { 1395 1396 RealAddress = Ascii2Hex(FileContent[Pos++]); … … 1402 1403 RealAddress <<= 8; 1403 1404 } 1404 else if (RecordType == 0x04) // 04 - Extended linear address record, used by IAR1405 { 1406 for (i = 0; i < RecordLength * 2; i++) // double amount of nibbles1405 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 1407 1408 { 1408 1409 RealAddress <<= 4; 1409 if (i == 0)1410 if (i == 0) 1410 1411 { 1411 1412 RealAddress = Ascii2Hex(FileContent[Pos++]); … … 1417 1418 } 1418 1419 RealAddress <<= 16; 1419 if(!BinaryOffsetDefined)1420 {1421 // set startaddress of BinaryContent1422 // use of LPC_FLASHMASK to allow a memory range, not taking the first1423 // [04] record as actual start-address.1424 IspEnvironment->BinaryOffset = RealAddress & LPC_FLASHMASK;1425 }1426 else1427 {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 record1438 { 1439 StartAddress = 0;1440 for(i = 0; i < RecordLength * 2; i++) // double amount of nibbles1420 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 1441 1442 { 1442 1443 StartAddress <<= 4; 1443 if (i == 0)1444 if (i == 0) 1444 1445 { 1445 1446 StartAddress = Ascii2Hex(FileContent[Pos++]); … … 1450 1451 } 1451 1452 } 1452 DebugPrintf( 1,"Start Address = 0x%8X\n", StartAddress);1453 DebugPrintf(1,"Start Address = 0x%8X\n", StartAddress); 1453 1454 IspEnvironment->StartAddress = StartAddress; 1454 }1455 1456 while (FileContent[Pos++] != 0x0a) // Search till line end1455 } 1456 1457 while (FileContent[Pos++] != 0x0a) // Search till line end 1457 1458 { 1458 1459 } 1459 1460 } 1460 1461 1461 DebugPrintf( 2, "\tconverted to binary format...\n");1462 1463 // When debugging is switched on, output result of conversion to file debugout.bin1464 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) 1465 1466 { 1466 1467 int fdout; … … 1470 1471 } 1471 1472 } 1473 } 1474 1475 1476 /***************************** LoadFile *********************************/ 1477 /** Loads the requested file to download into memory. 1478 \param [in] IspEnvironment structure containing input filename 1479 */ 1480 static 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 } 1472 1720 else 1473 1721 { … … 1477 1725 } 1478 1726 1479 DebugPrintf( 2, "\timage size : %ld\n", IspEnvironment->BinaryLength);1480 1481 // check length to flash for correct alignment, can happen with broken ld-scripts1727 DebugPrintf(2, "\timage size : %ld\n", IspEnvironment->BinaryLength); 1728 1729 // check length to flash for correct alignment, can happen with broken ld-scripts 1482 1730 if (IspEnvironment->BinaryLength % 4 != 0) 1483 1731 { 1484 1732 unsigned long NewBinaryLength = ((IspEnvironment->BinaryLength + 3)/4) * 4; 1485 1733 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); 1487 1735 1488 1736 IspEnvironment->BinaryLength = NewBinaryLength; 1489 1737 } 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 1742 int 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 1519 1758 ClearSerialPortBuffers(IspEnvironment); 1520 1759 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) 1538 1764 { 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 1550 1776 } 1551 else 1777 1778 if (downloadResult != 0) 1552 1779 { 1553 DebugPrintf( 3, "No (or incomplete) answer on sync attempt\n"); 1780 CloseSerialPort(IspEnvironment); 1781 exit(downloadResult); 1554 1782 } 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
