1 /***************************************************************************
2 * Copyright (C) 2011 by Marc Willam, Holger Wech *
4 * Copyright (C) 2011 Ronny Strutz *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
20 ***************************************************************************/
26 #include <helper/binarybuffer.h>
27 #include <target/algorithm.h>
28 #include <target/armv7m.h>
30 #define FLASH_DQ6 0x00000040 /* Data toggle flag bit (TOGG) position */
31 #define FLASH_DQ5 0x00000020 /* Time limit exceeding flag bit (TLOV) position */
45 struct working_area
*write_algorithm
;
46 enum fm3_variant variant
;
50 FLASH_BANK_COMMAND_HANDLER(fm3_flash_bank_command
)
52 struct fm3_flash_bank
*fm3_info
;
56 LOG_WARNING("incomplete flash_bank fm3 configuration");
57 return ERROR_FLASH_BANK_INVALID
;
60 LOG_INFO("******HWE* FLASH CMD Parameter %s", CMD_ARGV
[5]);
62 fm3_info
= malloc(sizeof(struct fm3_flash_bank
));
63 bank
->driver_priv
= fm3_info
;
65 if (strcmp(CMD_ARGV
[5], "mb9bfxx1.cpu") == 0)
67 fm3_info
->variant
= mb9bfxx1
;
69 else if (strcmp(CMD_ARGV
[5], "mb9bfxx2.cpu") == 0)
71 fm3_info
->variant
= mb9bfxx2
;
73 else if (strcmp(CMD_ARGV
[5], "mb9bfxx3.cpu") == 0)
75 fm3_info
->variant
= mb9bfxx3
;
77 else if (strcmp(CMD_ARGV
[5], "mb9bfxx4.cpu") == 0)
79 fm3_info
->variant
= mb9bfxx4
;
81 else if (strcmp(CMD_ARGV
[5], "mb9bfxx5.cpu") == 0)
83 fm3_info
->variant
= mb9bfxx5
;
85 else if (strcmp(CMD_ARGV
[5], "mb9bfxx6.cpu") == 0)
87 fm3_info
->variant
= mb9bfxx6
;
88 LOG_INFO("******HWE* fm3 Variant set to: mb9bfxx6");
92 LOG_ERROR("unknown fm3 variant: %s", CMD_ARGV
[5]);
94 return ERROR_FLASH_BANK_INVALID
;
97 fm3_info
->write_algorithm
= NULL
;
103 static int fm3_busy_wait(struct target
*target
, uint32_t offset
, int timeout_ms
)
105 int retval
= ERROR_OK
;
106 uint16_t state1
, state2
;
110 target_read_u16(target
, offset
, &state1
); /* dummy-read - see flash manual */
111 target_read_u16(target
, offset
, &state1
);
112 target_read_u16(target
, offset
, &state2
);
114 if ( (state1
& FLASH_DQ6
) == (state2
& FLASH_DQ6
) ) {
117 else if (state1
& FLASH_DQ5
) {
118 target_read_u16(target
, offset
, &state1
);
119 target_read_u16(target
, offset
, &state2
);
120 if ( (state1
& FLASH_DQ6
) != (state2
& FLASH_DQ6
) )
121 retval
= ERROR_FLASH_OPERATION_FAILED
;
127 if (ms
> timeout_ms
) {
128 LOG_ERROR("toggle bit reading timed out!");
129 retval
= ERROR_FLASH_OPERATION_FAILED
;
134 if (retval
== ERROR_OK
)
135 LOG_DEBUG("fm3_busy_wait(%x) needs about %d ms", offset
, ms
);
140 static int fm3_erase(struct flash_bank
*bank
, int first
, int last
)
142 struct target
*target
= bank
->target
;
143 int retval
= ERROR_OK
;
144 uint32_t u32DummyRead
;
147 if (target
->state
!= TARGET_HALTED
) {
148 LOG_ERROR("Target not halted");
149 return ERROR_TARGET_NOT_HALTED
;
152 LOG_INFO("Fujitsu MB9Bxxx: Sector Erase ... (%d to %d)", first
, last
);
154 target_write_u32(target
, 0x40000000, 0x0001); /* FASZR = 0x01, Enables CPU Programming Mode */
155 target_read_u32(target
, 0x40000000, &u32DummyRead
); /* dummy read of FASZR */
157 for (sector
= first
; sector
<= last
; sector
++) {
158 uint32_t offset
= bank
->sectors
[sector
].offset
;
160 for (odd
= 0; odd
< 2 ; odd
++) {
165 target_write_u16(target
, 0x1550, 0x00AA);
166 target_write_u16(target
, 0x0AA8, 0x0055);
167 target_write_u16(target
, 0x1550, 0x0080);
168 target_write_u16(target
, 0x1550, 0x00AA);
169 target_write_u16(target
, 0x0AA8, 0x0055);
170 target_write_u16(target
, offset
, 0x0030);
172 retval
= fm3_busy_wait(target
, offset
, 500);
174 if (retval
!= ERROR_OK
)
177 bank
->sectors
[sector
].is_erased
= 1;
180 target_write_u32(target
, 0x40000000, 0x0002);
181 target_read_u32(target
, 0x40000000, &u32DummyRead
); /* dummy read of FASZR */
186 static int fm3_write_block(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
188 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
189 struct target
*target
= bank
->target
;
190 uint32_t buffer_size
= 8192;
191 struct working_area
*source
;
192 uint32_t address
= bank
->base
+ offset
;
193 struct reg_param reg_params
[4];
194 struct armv7m_algorithm armv7m_info
;
195 int retval
= ERROR_OK
;
197 /* RAMCODE used for fm3 Flash programming: */
198 /* R0 keeps source start address (u32Source) */
199 /* R1 keeps target start address (u32Target) */
200 /* R2 keeps number of halfwords to write (u32Count) */
201 /* R3 returns result value (u32FlashResult) */
203 const uint8_t fm3_flash_write_code
[] = {
204 /* fm3_FLASH_IF->FASZ &= 0xFFFD; */
205 0x00, 0xBF, /* NOP */
206 0x5F, 0xF0, 0x80, 0x43, /* MOVS.W R3, #(fm3_FLASH_IF->FASZ) */
207 0x1B, 0x68, /* LDR R3, [R3] */
208 0x4F, 0xF6, 0xFD, 0x74, /* MOVW R4, #0xFFFD */
209 0x23, 0x40, /* ANDS R3, R3, R4 */
210 0x5F, 0xF0, 0x80, 0x44, /* MOVS.W R4, #(fm3_FLASH_IF->FASZ) */
211 0x23, 0x60, /* STR R3, [R4] */
212 /* fm3_FLASH_IF->FASZ |= 1; */
213 0x5F, 0xF0, 0x80, 0x43, /* MOVS.W R3, #(fm3_FLASH_IF->FASZ) */
214 0x1B, 0x68, /* LDR R3, [R3] */
215 0x53, 0xF0, 0x01, 0x03, /* ORRS.W R3, R3, #1 */
216 0x5F, 0xF0, 0x80, 0x44, /* MOVS.W R4, #(fm3_FLASH_IF->FASZ) */
217 0x23, 0x60, /* STR R3, [R4] */
218 /* u32DummyRead = fm3_FLASH_IF->FASZ; */
219 0x2B, 0x4B, /* LDR.N R3, ??u32DummyRead */
220 0x5F, 0xF0, 0x80, 0x44, /* MOVS.W R4, #(fm3_FLASH_IF->FASZ) */
221 0x24, 0x68, /* LDR R4, [R4] */
222 0x1C, 0x60, /* STR R4, [R3] */
223 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
224 0x2A, 0x4B, /* LDR.N R3, ??u32FlashResult */
225 0x00, 0x24, /* MOVS R4, #0 */
226 0x1C, 0x60, /* STR R4, [R3] */
227 /* while ((u32Count > 0 ) && (u32FlashResult */
228 /* == FLASH_WRITE_NO_RESULT)) */
229 0x01, 0x2A, /* L0: CMP R2, #1 */
230 0x32, 0xDB, /* BLT.N L1 */
231 0x27, 0x4B, /* LDR.N R3, ??u32FlashResult */
232 0x1B, 0x68, /* LDR R3, [R3] */
233 0x00, 0x2B, /* CMP R3, #0 */
234 0x2E, 0xD1, /* BNE.N L1 */
235 /* *(FLASH_SEQ_1550) = FLASH_WRITE_1; */
236 0x41, 0xF2, 0x50, 0x53, /* MOVW R3, #0x1550 */
237 0xAA, 0x24, /* MOVS R4. #0xAA */
238 0x1C, 0x80, /* STRH R4, [R3] */
239 /* *(FLASH_SEQ_0AA8) = FLASH_WRITE_2; */
240 0x40, 0xF6, 0xA8, 0x23, /* MOVW R3, #0x0AA8 */
241 0x55, 0x24, /* MOVS R4. #0x55 */
242 0x1C, 0x80, /* STRH R4, [R3] */
243 /* *(FLASH_SEQ_1550) = FLASH_WRITE_3; */
244 0x41, 0xF2, 0x50, 0x53, /* MOVW R3, #0x1550 */
245 0xA0, 0x24, /* MOVS R4. #0xA0 */
246 0x1C, 0x80, /* STRH R4, [R3] */
247 /* *(volatile uint16_t*)u32Target */
248 /* = *(volatile uint16_t*)u32Source; */
249 0x03, 0x88, /* LDRH R3, [R0] */
250 0x0B, 0x80, /* STRH R3, [R1] */
251 /* while (u32FlashResult == FLASH_WRITE_NO_RESTULT) */
252 0x1E, 0x4B, /* L2: LDR.N R3, ??u32FlashResult */
253 0x1B, 0x68, /* LDR R3, [R3] */
254 0x00, 0x2B, /* CMP R3, #0 */
255 0x11, 0xD1, /* BNE.N L3 */
256 /* if ((*(volatile uint16_t*)u32Target & FLASH_DQ5) */
258 0x0B, 0x88, /* LDRH R3, [R1] */
259 0x9B, 0x06, /* LSLS R3, R3, #0x1A */
260 0x02, 0xD5, /* BPL.N L4 */
261 /* u32FlashResult = FLASH_WRITE_TIMEOUT */
262 0x1B, 0x4B, /* LDR.N R3, ??u32FlashResult */
263 0x02, 0x24, /* MOVS R4, #2 */
264 0x1C, 0x60, /* STR R4, [R3] */
265 /* if ((*(volatile uint16_t *)u32Target & FLASH_DQ7) */
266 /* == (*(volatile uint16_t*)u32Source & FLASH_DQ7)) */
267 0x0B, 0x88, /* L4: LDRH R3, [R1] */
268 0x13, 0xF0, 0x80, 0x03, /* ANDS.W R3, R3, #0x80 */
269 0x04, 0x88, /* LDRH R4, [R0] */
270 0x14, 0xF0, 0x80, 0x04, /* ANDS.W R4, R4, #0x80 */
271 0xA3, 0x42, /* CMP R3, R4 */
272 0xED, 0xD1, /* BNE.N L2 */
273 /* u32FlashResult = FLASH_WRITE_OKAY */
274 0x15, 0x4B, /* LDR.N R3, ??u32FlashResult */
275 0x01, 0x24, /* MOVS R4, #1 */
276 0x1C, 0x60, /* STR R4, [R3] */
277 0xE9, 0xE7, /* B.N L2 */
278 /* if (u32FlashResult != FLASH_WRITE_TIMEOUT) */
279 0x13, 0x4B, /* LDR.N R3, ??u32FlashResult */
280 0x1B, 0x68, /* LDR R3, [R3] */
281 0x02, 0x2B, /* CMP R3, #2 */
282 0x02, 0xD0, /* BEQ.N L5 */
283 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
284 0x11, 0x4B, /* LDR.N R3, ??u32FlashResult */
285 0x00, 0x24, /* MOVS R4, #0 */
286 0x1C, 0x60, /* STR R4, [R3] */
288 0x52, 0x1E, /* L5: SUBS R2, R2, #1 */
289 /* u32Source += 2; */
290 0x80, 0x1C, /* ADDS R0, R0, #2 */
291 /* u32Target += 2; */
292 0x89, 0x1C, /* ADDS R1, R1, #2 */
293 0xCA, 0xE7, /* B.N L0 */
294 /* fm3_FLASH_IF->FASZ &= 0xFFFE; */
295 0x5F, 0xF0, 0x80, 0x43, /* L1: MOVS.W R3, #(fm3_FLASH_IF->FASZ) */
296 0x1B, 0x68, /* LDR R3, [R3] */
297 0x4F, 0xF6, 0xFE, 0x74, /* MOVW R4, #0xFFFE */
298 0x23, 0x40, /* ANDS R3, R3, R4 */
299 0x5F, 0xF0, 0x80, 0x44, /* MOVS.W R4, #(fm3_FLASH_IF->FASZ) */
300 0x23, 0x60, /* STR R3, [R4] */
301 /* fm3_FLASH_IF->FASZ |= 2; */
302 0x5F, 0xF0, 0x80, 0x43, /* MOVS.W R3, #(fm3_FLASH_IF->FASZ) */
303 0x1B, 0x68, /* LDR R3, [R3] */
304 0x53, 0xF0, 0x02, 0x03, /* ORRS.W R3, R3, #2 */
305 0x5F, 0xF0, 0x80, 0x44, /* MOVS.W R4, #(fm3_FLASH_IF->FASZ) */
306 0x23, 0x60, /* STR R4, [R3] */
307 /* u32DummyRead = fm3_FLASH_IF->FASZ; */
308 0x04, 0x4B, /* LDR.N R3, ??u32DummyRead */
309 0x5F, 0xF0, 0x80, 0x44, /* MOVS.W R4, #(fm3_FLASH_IF->FASZ) */
310 0x24, 0x68, /* LDR R4, [R4] */
311 0x1C, 0x60, /* STR R4, [R3] */
312 /* copy u32FlashResult to R3 for return value */
313 0xDF, 0xF8, 0x0C, 0x30, /* LDR.W R3, ??u32FlashResult */
314 0x1B, 0x68, /* LDR R3, [R3] */
315 /* Breakpoint here */
316 0x00, 0xBE, /* Breakpoint #0 */
317 0x00, 0x00, /* alignment padding bytes */
318 0x00, 0x80, 0xFF, 0x1F, /* u32DummyRead address in RAM (0x1FFF8000) */
319 0x04, 0x80, 0xFF, 0x1F /* u32FlashResult address in RAM (0x1FFF8004) */
322 LOG_INFO("Fujitsu MB9B500: FLASH Write ...");
324 /* disable HW watchdog */
325 target_write_u32(target
, 0x40011C00, 0x1ACCE551);
326 target_write_u32(target
, 0x40011C00, 0xE5331AAE);
327 target_write_u32(target
, 0x40011008, 0x00000000);
329 count
= count
/ 2; /* number bytes -> number halfwords */
331 /* check code alignment */
334 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
335 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
338 /* allocate working area with flash programming code */
339 if (target_alloc_working_area(target
, sizeof(fm3_flash_write_code
),
340 &fm3_info
->write_algorithm
) != ERROR_OK
)
342 LOG_WARNING("no working area available, can't do block memory writes");
343 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
346 retval
= target_write_buffer(target
, fm3_info
->write_algorithm
->address
,
347 sizeof(fm3_flash_write_code
), fm3_flash_write_code
);
348 if (retval
!= ERROR_OK
)
352 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
355 if (buffer_size
<= 256)
357 /* free working area, if write algorithm already allocated */
358 if (fm3_info
->write_algorithm
)
360 target_free_working_area(target
, fm3_info
->write_algorithm
);
363 LOG_WARNING("no large enough working area available, can't do block memory writes");
364 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
368 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
369 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
371 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); // source start address
372 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); // target start address
373 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); // number of halfwords to program
374 init_reg_param(®_params
[3], "r3", 32, PARAM_IN
); // result
376 /* write code buffer and use Flash programming code within fm3 */
377 /* Set breakpoint to 0 with time-out of 1000 ms */
380 uint32_t thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
382 /* for some reason the first 8 byte of code are corrupt when target_run_algorithm() returns */
383 /* need some more investigation on this */
384 retval
= target_write_buffer(target
,
385 fm3_info
->write_algorithm
->address
, 8, fm3_flash_write_code
);
386 if (retval
!= ERROR_OK
)
390 retval
= target_write_buffer(target
,
391 source
->address
, thisrun_count
* 2, buffer
);
392 if (retval
!= ERROR_OK
)
395 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
396 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
397 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
400 retval
= target_run_algorithm(target
, 0, NULL
, 4, reg_params
,
401 fm3_info
->write_algorithm
->address
, 0, 1000, &armv7m_info
);
402 if (retval
!= ERROR_OK
)
404 LOG_ERROR("error executing fm3 Flash programming algorithm");
405 retval
= ERROR_FLASH_OPERATION_FAILED
;
410 /* debug the corrupted 8 bytes */
411 unsigned char buf
[256];
412 retval
= target_read_buffer(target
, fm3_info
->write_algorithm
->address
, 256, buf
);
413 if (retval
!= ERROR_OK
)
414 printf("cannot read buffer\n");
416 for ( i
= 0; i
< sizeof(fm3_flash_write_code
); i
++)
417 if (buf
[i
] != fm3_flash_write_code
[i
])
418 printf("broken: %d %02x != %02x\n", i
, buf
[i
], fm3_flash_write_code
[i
]);
421 if (buf_get_u32(reg_params
[3].value
, 0, 32) != ERROR_OK
)
423 LOG_ERROR("Fujitsu MB9B500: FLASH programming ERROR (Timeout) -> Reg R3: %x",
424 buf_get_u32(reg_params
[3].value
, 0, 32));
425 retval
= ERROR_FLASH_OPERATION_FAILED
;
429 buffer
+= thisrun_count
* 2;
430 address
+= thisrun_count
* 2;
431 count
-= thisrun_count
;
434 target_free_working_area(target
, source
);
435 target_free_working_area(target
, fm3_info
->write_algorithm
);
437 destroy_reg_param(®_params
[0]);
438 destroy_reg_param(®_params
[1]);
439 destroy_reg_param(®_params
[2]);
440 destroy_reg_param(®_params
[3]);
445 static int fm3_probe(struct flash_bank
*bank
)
447 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
450 if (bank
->target
->state
!= TARGET_HALTED
)
452 LOG_ERROR("Target not halted");
453 return ERROR_TARGET_NOT_HALTED
;
456 num_pages
= 6; /* max number of Flash pages for malloc */
457 fm3_info
->probed
= 0;
459 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_pages
);
460 bank
->base
= 0x00000000;
461 num_pages
= 2; /* start with smallest Flash pages number */
462 bank
->size
= 32 * 1024; /* bytes */
464 bank
->sectors
[0].offset
= 0;
465 bank
->sectors
[0].size
= 16 * 1024;
466 bank
->sectors
[0].is_erased
= -1;
467 bank
->sectors
[0].is_protected
= -1;
469 bank
->sectors
[1].offset
= 0x4000;
470 bank
->sectors
[1].size
= 16 * 1024;
471 bank
->sectors
[1].is_erased
= -1;
472 bank
->sectors
[1].is_protected
= -1;
474 if (fm3_info
->variant
== mb9bfxx1
)
477 bank
->size
= 64 * 1024; /* bytes */
478 bank
->num_sectors
= num_pages
;
480 bank
->sectors
[2].offset
= 0x8000;
481 bank
->sectors
[2].size
= 32 * 1024;
482 bank
->sectors
[2].is_erased
= -1;
483 bank
->sectors
[2].is_protected
= -1;
486 if ( (fm3_info
->variant
== mb9bfxx2
)
487 || (fm3_info
->variant
== mb9bfxx4
)
488 || (fm3_info
->variant
== mb9bfxx5
)
489 || (fm3_info
->variant
== mb9bfxx6
))
492 bank
->size
= 128 * 1024; // bytes
493 bank
->num_sectors
= num_pages
;
495 bank
->sectors
[2].offset
= 0x8000;
496 bank
->sectors
[2].size
= 96 * 1024;
497 bank
->sectors
[2].is_erased
= -1;
498 bank
->sectors
[2].is_protected
= -1;
501 if ( (fm3_info
->variant
== mb9bfxx4
)
502 || (fm3_info
->variant
== mb9bfxx5
)
503 || (fm3_info
->variant
== mb9bfxx6
))
506 bank
->size
= 256 * 1024; // bytes
507 bank
->num_sectors
= num_pages
;
509 bank
->sectors
[3].offset
= 0x20000;
510 bank
->sectors
[3].size
= 128 * 1024;
511 bank
->sectors
[3].is_erased
= -1;
512 bank
->sectors
[3].is_protected
= -1;
515 if ( (fm3_info
->variant
== mb9bfxx5
)
516 || (fm3_info
->variant
== mb9bfxx6
))
519 bank
->size
= 384 * 1024; // bytes
520 bank
->num_sectors
= num_pages
;
522 bank
->sectors
[4].offset
= 0x40000;
523 bank
->sectors
[4].size
= 128 * 1024;
524 bank
->sectors
[4].is_erased
= -1;
525 bank
->sectors
[4].is_protected
= -1;
528 if (fm3_info
->variant
== mb9bfxx6
)
531 bank
->size
= 512 * 1024; // bytes
532 bank
->num_sectors
= num_pages
;
534 bank
->sectors
[5].offset
= 0x60000;
535 bank
->sectors
[5].size
= 128 * 1024;
536 bank
->sectors
[5].is_erased
= -1;
537 bank
->sectors
[5].is_protected
= -1;
540 fm3_info
->probed
= 1;
545 static int fm3_auto_probe(struct flash_bank
*bank
)
547 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
548 if (fm3_info
->probed
)
550 return fm3_probe(bank
);
553 static int fm3_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
555 snprintf(buf
, buf_size
, "Fujitsu fm3 Device does not support Chip-ID (Type unknown)");
559 static int fm3_chip_erase(struct flash_bank
*bank
)
561 struct target
*target
= bank
->target
;
562 int retval
= ERROR_OK
;
563 uint32_t u32DummyRead
;
565 if (target
->state
!= TARGET_HALTED
)
567 LOG_ERROR("Target not halted");
568 return ERROR_TARGET_NOT_HALTED
;
571 LOG_INFO("Fujitsu MB9Bxxx: Chip Erase ... (may take several seconds)");
573 /* Implement Flash chip erase (mass erase) completely on host */
574 target_write_u32(target
, 0x40000000, 0x0001); /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */
575 target_read_u32(target
, 0x40000000, &u32DummyRead
); /* dummy read of FASZR */
577 target_write_u16(target
, 0x00001550, 0x00AA); /* Flash unlock sequence */
578 target_write_u16(target
, 0x00000AA8, 0x0055);
579 target_write_u16(target
, 0x00001550, 0x0080);
580 target_write_u16(target
, 0x00001550, 0x00AA);
581 target_write_u16(target
, 0x00000AA8, 0x0055);
582 target_write_u16(target
, 0x00001550, 0x0010); /* Chip Erase command */
584 retval
= fm3_busy_wait(target
, 0xAA8, 20000);
586 target_write_u32(target
, 0x40000000, 0x0002);
587 target_read_u32(target
, 0x40000000, &u32DummyRead
); /* dummy read of FASZR */
592 COMMAND_HANDLER(fm3_handle_chip_erase_command
)
598 command_print(CMD_CTX
, "fm3 chip_erase <bank>");
602 struct flash_bank
*bank
;
603 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
604 if (ERROR_OK
!= retval
)
607 if (fm3_chip_erase(bank
) == ERROR_OK
)
609 /* set all sectors as erased */
610 for (i
= 0; i
< bank
->num_sectors
; i
++)
611 bank
->sectors
[i
].is_erased
= 1;
613 command_print(CMD_CTX
, "fm3 chip erase complete");
617 command_print(CMD_CTX
, "fm3 chip erase failed");
623 static const struct command_registration fm3_exec_command_handlers
[] = {
625 .name
= "chip_erase",
626 .handler
= fm3_handle_chip_erase_command
,
627 .mode
= COMMAND_EXEC
,
629 .help
= "Erase entire Flash device.",
631 COMMAND_REGISTRATION_DONE
634 static const struct command_registration fm3_command_handlers
[] = {
638 .help
= "fm3 Flash command group",
639 .chain
= fm3_exec_command_handlers
,
641 COMMAND_REGISTRATION_DONE
644 struct flash_driver fm3_flash
= {
646 .commands
= fm3_command_handlers
,
647 .flash_bank_command
= fm3_flash_bank_command
,
649 .write
= fm3_write_block
,
651 .auto_probe
= fm3_auto_probe
,
652 .erase_check
= default_flash_mem_blank_check
,
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)