3574a897d47890d378ea10bfb49206510c0137ed
[openocd.git] / src / flash / str7x.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 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "replacements.h"
25
26 #include "str7x.h"
27 #include "flash.h"
28 #include "target.h"
29 #include "log.h"
30 #include "armv4_5.h"
31 #include "algorithm.h"
32 #include "binarybuffer.h"
33
34 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
37
38 str7x_mem_layout_t mem_layout[] = {
39 {0x00000000, 0x02000, 0x01},
40 {0x00002000, 0x02000, 0x02},
41 {0x00004000, 0x02000, 0x04},
42 {0x00006000, 0x02000, 0x08},
43 {0x00008000, 0x08000, 0x10},
44 {0x00010000, 0x10000, 0x20},
45 {0x00020000, 0x10000, 0x40},
46 {0x00030000, 0x10000, 0x80},
47 {0x000C0000, 0x02000, 0x10000},
48 {0x000C2000, 0x02000, 0x20000},
49 };
50
51 int str7x_register_commands(struct command_context_s *cmd_ctx);
52 int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
53 int str7x_erase(struct flash_bank_s *bank, int first, int last);
54 int str7x_protect(struct flash_bank_s *bank, int set, int first, int last);
55 int str7x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
56 int str7x_probe(struct flash_bank_s *bank);
57 int str7x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
58 int str7x_protect_check(struct flash_bank_s *bank);
59 int str7x_erase_check(struct flash_bank_s *bank);
60 int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size);
61
62 int str7x_handle_disable_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
63
64 flash_driver_t str7x_flash =
65 {
66 .name = "str7x",
67 .register_commands = str7x_register_commands,
68 .flash_bank_command = str7x_flash_bank_command,
69 .erase = str7x_erase,
70 .protect = str7x_protect,
71 .write = str7x_write,
72 .probe = str7x_probe,
73 .auto_probe = str7x_probe,
74 .erase_check = str7x_erase_check,
75 .protect_check = str7x_protect_check,
76 .info = str7x_info
77 };
78
79 int str7x_register_commands(struct command_context_s *cmd_ctx)
80 {
81 command_t *str7x_cmd = register_command(cmd_ctx, NULL, "str7x", NULL, COMMAND_ANY, NULL);
82
83 register_command(cmd_ctx, str7x_cmd, "disable_jtag", str7x_handle_disable_jtag_command, COMMAND_EXEC,
84 "disable jtag access");
85
86 return ERROR_OK;
87 }
88
89 int str7x_get_flash_adr(struct flash_bank_s *bank, u32 reg)
90 {
91 return (bank->base | reg);
92 }
93
94 int str7x_build_block_list(struct flash_bank_s *bank)
95 {
96 str7x_flash_bank_t *str7x_info = bank->driver_priv;
97
98 int i;
99 int num_sectors = 0, b0_sectors = 0, b1_sectors = 0;
100
101 switch (bank->size)
102 {
103 case 16 * 1024:
104 b0_sectors = 2;
105 break;
106 case 64 * 1024:
107 b0_sectors = 5;
108 break;
109 case 128 * 1024:
110 b0_sectors = 6;
111 break;
112 case 256 * 1024:
113 b0_sectors = 8;
114 break;
115 default:
116 ERROR("BUG: unknown bank->size encountered");
117 exit(-1);
118 }
119
120 if( str7x_info->bank1 == 1 )
121 {
122 b1_sectors += 2;
123 }
124
125 num_sectors = b0_sectors + b1_sectors;
126
127 bank->num_sectors = num_sectors;
128 bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
129 str7x_info->sector_bits = malloc(sizeof(u32) * num_sectors);
130 str7x_info->sector_bank = malloc(sizeof(u32) * num_sectors);
131
132 num_sectors = 0;
133
134 for (i = 0; i < b0_sectors; i++)
135 {
136 bank->sectors[num_sectors].offset = mem_layout[i].sector_start;
137 bank->sectors[num_sectors].size = mem_layout[i].sector_size;
138 bank->sectors[num_sectors].is_erased = -1;
139 bank->sectors[num_sectors].is_protected = 1;
140 str7x_info->sector_bank[num_sectors] = 0;
141 str7x_info->sector_bits[num_sectors++] = mem_layout[i].sector_bit;
142 }
143
144 if (b1_sectors)
145 {
146 for (i = 8; i < 10; i++)
147 {
148 bank->sectors[num_sectors].offset = mem_layout[i].sector_start;
149 bank->sectors[num_sectors].size = mem_layout[i].sector_size;
150 bank->sectors[num_sectors].is_erased = -1;
151 bank->sectors[num_sectors].is_protected = 1;
152 str7x_info->sector_bank[num_sectors] = 1;
153 str7x_info->sector_bits[num_sectors++] = mem_layout[i].sector_bit;
154 }
155 }
156
157 return ERROR_OK;
158 }
159
160 /* flash bank str7x <base> <size> 0 0 <target#> <str71_variant>
161 */
162 int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
163 {
164 str7x_flash_bank_t *str7x_info;
165
166 if (argc < 7)
167 {
168 WARNING("incomplete flash_bank str7x configuration");
169 return ERROR_FLASH_BANK_INVALID;
170 }
171
172 str7x_info = malloc(sizeof(str7x_flash_bank_t));
173 bank->driver_priv = str7x_info;
174
175 /* set default bits for str71x flash */
176 str7x_info->bank1 = 1;
177 str7x_info->busy_bits = (FLASH_LOCK|FLASH_BSYA1|FLASH_BSYA0);
178 str7x_info->disable_bit = (1<<1);
179
180 if (strcmp(args[6], "STR71x") == 0)
181 {
182 if (bank->base != 0x40000000)
183 {
184 WARNING("overriding flash base address for STR71x device with 0x40000000");
185 bank->base = 0x40000000;
186 }
187 }
188 else if (strcmp(args[6], "STR73x") == 0)
189 {
190 str7x_info->bank1 = 0;
191 str7x_info->busy_bits = (FLASH_LOCK|FLASH_BSYA0);
192
193 if (bank->base != 0x80000000)
194 {
195 WARNING("overriding flash base address for STR73x device with 0x80000000");
196 bank->base = 0x80000000;
197 }
198 }
199 else if (strcmp(args[6], "STR75x") == 0)
200 {
201 str7x_info->disable_bit = (1<<0);
202
203 if (bank->base != 0x20000000)
204 {
205 WARNING("overriding flash base address for STR75x device with 0x20000000");
206 bank->base = 0x20000000;
207 }
208 }
209 else
210 {
211 ERROR("unknown STR7x variant: '%s'", args[6]);
212 free(str7x_info);
213 return ERROR_FLASH_BANK_INVALID;
214 }
215
216 str7x_build_block_list(bank);
217
218 str7x_info->write_algorithm = NULL;
219
220 return ERROR_OK;
221 }
222
223 u32 str7x_status(struct flash_bank_s *bank)
224 {
225 target_t *target = bank->target;
226 u32 retval;
227
228 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), &retval);
229
230 return retval;
231 }
232
233 u32 str7x_result(struct flash_bank_s *bank)
234 {
235 target_t *target = bank->target;
236 u32 retval;
237
238 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_ER), &retval);
239
240 return retval;
241 }
242
243 int str7x_blank_check(struct flash_bank_s *bank, int first, int last)
244 {
245 target_t *target = bank->target;
246 u8 *buffer;
247 int i;
248 int nBytes;
249
250 if ((first < 0) || (last > bank->num_sectors))
251 return ERROR_FLASH_SECTOR_INVALID;
252
253 if (bank->target->state != TARGET_HALTED)
254 {
255 return ERROR_TARGET_NOT_HALTED;
256 }
257
258 buffer = malloc(256);
259
260 for (i = first; i <= last; i++)
261 {
262 bank->sectors[i].is_erased = 1;
263
264 target->type->read_memory(target, bank->base + bank->sectors[i].offset, 4, 256/4, buffer);
265
266 for (nBytes = 0; nBytes < 256; nBytes++)
267 {
268 if (buffer[nBytes] != 0xFF)
269 {
270 bank->sectors[i].is_erased = 0;
271 break;
272 }
273 }
274 }
275
276 free(buffer);
277
278 return ERROR_OK;
279 }
280
281 int str7x_protect_check(struct flash_bank_s *bank)
282 {
283 str7x_flash_bank_t *str7x_info = bank->driver_priv;
284 target_t *target = bank->target;
285
286 int i;
287 u32 retval;
288
289 if (bank->target->state != TARGET_HALTED)
290 {
291 return ERROR_TARGET_NOT_HALTED;
292 }
293
294 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVWPAR), &retval);
295
296 for (i = 0; i < bank->num_sectors; i++)
297 {
298 if (retval & str7x_info->sector_bits[i])
299 bank->sectors[i].is_protected = 0;
300 else
301 bank->sectors[i].is_protected = 1;
302 }
303
304 return ERROR_OK;
305 }
306
307 int str7x_erase(struct flash_bank_s *bank, int first, int last)
308 {
309 str7x_flash_bank_t *str7x_info = bank->driver_priv;
310 target_t *target = bank->target;
311
312 int i;
313 u32 cmd;
314 u32 retval;
315 u32 b0_sectors = 0, b1_sectors = 0;
316
317 for (i = first; i <= last; i++)
318 {
319 if (str7x_info->sector_bank[i] == 0)
320 b0_sectors |= str7x_info->sector_bits[i];
321 else if (str7x_info->sector_bank[i] == 1)
322 b1_sectors |= str7x_info->sector_bits[i];
323 else
324 ERROR("BUG: str7x_info->sector_bank[i] neither 0 nor 1 (%i)", str7x_info->sector_bank[i]);
325 }
326
327 if (b0_sectors)
328 {
329 DEBUG("b0_sectors: 0x%x", b0_sectors);
330
331 /* clear FLASH_ER register */
332 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
333
334 cmd = FLASH_SER;
335 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
336
337 cmd = b0_sectors;
338 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);
339
340 cmd = FLASH_SER|FLASH_WMS;
341 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
342
343 while (((retval = str7x_status(bank)) & str7x_info->busy_bits)){
344 usleep(1000);
345 }
346
347 retval = str7x_result(bank);
348
349 if (retval)
350 {
351 ERROR("error erasing flash bank, FLASH_ER: 0x%x", retval);
352 return ERROR_FLASH_OPERATION_FAILED;
353 }
354 }
355
356 if (b1_sectors)
357 {
358 DEBUG("b1_sectors: 0x%x", b1_sectors);
359
360 /* clear FLASH_ER register */
361 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
362
363 cmd = FLASH_SER;
364 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
365
366 cmd = b1_sectors;
367 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);
368
369 cmd = FLASH_SER|FLASH_WMS;
370 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
371
372 while (((retval = str7x_status(bank)) & str7x_info->busy_bits)){
373 usleep(1000);
374 }
375
376 retval = str7x_result(bank);
377
378 if (retval)
379 {
380 ERROR("error erasing flash bank, FLASH_ER: 0x%x", retval);
381 return ERROR_FLASH_OPERATION_FAILED;
382 }
383 }
384
385 for (i = first; i <= last; i++)
386 bank->sectors[i].is_erased = 1;
387
388 return ERROR_OK;
389 }
390
391 int str7x_protect(struct flash_bank_s *bank, int set, int first, int last)
392 {
393 str7x_flash_bank_t *str7x_info = bank->driver_priv;
394 target_t *target = bank->target;
395 int i;
396 u32 cmd;
397 u32 retval;
398 u32 protect_blocks;
399
400 if (bank->target->state != TARGET_HALTED)
401 {
402 return ERROR_TARGET_NOT_HALTED;
403 }
404
405 protect_blocks = 0xFFFFFFFF;
406
407 if (set)
408 {
409 for (i = first; i <= last; i++)
410 protect_blocks &= ~(str7x_info->sector_bits[i]);
411 }
412
413 /* clear FLASH_ER register */
414 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
415
416 cmd = FLASH_SPR;
417 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
418
419 cmd = str7x_get_flash_adr(bank, FLASH_NVWPAR);
420 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), cmd);
421
422 cmd = protect_blocks;
423 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), cmd);
424
425 cmd = FLASH_SPR|FLASH_WMS;
426 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
427
428 while (((retval = str7x_status(bank)) & str7x_info->busy_bits)){
429 usleep(1000);
430 }
431
432 retval = str7x_result(bank);
433
434 DEBUG("retval: 0x%8.8x", retval);
435
436 if (retval & FLASH_ERER)
437 return ERROR_FLASH_SECTOR_NOT_ERASED;
438 else if (retval & FLASH_WPF)
439 return ERROR_FLASH_OPERATION_FAILED;
440
441 return ERROR_OK;
442 }
443
444 int str7x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
445 {
446 str7x_flash_bank_t *str7x_info = bank->driver_priv;
447 target_t *target = bank->target;
448 u32 buffer_size = 8192;
449 working_area_t *source;
450 u32 address = bank->base + offset;
451 reg_param_t reg_params[6];
452 armv4_5_algorithm_t armv4_5_info;
453 int retval = ERROR_OK;
454
455 u32 str7x_flash_write_code[] = {
456 /* write: */
457 0xe3a04201, /* mov r4, #0x10000000 */
458 0xe5824000, /* str r4, [r2, #0x0] */
459 0xe5821010, /* str r1, [r2, #0x10] */
460 0xe4904004, /* ldr r4, [r0], #4 */
461 0xe5824008, /* str r4, [r2, #0x8] */
462 0xe4904004, /* ldr r4, [r0], #4 */
463 0xe582400c, /* str r4, [r2, #0xc] */
464 0xe3a04209, /* mov r4, #0x90000000 */
465 0xe5824000, /* str r4, [r2, #0x0] */
466 /* busy: */
467 0xe5924000, /* ldr r4, [r2, #0x0] */
468 0xe1140005, /* tst r4, r5 */
469 0x1afffffc, /* bne busy */
470 0xe5924014, /* ldr r4, [r2, #0x14] */
471 0xe31400ff, /* tst r4, #0xff */
472 0x03140c01, /* tsteq r4, #0x100 */
473 0x1a000002, /* bne exit */
474 0xe2811008, /* add r1, r1, #0x8 */
475 0xe2533001, /* subs r3, r3, #1 */
476 0x1affffec, /* bne write */
477 /* exit: */
478 0xeafffffe, /* b exit */
479 };
480
481 /* flash write code */
482 if (target_alloc_working_area(target, 4 * 20, &str7x_info->write_algorithm) != ERROR_OK)
483 {
484 WARNING("no working area available, can't do block memory writes");
485 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
486 };
487
488 target_write_buffer(target, str7x_info->write_algorithm->address, 20 * 4, (u8*)str7x_flash_write_code);
489
490 /* memory buffer */
491 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
492 {
493 buffer_size /= 2;
494 if (buffer_size <= 256)
495 {
496 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
497 if (str7x_info->write_algorithm)
498 target_free_working_area(target, str7x_info->write_algorithm);
499
500 WARNING("no large enough working area available, can't do block memory writes");
501 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
502 }
503 }
504
505 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
506 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
507 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
508
509 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
510 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
511 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
512 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
513 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
514 init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
515
516 while (count > 0)
517 {
518 u32 thisrun_count = (count > (buffer_size / 8)) ? (buffer_size / 8) : count;
519
520 target_write_buffer(target, source->address, thisrun_count * 8, buffer);
521
522 buf_set_u32(reg_params[0].value, 0, 32, source->address);
523 buf_set_u32(reg_params[1].value, 0, 32, address);
524 buf_set_u32(reg_params[2].value, 0, 32, str7x_get_flash_adr(bank, FLASH_CR0));
525 buf_set_u32(reg_params[3].value, 0, 32, thisrun_count);
526 buf_set_u32(reg_params[5].value, 0, 32, str7x_info->busy_bits);
527
528 if ((retval = target->type->run_algorithm(target, 0, NULL, 6, reg_params, str7x_info->write_algorithm->address, str7x_info->write_algorithm->address + (19 * 4), 10000, &armv4_5_info)) != ERROR_OK)
529 {
530 ERROR("error executing str7x flash write algorithm");
531 break;
532 }
533
534 if (buf_get_u32(reg_params[4].value, 0, 32) != 0x00)
535 {
536 retval = ERROR_FLASH_OPERATION_FAILED;
537 break;
538 }
539
540 buffer += thisrun_count * 8;
541 address += thisrun_count * 8;
542 count -= thisrun_count;
543 }
544
545 target_free_working_area(target, source);
546 target_free_working_area(target, str7x_info->write_algorithm);
547
548 destroy_reg_param(&reg_params[0]);
549 destroy_reg_param(&reg_params[1]);
550 destroy_reg_param(&reg_params[2]);
551 destroy_reg_param(&reg_params[3]);
552 destroy_reg_param(&reg_params[4]);
553 destroy_reg_param(&reg_params[5]);
554
555 return retval;
556 }
557
558 int str7x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
559 {
560 target_t *target = bank->target;
561 str7x_flash_bank_t *str7x_info = bank->driver_priv;
562 u32 dwords_remaining = (count / 8);
563 u32 bytes_remaining = (count & 0x00000007);
564 u32 address = bank->base + offset;
565 u32 bytes_written = 0;
566 u32 cmd;
567 u32 retval;
568 u32 check_address = offset;
569 int i;
570
571 if (offset & 0x7)
572 {
573 WARNING("offset 0x%x breaks required 8-byte alignment", offset);
574 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
575 }
576
577 for (i = 0; i < bank->num_sectors; i++)
578 {
579 u32 sec_start = bank->sectors[i].offset;
580 u32 sec_end = sec_start + bank->sectors[i].size;
581
582 /* check if destination falls within the current sector */
583 if ((check_address >= sec_start) && (check_address < sec_end))
584 {
585 /* check if destination ends in the current sector */
586 if (offset + count < sec_end)
587 check_address = offset + count;
588 else
589 check_address = sec_end;
590 }
591 }
592
593 if (check_address != offset + count)
594 return ERROR_FLASH_DST_OUT_OF_BANK;
595
596 /* clear FLASH_ER register */
597 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
598
599 /* multiple dwords (8-byte) to be programmed? */
600 if (dwords_remaining > 0)
601 {
602 /* try using a block write */
603 if ((retval = str7x_write_block(bank, buffer, offset, dwords_remaining)) != ERROR_OK)
604 {
605 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
606 {
607 /* if block write failed (no sufficient working area),
608 * we use normal (slow) single dword accesses */
609 WARNING("couldn't use block writes, falling back to single memory accesses");
610 }
611 else if (retval == ERROR_FLASH_OPERATION_FAILED)
612 {
613 /* if an error occured, we examine the reason, and quit */
614 retval = str7x_result(bank);
615
616 ERROR("flash writing failed with error code: 0x%x", retval);
617 return ERROR_FLASH_OPERATION_FAILED;
618 }
619 }
620 else
621 {
622 buffer += dwords_remaining * 8;
623 address += dwords_remaining * 8;
624 dwords_remaining = 0;
625 }
626 }
627
628 while (dwords_remaining > 0)
629 {
630 // command
631 cmd = FLASH_DWPG;
632 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
633
634 // address
635 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
636
637 // data word 1
638 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, buffer + bytes_written);
639 bytes_written += 4;
640
641 // data word 2
642 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, buffer + bytes_written);
643 bytes_written += 4;
644
645 /* start programming cycle */
646 cmd = FLASH_DWPG | FLASH_WMS;
647 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
648
649 while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
650 {
651 usleep(1000);
652 }
653
654 retval = str7x_result(bank);
655
656 if (retval & FLASH_PGER)
657 return ERROR_FLASH_OPERATION_FAILED;
658 else if (retval & FLASH_WPF)
659 return ERROR_FLASH_OPERATION_FAILED;
660
661 dwords_remaining--;
662 address += 8;
663 }
664
665 if (bytes_remaining)
666 {
667 u8 last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
668 int i = 0;
669
670 while(bytes_remaining > 0)
671 {
672 last_dword[i++] = *(buffer + bytes_written);
673 bytes_remaining--;
674 bytes_written++;
675 }
676
677 // command
678 cmd = FLASH_DWPG;
679 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
680
681 // address
682 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
683
684 // data word 1
685 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, last_dword);
686 bytes_written += 4;
687
688 // data word 2
689 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, last_dword + 4);
690 bytes_written += 4;
691
692 /* start programming cycle */
693 cmd = FLASH_DWPG | FLASH_WMS;
694 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
695
696 while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
697 {
698 usleep(1000);
699 }
700
701 retval = str7x_result(bank);
702
703 if (retval & FLASH_PGER)
704 return ERROR_FLASH_OPERATION_FAILED;
705 else if (retval & FLASH_WPF)
706 return ERROR_FLASH_OPERATION_FAILED;
707 }
708
709 return ERROR_OK;
710 }
711
712 int str7x_probe(struct flash_bank_s *bank)
713 {
714 return ERROR_OK;
715 }
716
717 int str7x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
718 {
719 return ERROR_OK;
720 }
721
722 int str7x_erase_check(struct flash_bank_s *bank)
723 {
724 return str7x_blank_check(bank, 0, bank->num_sectors - 1);
725 }
726
727 int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size)
728 {
729 snprintf(buf, buf_size, "str7x flash driver info" );
730 return ERROR_OK;
731 }
732
733 int str7x_handle_disable_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
734 {
735 flash_bank_t *bank;
736 target_t *target = NULL;
737 str7x_flash_bank_t *str7x_info = NULL;
738
739 u32 flash_cmd;
740 u32 retval;
741 u16 ProtectionLevel = 0;
742 u16 ProtectionRegs;
743
744 if (argc < 1)
745 {
746 command_print(cmd_ctx, "str7x disable_jtag <bank>");
747 return ERROR_OK;
748 }
749
750 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
751 if (!bank)
752 {
753 command_print(cmd_ctx, "str7x disable_jtag <bank> ok");
754 return ERROR_OK;
755 }
756
757 str7x_info = bank->driver_priv;
758
759 target = bank->target;
760
761 if (target->state != TARGET_HALTED)
762 {
763 return ERROR_TARGET_NOT_HALTED;
764 }
765
766 /* first we get protection status */
767 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), &retval);
768
769 if (!(retval & str7x_info->disable_bit))
770 {
771 ProtectionLevel = 1;
772 }
773
774 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), &retval);
775 ProtectionRegs = ~(retval >> 16);
776
777 while (((ProtectionRegs) != 0) && (ProtectionLevel < 16))
778 {
779 ProtectionRegs >>= 1;
780 ProtectionLevel++;
781 }
782
783 if (ProtectionLevel == 0)
784 {
785 flash_cmd = FLASH_SPR;
786 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
787 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFB8);
788 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), 0xFFFFFFFD);
789 flash_cmd = FLASH_SPR | FLASH_WMS;
790 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
791 }
792 else
793 {
794 flash_cmd = FLASH_SPR;
795 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
796 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFBC);
797 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), ~(1<<(15+ProtectionLevel)));
798 flash_cmd = FLASH_SPR | FLASH_WMS;
799 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
800 }
801
802 return ERROR_OK;
803 }
804

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)