1 /***************************************************************************
2 * Copyright (C) 2008 by Kevin McGuire *
3 * Copyright (C) 2008 by Marcel Wijlaars *
4 * Copyright (C) 2009 by Michael Ashton *
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 ***************************************************************************/
28 #include "binarybuffer.h"
29 #include "time_support.h"
32 static int aduc702x_build_sector_list(struct flash_bank_s
*bank
);
33 static int aduc702x_check_flash_completion(target_t
* target
, unsigned int timeout_ms
);
34 static int aduc702x_set_write_enable(target_t
*target
, int enable
);
36 #define ADUC702x_FLASH 0xfffff800
37 #define ADUC702x_FLASH_FEESTA (0*4)
38 #define ADUC702x_FLASH_FEEMOD (1*4)
39 #define ADUC702x_FLASH_FEECON (2*4)
40 #define ADUC702x_FLASH_FEEDAT (3*4)
41 #define ADUC702x_FLASH_FEEADR (4*4)
42 #define ADUC702x_FLASH_FEESIGN (5*4)
43 #define ADUC702x_FLASH_FEEPRO (6*4)
44 #define ADUC702x_FLASH_FEEHIDE (7*4)
55 } ADUC702x_FLASH_MMIO
;
57 struct aduc702x_flash_bank
{
58 working_area_t
*write_algorithm
;
61 /* flash bank aduc702x 0 0 0 0 <target#>
62 * The ADC7019-28 devices all have the same flash layout */
63 FLASH_BANK_COMMAND_HANDLER(aduc702x_flash_bank_command
)
65 struct aduc702x_flash_bank
*nbank
;
67 nbank
= malloc(sizeof(struct aduc702x_flash_bank
));
70 bank
->size
= 0xF800; // top 4k not accessible
71 bank
->driver_priv
= nbank
;
73 aduc702x_build_sector_list(bank
);
78 static int aduc702x_build_sector_list(struct flash_bank_s
*bank
)
80 //aduc7026_flash_bank_t *aduc7026_info = bank->driver_priv;
86 bank
->num_sectors
= bank
->size
/ 512;
87 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
88 for (i
= 0; i
< bank
->num_sectors
; ++i
)
90 bank
->sectors
[i
].offset
= offset
;
91 bank
->sectors
[i
].size
= 512;
92 offset
+= bank
->sectors
[i
].size
;
93 bank
->sectors
[i
].is_erased
= -1;
94 bank
->sectors
[i
].is_protected
= 0;
100 static int aduc702x_protect_check(struct flash_bank_s
*bank
)
102 printf("aduc702x_protect_check not implemented yet.\n");
106 static int aduc702x_erase(struct flash_bank_s
*bank
, int first
, int last
)
112 target_t
*target
= bank
->target
;
114 aduc702x_set_write_enable(target
, 1);
117 if (((first
| last
) == 0) || ((first
== 0) && (last
>= bank
->num_sectors
))) {
118 LOG_DEBUG("performing mass erase.\n");
119 target_write_u16(target
, ADUC702x_FLASH
+ ADUC702x_FLASH_FEEDAT
, 0x3cff);
120 target_write_u16(target
, ADUC702x_FLASH
+ ADUC702x_FLASH_FEEADR
, 0xffc3);
121 target_write_u8(target
, ADUC702x_FLASH
+ ADUC702x_FLASH_FEECON
, 0x06);
123 if (aduc702x_check_flash_completion(target
, 3500) != ERROR_OK
)
125 LOG_ERROR("mass erase failed\n");
126 aduc702x_set_write_enable(target
, 0);
127 return ERROR_FLASH_OPERATION_FAILED
;
130 LOG_DEBUG("mass erase successful.\n");
135 count
= last
- first
+ 1;
136 for (x
= 0; x
< count
; ++x
)
138 adr
= bank
->base
+ ((first
+ x
) * 512);
140 target_write_u16(target
, ADUC702x_FLASH
+ ADUC702x_FLASH_FEEADR
, adr
);
141 target_write_u8(target
, ADUC702x_FLASH
+ ADUC702x_FLASH_FEECON
, 0x05);
143 if (aduc702x_check_flash_completion(target
, 50) != ERROR_OK
)
145 LOG_ERROR("failed to erase sector at address 0x%08lX\n", adr
);
146 aduc702x_set_write_enable(target
, 0);
147 return ERROR_FLASH_SECTOR_NOT_ERASED
;
150 LOG_DEBUG("erased sector at address 0x%08lX\n", adr
);
154 aduc702x_set_write_enable(target
, 0);
159 static int aduc702x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
161 printf("aduc702x_protect not implemented yet.\n");
162 return ERROR_FLASH_OPERATION_FAILED
;
165 /* If this fn returns ERROR_TARGET_RESOURCE_NOT_AVAILABLE, then the caller can fall
166 * back to another mechanism that does not require onboard RAM
168 * Caller should not check for other return values specifically
170 static int aduc702x_write_block(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
172 struct aduc702x_flash_bank
*aduc702x_info
= bank
->driver_priv
;
173 target_t
*target
= bank
->target
;
174 uint32_t buffer_size
= 7000;
175 working_area_t
*source
;
176 uint32_t address
= bank
->base
+ offset
;
177 reg_param_t reg_params
[6];
178 armv4_5_algorithm_t armv4_5_info
;
179 int retval
= ERROR_OK
;
181 if (((count
%2)!=0)||((offset
%2)!=0))
183 LOG_ERROR("write block must be multiple of two bytes in offset & length");
189 r0 - address of source data (absolute)
190 r1 - number of halfwords to be copied
191 r2 - start address in flash (offset from beginning of flash memory)
193 r4 - base address of flash controller (0xFFFFF800)
198 r6 - set to 2, used to write flash command
201 uint32_t aduc702x_flash_write_code
[] = {
203 0xe3a05008, // mov r5, #8 ; 0x8
204 0xe5845004, // str r5, [r4, #4]
205 0xe3a06002, // mov r6, #2 ; 0x2
207 0xe1c421b0, // strh r2, [r4, #16]
208 0xe0d050b2, // ldrh r5, [r0], #2
209 0xe1c450bc, // strh r5, [r4, #12]
210 0xe5c46008, // strb r6, [r4, #8]
212 0xe1d430b0, // ldrh r3, [r4]
213 0xe3130004, // tst r3, #4 ; 0x4
214 0x1afffffc, // bne 1001c <wait_complete>
215 0xe2822002, // add r2, r2, #2 ; 0x2
216 0xe2511001, // subs r1, r1, #1 ; 0x1
217 0x0a000001, // beq 1003c <done>
218 0xe3130001, // tst r3, #1 ; 0x1
219 0x1afffff3, // bne 1000c <next>
221 0xeafffffe // b 1003c <done>
224 /* flash write code */
225 if (target_alloc_working_area(target
, sizeof(aduc702x_flash_write_code
),
226 &aduc702x_info
->write_algorithm
) != ERROR_OK
)
228 LOG_WARNING("no working area available, can't do block memory writes");
229 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
232 retval
=target_write_buffer(target
, aduc702x_info
->write_algorithm
->address
,
233 sizeof(aduc702x_flash_write_code
), (uint8_t*)aduc702x_flash_write_code
);
234 if (retval
!=ERROR_OK
)
240 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
243 if (buffer_size
<= 256)
245 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
246 if (aduc702x_info
->write_algorithm
)
247 target_free_working_area(target
, aduc702x_info
->write_algorithm
);
249 LOG_WARNING("no large enough working area available, can't do block memory writes");
250 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
254 armv4_5_info
.common_magic
= ARMV4_5_COMMON_MAGIC
;
255 armv4_5_info
.core_mode
= ARMV4_5_MODE_SVC
;
256 armv4_5_info
.core_state
= ARMV4_5_STATE_ARM
;
258 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
259 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
260 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
261 init_reg_param(®_params
[3], "r3", 32, PARAM_IN
);
262 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
);
266 uint32_t thisrun_count
= (count
> buffer_size
) ? buffer_size
: count
;
268 retval
=target_write_buffer(target
, source
->address
, thisrun_count
, buffer
);
269 if (retval
!=ERROR_OK
)
274 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
275 buf_set_u32(reg_params
[1].value
, 0, 32, thisrun_count
/2);
276 buf_set_u32(reg_params
[2].value
, 0, 32, address
);
277 buf_set_u32(reg_params
[4].value
, 0, 32, 0xFFFFF800);
279 if ((retval
= target_run_algorithm(target
, 0, NULL
, 5,
280 reg_params
, aduc702x_info
->write_algorithm
->address
,
281 aduc702x_info
->write_algorithm
->address
+ sizeof(aduc702x_flash_write_code
) - 4,
282 10000, &armv4_5_info
)) != ERROR_OK
)
284 LOG_ERROR("error executing aduc702x flash write algorithm");
288 if ((buf_get_u32(reg_params
[3].value
, 0, 32) & 1) != 1)
290 /* FIX!!!! what does this mean??? replace w/sensible error message */
291 LOG_ERROR("aduc702x detected error writing flash");
296 buffer
+= thisrun_count
;
297 address
+= thisrun_count
;
298 count
-= thisrun_count
;
301 target_free_working_area(target
, source
);
302 target_free_working_area(target
, aduc702x_info
->write_algorithm
);
304 destroy_reg_param(®_params
[0]);
305 destroy_reg_param(®_params
[1]);
306 destroy_reg_param(®_params
[2]);
307 destroy_reg_param(®_params
[3]);
308 destroy_reg_param(®_params
[4]);
313 /* All-JTAG, single-access method. Very slow. Used only if there is no
314 * working area available. */
315 static int aduc702x_write_single(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
319 target_t
*target
= bank
->target
;
321 aduc702x_set_write_enable(target
, 1);
323 for (x
= 0; x
< count
; x
+= 2) {
325 target_write_u16(target
, ADUC702x_FLASH
+ ADUC702x_FLASH_FEEADR
, offset
+ x
);
328 if ((x
+ 1) == count
)
331 target_read_u8(target
, offset
+ x
+ 1, &b
);
336 target_write_u16(target
, ADUC702x_FLASH
+ ADUC702x_FLASH_FEEDAT
, buffer
[x
] | (b
<< 8));
338 // do single-write command
339 target_write_u8(target
, ADUC702x_FLASH
+ ADUC702x_FLASH_FEECON
, 0x02);
341 if (aduc702x_check_flash_completion(target
, 1) != ERROR_OK
)
343 LOG_ERROR("single write failed for address 0x%08lX\n", (unsigned long)(offset
+ x
));
344 aduc702x_set_write_enable(target
, 0);
345 return ERROR_FLASH_OPERATION_FAILED
;
349 LOG_DEBUG("wrote %d bytes at address 0x%08lX\n", (int)count
, (unsigned long)(offset
+ x
));
351 aduc702x_set_write_enable(target
, 0);
356 int aduc702x_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
360 /* try using a block write */
361 if ((retval
= aduc702x_write_block(bank
, buffer
, offset
, count
)) != ERROR_OK
)
363 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
365 /* if block write failed (no sufficient working area),
366 * use normal (slow) JTAG method */
367 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
369 if ((retval
= aduc702x_write_single(bank
, buffer
, offset
, count
)) != ERROR_OK
)
371 LOG_ERROR("slow write failed");
372 return ERROR_FLASH_OPERATION_FAILED
;
380 static int aduc702x_probe(struct flash_bank_s
*bank
)
385 static int aduc702x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
387 snprintf(buf
, buf_size
, "aduc702x flash driver info");
392 * enable = 1 enables writes & erases, 0 disables them */
393 static int aduc702x_set_write_enable(target_t
*target
, int enable
)
395 // don't bother to preserve int enable bit here
396 target_write_u16(target
, ADUC702x_FLASH
+ ADUC702x_FLASH_FEEMOD
, enable
? 8 : 0);
401 /* wait up to timeout_ms for controller to not be busy,
402 * then check whether the command passed or failed.
404 * this function sleeps 1ms between checks (after the first one),
405 * so in some cases may slow things down without a usleep after the first read */
406 static int aduc702x_check_flash_completion(target_t
* target
, unsigned int timeout_ms
)
410 long long endtime
= timeval_ms() + timeout_ms
;
412 target_read_u8(target
, ADUC702x_FLASH
+ ADUC702x_FLASH_FEESTA
, &v
);
413 if ((v
& 4) == 0) break;
415 if (timeval_ms() >= endtime
) break;
418 if (v
& 2) return ERROR_FAIL
;
419 // if a command is ignored, both the success and fail bits may be 0
420 else if ((v
& 3) == 0) return ERROR_FAIL
;
421 else return ERROR_OK
;
424 struct flash_driver aduc702x_flash
= {
426 .flash_bank_command
= &aduc702x_flash_bank_command
,
427 .erase
= &aduc702x_erase
,
428 .protect
= &aduc702x_protect
,
429 .write
= &aduc702x_write
,
430 .probe
= &aduc702x_probe
,
431 .auto_probe
= &aduc702x_probe
,
432 .erase_check
= &default_flash_blank_check
,
433 .protect_check
= &aduc702x_protect_check
,
434 .info
= &aduc702x_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)