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 ***************************************************************************/
26 #include "algorithm.h"
27 #include "binarybuffer.h"
33 str7x_mem_layout_t mem_layout
[] = {
34 {0x00000000, 0x02000, 0x01},
35 {0x00002000, 0x02000, 0x01},
36 {0x00004000, 0x02000, 0x01},
37 {0x00006000, 0x02000, 0x01},
38 {0x00008000, 0x08000, 0x01},
39 {0x00010000, 0x10000, 0x01},
40 {0x00020000, 0x10000, 0x01},
41 {0x00030000, 0x10000, 0x01},
42 {0x000C0000, 0x02000, 0x10},
43 {0x000C2000, 0x02000, 0x10},
47 int str7x_register_commands(struct command_context_s
*cmd_ctx
);
48 int str7x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
49 int str7x_erase(struct flash_bank_s
*bank
, int first
, int last
);
50 int str7x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
51 int str7x_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
52 int str7x_probe(struct flash_bank_s
*bank
);
53 int str7x_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
54 int str7x_protect_check(struct flash_bank_s
*bank
);
55 int str7x_erase_check(struct flash_bank_s
*bank
);
56 int str7x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
58 flash_driver_t str7x_flash
=
61 .register_commands
= str7x_register_commands
,
62 .flash_bank_command
= str7x_flash_bank_command
,
64 .protect
= str7x_protect
,
67 .erase_check
= str7x_erase_check
,
68 .protect_check
= str7x_protect_check
,
72 int str7x_register_commands(struct command_context_s
*cmd_ctx
)
78 int str7x_get_flash_adr(struct flash_bank_s
*bank
, u32 reg
)
80 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
81 return (str7x_info
->flash_base
|reg
);
84 int str7x_build_block_list(struct flash_bank_s
*bank
)
86 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
106 ERROR("BUG: unknown bank->size encountered");
110 if( str7x_info
->bank1
== 1 )
115 bank
->num_sectors
= num_sectors
;
116 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
118 for (i
= 0; i
< num_sectors
; i
++)
120 bank
->sectors
[i
].offset
= mem_layout
[i
].sector_start
;
121 bank
->sectors
[i
].size
= mem_layout
[i
].sector_size
;
122 bank
->sectors
[i
].is_erased
= -1;
123 bank
->sectors
[i
].is_protected
= 1;
129 /* flash bank str7x <base> <size> 0 0 <str71_variant> <target#>
131 int str7x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
133 str7x_flash_bank_t
*str7x_info
;
137 WARNING("incomplete flash_bank str7x configuration");
138 return ERROR_FLASH_BANK_INVALID
;
141 str7x_info
= malloc(sizeof(str7x_flash_bank_t
));
142 bank
->driver_priv
= str7x_info
;
144 if (strcmp(args
[5], "STR71x") == 0)
146 str7x_info
->bank1
= 1;
147 str7x_info
->flash_base
= 0x40000000;
149 else if (strcmp(args
[5], "STR73x") == 0)
151 str7x_info
->bank1
= 0;
152 str7x_info
->flash_base
= 0x80000000;
156 ERROR("unknown STR7x variant");
158 return ERROR_FLASH_BANK_INVALID
;
161 str7x_info
->target
= get_target_by_num(strtoul(args
[6], NULL
, 0));
162 if (!str7x_info
->target
)
164 ERROR("no target '%i' configured", args
[6]);
168 str7x_build_block_list(bank
);
173 u32
str7x_status(struct flash_bank_s
*bank
)
175 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
176 target_t
*target
= str7x_info
->target
;
179 target
->type
->read_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&retval
);
184 u32
str7x_result(struct flash_bank_s
*bank
)
186 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
187 target_t
*target
= str7x_info
->target
;
190 target
->type
->read_memory(target
, str7x_get_flash_adr(bank
, FLASH_ER
), 4, 1, (u8
*)&retval
);
195 int str7x_blank_check(struct flash_bank_s
*bank
, int first
, int last
)
197 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
198 target_t
*target
= str7x_info
->target
;
203 if ((first
< 0) || (last
> bank
->num_sectors
))
204 return ERROR_FLASH_SECTOR_INVALID
;
206 if (str7x_info
->target
->state
!= TARGET_HALTED
)
208 return ERROR_TARGET_NOT_HALTED
;
211 buffer
= malloc(256);
213 for (i
= first
; i
<= last
; i
++)
215 bank
->sectors
[i
].is_erased
= 1;
217 target
->type
->read_memory(target
, bank
->base
+ bank
->sectors
[i
].offset
, 4, 256/4, buffer
);
219 for (nBytes
= 0; nBytes
< 256; nBytes
++)
221 if (buffer
[nBytes
] != 0xFF)
223 bank
->sectors
[i
].is_erased
= 0;
234 int str7x_protect_check(struct flash_bank_s
*bank
)
236 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
237 target_t
*target
= str7x_info
->target
;
242 if (str7x_info
->target
->state
!= TARGET_HALTED
)
244 return ERROR_TARGET_NOT_HALTED
;
247 target
->type
->read_memory(target
, str7x_get_flash_adr(bank
, FLASH_NVWPAR
), 4, 1, (u8
*)&retval
);
249 for (i
= 0; i
< bank
->num_sectors
; i
++)
251 if (retval
& (mem_layout
[i
].reg_offset
<< i
))
252 bank
->sectors
[i
].is_protected
= 0;
254 bank
->sectors
[i
].is_protected
= 1;
260 int str7x_erase(struct flash_bank_s
*bank
, int first
, int last
)
262 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
263 target_t
*target
= str7x_info
->target
;
270 if (str7x_info
->target
->state
!= TARGET_HALTED
)
272 return ERROR_TARGET_NOT_HALTED
;
277 for (i
= first
; i
<= last
; i
++)
278 erase_blocks
|= (mem_layout
[i
].reg_offset
<< i
);
281 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&cmd
);
284 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR1
), 4, 1, (u8
*)&cmd
);
286 cmd
= FLASH_SER
|FLASH_WMS
;
287 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&cmd
);
289 while (((retval
= str7x_status(bank
)) & (FLASH_BSYA1
|FLASH_BSYA2
))){
293 retval
= str7x_result(bank
);
295 if (retval
& FLASH_ERER
)
296 return ERROR_FLASH_SECTOR_NOT_ERASED
;
297 else if (retval
& FLASH_WPF
)
298 return ERROR_FLASH_OPERATION_FAILED
;
300 for (i
= first
; i
<= last
; i
++)
301 bank
->sectors
[i
].is_erased
= 1;
306 int str7x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
308 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
309 target_t
*target
= str7x_info
->target
;
315 if (str7x_info
->target
->state
!= TARGET_HALTED
)
317 return ERROR_TARGET_NOT_HALTED
;
320 protect_blocks
= 0xFFFFFFFF;
324 for (i
= first
; i
<= last
; i
++)
325 protect_blocks
&= ~(mem_layout
[i
].reg_offset
<< i
);
329 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&cmd
);
331 cmd
= str7x_get_flash_adr(bank
, FLASH_NVWPAR
);
332 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_AR
), 4, 1, (u8
*)&cmd
);
334 cmd
= protect_blocks
;
335 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_DR0
), 4, 1, (u8
*)&cmd
);
337 cmd
= FLASH_SPR
|FLASH_WMS
;
338 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&cmd
);
340 while (((retval
= str7x_status(bank
)) & (FLASH_BSYA1
|FLASH_BSYA2
))){
344 retval
= str7x_result(bank
);
346 if (retval
& FLASH_ERER
)
347 return ERROR_FLASH_SECTOR_NOT_ERASED
;
348 else if (retval
& FLASH_WPF
)
349 return ERROR_FLASH_OPERATION_FAILED
;
354 int str7x_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
356 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
357 target_t
*target
= str7x_info
->target
;
358 u32 dwords_remaining
= (count
/ 8);
359 u32 bytes_remaining
= (count
& 0x00000007);
360 u32 address
= bank
->base
+ offset
;
361 u32
*wordbuffer
= (u32
*)buffer
;
362 u32 bytes_written
= 0;
366 if (str7x_info
->target
->state
!= TARGET_HALTED
)
368 return ERROR_TARGET_NOT_HALTED
;
371 if (offset
+ count
> bank
->size
)
372 return ERROR_FLASH_DST_OUT_OF_BANK
;
374 while (dwords_remaining
> 0)
378 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&cmd
);
382 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_AR
), 4, 1, (u8
*)&cmd
);
385 cmd
= wordbuffer
[bytes_written
/4];
386 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_DR0
), 4, 1, (u8
*)&cmd
);
390 cmd
= wordbuffer
[bytes_written
/4];
391 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_DR1
), 4, 1, (u8
*)&cmd
);
394 /* start programming cycle */
395 cmd
= FLASH_DWPG
|FLASH_WMS
;
396 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&cmd
);
398 while (((retval
= str7x_status(bank
)) & (FLASH_BSYA1
|FLASH_BSYA2
))){
402 retval
= str7x_result(bank
);
404 if (retval
& FLASH_PGER
)
405 return ERROR_FLASH_OPERATION_FAILED
;
406 else if (retval
& FLASH_WPF
)
407 return ERROR_FLASH_OPERATION_FAILED
;
413 while( bytes_remaining
> 0 )
417 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&cmd
);
421 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_AR
), 4, 1, (u8
*)&cmd
);
424 cmd
= buffer
[bytes_written
];
425 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_DR0
), 4, 1, (u8
*)&cmd
);
427 /* start programming cycle */
428 cmd
= FLASH_WPG
|FLASH_WMS
;
429 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), 4, 1, (u8
*)&cmd
);
431 while (((retval
= str7x_status(bank
)) & (FLASH_BSYA1
|FLASH_BSYA2
))){
435 retval
= str7x_result(bank
);
437 if (retval
& FLASH_PGER
)
438 return ERROR_FLASH_OPERATION_FAILED
;
439 else if (retval
& FLASH_WPF
)
440 return ERROR_FLASH_OPERATION_FAILED
;
450 int str7x_probe(struct flash_bank_s
*bank
)
455 int str7x_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
460 int str7x_erase_check(struct flash_bank_s
*bank
)
462 return str7x_blank_check(bank
, 0, bank
->num_sectors
- 1);
465 int str7x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
467 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)