7eab4124ad7e11181a234d66a09ff10eed74ab78
[fw/openocd] / src / flash / lpc2000.c
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "lpc2000.h"
26 #include "armv4_5.h"
27 #include "binarybuffer.h"
28
29
30 /* flash programming support for Philips LPC2xxx devices
31  * currently supported devices:
32  * variant 1 (lpc2000_v1):
33  * - 2104|5|6
34  * - 2114|9
35  * - 2124|9
36  * - 2194
37  * - 2212|4
38  * - 2292|4
39  *
40  * variant 2 (lpc2000_v2):
41  * - 213x
42  * - 214x
43  * - 2101|2|3
44  * - 2364|6|8
45  * - 2378
46  */
47
48 static int lpc2000_register_commands(struct command_context_s *cmd_ctx);
49 static int lpc2000_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
50 static int lpc2000_erase(struct flash_bank_s *bank, int first, int last);
51 static int lpc2000_protect(struct flash_bank_s *bank, int set, int first, int last);
52 static int lpc2000_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
53 static int lpc2000_probe(struct flash_bank_s *bank);
54 static int lpc2000_erase_check(struct flash_bank_s *bank);
55 static int lpc2000_protect_check(struct flash_bank_s *bank);
56 static int lpc2000_info(struct flash_bank_s *bank, char *buf, int buf_size);
57
58 static int lpc2000_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
59
60 flash_driver_t lpc2000_flash =
61 {
62         .name = "lpc2000",
63         .register_commands = lpc2000_register_commands,
64         .flash_bank_command = lpc2000_flash_bank_command,
65         .erase = lpc2000_erase,
66         .protect = lpc2000_protect,
67         .write = lpc2000_write,
68         .probe = lpc2000_probe,
69         .auto_probe = lpc2000_probe,
70         .erase_check = lpc2000_erase_check,
71         .protect_check = lpc2000_protect_check,
72         .info = lpc2000_info
73 };
74
75 static int lpc2000_register_commands(struct command_context_s *cmd_ctx)
76 {
77         command_t *lpc2000_cmd = register_command(cmd_ctx, NULL, "lpc2000", NULL, COMMAND_ANY, NULL);
78
79         register_command(cmd_ctx, lpc2000_cmd, "part_id", lpc2000_handle_part_id_command, COMMAND_EXEC,
80                                          "print part id of lpc2000 flash bank <num>");
81
82         return ERROR_OK;
83 }
84
85 static int lpc2000_build_sector_list(struct flash_bank_s *bank)
86 {
87         lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv;
88
89         /* default to a 4096 write buffer */
90         lpc2000_info->cmd51_max_buffer = 4096;
91
92         if (lpc2000_info->variant == 1)
93         {
94                 int i = 0;
95                 uint32_t offset = 0;
96
97                 /* variant 1 has different layout for 128kb and 256kb flashes */
98                 if (bank->size == 128 * 1024)
99                 {
100                         bank->num_sectors = 16;
101                         bank->sectors = malloc(sizeof(flash_sector_t) * 16);
102                         for (i = 0; i < 16; i++)
103                         {
104                                 bank->sectors[i].offset = offset;
105                                 bank->sectors[i].size = 8 * 1024;
106                                 offset += bank->sectors[i].size;
107                                 bank->sectors[i].is_erased = -1;
108                                 bank->sectors[i].is_protected = 1;
109                         }
110                 }
111                 else if (bank->size == 256 * 1024)
112                 {
113                         bank->num_sectors = 18;
114                         bank->sectors = malloc(sizeof(flash_sector_t) * 18);
115
116                         for (i = 0; i < 8; i++)
117                         {
118                                 bank->sectors[i].offset = offset;
119                                 bank->sectors[i].size = 8 * 1024;
120                                 offset += bank->sectors[i].size;
121                                 bank->sectors[i].is_erased = -1;
122                                 bank->sectors[i].is_protected = 1;
123                         }
124                         for (i = 8; i < 10; i++)
125                         {
126                                 bank->sectors[i].offset = offset;
127                                 bank->sectors[i].size = 64 * 1024;
128                                 offset += bank->sectors[i].size;
129                                 bank->sectors[i].is_erased = -1;
130                                 bank->sectors[i].is_protected = 1;
131                         }
132                         for (i = 10; i < 18; i++)
133                         {
134                                 bank->sectors[i].offset = offset;
135                                 bank->sectors[i].size = 8 * 1024;
136                                 offset += bank->sectors[i].size;
137                                 bank->sectors[i].is_erased = -1;
138                                 bank->sectors[i].is_protected = 1;
139                         }
140                 }
141                 else
142                 {
143                         LOG_ERROR("BUG: unknown bank->size encountered");
144                         exit(-1);
145                 }
146         }
147         else if (lpc2000_info->variant == 2)
148         {
149                 int num_sectors;
150                 int i;
151                 uint32_t offset = 0;
152
153                 /* variant 2 has a uniform layout, only number of sectors differs */
154                 switch (bank->size)
155                 {
156                         case 4 * 1024:
157                                 lpc2000_info->cmd51_max_buffer = 1024;
158                                 num_sectors = 1;
159                                 break;
160                         case 8 * 1024:
161                                 lpc2000_info->cmd51_max_buffer = 1024;
162                                 num_sectors = 2;
163                                 break;
164                         case 16 * 1024:
165                                 num_sectors = 4;
166                                 break;
167                         case 32 * 1024:
168                                 num_sectors = 8;
169                                 break;
170                         case 64 * 1024:
171                                 num_sectors = 9;
172                                 break;
173                         case 128 * 1024:
174                                 num_sectors = 11;
175                                 break;
176                         case 256 * 1024:
177                                 num_sectors = 15;
178                                 break;
179                         case 512 * 1024:
180                         case 500 * 1024:
181                                 num_sectors = 27;
182                                 break;
183                         default:
184                                 LOG_ERROR("BUG: unknown bank->size encountered");
185                                 exit(-1);
186                                 break;
187                 }
188
189                 bank->num_sectors = num_sectors;
190                 bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
191
192                 for (i = 0; i < num_sectors; i++)
193                 {
194                         if ((i >= 0) && (i < 8))
195                         {
196                                 bank->sectors[i].offset = offset;
197                                 bank->sectors[i].size = 4 * 1024;
198                                 offset += bank->sectors[i].size;
199                                 bank->sectors[i].is_erased = -1;
200                                 bank->sectors[i].is_protected = 1;
201                         }
202                         if ((i >= 8) && (i < 22))
203                         {
204                                 bank->sectors[i].offset = offset;
205                                 bank->sectors[i].size = 32 * 1024;
206                                 offset += bank->sectors[i].size;
207                                 bank->sectors[i].is_erased = -1;
208                                 bank->sectors[i].is_protected = 1;
209                         }
210                         if ((i >= 22) && (i < 27))
211                         {
212                                 bank->sectors[i].offset = offset;
213                                 bank->sectors[i].size = 4 * 1024;
214                                 offset += bank->sectors[i].size;
215                                 bank->sectors[i].is_erased = -1;
216                                 bank->sectors[i].is_protected = 1;
217                         }
218                 }
219         }
220         else
221         {
222                 LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
223                 exit(-1);
224         }
225
226         return ERROR_OK;
227 }
228
229 /* call LPC2000 IAP function
230  * uses 172 bytes working area
231  * 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait)
232  * 0x8 to 0x1f: command parameter table
233  * 0x20 to 0x2b: command result table
234  * 0x2c to 0xac: stack (only 128b needed)
235  */
236 static int lpc2000_iap_call(flash_bank_t *bank, int code, uint32_t param_table[5], uint32_t result_table[2])
237 {
238         int retval;
239         lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv;
240         target_t *target = bank->target;
241         mem_param_t mem_params[2];
242         reg_param_t reg_params[5];
243         armv4_5_algorithm_t armv4_5_info;
244         uint32_t status_code;
245
246         /* regrab previously allocated working_area, or allocate a new one */
247         if (!lpc2000_info->iap_working_area)
248         {
249                 uint8_t jump_gate[8];
250
251                 /* make sure we have a working area */
252                 if (target_alloc_working_area(target, 172, &lpc2000_info->iap_working_area) != ERROR_OK)
253                 {
254                         LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
255                         return ERROR_FLASH_OPERATION_FAILED;
256                 }
257
258                 /* write IAP code to working area */
259                 target_buffer_set_u32(target, jump_gate, ARMV4_5_BX(12));
260                 target_buffer_set_u32(target, jump_gate + 4, ARMV4_5_B(0xfffffe, 0));
261                 if((retval = target_write_memory(target, lpc2000_info->iap_working_area->address, 4, 2, jump_gate)) != ERROR_OK)
262                 {
263                         return retval;
264                 }
265         }
266
267         armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
268         armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
269         armv4_5_info.core_state = ARMV4_5_STATE_ARM;
270
271         /* command parameter table */
272         init_mem_param(&mem_params[0], lpc2000_info->iap_working_area->address + 8, 4 * 6, PARAM_OUT);
273         target_buffer_set_u32(target, mem_params[0].value, code);
274         target_buffer_set_u32(target, mem_params[0].value + 0x4, param_table[0]);
275         target_buffer_set_u32(target, mem_params[0].value + 0x8, param_table[1]);
276         target_buffer_set_u32(target, mem_params[0].value + 0xc, param_table[2]);
277         target_buffer_set_u32(target, mem_params[0].value + 0x10, param_table[3]);
278         target_buffer_set_u32(target, mem_params[0].value + 0x14, param_table[4]);
279
280         init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
281         buf_set_u32(reg_params[0].value, 0, 32, lpc2000_info->iap_working_area->address + 0x8);
282
283         /* command result table */
284         init_mem_param(&mem_params[1], lpc2000_info->iap_working_area->address + 0x20, 4 * 3, PARAM_IN);
285
286         init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
287         buf_set_u32(reg_params[1].value, 0, 32, lpc2000_info->iap_working_area->address + 0x20);
288
289         /* IAP entry point */
290         init_reg_param(&reg_params[2], "r12", 32, PARAM_OUT);
291         buf_set_u32(reg_params[2].value, 0, 32, 0x7ffffff1);
292
293         /* IAP stack */
294         init_reg_param(&reg_params[3], "r13_svc", 32, PARAM_OUT);
295         buf_set_u32(reg_params[3].value, 0, 32, lpc2000_info->iap_working_area->address + 0xac);
296
297         /* return address */
298         init_reg_param(&reg_params[4], "lr_svc", 32, PARAM_OUT);
299         buf_set_u32(reg_params[4].value, 0, 32, lpc2000_info->iap_working_area->address + 0x4);
300
301         target_run_algorithm(target, 2, mem_params, 5, reg_params, lpc2000_info->iap_working_area->address, lpc2000_info->iap_working_area->address + 0x4, 10000, &armv4_5_info);
302
303         status_code = buf_get_u32(mem_params[1].value, 0, 32);
304         result_table[0] = target_buffer_get_u32(target, mem_params[1].value);
305         result_table[1] = target_buffer_get_u32(target, mem_params[1].value + 4);
306
307         destroy_mem_param(&mem_params[0]);
308         destroy_mem_param(&mem_params[1]);
309
310         destroy_reg_param(&reg_params[0]);
311         destroy_reg_param(&reg_params[1]);
312         destroy_reg_param(&reg_params[2]);
313         destroy_reg_param(&reg_params[3]);
314         destroy_reg_param(&reg_params[4]);
315
316         return status_code;
317 }
318
319 static int lpc2000_iap_blank_check(struct flash_bank_s *bank, int first, int last)
320 {
321         uint32_t param_table[5];
322         uint32_t result_table[2];
323         int status_code;
324         int i;
325
326         if ((first < 0) || (last >= bank->num_sectors))
327                 return ERROR_FLASH_SECTOR_INVALID;
328
329         for (i = first; i <= last; i++)
330         {
331                 /* check single sector */
332                 param_table[0] = param_table[1] = i;
333                 status_code = lpc2000_iap_call(bank, 53, param_table, result_table);
334
335                 switch (status_code)
336                 {
337                         case ERROR_FLASH_OPERATION_FAILED:
338                                 return ERROR_FLASH_OPERATION_FAILED;
339                         case LPC2000_CMD_SUCCESS:
340                                 bank->sectors[i].is_erased = 1;
341                                 break;
342                         case LPC2000_SECTOR_NOT_BLANK:
343                                 bank->sectors[i].is_erased = 0;
344                                 break;
345                         case LPC2000_INVALID_SECTOR:
346                                 bank->sectors[i].is_erased = 0;
347                                 break;
348                         case LPC2000_BUSY:
349                                 return ERROR_FLASH_BUSY;
350                                 break;
351                         default:
352                                 LOG_ERROR("BUG: unknown LPC2000 status code");
353                                 exit(-1);
354                 }
355         }
356
357         return ERROR_OK;
358 }
359
360 /* flash bank lpc2000 <base> <size> 0 0 <target#> <lpc_variant> <cclk> [calc_checksum]
361  */
362 static int lpc2000_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
363 {
364         lpc2000_flash_bank_t *lpc2000_info;
365
366         if (argc < 8)
367         {
368                 LOG_WARNING("incomplete flash_bank lpc2000 configuration");
369                 return ERROR_FLASH_BANK_INVALID;
370         }
371
372         lpc2000_info = malloc(sizeof(lpc2000_flash_bank_t));
373         bank->driver_priv = lpc2000_info;
374
375         if (strcmp(args[6], "lpc2000_v1") == 0)
376         {
377                 lpc2000_info->variant = 1;
378                 lpc2000_info->cmd51_dst_boundary = 512;
379                 lpc2000_info->cmd51_can_256b = 0;
380                 lpc2000_info->cmd51_can_8192b = 1;
381         }
382         else if (strcmp(args[6], "lpc2000_v2") == 0)
383         {
384                 lpc2000_info->variant = 2;
385                 lpc2000_info->cmd51_dst_boundary = 256;
386                 lpc2000_info->cmd51_can_256b = 1;
387                 lpc2000_info->cmd51_can_8192b = 0;
388         }
389         else
390         {
391                 LOG_ERROR("unknown LPC2000 variant");
392                 free(lpc2000_info);
393                 return ERROR_FLASH_BANK_INVALID;
394         }
395
396         lpc2000_info->iap_working_area = NULL;
397         lpc2000_info->cclk = strtoul(args[7], NULL, 0);
398         lpc2000_info->calc_checksum = 0;
399         lpc2000_build_sector_list(bank);
400
401         if (argc >= 9)
402         {
403                 if (strcmp(args[8], "calc_checksum") == 0)
404                         lpc2000_info->calc_checksum = 1;
405         }
406
407         return ERROR_OK;
408 }
409
410 static int lpc2000_erase(struct flash_bank_s *bank, int first, int last)
411 {
412         lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv;
413         uint32_t param_table[5];
414         uint32_t result_table[2];
415         int status_code;
416
417         if (bank->target->state != TARGET_HALTED)
418         {
419                 LOG_ERROR("Target not halted");
420                 return ERROR_TARGET_NOT_HALTED;
421         }
422
423         param_table[0] = first;
424         param_table[1] = last;
425         param_table[2] = lpc2000_info->cclk;
426
427         /* Prepare sectors */
428         status_code = lpc2000_iap_call(bank, 50, param_table, result_table);
429         switch (status_code)
430         {
431                 case ERROR_FLASH_OPERATION_FAILED:
432                         return ERROR_FLASH_OPERATION_FAILED;
433                 case LPC2000_CMD_SUCCESS:
434                         break;
435                 case LPC2000_INVALID_SECTOR:
436                         return ERROR_FLASH_SECTOR_INVALID;
437                         break;
438                 default:
439                         LOG_WARNING("lpc2000 prepare sectors returned %i", status_code);
440                         return ERROR_FLASH_OPERATION_FAILED;
441         }
442
443         /* Erase sectors */
444         status_code = lpc2000_iap_call(bank, 52, param_table, result_table);
445         switch (status_code)
446         {
447                 case ERROR_FLASH_OPERATION_FAILED:
448                         return ERROR_FLASH_OPERATION_FAILED;
449                 case LPC2000_CMD_SUCCESS:
450                         break;
451                 case LPC2000_INVALID_SECTOR:
452                         return ERROR_FLASH_SECTOR_INVALID;
453                         break;
454                 default:
455                         LOG_WARNING("lpc2000 erase sectors returned %i", status_code);
456                         return ERROR_FLASH_OPERATION_FAILED;
457         }
458
459         return ERROR_OK;
460 }
461
462 static int lpc2000_protect(struct flash_bank_s *bank, int set, int first, int last)
463 {
464         /* can't protect/unprotect on the lpc2000 */
465         return ERROR_OK;
466 }
467
468 static int lpc2000_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
469 {
470         lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv;
471         target_t *target = bank->target;
472         uint32_t dst_min_alignment;
473         uint32_t bytes_remaining = count;
474         uint32_t bytes_written = 0;
475         int first_sector = 0;
476         int last_sector = 0;
477         uint32_t param_table[5];
478         uint32_t result_table[2];
479         int status_code;
480         int i;
481         working_area_t *download_area;
482         int retval = ERROR_OK;
483
484         if (bank->target->state != TARGET_HALTED)
485         {
486                 LOG_ERROR("Target not halted");
487                 return ERROR_TARGET_NOT_HALTED;
488         }
489
490         if (offset + count > bank->size)
491                 return ERROR_FLASH_DST_OUT_OF_BANK;
492
493         if (lpc2000_info->cmd51_can_256b)
494                 dst_min_alignment = 256;
495         else
496                 dst_min_alignment = 512;
497
498         if (offset % dst_min_alignment)
499         {
500                 LOG_WARNING("offset 0x%" PRIx32 " breaks required alignment 0x%" PRIx32, offset, dst_min_alignment);
501                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
502         }
503
504         for (i = 0; i < bank->num_sectors; i++)
505         {
506                 if (offset >= bank->sectors[i].offset)
507                         first_sector = i;
508                 if (offset + CEIL(count, dst_min_alignment) * dst_min_alignment > bank->sectors[i].offset)
509                         last_sector = i;
510         }
511
512         LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
513
514         /* check if exception vectors should be flashed */
515         if ((offset == 0) && (count >= 0x20) && lpc2000_info->calc_checksum)
516         {
517                 uint32_t checksum = 0;
518                 int i = 0;
519                 for (i = 0; i < 8; i++)
520                 {
521                         LOG_DEBUG("0x%2.2x: 0x%8.8" PRIx32, i * 4, buf_get_u32(buffer + (i * 4), 0, 32));
522                         if (i != 5)
523                                 checksum += buf_get_u32(buffer + (i * 4), 0, 32);
524                 }
525                 checksum = 0 - checksum;
526                 LOG_DEBUG("checksum: 0x%8.8" PRIx32, checksum);
527
528                 uint32_t original_value=buf_get_u32(buffer + (5 * 4), 0, 32);
529                 if (original_value!=checksum)
530                 {
531                         LOG_WARNING("Verification will fail since checksum in image(0x%8.8" PRIx32 ") written to flash was different from calculated vector checksum(0x%8.8" PRIx32 ").",
532                                         original_value, checksum);
533                         LOG_WARNING("To remove this warning modify build tools on developer PC to inject correct LPC vector checksum.");
534                 }
535
536                 buf_set_u32(buffer + 0x14, 0, 32, checksum);
537         }
538
539         /* allocate a working area */
540         if (target_alloc_working_area(target, lpc2000_info->cmd51_max_buffer, &download_area) != ERROR_OK)
541         {
542                 LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
543                 return ERROR_FLASH_OPERATION_FAILED;
544         }
545
546         while (bytes_remaining > 0)
547         {
548                 uint32_t thisrun_bytes;
549                 if (bytes_remaining >= lpc2000_info->cmd51_max_buffer)
550                         thisrun_bytes = lpc2000_info->cmd51_max_buffer;
551                 else if (bytes_remaining >= 1024)
552                         thisrun_bytes = 1024;
553                 else if ((bytes_remaining >= 512) || (!lpc2000_info->cmd51_can_256b))
554                         thisrun_bytes = 512;
555                 else
556                         thisrun_bytes = 256;
557
558                 /* Prepare sectors */
559                 param_table[0] = first_sector;
560                 param_table[1] = last_sector;
561                 status_code = lpc2000_iap_call(bank, 50, param_table, result_table);
562                 switch (status_code)
563                 {
564                         case ERROR_FLASH_OPERATION_FAILED:
565                                 retval = ERROR_FLASH_OPERATION_FAILED;
566                                 break;
567                         case LPC2000_CMD_SUCCESS:
568                                 break;
569                         case LPC2000_INVALID_SECTOR:
570                                 retval = ERROR_FLASH_SECTOR_INVALID;
571                                 break;
572                         default:
573                                 LOG_WARNING("lpc2000 prepare sectors returned %i", status_code);
574                                 retval = ERROR_FLASH_OPERATION_FAILED;
575                                 break;
576                 }
577
578                 /* Exit if error occured */
579                 if (retval != ERROR_OK)
580                         break;
581
582                 if (bytes_remaining >= thisrun_bytes)
583                 {
584                         if ((retval = target_write_buffer(bank->target, download_area->address, thisrun_bytes, buffer + bytes_written)) != ERROR_OK)
585                         {
586                                 retval = ERROR_FLASH_OPERATION_FAILED;
587                                 break;
588                         }
589                 }
590                 else
591                 {
592                         uint8_t *last_buffer = malloc(thisrun_bytes);
593                         uint32_t i;
594                         memcpy(last_buffer, buffer + bytes_written, bytes_remaining);
595                         for (i = bytes_remaining; i < thisrun_bytes; i++)
596                                 last_buffer[i] = 0xff;
597                         target_write_buffer(bank->target, download_area->address, thisrun_bytes, last_buffer);
598                         free(last_buffer);
599                 }
600
601                 LOG_DEBUG("writing 0x%" PRIx32 " bytes to address 0x%" PRIx32 , thisrun_bytes, bank->base + offset + bytes_written);
602
603                 /* Write data */
604                 param_table[0] = bank->base + offset + bytes_written;
605                 param_table[1] = download_area->address;
606                 param_table[2] = thisrun_bytes;
607                 param_table[3] = lpc2000_info->cclk;
608                 status_code = lpc2000_iap_call(bank, 51, param_table, result_table);
609                 switch (status_code)
610                 {
611                         case ERROR_FLASH_OPERATION_FAILED:
612                                 retval = ERROR_FLASH_OPERATION_FAILED;
613                                 break;
614                         case LPC2000_CMD_SUCCESS:
615                                 break;
616                         case LPC2000_INVALID_SECTOR:
617                                 retval = ERROR_FLASH_SECTOR_INVALID;
618                                 break;
619                         default:
620                                 LOG_WARNING("lpc2000 returned %i", status_code);
621                                 retval = ERROR_FLASH_OPERATION_FAILED;
622                                 break;
623                 }
624
625                 /* Exit if error occured */
626                 if (retval != ERROR_OK)
627                         break;
628
629                 if (bytes_remaining > thisrun_bytes)
630                         bytes_remaining -= thisrun_bytes;
631                 else
632                         bytes_remaining = 0;
633                 bytes_written += thisrun_bytes;
634         }
635
636         target_free_working_area(target, download_area);
637
638         return retval;
639 }
640
641 static int lpc2000_probe(struct flash_bank_s *bank)
642 {
643         /* we can't probe on an lpc2000
644          * if this is an lpc2xxx, it has the configured flash
645          */
646         return ERROR_OK;
647 }
648
649 static int lpc2000_erase_check(struct flash_bank_s *bank)
650 {
651         if (bank->target->state != TARGET_HALTED)
652         {
653                 LOG_ERROR("Target not halted");
654                 return ERROR_TARGET_NOT_HALTED;
655         }
656
657         return lpc2000_iap_blank_check(bank, 0, bank->num_sectors - 1);
658 }
659
660 static int lpc2000_protect_check(struct flash_bank_s *bank)
661 {
662         /* sectors are always protected */
663         return ERROR_OK;
664 }
665
666 static int lpc2000_info(struct flash_bank_s *bank, char *buf, int buf_size)
667 {
668         lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv;
669
670         snprintf(buf, buf_size, "lpc2000 flash driver variant: %i, clk: %" PRIi32 , lpc2000_info->variant, lpc2000_info->cclk);
671
672         return ERROR_OK;
673 }
674
675 static int lpc2000_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
676 {
677         flash_bank_t *bank;
678         uint32_t param_table[5];
679         uint32_t result_table[2];
680         int status_code;
681
682         if (argc < 1)
683         {
684                 return ERROR_COMMAND_SYNTAX_ERROR;
685         }
686
687         bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
688         if (!bank)
689         {
690                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
691                 return ERROR_OK;
692         }
693
694         if (bank->target->state != TARGET_HALTED)
695         {
696                 LOG_ERROR("Target not halted");
697                 return ERROR_TARGET_NOT_HALTED;
698         }
699
700         if ((status_code = lpc2000_iap_call(bank, 54, param_table, result_table)) != 0x0)
701         {
702                 if (status_code == ERROR_FLASH_OPERATION_FAILED)
703                 {
704                         command_print(cmd_ctx, "no sufficient working area specified, can't access LPC2000 IAP interface");
705                         return ERROR_OK;
706                 }
707                 command_print(cmd_ctx, "lpc2000 IAP returned status code %i", status_code);
708         }
709         else
710         {
711                 command_print(cmd_ctx, "lpc2000 part id: 0x%8.8" PRIx32 , result_table[0]);
712         }
713
714         return ERROR_OK;
715 }