1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
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. *
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. *
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 ***************************************************************************/
24 #include "replacements.h"
31 #include "algorithm.h"
32 #include "binarybuffer.h"
38 str7x_mem_layout_t mem_layout
[] = {
39 {0x00000000, 0x02000, 0x01},
40 {0x00002000, 0x02000, 0x01},
41 {0x00004000, 0x02000, 0x01},
42 {0x00006000, 0x02000, 0x01},
43 {0x00008000, 0x08000, 0x01},
44 {0x00010000, 0x10000, 0x01},
45 {0x00020000, 0x10000, 0x01},
46 {0x00030000, 0x10000, 0x01},
47 {0x000C0000, 0x02000, 0x10},
48 {0x000C2000, 0x02000, 0x10},
52 int str7x_register_commands(struct command_context_s
*cmd_ctx
);
53 int str7x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
54 int str7x_erase(struct flash_bank_s
*bank
, int first
, int last
);
55 int str7x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
56 int str7x_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
57 int str7x_probe(struct flash_bank_s
*bank
);
58 int str7x_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
59 int str7x_protect_check(struct flash_bank_s
*bank
);
60 int str7x_erase_check(struct flash_bank_s
*bank
);
61 int str7x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
63 flash_driver_t str7x_flash
=
66 .register_commands
= str7x_register_commands
,
67 .flash_bank_command
= str7x_flash_bank_command
,
69 .protect
= str7x_protect
,
72 .erase_check
= str7x_erase_check
,
73 .protect_check
= str7x_protect_check
,
77 int str7x_register_commands(struct command_context_s
*cmd_ctx
)
83 int str7x_get_flash_adr(struct flash_bank_s
*bank
, u32 reg
)
85 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
86 return (str7x_info
->flash_base
|reg
);
89 int str7x_build_block_list(struct flash_bank_s
*bank
)
91 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
111 ERROR("BUG: unknown bank->size encountered");
115 if( str7x_info
->bank1
== 1 )
120 bank
->num_sectors
= num_sectors
;
121 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
123 for (i
= 0; i
< num_sectors
; i
++)
125 bank
->sectors
[i
].offset
= mem_layout
[i
].sector_start
;
126 bank
->sectors
[i
].size
= mem_layout
[i
].sector_size
;
127 bank
->sectors
[i
].is_erased
= -1;
128 bank
->sectors
[i
].is_protected
= 1;
134 /* flash bank str7x <base> <size> 0 0 <str71_variant> <target#>
136 int str7x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
138 str7x_flash_bank_t
*str7x_info
;
142 WARNING("incomplete flash_bank str7x configuration");
143 return ERROR_FLASH_BANK_INVALID
;
146 str7x_info
= malloc(sizeof(str7x_flash_bank_t
));
147 bank
->driver_priv
= str7x_info
;
149 if (strcmp(args
[5], "STR71x") == 0)
151 str7x_info
->bank1
= 1;
152 str7x_info
->flash_base
= 0x40000000;
154 else if (strcmp(args
[5], "STR73x") == 0)
156 str7x_info
->bank1
= 0;
157 str7x_info
->flash_base
= 0x80000000;
161 ERROR("unknown STR7x variant");
163 return ERROR_FLASH_BANK_INVALID
;
166 str7x_info
->target
= get_target_by_num(strtoul(args
[6], NULL
, 0));
167 if (!str7x_info
->target
)
169 ERROR("no target '%s' configured", args
[6]);
173 str7x_build_block_list(bank
);
178 u32
str7x_status(struct flash_bank_s
*bank
)
180 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
181 target_t
*target
= str7x_info
->target
;
184 target
->type
->read_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&retval
);
189 u32
str7x_result(struct flash_bank_s
*bank
)
191 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
192 target_t
*target
= str7x_info
->target
;
195 target
->type
->read_memory(target
, str7x_get_flash_adr(bank
, FLASH_ER
), 4, 1, (u8
*)&retval
);
200 int str7x_blank_check(struct flash_bank_s
*bank
, int first
, int last
)
202 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
203 target_t
*target
= str7x_info
->target
;
208 if ((first
< 0) || (last
> bank
->num_sectors
))
209 return ERROR_FLASH_SECTOR_INVALID
;
211 if (str7x_info
->target
->state
!= TARGET_HALTED
)
213 return ERROR_TARGET_NOT_HALTED
;
216 buffer
= malloc(256);
218 for (i
= first
; i
<= last
; i
++)
220 bank
->sectors
[i
].is_erased
= 1;
222 target
->type
->read_memory(target
, bank
->base
+ bank
->sectors
[i
].offset
, 4, 256/4, buffer
);
224 for (nBytes
= 0; nBytes
< 256; nBytes
++)
226 if (buffer
[nBytes
] != 0xFF)
228 bank
->sectors
[i
].is_erased
= 0;
239 int str7x_protect_check(struct flash_bank_s
*bank
)
241 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
242 target_t
*target
= str7x_info
->target
;
247 if (str7x_info
->target
->state
!= TARGET_HALTED
)
249 return ERROR_TARGET_NOT_HALTED
;
252 target
->type
->read_memory(target
, str7x_get_flash_adr(bank
, FLASH_NVWPAR
), 4, 1, (u8
*)&retval
);
254 for (i
= 0; i
< bank
->num_sectors
; i
++)
256 if (retval
& (mem_layout
[i
].reg_offset
<< i
))
257 bank
->sectors
[i
].is_protected
= 0;
259 bank
->sectors
[i
].is_protected
= 1;
265 int str7x_erase(struct flash_bank_s
*bank
, int first
, int last
)
267 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
268 target_t
*target
= str7x_info
->target
;
275 if (str7x_info
->target
->state
!= TARGET_HALTED
)
277 return ERROR_TARGET_NOT_HALTED
;
282 for (i
= first
; i
<= last
; i
++)
283 erase_blocks
|= (mem_layout
[i
].reg_offset
<< i
);
286 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&cmd
);
289 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR1
), 4, 1, (u8
*)&cmd
);
291 cmd
= FLASH_SER
|FLASH_WMS
;
292 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&cmd
);
294 while (((retval
= str7x_status(bank
)) & (FLASH_BSYA1
|FLASH_BSYA2
))){
298 retval
= str7x_result(bank
);
300 if (retval
& FLASH_ERER
)
301 return ERROR_FLASH_SECTOR_NOT_ERASED
;
302 else if (retval
& FLASH_WPF
)
303 return ERROR_FLASH_OPERATION_FAILED
;
305 for (i
= first
; i
<= last
; i
++)
306 bank
->sectors
[i
].is_erased
= 1;
311 int str7x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
313 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
314 target_t
*target
= str7x_info
->target
;
320 if (str7x_info
->target
->state
!= TARGET_HALTED
)
322 return ERROR_TARGET_NOT_HALTED
;
325 protect_blocks
= 0xFFFFFFFF;
329 for (i
= first
; i
<= last
; i
++)
330 protect_blocks
&= ~(mem_layout
[i
].reg_offset
<< i
);
334 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&cmd
);
336 cmd
= str7x_get_flash_adr(bank
, FLASH_NVWPAR
);
337 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_AR
), 4, 1, (u8
*)&cmd
);
339 cmd
= protect_blocks
;
340 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_DR0
), 4, 1, (u8
*)&cmd
);
342 cmd
= FLASH_SPR
|FLASH_WMS
;
343 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&cmd
);
345 while (((retval
= str7x_status(bank
)) & (FLASH_BSYA1
|FLASH_BSYA2
))){
349 retval
= str7x_result(bank
);
351 if (retval
& FLASH_ERER
)
352 return ERROR_FLASH_SECTOR_NOT_ERASED
;
353 else if (retval
& FLASH_WPF
)
354 return ERROR_FLASH_OPERATION_FAILED
;
359 int str7x_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
361 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
362 target_t
*target
= str7x_info
->target
;
363 u32 dwords_remaining
= (count
/ 8);
364 u32 bytes_remaining
= (count
& 0x00000007);
365 u32 address
= bank
->base
+ offset
;
366 u32
*wordbuffer
= (u32
*)buffer
;
367 u32 bytes_written
= 0;
371 if (str7x_info
->target
->state
!= TARGET_HALTED
)
373 return ERROR_TARGET_NOT_HALTED
;
376 if (offset
+ count
> bank
->size
)
377 return ERROR_FLASH_DST_OUT_OF_BANK
;
379 while (dwords_remaining
> 0)
383 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&cmd
);
387 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_AR
), 4, 1, (u8
*)&cmd
);
390 cmd
= wordbuffer
[bytes_written
/4];
391 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_DR0
), 4, 1, (u8
*)&cmd
);
395 cmd
= wordbuffer
[bytes_written
/4];
396 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_DR1
), 4, 1, (u8
*)&cmd
);
399 /* start programming cycle */
400 cmd
= FLASH_DWPG
|FLASH_WMS
;
401 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&cmd
);
403 while (((retval
= str7x_status(bank
)) & (FLASH_BSYA1
|FLASH_BSYA2
))){
407 retval
= str7x_result(bank
);
409 if (retval
& FLASH_PGER
)
410 return ERROR_FLASH_OPERATION_FAILED
;
411 else if (retval
& FLASH_WPF
)
412 return ERROR_FLASH_OPERATION_FAILED
;
418 while( bytes_remaining
> 0 )
422 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&cmd
);
426 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_AR
), 4, 1, (u8
*)&cmd
);
429 cmd
= buffer
[bytes_written
];
430 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_DR0
), 4, 1, (u8
*)&cmd
);
432 /* start programming cycle */
433 cmd
= FLASH_WPG
|FLASH_WMS
;
434 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&cmd
);
436 while (((retval
= str7x_status(bank
)) & (FLASH_BSYA1
|FLASH_BSYA2
))){
440 retval
= str7x_result(bank
);
442 if (retval
& FLASH_PGER
)
443 return ERROR_FLASH_OPERATION_FAILED
;
444 else if (retval
& FLASH_WPF
)
445 return ERROR_FLASH_OPERATION_FAILED
;
455 int str7x_probe(struct flash_bank_s
*bank
)
460 int str7x_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
465 int str7x_erase_check(struct flash_bank_s
*bank
)
467 return str7x_blank_check(bank
, 0, bank
->num_sectors
- 1);
470 int str7x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
472 snprintf(buf
, buf_size
, "str7x flash driver info" );
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)