1 /******************************************************************************
\r
3 Project: Portable command line ISP for NXP LPC1000 / LPC2000 family
\r
4 and Analog Devices ADUC70xx
\r
8 Compiler: Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
\r
9 GCC Cygwin, GCC Linux, GCC ARM ELF
\r
11 Author: Martin Maurer (Martin.Maurer@clibb.de)
\r
13 Copyright: (c) Martin Maurer 2003-2011, All rights reserved
\r
14 Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
\r
16 This file is part of lpc21isp.
\r
18 lpc21isp is free software: you can redistribute it and/or modify
\r
19 it under the terms of the GNU Lesser General Public License as published by
\r
20 the Free Software Foundation, either version 3 of the License, or
\r
23 lpc21isp is distributed in the hope that it will be useful,
\r
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
26 GNU Lesser General Public License for more details.
\r
28 You should have received a copy of the GNU Lesser General Public License
\r
29 and GNU General Public License along with lpc21isp.
\r
30 If not, see <http://www.gnu.org/licenses/>.
\r
33 // This file is for the Actual Programming of the LPC Chips
\r
37 #if !defined __BORLANDC__
\r
40 #endif // defined(_WIN32)
\r
41 #include "lpc21isp.h"
\r
44 #include "lpcprog.h"
\r
46 static const unsigned int SectorTable_210x[] =
\r
48 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
\r
49 8192, 8192, 8192, 8192, 8192, 8192, 8192
\r
52 static const unsigned int SectorTable_2103[] =
\r
54 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096
\r
57 static const unsigned int SectorTable_2109[] =
\r
59 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192
\r
62 static const unsigned int SectorTable_211x[] =
\r
64 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
\r
65 8192, 8192, 8192, 8192, 8192, 8192, 8192,
\r
68 static const unsigned int SectorTable_212x[] =
\r
70 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
\r
71 65536, 65536, 8192, 8192, 8192, 8192, 8192, 8192, 8192
\r
74 // Used for devices with 500K (LPC2138 and LPC2148) and
\r
75 // for devices with 504K (1 extra 4k block at the end)
\r
76 static const unsigned int SectorTable_213x[] =
\r
78 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096,
\r
79 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
\r
80 32768, 32768, 32768, 32768, 32768, 32768, 4096, 4096,
\r
81 4096, 4096, 4096, 4096
\r
84 // Used for LPC17xx devices
\r
85 static const unsigned int SectorTable_17xx[] =
\r
87 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096,
\r
88 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096,
\r
89 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
\r
90 32768, 32768, 32768, 32768, 32768, 32768
\r
93 // Used for LPC18xx devices
\r
94 static const unsigned int SectorTable_18xx[] =
\r
96 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
\r
97 65536, 65536, 65536, 65536, 65536, 65536, 65536
\r
100 // Used for LPC43xx devices
\r
101 static const unsigned int SectorTable_43xx[] =
\r
103 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
\r
104 65536, 65536, 65536, 65536, 65536, 65536, 65536
\r
107 // Used for LPC8xx devices
\r
108 static const unsigned int SectorTable_8xx[] =
\r
110 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
\r
111 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024
\r
114 static int unsigned SectorTable_RAM[] = { 65000 };
\r
116 static LPC_DEVICE_TYPE LPCtypes[] =
\r
118 { 0, 0, 0, 0, 0, 0, 0, 0, 0, CHIP_VARIANT_NONE }, /* unknown */
\r
120 // id, id2, use id2, name of product, flash size, ram size, total number of sector, max copy size, sector table, chip variant
\r
122 { 0x00008100, 0x00000000, 0, "810M021FN8", 4, 1, 4, 256, SectorTable_8xx, CHIP_VARIANT_LPC8XX },
\r
123 { 0x00008110, 0x00000000, 0, "811M001FDH16", 8, 2, 8, 1024, SectorTable_8xx, CHIP_VARIANT_LPC8XX },
\r
124 { 0x00008120, 0x00000000, 0, "812M101FDH16", 16, 4, 16, 1024, SectorTable_8xx, CHIP_VARIANT_LPC8XX },
\r
125 { 0x00008121, 0x00000000, 0, "812M101FD20", 16, 4, 16, 1024, SectorTable_8xx, CHIP_VARIANT_LPC8XX },
\r
126 { 0x00008122, 0x00000000, 0, "812M101FDH20", 16, 4, 16, 1024, SectorTable_8xx, CHIP_VARIANT_LPC8XX },
\r
128 { 0x2500102B, 0x00000000, 0, "1102", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
130 { 0x0A07102B, 0x00000000, 0, "1110.../002", 4, 1, 1, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
131 { 0x1A07102B, 0x00000000, 0, "1110.../002", 4, 1, 1, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
132 { 0x0A16D02B, 0x00000000, 0, "1111.../002", 8, 2, 2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
133 { 0x1A16D02B, 0x00000000, 0, "1111.../002", 8, 2, 2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
134 { 0x041E502B, 0x00000000, 0, "1111.../101", 8, 2, 2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
135 { 0x2516D02B, 0x00000000, 0, "1111.../102", 8, 2, 2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
136 { 0x0416502B, 0x00000000, 0, "1111.../201", 8, 4, 2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
137 { 0x2516902B, 0x00000000, 0, "1111.../202", 8, 4, 2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
138 { 0x042D502B, 0x00000000, 0, "1112.../101", 16, 2, 4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
139 { 0x2524D02B, 0x00000000, 0, "1112.../102", 16, 2, 4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
140 { 0x0A24902B, 0x00000000, 0, "1112.../102", 16, 4, 4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
141 { 0x1A24902B, 0x00000000, 0, "1112.../102", 16, 4, 4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
142 { 0x0425502B, 0x00000000, 0, "1112.../201", 16, 4, 4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
143 { 0x2524902B, 0x00000000, 0, "1112.../202", 16, 4, 4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
144 { 0x0434502B, 0x00000000, 0, "1113.../201", 24, 4, 6, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
145 { 0x2532902B, 0x00000000, 0, "1113.../202", 24, 4, 6, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
146 { 0x0434102B, 0x00000000, 0, "1113.../301", 24, 8, 6, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
147 { 0x2532102B, 0x00000000, 0, "1113.../302", 24, 8, 6, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
148 { 0x0A40902B, 0x00000000, 0, "1114.../102", 32, 4, 8, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
149 { 0x1A40902B, 0x00000000, 0, "1114.../102", 32, 4, 8, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
150 { 0x0444502B, 0x00000000, 0, "1114.../201", 32, 4, 8, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
151 { 0x2540902B, 0x00000000, 0, "1114.../202", 32, 4, 8, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
152 { 0x0444102B, 0x00000000, 0, "1114.../301", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
153 { 0x2540102B, 0x00000000, 0, "1114.../302", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
155 { 0x00040042, 0x00000000, 0, "1114.../203", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
156 { 0x00040040, 0x00000000, 0, "1114.../303", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
157 { 0x00040060, 0x00000000, 0, "1114.../323", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
158 { 0x00040070, 0x00000000, 0, "1114.../333", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
159 { 0x00050080, 0x00000000, 0, "1115.../303", 64, 8, 16, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
161 { 0x1421102B, 0x00000000, 0, "11C12.../301", 16, 8, 4, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
162 { 0x1440102B, 0x00000000, 0, "11C14.../301", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
163 { 0x1431102B, 0x00000000, 0, "11C22.../301", 16, 8, 4, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
164 { 0x1430102B, 0x00000000, 0, "11C24.../301", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
166 { 0x0364002B, 0x00000000, 0, "1224.../101", 32, 8, 4, 2048, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
167 { 0x0364202B, 0x00000000, 0, "1224.../121", 48, 12, 32, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
168 { 0x0365002B, 0x00000000, 0, "1225.../301", 64, 16, 32, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
169 { 0x0365202B, 0x00000000, 0, "1225.../321", 80, 20, 32, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
170 { 0x0366002B, 0x00000000, 0, "1226", 96, 24, 32, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
171 { 0x0367002B, 0x00000000, 0, "1227", 128, 32, 32, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
\r
173 { 0x2C42502B, 0x00000000, 0, "1311", 8, 4, 2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
\r
174 { 0x1816902B, 0x00000000, 0, "1311/01", 8, 4, 2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
\r
175 { 0x2C40102B, 0x00000000, 0, "1313", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
\r
176 { 0x1830102B, 0x00000000, 0, "1313/01", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
\r
177 { 0x3D01402B, 0x00000000, 0, "1342", 16, 4, 4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
\r
178 { 0x3D00002B, 0x00000000, 0, "1343", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
\r
180 { 0x25001118, 0x00000000, 0, "1751", 32, 8, 8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
181 { 0x25001121, 0x00000000, 0, "1752", 64, 16, 16, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
182 { 0x25011722, 0x00000000, 0, "1754", 128, 32, 18, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
183 { 0x25011723, 0x00000000, 0, "1756", 256, 32, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
184 { 0x25013F37, 0x00000000, 0, "1758", 512, 64, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
185 { 0x25113737, 0x00000000, 0, "1759", 512, 64, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
186 { 0x26011922, 0x00000000, 0, "1764", 128, 32, 18, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
187 { 0x26013733, 0x00000000, 0, "1765", 256, 64, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
188 { 0x26013F33, 0x00000000, 0, "1766", 256, 64, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
189 { 0x26012837, 0x00000000, 0, "1767", 512, 64, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
190 { 0x26013F37, 0x00000000, 0, "1768", 512, 64, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
191 { 0x26113F37, 0x00000000, 0, "1769", 512, 64, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
193 { 0x27011132, 0x00000000, 0, "1774", 128, 40, 18, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
194 { 0x27191F43, 0x00000000, 0, "1776", 256, 80, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
195 { 0x27193747, 0x00000000, 0, "1777", 512, 96, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
196 { 0x27193F47, 0x00000000, 0, "1778", 512, 96, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
197 { 0x281D1743, 0x00000000, 0, "1785", 256, 80, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
198 { 0x281D1F43, 0x00000000, 0, "1786", 256, 80, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
199 { 0x281D3747, 0x00000000, 0, "1787", 512, 96, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
200 { 0x281D3F47, 0x00000000, 0, "1788", 512, 96, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
\r
203 { 0xF00B1B3F, 0x00000000, 1, "1810", 0, 32, 0, 8192, SectorTable_18xx, CHIP_VARIANT_LPC18XX }, // Flashless
\r
204 { 0xF00A9B3C, 0x00000000, 1, "1820", 0, 32, 0, 8192, SectorTable_18xx, CHIP_VARIANT_LPC18XX }, // Flashless
\r
205 { 0xF0009A30, 0x00000000, 1, "1830", 0, 32, 0, 8192, SectorTable_18xx, CHIP_VARIANT_LPC18XX }, // Flashless
\r
206 { 0xF001DA30, 0x00000044, 1, "1833", 512, 32, 11, 8192, SectorTable_18xx, CHIP_VARIANT_LPC18XX },
\r
207 { 0xF001DA30, 0x00000000, 1, "1837", 1024, 32, 15, 8192, SectorTable_18xx, CHIP_VARIANT_LPC18XX },
\r
208 { 0xF0009830, 0x00000000, 1, "1850", 0, 32, 0, 8192, SectorTable_18xx, CHIP_VARIANT_LPC18XX }, // Flashless
\r
209 { 0xF001D830, 0x00000044, 1, "1853", 512, 32, 11, 8192, SectorTable_18xx, CHIP_VARIANT_LPC18XX }, // TODO - distinguish these parts (word 1)
\r
210 { 0xF001D830, 0x00000000, 1, "1857", 1024, 32, 15, 8192, SectorTable_18xx, CHIP_VARIANT_LPC18XX }, // TODO - distinguish these parts (word 1)
\r
212 { 0x0004FF11, 0x00000000, 0, "2103", 32, 8, 8, 4096, SectorTable_2103, CHIP_VARIANT_LPC2XXX },
\r
213 { 0xFFF0FF12, 0x00000000, 0, "2104", 128, 16, 15, 8192, SectorTable_210x, CHIP_VARIANT_LPC2XXX },
\r
214 { 0xFFF0FF22, 0x00000000, 0, "2105", 128, 32, 15, 8192, SectorTable_210x, CHIP_VARIANT_LPC2XXX },
\r
215 { 0xFFF0FF32, 0x00000000, 0, "2106", 128, 64, 15, 8192, SectorTable_210x, CHIP_VARIANT_LPC2XXX },
\r
216 { 0x0201FF01, 0x00000000, 0, "2109", 64, 8, 8, 4096, SectorTable_2109, CHIP_VARIANT_LPC2XXX },
\r
217 { 0x0101FF12, 0x00000000, 0, "2114", 128, 16, 15, 8192, SectorTable_211x, CHIP_VARIANT_LPC2XXX },
\r
218 { 0x0201FF12, 0x00000000, 0, "2119", 128, 16, 15, 8192, SectorTable_211x, CHIP_VARIANT_LPC2XXX },
\r
219 { 0x0101FF13, 0x00000000, 0, "2124", 256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
\r
220 { 0x0201FF13, 0x00000000, 0, "2129", 256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
\r
221 { 0x0002FF01, 0x00000000, 0, "2131", 32, 8, 8, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
222 { 0x0002FF11, 0x00000000, 0, "2132", 64, 16, 9, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
223 { 0x0002FF12, 0x00000000, 0, "2134", 128, 16, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
224 { 0x0002FF23, 0x00000000, 0, "2136", 256, 32, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
225 { 0x0002FF25, 0x00000000, 0, "2138", 512, 32, 27, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
226 { 0x0402FF01, 0x00000000, 0, "2141", 32, 8, 8, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
227 { 0x0402FF11, 0x00000000, 0, "2142", 64, 16, 9, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
228 { 0x0402FF12, 0x00000000, 0, "2144", 128, 16, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
229 { 0x0402FF23, 0x00000000, 0, "2146", 256, 40, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
230 { 0x0402FF25, 0x00000000, 0, "2148", 512, 40, 27, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
231 { 0x0301FF13, 0x00000000, 0, "2194", 256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
\r
232 { 0x0301FF12, 0x00000000, 0, "2210", 0, 16, 0, 8192, SectorTable_211x, CHIP_VARIANT_LPC2XXX }, /* table is a "don't care" */
\r
233 { 0x0401FF12, 0x00000000, 0, "2212", 128, 16, 15, 8192, SectorTable_211x, CHIP_VARIANT_LPC2XXX },
\r
234 { 0x0601FF13, 0x00000000, 0, "2214", 256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
\r
235 /* "2290"; same id as the LPC2210 */
\r
236 { 0x0401FF13, 0x00000000, 0, "2292", 256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
\r
237 { 0x0501FF13, 0x00000000, 0, "2294", 256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
\r
238 { 0x1600F701, 0x00000000, 0, "2361", 128, 34, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 4.1 -- 5 Sep 2012 */
\r
239 { 0x1600FF22, 0x00000000, 0, "2362", 128, 34, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 4.1 -- 5 Sep 2012 */
\r
240 { 0x0603FB02, 0x00000000, 0, "2364", 128, 34, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 01 -- 6 July 2007 */
\r
241 { 0x1600F902, 0x00000000, 0, "2364", 128, 34, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
242 { 0x1600E823, 0x00000000, 0, "2365", 256, 58, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
243 { 0x0603FB23, 0x00000000, 0, "2366", 256, 58, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 01 -- 6 July 2007 */
\r
244 { 0x1600F923, 0x00000000, 0, "2366", 256, 58, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
245 { 0x1600E825, 0x00000000, 0, "2367", 512, 58, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
246 { 0x0603FB25, 0x00000000, 0, "2368", 512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 01 -- 6 July 2007 */
\r
247 { 0x1600F925, 0x00000000, 0, "2368", 512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
248 { 0x1700E825, 0x00000000, 0, "2377", 512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
249 { 0x0703FF25, 0x00000000, 0, "2378", 512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 01 -- 6 July 2007 */
\r
250 { 0x1600FD25, 0x00000000, 0, "2378", 512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 01 -- 29 October 2007 */
\r
251 { 0x1700FD25, 0x00000000, 0, "2378", 512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
252 { 0x1700FF35, 0x00000000, 0, "2387", 512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 03 -- 25 August 2008 */
\r
253 { 0x1800F935, 0x00000000, 0, "2387", 512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
254 { 0x1800FF35, 0x00000000, 0, "2388", 512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
255 { 0x1500FF35, 0x00000000, 0, "2458", 512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
256 { 0x1600FF30, 0x00000000, 0, "2460", 0, 98, 0, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
257 { 0x1600FF35, 0x00000000, 0, "2468", 512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
258 { 0x1701FF30, 0x00000000, 0, "2470", 0, 98, 0, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
259 { 0x1701FF35, 0x00000000, 0, "2478", 512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
\r
261 { 0xA00A8B3F, 0x00000000, 1, "4310", 0, 168, 0, 4096, SectorTable_43xx, CHIP_VARIANT_LPC43XX }, /* From UM10503 Rev. 1.4 -- 3 Sep 2012 */
\r
262 { 0xA0008B3C, 0x00000000, 1, "4320", 0, 200, 0, 4096, SectorTable_43xx, CHIP_VARIANT_LPC43XX }, /* From UM10503 Rev. 1.4 -- 3 Sep 2012 */
\r
263 { 0xA0000A30, 0x00000000, 1, "4330", 0, 264, 0, 4096, SectorTable_43xx, CHIP_VARIANT_LPC43XX }, /* From UM10503 Rev. 1.4 -- 3 Sep 2012 */
\r
264 { 0xA001CA30, 0x00000044, 1, "4333", 512, 512, 11, 4096, SectorTable_43xx, CHIP_VARIANT_LPC43XX }, /* info not yet available */
\r
265 { 0xA001CA30, 0x00000000, 1, "4337", 1024, 512, 15, 4096, SectorTable_43xx, CHIP_VARIANT_LPC43XX }, /* info not yet available */
\r
266 { 0xA0000830, 0x00000000, 1, "4350", 0, 264, 0, 4096, SectorTable_43xx, CHIP_VARIANT_LPC43XX }, /* From UM10503 Rev. 1.4 -- 3 Sep 2012 */
\r
267 { 0xA001C830, 0x00000044, 1, "4353", 512, 512, 11, 4096, SectorTable_43xx, CHIP_VARIANT_LPC43XX }, /* From UM10503 Rev. 1.4 -- 3 Sep 2012 */
\r
268 { 0xA001C830, 0x00000000, 1, "4357", 1024, 512, 15, 4096, SectorTable_43xx, CHIP_VARIANT_LPC43XX }, /* From UM10503 Rev. 1.4 -- 3 Sep 2012 */
\r
269 { 0xA001C830, 0x0EF60000, 1, "4357", 1024, 512, 15, 4096, SectorTable_43xx, CHIP_VARIANT_LPC43XX } /* info not yet available */
\r
272 /***************************** NXP Download *********************************/
\r
273 /** Download the file from the internal memory image to the NXP microcontroller.
\r
274 * This function is visible from outside if COMPILE_FOR_LPC21
\r
277 /***************************** FormatCommand ********************************/
\r
278 /** 2013-06-28 Torsten Lang, Uwe Schneider GmbH
\r
279 According to the various NXP user manuals the ISP bootloader commands should
\r
280 be terminated with <CR><LF>, the echo and/or answer should have the same line
\r
281 termination. So far for the theory...
\r
282 In fact, the bootloader also accepts <LF> as line termination, but it may or
\r
283 may not echo the linebreak character. Some bootloaders convert the character
\r
284 into <CR><LF>, some leave the <LF> and append another one (<LF><LF> in the
\r
285 answer). Furthermore, during uuencoded data transfer the bootloader may or
\r
286 may not append an additional <LF> character at the end of the answer
\r
287 (leading to a <CR><LF><LF> sequence).
\r
288 A reliable way to handle these deviations from the UM is to strictly send the
\r
289 commands according to the description in the UM and to re-format commands
\r
290 and answers after a transfer.
\r
291 FormatCommand works in a way that it drops any leading linefeeds which only
\r
292 can be surplus <LF> characters from a previous answer. It then converts any
\r
293 sequence of <CR> and <LF> into a single <LF> character.
\r
294 FormatCommand can work in place, meaning that In==Out is allowed!
\r
295 \param [in] In Pointer to input buffer.
\r
296 \param [out] Out Pointer to output buffer.
\r
299 static void FormatCommand(const char *In, char *Out)
\r
302 for (i = 0, j = 0; In[j] != '\0'; i++, j++)
\r
304 if ((In[j] == '\r') || (In[j] == '\n'))
\r
306 if (i > 0) // Ignore leading line breaks (they must be leftovers from a previous answer)
\r
314 while ((In[j+1] == '\r') || (In[j+1] == '\n'))
\r
327 static int SendAndVerify(ISP_ENVIRONMENT *IspEnvironment, const char *Command,
\r
328 char *AnswerBuffer, int AnswerLength)
\r
330 unsigned long realsize;
\r
332 char *FormattedCommand;
\r
334 SendComPort(IspEnvironment, Command);
\r
335 ReceiveComPort(IspEnvironment, AnswerBuffer, AnswerLength - 1, &realsize, 2, 5000);
\r
337 cmdlen = strlen(Command);
\r
338 FormattedCommand = (char *)alloca(cmdlen+1);
\r
339 FormatCommand(Command, FormattedCommand);
\r
340 FormatCommand(AnswerBuffer, AnswerBuffer);
\r
341 cmdlen = strlen(FormattedCommand);
\r
342 return (strncmp(AnswerBuffer, FormattedCommand, cmdlen) == 0
\r
343 && strcmp(AnswerBuffer + cmdlen, "0\n") == 0);
\r
348 /***************************** NxpOutputErrorMessage ***********************/
\r
349 /** Given an error number find and print the appropriate error message.
\r
350 \param [in] ErrorNumber The number of the error.
\r
352 #if defined COMPILE_FOR_LPC21
\r
354 #define NxpOutputErrorMessage(in) // Cleanly remove this feature from the embedded version !!
\r
358 static void NxpOutputErrorMessage(unsigned char ErrorNumber)
\r
360 switch (ErrorNumber)
\r
363 DebugPrintf(1, "CMD_SUCCESS\n");
\r
367 DebugPrintf(1, "INVALID_COMMAND\n");
\r
371 DebugPrintf(1, "SRC_ADDR_ERROR: Source address is not on word boundary.\n");
\r
374 DebugPrintf(1, "DST_ADDR_ERROR: Destination address is not on a correct boundary.\n");
\r
378 DebugPrintf(1, "SRC_ADDR_NOT_MAPPED: Source address is not mapped in the memory map.\n"
\r
379 " Count value is taken into consideration where applicable.\n");
\r
383 DebugPrintf(1, "DST_ADDR_NOT_MAPPED: Destination address is not mapped in the memory map.\n"
\r
384 " Count value is taken into consideration where applicable.\n");
\r
388 DebugPrintf(1, "COUNT_ERROR: Byte count is not multiple of 4 or is not a permitted value.\n");
\r
392 DebugPrintf(1, "INVALID_SECTOR: Sector number is invalid or end sector number is\n"
\r
393 " greater than start sector number.\n");
\r
397 DebugPrintf(1, "SECTOR_NOT_BLANK\n");
\r
401 DebugPrintf(1, "SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION:\n"
\r
402 "Command to prepare sector for write operation was not executed.\n");
\r
406 DebugPrintf(1, "COMPARE_ERROR: Source and destination data not equal.\n");
\r
410 DebugPrintf(1, "BUSY: Flash programming hardware interface is busy.\n");
\r
414 DebugPrintf(1, "PARAM_ERROR: Insufficient number of parameters or invalid parameter.\n");
\r
418 DebugPrintf(1, "ADDR_ERROR: Address is not on word boundary.\n");
\r
422 DebugPrintf(1, "ADDR_NOT_MAPPED: Address is not mapped in the memory map.\n"
\r
423 " Count value is taken in to consideration where applicable.\n");
\r
427 DebugPrintf(1, "CMD_LOCKED\n");
\r
431 DebugPrintf(1, "INVALID_CODE: Unlock code is invalid.\n");
\r
435 DebugPrintf(1, "INVALID_BAUD_RATE: Invalid baud rate setting.\n");
\r
439 DebugPrintf(1, "INVALID_STOP_BIT: Invalid stop bit setting.\n");
\r
443 DebugPrintf( 1, "CODE READ PROTECTION ENABLED\n");
\r
450 DebugPrintf(1, "unknown error %u\n", ErrorNumber);
\r
454 //DebugPrintf(1, "error (%u), see NxpOutputErrorMessage() in lpc21isp.c for help \n\r", ErrorNumber);
\r
456 #endif // !defined COMPILE_FOR_LPC21
\r
458 /***************************** GetAndReportErrorNumber ***************************/
\r
459 /** Find error number in string. This will normally be the string
\r
460 returned from the microcontroller.
\r
461 \param [in] Answer the buffer to search for the error number.
\r
462 \return the error number found, if no linefeed found before the end of the
\r
463 string an error value of 255 is returned. If a non-numeric value is found
\r
464 then it is printed to stdout and an error value of 255 is returned.
\r
466 static unsigned char GetAndReportErrorNumber(const char *Answer)
\r
468 unsigned char Result = 0xFF; // Error !!!
\r
469 unsigned int i = 0;
\r
473 if (Answer[i] == 0x00)
\r
478 if (Answer[i] == 0x0a)
\r
482 if (Answer[i] < '0' || Answer[i] > '9')
\r
484 DebugPrintf(1, "ErrorString: %s", &Answer[i]);
\r
488 Result = (unsigned char) (atoi(&Answer[i]));
\r
495 NxpOutputErrorMessage(Result);
\r
501 int NxpDownload(ISP_ENVIRONMENT *IspEnvironment)
\r
503 unsigned long realsize;
\r
505 char ExpectedAnswer[128];
\r
507 /*const*/ char *strippedAnswer, *endPtr;
\r
509 int nQuestionMarks;
\r
511 unsigned long Sector;
\r
512 unsigned long SectorLength;
\r
513 unsigned long SectorStart, SectorOffset, SectorChunk;
\r
514 char tmpString[128];
\r
515 char uuencode_table[64];
\r
517 unsigned long tmpStringPos;
\r
518 unsigned long BlockOffset;
\r
519 unsigned long Block;
\r
521 unsigned long Id[2];
\r
522 unsigned long CopyLength;
\r
524 unsigned long ivt_CRC; // CRC over interrupt vector table
\r
525 unsigned long block_CRC;
\r
526 time_t tStartUpload=0, tDoneUpload=0;
\r
527 char tmp_string[64];
\r
530 #if !defined COMPILE_FOR_LPC21
\r
532 #if defined __BORLANDC__
\r
533 #define local_static static
\r
535 #define local_static
\r
540 // Puffer for data to resend after "RESEND\r\n" Target responce
\r
541 local_static char sendbuf0[128];
\r
542 local_static char sendbuf1[128];
\r
543 local_static char sendbuf2[128];
\r
544 local_static char sendbuf3[128];
\r
545 local_static char sendbuf4[128];
\r
546 local_static char sendbuf5[128];
\r
547 local_static char sendbuf6[128];
\r
548 local_static char sendbuf7[128];
\r
549 local_static char sendbuf8[128];
\r
550 local_static char sendbuf9[128];
\r
551 local_static char sendbuf10[128];
\r
552 local_static char sendbuf11[128];
\r
553 local_static char sendbuf12[128];
\r
554 local_static char sendbuf13[128];
\r
555 local_static char sendbuf14[128];
\r
556 local_static char sendbuf15[128];
\r
557 local_static char sendbuf16[128];
\r
558 local_static char sendbuf17[128];
\r
559 local_static char sendbuf18[128];
\r
560 local_static char sendbuf19[128];
\r
562 char * sendbuf[20] = { sendbuf0, sendbuf1, sendbuf2, sendbuf3, sendbuf4,
\r
563 sendbuf5, sendbuf6, sendbuf7, sendbuf8, sendbuf9,
\r
564 sendbuf10, sendbuf11, sendbuf12, sendbuf13, sendbuf14,
\r
565 sendbuf15, sendbuf16, sendbuf17, sendbuf18, sendbuf19};
\r
568 DebugPrintf(2, "Synchronizing (ESC to abort)");
\r
570 PrepareKeyboardTtySettings();
\r
572 #if defined INTEGRATED_IN_WIN_APP
\r
573 if (IspEnvironment->NoSync)
\r
580 for (nQuestionMarks = found = 0; !found && nQuestionMarks < IspEnvironment->nQuestionMarks; nQuestionMarks++)
\r
582 #if defined INTEGRATED_IN_WIN_APP
\r
583 // allow calling application to abort when syncing takes too long
\r
585 if (!AppSyncing(nQuestionMarks))
\r
587 return (USER_ABORT_SYNC);
\r
590 #ifndef Exclude_kbhit
\r
593 if (getch() == 0x1b)
\r
595 ResetKeyboardTtySettings();
\r
596 DebugPrintf(2, "\nUser aborted during synchronisation\n");
\r
597 return (USER_ABORT_SYNC);
\r
603 DebugPrintf(2, ".");
\r
604 SendComPort(IspEnvironment, "?");
\r
606 memset(Answer,0,sizeof(Answer));
\r
607 ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,100);
\r
609 strippedAnswer = Answer;
\r
610 strippedsize = realsize;
\r
611 while ((strippedsize > 0) && ((*strippedAnswer == '?') || (*strippedAnswer == 0)))
\r
617 sprintf(tmp_string, "StrippedAnswer(Length=%d): ", strippedsize);
\r
618 DumpString(3, strippedAnswer, strippedsize, tmp_string);
\r
620 tStartUpload = time(NULL);
\r
622 FormatCommand(strippedAnswer, strippedAnswer);
\r
623 if (strcmp(strippedAnswer, "Synchronized\n") == 0)
\r
627 #if !defined COMPILE_FOR_LPC21
\r
630 ResetTarget(IspEnvironment, PROGRAM_MODE);
\r
636 ResetKeyboardTtySettings();
\r
640 DebugPrintf(1, " no answer on '?'\n");
\r
641 return (NO_ANSWER_QM);
\r
644 #if defined INTEGRATED_IN_WIN_APP
\r
645 AppSyncing(-1); // flag syncing done
\r
648 DebugPrintf(2, " OK\n");
\r
650 SendComPort(IspEnvironment, "Synchronized\r\n");
\r
652 ReceiveComPort(IspEnvironment, Answer, sizeof(Answer) - 1, &realsize, 2, 1000);
\r
654 FormatCommand(Answer, Answer);
\r
655 if (strcmp(Answer, "Synchronized\nOK\n") != 0)
\r
657 DebugPrintf(1, "No answer on 'Synchronized'\n");
\r
658 return (NO_ANSWER_SYNC);
\r
661 DebugPrintf(3, "Synchronized 1\n");
\r
663 DebugPrintf(3, "Setting oscillator\n");
\r
665 sprintf(temp, "%s\r\n", IspEnvironment->StringOscillator);
\r
667 SendComPort(IspEnvironment, temp);
\r
669 ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2, 1000);
\r
671 sprintf(temp, "%s\nOK\n", IspEnvironment->StringOscillator);
\r
673 FormatCommand(Answer, Answer);
\r
674 if (strcmp(Answer, temp) != 0)
\r
676 DebugPrintf(1, "No answer on Oscillator-Command\n");
\r
677 return (NO_ANSWER_OSC);
\r
680 DebugPrintf(3, "Unlock\n");
\r
682 cmdstr = "U 23130\r\n";
\r
684 if (!SendAndVerify(IspEnvironment, cmdstr, Answer, sizeof Answer))
\r
686 DebugPrintf(1, "Unlock-Command:\n");
\r
687 return (UNLOCK_ERROR + GetAndReportErrorNumber(Answer));
\r
690 DebugPrintf(2, "Read bootcode version: ");
\r
694 SendComPort(IspEnvironment, cmdstr);
\r
696 ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 4,5000);
\r
698 FormatCommand(cmdstr, temp);
\r
699 FormatCommand(Answer, Answer);
\r
700 if (strncmp(Answer, temp, strlen(temp)) != 0)
\r
702 DebugPrintf(1, "no answer on Read Boot Code Version\n");
\r
703 return (NO_ANSWER_RBV);
\r
706 if (strncmp(Answer + strlen(temp), "0\n", 2) == 0)
\r
708 strippedAnswer = Answer + strlen(temp) + 2;
\r
710 int maj, min, build;
\r
711 if (sscanf(strippedAnswer, "%d %d %d", &build, &min, &maj) == 2) {
\r
716 DebugPrintf(2, "%d.%d.%d\n", maj, min, build);
\r
718 DebugPrintf(2, strippedAnswer);
\r
722 DebugPrintf(2, "unknown\n");
\r
725 DebugPrintf(2, "Read part ID: ");
\r
729 SendComPort(IspEnvironment, cmdstr);
\r
731 ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 3, 5000);
\r
733 FormatCommand(cmdstr, temp);
\r
734 FormatCommand(Answer, Answer);
\r
735 if (strncmp(Answer, temp, strlen(temp)) != 0)
\r
737 DebugPrintf(1, "no answer on Read Part Id\n");
\r
738 return (NO_ANSWER_RPID);
\r
741 strippedAnswer = (strncmp(Answer, "J\n0\n", 4) == 0) ? Answer + 4 : Answer;
\r
743 Id[0] = strtoul(strippedAnswer, &endPtr, 10);
\r
745 *endPtr = '\0'; /* delete \r\n */
\r
746 for (i = sizeof LPCtypes / sizeof LPCtypes[0] - 1; i > 0 && LPCtypes[i].id != Id[0]; i--)
\r
748 IspEnvironment->DetectedDevice = i;
\r
749 if (LPCtypes[IspEnvironment->DetectedDevice].EvalId2 != 0)
\r
751 /* Read out the second configuration word and run the search again */
\r
754 if ((endPtr[0] == '\0') || (endPtr[strlen(endPtr)-1] != '\n'))
\r
756 /* No or incomplete word 2 */
\r
757 ReceiveComPort(IspEnvironment, endPtr, sizeof(Answer)-(endPtr-Answer)-1, &realsize, 1, 100);
\r
760 FormatCommand(endPtr, endPtr);
\r
761 if ((*endPtr == '\0') || (*endPtr == '\n'))
\r
763 DebugPrintf(1, "incomplete answer on Read Part Id (second configuration word missing)\n");
\r
764 return (NO_ANSWER_RPID);
\r
767 Id[1] = strtoul(endPtr, &endPtr, 10);
\r
768 *endPtr = '\0'; /* delete \r\n */
\r
770 /* now search the table again */
\r
771 for (i = sizeof LPCtypes / sizeof LPCtypes[0] - 1; i > 0 && (LPCtypes[i].id != Id[0] || LPCtypes[i].id2 != Id[1]); i--)
\r
773 IspEnvironment->DetectedDevice = i;
\r
775 if (IspEnvironment->DetectedDevice == 0) {
\r
776 DebugPrintf(2, "unknown");
\r
779 DebugPrintf(2, "LPC%s, %d kiB FLASH / %d kiB SRAM",
\r
780 LPCtypes[IspEnvironment->DetectedDevice].Product,
\r
781 LPCtypes[IspEnvironment->DetectedDevice].FlashSize,
\r
782 LPCtypes[IspEnvironment->DetectedDevice].RAMSize);
\r
784 if (LPCtypes[IspEnvironment->DetectedDevice].EvalId2 != 0)
\r
786 DebugPrintf(2, " (0x%08lX / 0x%08lX)\n", Id[0], Id[1]);
\r
790 DebugPrintf(2, " (0x%08lX)\n", Id[0]);
\r
793 if (!IspEnvironment->DetectOnly)
\r
795 // Build up uuencode table
\r
796 uuencode_table[0] = 0x60; // 0x20 is translated to 0x60 !
\r
798 for (i = 1; i < 64; i++)
\r
800 uuencode_table[i] = (char)(0x20 + i);
\r
803 if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX)
\r
805 // Patch 0x14, otherwise it is not running and jumps to boot mode
\r
809 // Clear the vector at 0x14 so it doesn't affect the checksum:
\r
810 for (i = 0; i < 4; i++)
\r
812 IspEnvironment->BinaryContent[i + 0x14] = 0;
\r
815 // Calculate a native checksum of the little endian vector table:
\r
816 for (i = 0; i < (4 * 8);) {
\r
817 ivt_CRC += IspEnvironment->BinaryContent[i++];
\r
818 ivt_CRC += IspEnvironment->BinaryContent[i++] << 8;
\r
819 ivt_CRC += IspEnvironment->BinaryContent[i++] << 16;
\r
820 ivt_CRC += IspEnvironment->BinaryContent[i++] << 24;
\r
823 /* Negate the result and place in the vector at 0x14 as little endian
\r
824 * again. The resulting vector table should checksum to 0. */
\r
825 ivt_CRC = (unsigned long) (0 - ivt_CRC);
\r
826 for (i = 0; i < 4; i++)
\r
828 IspEnvironment->BinaryContent[i + 0x14] = (unsigned char)(ivt_CRC >> (8 * i));
\r
831 DebugPrintf(3, "Position 0x14 patched: ivt_CRC = 0x%08lX\n", ivt_CRC);
\r
833 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX ||
\r
834 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX ||
\r
835 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX ||
\r
836 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX ||
\r
837 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX ||
\r
838 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC8XX)
\r
840 // Patch 0x1C, otherwise it is not running and jumps to boot mode
\r
844 // Clear the vector at 0x1C so it doesn't affect the checksum:
\r
845 for (i = 0; i < 4; i++)
\r
847 IspEnvironment->BinaryContent[i + 0x1C] = 0;
\r
850 // Calculate a native checksum of the little endian vector table:
\r
851 for (i = 0; i < (4 * 8);) {
\r
852 ivt_CRC += IspEnvironment->BinaryContent[i++];
\r
853 ivt_CRC += IspEnvironment->BinaryContent[i++] << 8;
\r
854 ivt_CRC += IspEnvironment->BinaryContent[i++] << 16;
\r
855 ivt_CRC += IspEnvironment->BinaryContent[i++] << 24;
\r
858 /* Negate the result and place in the vector at 0x1C as little endian
\r
859 * again. The resulting vector table should checksum to 0. */
\r
860 ivt_CRC = (unsigned long) (0 - ivt_CRC);
\r
861 for (i = 0; i < 4; i++)
\r
863 IspEnvironment->BinaryContent[i + 0x1C] = (unsigned char)(ivt_CRC >> (8 * i));
\r
866 DebugPrintf(3, "Position 0x1C patched: ivt_CRC = 0x%08lX\n", ivt_CRC);
\r
870 DebugPrintf(1, "Internal error: wrong chip variant %d (detected device %d)\n", LPCtypes[IspEnvironment->DetectedDevice].ChipVariant, IspEnvironment->DetectedDevice);
\r
876 DebugPrintf(2, "Read Unique ID:\n");
\r
880 SendComPort(IspEnvironment, cmdstr);
\r
882 ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 5,5000);
\r
884 FormatCommand(cmdstr, temp);
\r
885 FormatCommand(Answer, Answer);
\r
886 if (strncmp(Answer, temp, strlen(temp)) != 0)
\r
888 DebugPrintf(1, "no answer on Read Unique ID\n");
\r
889 return (NO_ANSWER_RBV);
\r
892 if (strncmp(Answer + strlen(cmdstr), "0\n", 2) == 0)
\r
894 strippedAnswer = Answer + strlen(temp) + 2;
\r
895 DebugPrintf(2, strippedAnswer);
\r
899 DebugPrintf(2, "unknown\n");
\r
903 /* In case of a download to RAM, use full RAM for downloading
\r
904 * set the flash parameters to full RAM also.
\r
905 * This makes sure that all code is downloaded as one big sector
\r
908 if ( (IspEnvironment->BinaryOffset >= ReturnValueLpcRamStart(IspEnvironment))
\r
909 &&(IspEnvironment->BinaryOffset + IspEnvironment->BinaryLength <= ReturnValueLpcRamStart(IspEnvironment)+(LPCtypes[IspEnvironment->DetectedDevice].RAMSize*1024)))
\r
911 LPCtypes[IspEnvironment->DetectedDevice].FlashSectors = 1;
\r
912 LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize = LPCtypes[IspEnvironment->DetectedDevice].RAMSize*1024 - (ReturnValueLpcRamBase(IspEnvironment) - ReturnValueLpcRamStart(IspEnvironment));
\r
913 LPCtypes[IspEnvironment->DetectedDevice].SectorTable = SectorTable_RAM;
\r
914 SectorTable_RAM[0] = LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize;
\r
916 if (IspEnvironment->DetectOnly)
\r
919 if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC8XX)
\r
921 // XON/XOFF must be switched off for LPC8XX
\r
922 // otherwise problem during binary transmission of data to LPC8XX
\r
923 DebugPrintf(3, "Switch off XON/XOFF !!!\n");
\r
924 ControlXonXoffSerialPort(IspEnvironment, 0);
\r
927 // Start with sector 1 and go upward... Sector 0 containing the interrupt vectors
\r
928 // will be loaded last, since it contains a checksum and device will re-enter
\r
929 // bootloader mode as long as this checksum is invalid.
\r
930 DebugPrintf(2, "Will start programming at Sector 1 if possible, and conclude with Sector 0 to ensure that checksum is written last.\n");
\r
931 if (LPCtypes[IspEnvironment->DetectedDevice].SectorTable[0] >= IspEnvironment->BinaryLength)
\r
938 SectorStart = LPCtypes[IspEnvironment->DetectedDevice].SectorTable[0];
\r
942 if (IspEnvironment->WipeDevice == 1)
\r
944 DebugPrintf(2, "Wiping Device. ");
\r
946 if (LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX ||
\r
947 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX)
\r
949 // TODO: Quick and dirty hack to address bank 0
\r
950 sprintf(tmpString, "P %d %d 0\r\n", 0, LPCtypes[IspEnvironment->DetectedDevice].FlashSectors-1);
\r
954 sprintf(tmpString, "P %d %d\r\n", 0, LPCtypes[IspEnvironment->DetectedDevice].FlashSectors-1);
\r
957 if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
\r
959 DebugPrintf(1, "Wrong answer on Prepare-Command\n");
\r
960 return (WRONG_ANSWER_PREP + GetAndReportErrorNumber(Answer));
\r
963 if (LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX ||
\r
964 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX)
\r
966 // TODO: Quick and dirty hack to address bank 0
\r
967 sprintf(tmpString, "E %d %d 0\r\n", 0, LPCtypes[IspEnvironment->DetectedDevice].FlashSectors-1);
\r
971 sprintf(tmpString, "E %d %d\r\n", 0, LPCtypes[IspEnvironment->DetectedDevice].FlashSectors-1);
\r
973 if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
\r
975 DebugPrintf(1, "Wrong answer on Erase-Command\n");
\r
976 return (WRONG_ANSWER_ERAS + GetAndReportErrorNumber(Answer));
\r
978 DebugPrintf(2, "OK \n");
\r
980 if (LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX ||
\r
981 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX)
\r
983 DebugPrintf(2, "ATTENTION: Only bank A was wiped!!!\n");
\r
987 //no wiping requested: erasing sector 0 first
\r
988 DebugPrintf(2, "Erasing sector 0 first, to invalidate checksum. ");
\r
990 if (LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX ||
\r
991 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX)
\r
993 // TODO: Quick and dirty hack to address bank 0
\r
994 sprintf(tmpString, "P %d %d 0\r\n", 0, 0);
\r
998 sprintf(tmpString, "P %d %d\r\n", 0, 0);
\r
1001 if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
\r
1003 DebugPrintf(1, "Wrong answer on Prepare-Command\n");
\r
1004 return (WRONG_ANSWER_PREP + GetAndReportErrorNumber(Answer));
\r
1007 if (LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX ||
\r
1008 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX)
\r
1010 // TODO: Quick and dirty hack to address bank 0
\r
1011 sprintf(tmpString, "E %d %d 0\r\n", 0, 0);
\r
1015 sprintf(tmpString, "E %d %d\r\n", 0, 0);
\r
1018 if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
\r
1020 DebugPrintf(1, "Wrong answer on Erase-Command\n");
\r
1021 return (WRONG_ANSWER_ERAS + GetAndReportErrorNumber(Answer));
\r
1023 DebugPrintf(2, "OK \n");
\r
1027 if (Sector >= LPCtypes[IspEnvironment->DetectedDevice].FlashSectors)
\r
1029 DebugPrintf(1, "Program too large; running out of Flash sectors.\n");
\r
1030 return (PROGRAM_TOO_LARGE);
\r
1033 DebugPrintf(2, "Sector %ld: ", Sector);
\r
1036 if ( (IspEnvironment->BinaryOffset < ReturnValueLpcRamStart(IspEnvironment)) // Skip Erase when running from RAM
\r
1037 ||(IspEnvironment->BinaryOffset >= ReturnValueLpcRamStart(IspEnvironment)+(LPCtypes[IspEnvironment->DetectedDevice].RAMSize*1024)))
\r
1039 if (LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX ||
\r
1040 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX)
\r
1042 // TODO: Quick and dirty hack to address bank 0
\r
1043 sprintf(tmpString, "P %ld %ld 0\r\n", Sector, Sector);
\r
1047 sprintf(tmpString, "P %ld %ld\r\n", Sector, Sector);
\r
1050 if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
\r
1052 DebugPrintf(1, "Wrong answer on Prepare-Command (1) (Sector %ld)\n", Sector);
\r
1053 return (WRONG_ANSWER_PREP + GetAndReportErrorNumber(Answer));
\r
1056 DebugPrintf(2, ".");
\r
1058 if (IspEnvironment->WipeDevice == 0 && (Sector!=0)) //Sector 0 already erased
\r
1060 if (LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX ||
\r
1061 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX)
\r
1063 // TODO: Quick and dirty hack to address bank 0
\r
1064 sprintf(tmpString, "E %ld %ld 0\r\n", Sector, Sector);
\r
1068 sprintf(tmpString, "E %ld %ld\r\n", Sector, Sector);
\r
1071 if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
\r
1073 DebugPrintf(1, "Wrong answer on Erase-Command (Sector %ld)\n", Sector);
\r
1074 return (WRONG_ANSWER_ERAS + GetAndReportErrorNumber(Answer));
\r
1077 DebugPrintf(2, ".");
\r
1082 SectorLength = LPCtypes[IspEnvironment->DetectedDevice].SectorTable[Sector];
\r
1083 if (SectorLength > IspEnvironment->BinaryLength - SectorStart)
\r
1085 SectorLength = IspEnvironment->BinaryLength - SectorStart;
\r
1088 for (SectorOffset = 0; SectorOffset < SectorLength; SectorOffset += SectorChunk)
\r
1090 // Check if we are to write only 0xFFs - it would be just a waste of time..
\r
1091 if (SectorOffset == 0) {
\r
1092 for (SectorOffset = 0; SectorOffset < SectorLength; ++SectorOffset)
\r
1094 if (IspEnvironment->BinaryContent[SectorStart + SectorOffset] != 0xFF)
\r
1097 if (SectorOffset == SectorLength) // all data contents were 0xFFs
\r
1099 DebugPrintf(2, "Whole sector contents is 0xFFs, skipping programming.");
\r
1103 SectorOffset = 0; // re-set otherwise
\r
1106 if (SectorOffset > 0)
\r
1108 // Add a visible marker between segments in a sector
\r
1109 DebugPrintf(2, "|"); /* means: partial segment copied */
\r
1113 // If the Flash ROM sector size is bigger than the number of bytes
\r
1114 // we can copy from RAM to Flash, we must "chop up" the sector and
\r
1115 // copy these individually.
\r
1116 // This is especially needed in the case where a Flash sector is
\r
1117 // bigger than the amount of SRAM.
\r
1118 SectorChunk = SectorLength - SectorOffset;
\r
1119 if (SectorChunk > (unsigned)LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize)
\r
1121 SectorChunk = LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize;
\r
1124 // Write multiple of 45 * 4 Byte blocks to RAM, but copy maximum of on sector to Flash
\r
1125 // In worst case we transfer up to 180 byte too much to RAM
\r
1126 // but then we can always use full 45 byte blocks and length is multiple of 4
\r
1127 CopyLength = SectorChunk;
\r
1129 if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX ||
\r
1130 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX ||
\r
1131 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX ||
\r
1132 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX ||
\r
1133 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX ||
\r
1134 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX)
\r
1136 if ((CopyLength % (45 * 4)) != 0)
\r
1138 CopyLength += ((45 * 4) - (CopyLength % (45 * 4)));
\r
1142 sprintf(tmpString, "W %ld %ld\r\n", ReturnValueLpcRamBase(IspEnvironment), CopyLength);
\r
1144 if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
\r
1146 DebugPrintf(1, "Wrong answer on Write-Command\n");
\r
1147 return (WRONG_ANSWER_WRIT + GetAndReportErrorNumber(Answer));
\r
1150 DebugPrintf(2, ".");
\r
1153 if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX ||
\r
1154 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX ||
\r
1155 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX ||
\r
1156 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX ||
\r
1157 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX ||
\r
1158 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX)
\r
1163 // Transfer blocks of 45 * 4 bytes to RAM
\r
1164 for (Pos = SectorStart + SectorOffset; (Pos < SectorStart + SectorOffset + CopyLength) && (Pos < IspEnvironment->BinaryLength); Pos += (45 * 4))
\r
1166 for (Block = 0; Block < 4; Block++) // Each block 45 bytes
\r
1168 DebugPrintf(2, ".");
\r
1171 #if defined INTEGRATED_IN_WIN_APP
\r
1172 // inform the calling application about having written another chuck of data
\r
1176 // Uuencode one 45 byte block
\r
1179 #if !defined COMPILE_FOR_LPC21
\r
1180 sendbuf[Line][tmpStringPos++] = (char)(' ' + 45); // Encode Length of block
\r
1182 tmpString[tmpStringPos++] = (char)(' ' + 45); // Encode Length of block
\r
1185 for (BlockOffset = 0; BlockOffset < 45; BlockOffset++)
\r
1187 if ( (IspEnvironment->BinaryOffset < ReturnValueLpcRamStart(IspEnvironment))
\r
1188 ||(IspEnvironment->BinaryOffset >= ReturnValueLpcRamStart(IspEnvironment)+(LPCtypes[IspEnvironment->DetectedDevice].RAMSize*1024)))
\r
1189 { // Flash: use full memory
\r
1190 c = IspEnvironment->BinaryContent[Pos + Block * 45 + BlockOffset];
\r
1193 { // RAM: Skip first 0x200 bytes, these are used by the download program in LPC21xx
\r
1194 c = IspEnvironment->BinaryContent[Pos + Block * 45 + BlockOffset + 0x200];
\r
1199 k = (k << 8) + (c & 255);
\r
1201 if ((BlockOffset % 3) == 2) // Collecting always 3 Bytes, then do processing in 4 Bytes
\r
1203 #if !defined COMPILE_FOR_LPC21
\r
1204 sendbuf[Line][tmpStringPos++] = uuencode_table[(k >> 18) & 63];
\r
1205 sendbuf[Line][tmpStringPos++] = uuencode_table[(k >> 12) & 63];
\r
1206 sendbuf[Line][tmpStringPos++] = uuencode_table[(k >> 6) & 63];
\r
1207 sendbuf[Line][tmpStringPos++] = uuencode_table[ k & 63];
\r
1209 tmpString[tmpStringPos++] = uuencode_table[(k >> 18) & 63];
\r
1210 tmpString[tmpStringPos++] = uuencode_table[(k >> 12) & 63];
\r
1211 tmpString[tmpStringPos++] = uuencode_table[(k >> 6) & 63];
\r
1212 tmpString[tmpStringPos++] = uuencode_table[ k & 63];
\r
1218 #if !defined COMPILE_FOR_LPC21
\r
1219 sendbuf[Line][tmpStringPos++] = '\r';
\r
1220 sendbuf[Line][tmpStringPos++] = '\n';
\r
1221 sendbuf[Line][tmpStringPos++] = 0;
\r
1223 SendComPort(IspEnvironment, sendbuf[Line]);
\r
1224 // receive only for debug proposes
\r
1225 ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1, 5000);
\r
1226 FormatCommand(sendbuf[Line], tmpString);
\r
1227 FormatCommand(Answer, Answer);
\r
1228 if (strncmp(Answer, tmpString, strlen(tmpString)) != 0)
\r
1230 DebugPrintf(1, "Error on writing data (1)\n");
\r
1231 return (ERROR_WRITE_DATA);
\r
1234 tmpString[tmpStringPos++] = '\r';
\r
1235 tmpString[tmpStringPos++] = '\n';
\r
1236 tmpString[tmpStringPos++] = 0;
\r
1238 SendComPort(IspEnvironment, tmpString);
\r
1239 ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1, 5000);
\r
1240 FormatCommand(tmpString, tmpString);
\r
1241 FormatCommand(Answer, Answer);
\r
1242 if (strncmp(Answer, tmpString, tmpStringPos) != 0)
\r
1244 DebugPrintf(1, "Error on writing data (1)\n");
\r
1245 return (ERROR_WRITE_DATA);
\r
1251 DebugPrintf(3, "Line = %d\n", Line);
\r
1255 #if !defined COMPILE_FOR_LPC21
\r
1256 for (repeat = 0; repeat < 3; repeat++)
\r
1259 // DebugPrintf(1, "block_CRC = %ld\n", block_CRC);
\r
1261 sprintf(tmpString, "%ld\r\n", block_CRC);
\r
1263 SendComPort(IspEnvironment, tmpString);
\r
1265 ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2, 5000);
\r
1267 sprintf(tmpString, "%ld\nOK\n", block_CRC);
\r
1269 FormatCommand(tmpString, tmpString);
\r
1270 FormatCommand(Answer, Answer);
\r
1271 if (strcmp(Answer, tmpString) != 0)
\r
1273 for (i = 0; i < Line; i++)
\r
1275 SendComPort(IspEnvironment, sendbuf[i]);
\r
1276 ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1, 5000);
\r
1285 DebugPrintf(1, "Error on writing block_CRC (1)\n");
\r
1286 return (ERROR_WRITE_CRC);
\r
1289 // DebugPrintf(1, "block_CRC = %ld\n", block_CRC);
\r
1290 sprintf(tmpString, "%ld\r\n", block_CRC);
\r
1291 SendComPort(IspEnvironment, tmpString);
\r
1293 ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000);
\r
1295 sprintf(tmpString, "%ld\nOK\n", block_CRC);
\r
1296 FormatCommand(tmpString, tmpString);
\r
1297 FormatCommand(Answer, Answer);
\r
1298 if (strcmp(Answer, tmpString) != 0)
\r
1300 DebugPrintf(1, "Error on writing block_CRC (2)\n");
\r
1301 return (ERROR_WRITE_CRC);
\r
1312 #if !defined COMPILE_FOR_LPC21
\r
1313 for (repeat = 0; repeat < 3; repeat++)
\r
1315 sprintf(tmpString, "%ld\r\n", block_CRC);
\r
1317 SendComPort(IspEnvironment, tmpString);
\r
1319 ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000);
\r
1321 sprintf(tmpString, "%ld\nOK\n", block_CRC);
\r
1323 FormatCommand(tmpString, tmpString);
\r
1324 FormatCommand(Answer, Answer);
\r
1325 if (strcmp(Answer, tmpString) != 0)
\r
1327 for (i = 0; i < Line; i++)
\r
1329 SendComPort(IspEnvironment, sendbuf[i]);
\r
1330 ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,5000);
\r
1339 DebugPrintf(1, "Error on writing block_CRC (3)\n");
\r
1340 return (ERROR_WRITE_CRC2);
\r
1343 sprintf(tmpString, "%ld\r\n", block_CRC);
\r
1344 SendComPort(IspEnvironment, tmpString);
\r
1346 ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000);
\r
1348 sprintf(tmpString, "%ld\nOK\n", block_CRC);
\r
1349 FormatCommand(tmpString, tmpString);
\r
1350 FormatCommand(Answer, Answer);
\r
1351 if (strcmp(Answer, tmpString) != 0)
\r
1353 DebugPrintf(1, "Error on writing block_CRC (4)\n");
\r
1354 return (ERROR_WRITE_CRC2);
\r
1359 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC8XX)
\r
1361 unsigned char BigAnswer[4096];
\r
1362 unsigned long CopyLengthPartialOffset = 0;
\r
1363 unsigned long CopyLengthPartialRemainingBytes;
\r
1365 while(CopyLengthPartialOffset < CopyLength)
\r
1367 CopyLengthPartialRemainingBytes = CopyLength - CopyLengthPartialOffset;
\r
1368 if(CopyLengthPartialRemainingBytes > 256)
\r
1370 // There seems to be an error in LPC812:
\r
1371 // When too much bytes are written at high speed,
\r
1373 // Workaround: Use smaller blocks
\r
1374 CopyLengthPartialRemainingBytes = 256;
\r
1377 SendComPortBlock(IspEnvironment, &IspEnvironment->BinaryContent[SectorStart + SectorOffset + CopyLengthPartialOffset], CopyLengthPartialRemainingBytes);
\r
1379 if (ReceiveComPortBlockComplete(IspEnvironment, &BigAnswer, CopyLengthPartialRemainingBytes, 10000) != 0)
\r
1381 return (ERROR_WRITE_DATA);
\r
1384 if(memcmp(&IspEnvironment->BinaryContent[SectorStart + SectorOffset + CopyLengthPartialOffset], BigAnswer, CopyLengthPartialRemainingBytes))
\r
1386 return (ERROR_WRITE_DATA);
\r
1389 CopyLengthPartialOffset += CopyLengthPartialRemainingBytes;
\r
1393 if ( (IspEnvironment->BinaryOffset < ReturnValueLpcRamStart(IspEnvironment))
\r
1394 ||(IspEnvironment->BinaryOffset >= ReturnValueLpcRamStart(IspEnvironment)+(LPCtypes[IspEnvironment->DetectedDevice].RAMSize*1024)))
\r
1396 // Prepare command must be repeated before every write
\r
1397 if (LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX ||
\r
1398 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX)
\r
1400 // TODO: Quick and dirty hack to address bank 0
\r
1401 sprintf(tmpString, "P %ld %ld 0\r\n", Sector, Sector);
\r
1405 sprintf(tmpString, "P %ld %ld\r\n", Sector, Sector);
\r
1408 if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
\r
1410 DebugPrintf(1, "Wrong answer on Prepare-Command (2) (Sector %ld)\n", Sector);
\r
1411 return (WRONG_ANSWER_PREP2 + GetAndReportErrorNumber(Answer));
\r
1414 // Round CopyLength up to one of the following values: 512, 1024,
\r
1415 // 4096, 8192; but do not exceed the maximum copy size (usually
\r
1416 // 8192, but chip-dependent)
\r
1417 if (CopyLength < 512)
\r
1421 else if (SectorLength < 1024)
\r
1423 CopyLength = 1024;
\r
1425 else if (SectorLength < 4096)
\r
1427 CopyLength = 4096;
\r
1431 CopyLength = 8192;
\r
1433 if (CopyLength > (unsigned)LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize)
\r
1435 CopyLength = LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize;
\r
1438 sprintf(tmpString, "C %ld %ld %ld\r\n", IspEnvironment->BinaryOffset + SectorStart + SectorOffset, ReturnValueLpcRamBase(IspEnvironment), CopyLength);
\r
1440 if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
\r
1442 DebugPrintf(1, "Wrong answer on Copy-Command\n");
\r
1443 return (WRONG_ANSWER_COPY + GetAndReportErrorNumber(Answer));
\r
1446 if (IspEnvironment->Verify)
\r
1449 //Avoid compare first 64 bytes.
\r
1450 //Because first 64 bytes are re-mapped to flash boot sector,
\r
1451 //and the compare result may not be correct.
\r
1452 if (SectorStart + SectorOffset<64)
\r
1454 sprintf(tmpString, "M %d %ld %ld\r\n", 64, ReturnValueLpcRamBase(IspEnvironment) + (64 - SectorStart - SectorOffset), CopyLength-(64 - SectorStart - SectorOffset));
\r
1458 sprintf(tmpString, "M %ld %ld %ld\r\n", SectorStart + SectorOffset, ReturnValueLpcRamBase(IspEnvironment), CopyLength);
\r
1461 if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
\r
1463 DebugPrintf(1, "Wrong answer on Compare-Command\n");
\r
1464 return (WRONG_ANSWER_COPY + GetAndReportErrorNumber(Answer));
\r
1470 DebugPrintf(2, "\n");
\r
1473 if ((SectorStart + SectorLength) >= IspEnvironment->BinaryLength && Sector!=0)
\r
1478 else if (Sector == 0) {
\r
1482 SectorStart += LPCtypes[IspEnvironment->DetectedDevice].SectorTable[Sector];
\r
1487 tDoneUpload = time(NULL);
\r
1488 if (IspEnvironment->Verify)
\r
1489 DebugPrintf(2, "Download Finished and Verified correct... taking %d seconds\n", tDoneUpload - tStartUpload);
\r
1491 DebugPrintf(2, "Download Finished... taking %d seconds\n", tDoneUpload - tStartUpload);
\r
1493 // For LPC18xx set boot bank to 0
\r
1494 if (LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX ||
\r
1495 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX)
\r
1497 if (!SendAndVerify(IspEnvironment, "S 0\r\n", Answer, sizeof Answer))
\r
1499 DebugPrintf(1, "Wrong answer on SetActiveBootFlashBank-Command\n");
\r
1500 return (WRONG_ANSWER_BTBNK + GetAndReportErrorNumber(Answer));
\r
1504 if(IspEnvironment->DoNotStart == 0)
\r
1506 DebugPrintf(2, "Now launching the brand new code\n");
\r
1509 if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX)
\r
1511 sprintf(tmpString, "G %ld A\r\n", IspEnvironment->StartAddress);
\r
1513 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX ||
\r
1514 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX ||
\r
1515 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX ||
\r
1516 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX ||
\r
1517 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX)
\r
1519 sprintf(tmpString, "G %ld T\r\n", IspEnvironment->StartAddress & ~1);
\r
1521 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC8XX)
\r
1523 sprintf(tmpString, "G 0 T\r\n");
\r
1527 DebugPrintf(1, "Internal Error %s %d\n", __FILE__, __LINE__);
\r
1531 SendComPort(IspEnvironment, tmpString); //goto 0 : run this fresh new downloaded code code
\r
1532 if ( (IspEnvironment->BinaryOffset < ReturnValueLpcRamStart(IspEnvironment))
\r
1533 ||(IspEnvironment->BinaryOffset >= ReturnValueLpcRamStart(IspEnvironment)+(LPCtypes[IspEnvironment->DetectedDevice].RAMSize*1024)))
\r
1534 { // Skip response on G command - show response on Terminal instead
\r
1535 ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2, 5000);
\r
1536 /* the reply string is frequently terminated with a -1 (EOF) because the
\r
1537 * connection gets broken; zero-terminate the string ourselves
\r
1539 while (realsize > 0 && ((signed char) Answer[(int)realsize - 1]) < 0)
\r
1541 Answer[(int)realsize] = '\0';
\r
1542 /* Better to check only the first 9 chars instead of complete receive buffer,
\r
1543 * because the answer can contain the output by the started programm
\r
1545 if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX)
\r
1547 sprintf(ExpectedAnswer, "G %ld A\n0", IspEnvironment->StartAddress);
\r
1549 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX ||
\r
1550 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX ||
\r
1551 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX ||
\r
1552 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX ||
\r
1553 LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX)
\r
1555 sprintf(ExpectedAnswer, "G %ld T\n0", IspEnvironment->StartAddress & ~1);
\r
1557 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC8XX)
\r
1559 sprintf(ExpectedAnswer, "G 0 T\n0");
\r
1563 DebugPrintf(1, "Internal Error %s %d\n", __FILE__, __LINE__);
\r
1567 FormatCommand(Answer, Answer);
\r
1568 if (realsize == 0 || strncmp((const char *)Answer, /*cmdstr*/ExpectedAnswer, strlen(/*cmdstr*/ExpectedAnswer)) != 0)
\r
1570 DebugPrintf(2, "Failed to run the new downloaded code: ");
\r
1571 return (FAILED_RUN + GetAndReportErrorNumber(Answer));
\r
1579 #endif // LPC_SUPPORT
\r
1582 unsigned long ReturnValueLpcRamStart(ISP_ENVIRONMENT *IspEnvironment)
\r
1584 if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX)
\r
1586 return LPC_RAMSTART_LPC43XX;
\r
1588 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX)
\r
1590 return LPC_RAMSTART_LPC2XXX;
\r
1592 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX)
\r
1594 return LPC_RAMSTART_LPC18XX;
\r
1596 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX)
\r
1598 return LPC_RAMSTART_LPC17XX;
\r
1600 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX)
\r
1602 return LPC_RAMSTART_LPC13XX;
\r
1604 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX)
\r
1606 return LPC_RAMSTART_LPC11XX;
\r
1608 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC8XX)
\r
1610 return LPC_RAMSTART_LPC8XX;
\r
1612 DebugPrintf(1, "Error in ReturnValueLpcRamStart (%d)\n", LPCtypes[IspEnvironment->DetectedDevice].ChipVariant);
\r
1617 unsigned long ReturnValueLpcRamBase(ISP_ENVIRONMENT *IspEnvironment)
\r
1619 if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC43XX)
\r
1621 return LPC_RAMBASE_LPC43XX;
\r
1623 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX)
\r
1625 return LPC_RAMBASE_LPC2XXX;
\r
1627 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC18XX)
\r
1629 return LPC_RAMBASE_LPC18XX;
\r
1631 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX)
\r
1633 return LPC_RAMBASE_LPC17XX;
\r
1635 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX)
\r
1637 return LPC_RAMBASE_LPC13XX;
\r
1639 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX)
\r
1641 return LPC_RAMBASE_LPC11XX;
\r
1643 else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC8XX)
\r
1645 return LPC_RAMBASE_LPC8XX;
\r
1647 DebugPrintf(1, "Error in ReturnValueLpcRamBase (%d)\n", LPCtypes[IspEnvironment->DetectedDevice].ChipVariant);
\r