kinetis cpu flash driver
[openocd.git] / src / flash / nor / kinetis.c
1 /***************************************************************************
2 * Copyright (C) 2011 by Mathias Kuester *
3 * kesmtp@freenet.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 "imp.h"
25 #include "helper/binarybuffer.h"
26
27 static int kinetis_get_master_bank(struct flash_bank *bank,
28 struct flash_bank **master_bank)
29 {
30 *master_bank = get_flash_bank_by_name_noprobe(bank->name);
31 if (*master_bank == NULL) {
32 LOG_ERROR("master flash bank '%s' does not exist",
33 (char *)bank->driver_priv);
34 return ERROR_FLASH_OPERATION_FAILED;
35 }
36
37 return ERROR_OK;
38 }
39
40 static int kinetis_update_bank_info(struct flash_bank *bank)
41 {
42 int result;
43 struct flash_bank *master_bank;
44
45 result = kinetis_get_master_bank(bank, &master_bank);
46
47 if (result != ERROR_OK) {
48 return result;
49 }
50
51 /* update the info we do not have */
52 bank->size = master_bank->size;
53 bank->chip_width = master_bank->chip_width;
54 bank->bus_width = master_bank->bus_width;
55 bank->num_sectors = master_bank->num_sectors;
56 bank->sectors = master_bank->sectors;
57
58 return ERROR_OK;
59 }
60
61 FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command)
62 {
63 if (CMD_ARGC < 6) {
64 LOG_ERROR("incomplete flash_bank kinetis configuration %d",
65 CMD_ARGC);
66 return ERROR_FLASH_OPERATION_FAILED;
67 }
68
69 LOG_INFO("add flash_bank kinetis %s", bank->name);
70
71 return ERROR_OK;
72 }
73
74 static int kinetis_protect(struct flash_bank *bank, int set, int first,
75 int last)
76 {
77 int result;
78 struct flash_bank *master_bank;
79
80 result = kinetis_get_master_bank(bank, &master_bank);
81
82 if (result != ERROR_OK) {
83 return result;
84 }
85
86 LOG_WARNING("kinetis_protect not supported yet");
87
88 if (bank->target->state != TARGET_HALTED) {
89 LOG_ERROR("Target not halted");
90 return ERROR_TARGET_NOT_HALTED;
91 }
92
93 return ERROR_OK;
94 }
95
96 static int kinetis_protect_check(struct flash_bank *bank)
97 {
98 int result;
99 struct flash_bank *master_bank;
100 uint8_t buffer[4];
101 uint32_t fprot, psize, psec;
102 int i, b;
103
104 if (bank->target->state != TARGET_HALTED) {
105 LOG_ERROR("Target not halted");
106 return ERROR_TARGET_NOT_HALTED;
107 }
108
109 result = kinetis_get_master_bank(bank, &master_bank);
110
111 if (result != ERROR_OK) {
112 return result;
113 }
114
115 /* read protection register FTFL_FPROT */
116 result = target_read_memory(bank->target, 0x40020010, 1, 4, buffer);
117
118 if (result != ERROR_OK) {
119 return result;
120 }
121
122 fprot = target_buffer_get_u32(bank->target, buffer);
123
124 /* every bit protect 1/32 of the full flash */
125 psize = bank->size / 32;
126 psec = 0;
127 b = 0;
128
129 for (i = 0; i < bank->num_sectors; i++) {
130 if ((fprot >> b) & 1)
131 bank->sectors[i].is_protected = 0;
132 else
133 bank->sectors[i].is_protected = 1;
134
135 psec += bank->sectors[i].size;
136
137 if (psec >= psize) {
138 psec = 0;
139 b++;
140 }
141 }
142
143 return ERROR_OK;
144 }
145
146 static int kinetis_ftfl_command(struct flash_bank *bank, uint32_t w0,
147 uint32_t w1, uint32_t w2)
148 {
149 uint8_t buffer[12];
150 int result, i;
151
152 /* wait for done */
153 for (i = 0; i < 50; i++) {
154 result =
155 target_read_memory(bank->target, 0x40020000, 1, 1, buffer);
156
157 if (result != ERROR_OK) {
158 return result;
159 }
160
161 if (buffer[0] & 0x80)
162 break;
163
164 buffer[0] = 0x00;
165 }
166
167 if (buffer[0] != 0x80) {
168 /* reset error flags */
169 buffer[0] = 0x30;
170 result =
171 target_write_memory(bank->target, 0x40020000, 1, 1, buffer);
172 if (result != ERROR_OK) {
173 return result;
174 }
175 }
176
177 target_buffer_set_u32(bank->target, buffer, w0);
178 target_buffer_set_u32(bank->target, buffer + 4, w1);
179 target_buffer_set_u32(bank->target, buffer + 8, w2);
180
181 result = target_write_memory(bank->target, 0x40020004, 4, 3, buffer);
182
183 if (result != ERROR_OK) {
184 return result;
185 }
186
187 /* start command */
188 buffer[0] = 0x80;
189 result = target_write_memory(bank->target, 0x40020000, 1, 1, buffer);
190 if (result != ERROR_OK) {
191 return result;
192 }
193
194 /* wait for done */
195 for (i = 0; i < 50; i++) {
196 result =
197 target_read_memory(bank->target, 0x40020000, 1, 1, buffer);
198
199 if (result != ERROR_OK) {
200 return result;
201 }
202
203 if (buffer[0] & 0x80)
204 break;
205
206 buffer[0] = 0x00;
207 }
208
209 if (buffer[0] != 0x80) {
210 LOG_ERROR
211 ("ftfl command failed FSTAT: %02X W0: %08X W1: %08X W2: %08X",
212 buffer[0], w0, w1, w2);
213
214 return ERROR_FLASH_OPERATION_FAILED;
215 }
216
217 return ERROR_OK;
218 }
219
220 static int kinetis_erase(struct flash_bank *bank, int first, int last)
221 {
222 struct flash_bank *master_bank;
223 int result, i;
224 uint32_t w0 = 0, w1 = 0, w2 = 0;
225
226 if (bank->target->state != TARGET_HALTED) {
227 LOG_ERROR("Target not halted");
228 return ERROR_TARGET_NOT_HALTED;
229 }
230
231 result = kinetis_get_master_bank(bank, &master_bank);
232
233 if (result != ERROR_OK) {
234 return result;
235 }
236
237 if ((first > bank->num_sectors) || (last > bank->num_sectors)) {
238 return ERROR_FLASH_OPERATION_FAILED;
239 }
240
241 for (i = first; i <= last; i++) {
242 /* set command and sector address */
243 w0 = (0x09 << 24) | bank->sectors[i].offset;
244
245 result = kinetis_ftfl_command(bank, w0, w1, w2);
246
247 if (result != ERROR_OK) {
248 LOG_WARNING("erase sector %d failed", i);
249 return ERROR_FLASH_OPERATION_FAILED;
250 }
251
252 bank->sectors[i].is_erased = 1;
253 }
254
255 if (first == 0) {
256 LOG_WARNING
257 ("flash configuration field erased, please reset the device");
258 }
259
260 return ERROR_OK;
261 }
262
263 static int kinetis_write(struct flash_bank *bank, uint8_t * buffer,
264 uint32_t offset, uint32_t count)
265 {
266 struct flash_bank *master_bank;
267 unsigned int i, result, fallback = 0;
268 uint8_t buf[8];
269 uint32_t wc, w0 = 0, w1 = 0, w2 = 0;
270
271 if (bank->target->state != TARGET_HALTED) {
272 LOG_ERROR("Target not halted");
273 return ERROR_TARGET_NOT_HALTED;
274 }
275
276 result = kinetis_get_master_bank(bank, &master_bank);
277
278 if (result != ERROR_OK) {
279 return result;
280 }
281
282 /* make flex ram available */
283 w0 = (0x81 << 24) | 0x00ff0000;
284
285 result = kinetis_ftfl_command(bank, w0, w1, w2);
286
287 if (result != ERROR_OK) {
288 return ERROR_FLASH_OPERATION_FAILED;
289 }
290
291 /* check if ram ready */
292 result = target_read_memory(bank->target, 0x40020001, 1, 1, buf);
293
294 if (result != ERROR_OK) {
295 return result;
296 }
297
298 if (!(buf[0] & (1 << 1))) {
299 /* fallback to longword write */
300 fallback = 1;
301
302 LOG_WARNING
303 ("ram not ready, fallback to slow longword write (FCNFG: %02X)",
304 buf[0]);
305 }
306
307 /* program section command */
308 if (fallback == 0) {
309 for (i = 0; i < count; i += (2 * 1024)) {
310 wc = 512;
311
312 if ((count - i) < (2 * 1024)) {
313 wc = count - i;
314 wc /= 4;
315 }
316
317 LOG_DEBUG("write section @ %08X with length %d",
318 offset + i, wc * 4);
319
320 /* write data to flexram */
321 result =
322 target_write_memory(bank->target, 0x14000000, 4, wc,
323 buffer + i);
324
325 if (result != ERROR_OK) {
326 LOG_ERROR("target_write_memory failed");
327
328 return result;
329 }
330
331 /* execute section command */
332 w0 = (0x0b << 24) | (offset + i);
333 w1 = (256 << 16);
334
335 result = kinetis_ftfl_command(bank, w0, w1, w2);
336
337 if (result != ERROR_OK) {
338 return ERROR_FLASH_OPERATION_FAILED;
339 }
340 }
341 }
342 /* program longword command */
343 else {
344 for (i = 0; i < count; i += 4) {
345 LOG_DEBUG("write longword @ %08X", offset + i);
346
347 w0 = (0x06 << 24) | (offset + i);
348 w1 = buf_get_u32(buffer + offset + i, 0, 32);
349
350 result = kinetis_ftfl_command(bank, w0, w1, w2);
351
352 if (result != ERROR_OK) {
353 return ERROR_FLASH_OPERATION_FAILED;
354 }
355 }
356 }
357
358 return ERROR_OK;
359 }
360
361 static int kinetis_probe(struct flash_bank *bank)
362 {
363 struct flash_bank *master_bank;
364 int result, i;
365 uint8_t buf[4];
366 uint32_t sim_sdid, sim_fcfg1, sim_fcfg2, offset = 0;
367 uint32_t nvm_size, pf_size, flash_size, ee_size;
368
369 if (bank->target->state != TARGET_HALTED) {
370 LOG_ERROR("Target not halted");
371 return ERROR_TARGET_NOT_HALTED;
372 }
373
374 result = kinetis_get_master_bank(bank, &master_bank);
375
376 if (result != ERROR_OK) {
377 return result;
378 }
379
380 result = target_read_memory(bank->target, 0x40048024, 1, 4, buf);
381 if (result != ERROR_OK) {
382 return result;
383 }
384 sim_sdid = target_buffer_get_u32(bank->target, buf);
385 result = target_read_memory(bank->target, 0x4004804c, 1, 4, buf);
386 if (result != ERROR_OK) {
387 return result;
388 }
389 sim_fcfg1 = target_buffer_get_u32(bank->target, buf);
390 result = target_read_memory(bank->target, 0x40048050, 1, 4, buf);
391 if (result != ERROR_OK) {
392 return result;
393 }
394 sim_fcfg2 = target_buffer_get_u32(bank->target, buf);
395
396 LOG_DEBUG("SDID: %08X FCFG1: %08X FCFG2: %08X", sim_sdid, sim_fcfg1,
397 sim_fcfg2);
398
399 switch ((sim_fcfg1 >> 28) & 0x0f) {
400 case 0x07:
401 nvm_size = 128 * 1024;
402 break;
403 case 0x09:
404 case 0x0f:
405 nvm_size = 256 * 1024;
406 break;
407 default:
408 nvm_size = 0;
409 break;
410 }
411
412 switch ((sim_fcfg1 >> 24) & 0x0f) {
413 case 0x07:
414 pf_size = 128 * 1024;
415 break;
416 case 0x09:
417 pf_size = 256 * 1024;
418 break;
419 case 0x0b:
420 case 0x0f:
421 pf_size = 512 * 1024;
422 break;
423 default:
424 pf_size = 0;
425 break;
426 }
427
428 /* pf_size is the total size */
429 flash_size = pf_size - nvm_size;
430
431 switch ((sim_fcfg1 >> 16) & 0x0f) {
432 case 0x02:
433 ee_size = 4 * 1024;
434 break;
435 case 0x03:
436 ee_size = 2 * 1024;
437 break;
438 case 0x04:
439 ee_size = 1 * 1024;
440 break;
441 case 0x05:
442 ee_size = 512;
443 break;
444 case 0x06:
445 ee_size = 256;
446 break;
447 case 0x07:
448 ee_size = 128;
449 break;
450 case 0x08:
451 ee_size = 64;
452 break;
453 case 0x09:
454 ee_size = 32;
455 break;
456 default:
457 ee_size = 0;
458 break;
459 }
460
461 LOG_DEBUG("NVM: %d PF: %d EE: %d BL1: %d", nvm_size, pf_size, ee_size,
462 (sim_fcfg2 >> 23) & 1);
463
464 if (flash_size != bank->size) {
465 LOG_WARNING("flash size is different %d != %d", flash_size,
466 bank->size);
467 }
468
469 bank->num_sectors = bank->size / (2 * 1024);
470 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
471
472 for (i = 0; i < bank->num_sectors; i++) {
473 bank->sectors[i].offset = offset;
474 bank->sectors[i].size = 2 * 1024;
475 offset += bank->sectors[i].size;
476 bank->sectors[i].is_erased = -1;
477 bank->sectors[i].is_protected = 1;
478 }
479
480 /* update the info we do not have */
481 return kinetis_update_bank_info(bank);
482 }
483
484 static int kinetis_auto_probe(struct flash_bank *bank)
485 {
486 return kinetis_probe(bank);
487 }
488
489 static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size)
490 {
491 int result;
492 struct flash_bank *master_bank;
493
494 result = kinetis_get_master_bank(bank, &master_bank);
495
496 if (result != ERROR_OK) {
497 return result;
498 }
499
500 snprintf(buf, buf_size,
501 "%s driver for flash bank %s at 0x%8.8" PRIx32 "",
502 bank->driver->name, master_bank->name, master_bank->base);
503
504 return ERROR_OK;
505 }
506
507 static int kinetis_blank_check(struct flash_bank *bank)
508 {
509 int result;
510 struct flash_bank *master_bank;
511
512 LOG_WARNING("kinetis_blank_check not supported yet");
513
514 if (bank->target->state != TARGET_HALTED) {
515 LOG_ERROR("Target not halted");
516 return ERROR_TARGET_NOT_HALTED;
517 }
518
519 result = kinetis_get_master_bank(bank, &master_bank);
520
521 if (result != ERROR_OK) {
522 return result;
523 }
524
525 return ERROR_OK;
526 }
527
528 static int kinetis_flash_read(struct flash_bank *bank,
529 uint8_t * buffer, uint32_t offset, uint32_t count)
530 {
531 int result;
532 struct flash_bank *master_bank;
533
534 LOG_WARNING("kinetis_flash_read not supported yet");
535
536 if (bank->target->state != TARGET_HALTED) {
537 LOG_ERROR("Target not halted");
538 return ERROR_TARGET_NOT_HALTED;
539 }
540
541 result = kinetis_get_master_bank(bank, &master_bank);
542
543 if (result != ERROR_OK) {
544 return result;
545 }
546
547 return ERROR_OK;
548 }
549
550 struct flash_driver kinetis_flash = {
551 .name = "kinetis",
552 .flash_bank_command = kinetis_flash_bank_command,
553 .erase = kinetis_erase,
554 .protect = kinetis_protect,
555 .write = kinetis_write,
556 .read = kinetis_flash_read,
557 .probe = kinetis_probe,
558 .auto_probe = kinetis_auto_probe,
559 .erase_check = kinetis_blank_check,
560 .protect_check = kinetis_protect_check,
561 .info = kinetis_info,
562 };

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)