flash: Analog Devices ADuCM360 support
[openocd.git] / src / flash / nor / mini51.c
blobdf6e7cefe2cb98f950296ef6e60119679ab4634a
1 /***************************************************************************
2 * Copyright (C) 2013 Cosmin Gorgovan *
3 * cosmin [at] linux-geek [dot] org *
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 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
19 ***************************************************************************/
22 Flash driver for the Nuvoton NuMicro Mini51 and M051 series microcontrollers
24 Part |APROM Size |Part ID (at 0x5000_0000)
25 ----------------------------------------------
26 MINI51LAN 4 KB 0x00205100
27 MINI51ZAN 4 KB 0x00205103
28 MINI51TAN 4 KB 0x00205104
29 MINI52LAN 8 KB 0x00205200
30 MINI52ZAN 8 KB 0x00205203
31 MINI52TAN 8 KB 0x00205204
32 MINI54LAN 16 KB 0x00205400
33 MINI54ZAN 16 KB 0x00205403
34 MINI54TAN 16 KB 0x00205404
35 M052LBN 8 KB 0x10005200
36 M054LBN 16 KB 0x10005400
37 M058LBN 32 KB 0x10005800
38 M0516LBN 64 KB 0x10005A00
39 M052ZBN 8 KB 0x10005203
40 M054ZBN 16 KB 0x10005403
41 M058ZBN 32 KB 0x10005803
42 M0516ZBN 64 KB 0x10005A03
43 M052LDN 8 KB 0x20005200
44 M054LDN 16 KB 0x20005400
45 M058LDN 32 KB 0x20005800
46 M0516LDN 64 KB 0x20005A00
47 M052ZDN 8 KB 0x20005203
48 M054ZDN 16 KB 0x20005403
49 M058ZDN 32 KB 0x20005803
50 M0516ZDN 64 KB 0x20005A03
51 M052LDE 8 KB 0x30005200
52 M054LDE 16 KB 0x30005400
53 M058LDE 32 KB 0x30005800
54 M0516LDE 64 KB 0x30005A00
55 M052ZDE 8 KB 0x30005203
56 M054ZDE 16 KB 0x30005403
57 M058ZDE 32 KB 0x30005803
58 M0516ZDE 64 KB 0x30005A03
60 Datasheet & TRM
61 ---------------
63 The ISP flash programming procedure is described on pages 130 and 131 of the (not very verbose) TRM.
65 http://www.keil.com/dd/docs/datashts/nuvoton/mini51/da00-mini51_52_54c1.pdf
67 M051 ISP datasheet pages 190-206:
68 http://www.nuvoton.com/hq/resource-download.jsp?tp_GUID=DA05-M052-54-58-516
70 This driver
71 -----------
73 * chip_erase, erase, read and write operations have been implemented;
74 * All operations support APROM, LDROM, FLASH DATA and CONFIG;
76 Flash access limitations
77 ------------------------
79 For implementing the read operation, please note that the APROM isn't memory mapped when booted from LDROM.
82 #ifdef HAVE_CONFIG_H
83 #include "config.h"
84 #endif
86 #include "imp.h"
88 #define PART_ID_REG 0x50000000
89 #define IPRSTC1 0x50000008
90 #define REGLOCKADDR 0x50000100
91 #define ISPCON 0x5000C000
92 #define ISPADR 0x5000C004
93 #define ISPDAT 0x5000C008
94 #define ISPCMD 0x5000C00C
95 #define ISPTRG 0x5000C010
96 /* Undocumented isp register */
97 #define ISPUNKNOWN 0x5000C01C
99 #define IPRSTC_CPU_RST 0x02
101 #define ISPCON_ISPFF 0x40
102 #define ISPCON_LDUEN 0x20
103 #define ISPCON_CFGUEN 0x10
104 #define ISPCON_APUEN 0x08
105 #define ISPCON_BS_LDROM 0x02
106 #define ISPCON_ISPEN 0x01
108 #define ISPCMD_READ 0x00
109 #define ISPCMD_PROGRAM 0x21
110 #define ISPCMD_ERASE 0x22
111 #define ISPCMD_CHIP_ERASE 0x26
113 #define ISPTRG_ISPGO 0x01
115 #define MINI51_APROM_BASE 0x00000000
116 #define MINI51_DATA_BASE 0x0001F000
117 #define MINI51_LDROM_BASE 0x00100000
118 #define MINI51_CONFIG_BASE 0x00300000
120 #define MINI51_KB 1024
121 #define MINI51_PAGE_SIZE 512
122 #define MINI51_TIMEOUT 1000
125 #define ENSURE_OK(status) if (status != ERROR_OK) return status
127 #define MINI51_MAX_FLASH_BANKS 4
129 struct mini51_flash_bank_type {
130 uint32_t base;
131 uint32_t size;
134 struct mini51_cpu_type {
135 char *name;
136 uint32_t ppid;
137 unsigned n_banks;
138 struct mini51_flash_bank_type bank[MINI51_MAX_FLASH_BANKS];
141 #define MINI51_BANKS_MINI51(aprom_size) \
142 .n_banks = 3, \
143 { {MINI51_APROM_BASE, (aprom_size)}, {MINI51_LDROM_BASE, 2*1024}, {MINI51_CONFIG_BASE, 512} }
145 #define MINI51_BANKS_M051(aprom_size) \
146 .n_banks = 4, \
147 { {MINI51_APROM_BASE, (aprom_size)}, {MINI51_DATA_BASE, 4*1024}, {MINI51_LDROM_BASE, 4*1024}, \
148 {MINI51_CONFIG_BASE, 1024} }
150 static const struct mini51_cpu_type mini51_cpu[] = {
151 { "MINI51LAN", 0x00205100, MINI51_BANKS_MINI51(4*1024) },
152 { "MINI51ZAN", 0x00205103, MINI51_BANKS_MINI51(4*1024) },
153 { "MINI51TAN", 0x00205104, MINI51_BANKS_MINI51(4*1024) },
154 { "MINI52LAN", 0x00205200, MINI51_BANKS_MINI51(8*1024) },
155 { "MINI52ZAN", 0x00205203, MINI51_BANKS_MINI51(8*1024) },
156 { "MINI52TAN", 0x00205204, MINI51_BANKS_MINI51(8*1024) },
157 { "MINI54LAN", 0x00205400, MINI51_BANKS_MINI51(16*1024) },
158 { "MINI54ZAN", 0x00205403, MINI51_BANKS_MINI51(16*1024) },
159 { "MINI54TAN", 0x00205404, MINI51_BANKS_MINI51(16*1024) },
161 { "M052LBN", 0x10005200, MINI51_BANKS_M051(8*1024) },
162 { "M054LBN", 0x10005400, MINI51_BANKS_M051(16*1024) },
163 { "M058LBN", 0x10005800, MINI51_BANKS_M051(32*1024) },
164 { "M0516LBN", 0x10005A00, MINI51_BANKS_M051(64*1024) },
165 { "M052ZBN", 0x10005203, MINI51_BANKS_M051(8*1024) },
166 { "M054ZBN", 0x10005403, MINI51_BANKS_M051(16*1024) },
167 { "M058ZBN", 0x10005803, MINI51_BANKS_M051(32*1024) },
168 { "M0516ZBN", 0x10005A03, MINI51_BANKS_M051(64*1024) },
169 { "M052LDN", 0x20005200, MINI51_BANKS_M051(8*1024) },
170 { "M054LDN", 0x20005400, MINI51_BANKS_M051(16*1024) },
171 { "M058LDN", 0x20005800, MINI51_BANKS_M051(32*1024) },
172 { "M0516LDN", 0x20005A00, MINI51_BANKS_M051(64*1024) },
173 { "M052ZDN", 0x20005203, MINI51_BANKS_M051(8*1024) },
174 { "M054ZDN", 0x20005403, MINI51_BANKS_M051(16*1024) },
175 { "M058ZDN", 0x20005803, MINI51_BANKS_M051(32*1024) },
176 { "M0516ZDN", 0x20005A03, MINI51_BANKS_M051(64*1024) },
177 { "M052LDE", 0x30005200, MINI51_BANKS_M051(8*1024) },
178 { "M054LDE", 0x30005400, MINI51_BANKS_M051(16*1024) },
179 { "M058LDE", 0x30005800, MINI51_BANKS_M051(32*1024) },
180 { "M0516LDE", 0x30005A00, MINI51_BANKS_M051(64*1024) },
181 { "M052ZDE", 0x30005203, MINI51_BANKS_M051(8*1024) },
182 { "M054ZDE", 0x30005403, MINI51_BANKS_M051(16*1024) },
183 { "M058ZDE", 0x30005803, MINI51_BANKS_M051(32*1024) },
184 { "M0516ZDE", 0x30005A03, MINI51_BANKS_M051(64*1024) },
187 struct mini51_flash_bank {
188 bool probed;
189 const struct mini51_cpu_type *cpu;
192 /* Private methods */
194 static int mini51_unlock_reg(struct target *target)
196 int status;
197 status = target_write_u32(target, REGLOCKADDR, 0x59);
198 if (status != ERROR_OK)
199 return status;
200 status = target_write_u32(target, REGLOCKADDR, 0x16);
201 if (status != ERROR_OK)
202 return status;
203 status = target_write_u32(target, REGLOCKADDR, 0x88);
204 if (status != ERROR_OK)
205 return status;
207 return ERROR_OK;
211 static int mini51_get_part_id(struct target *target, uint32_t *part_id)
213 int retu = target_read_u32(target, PART_ID_REG, part_id);
214 LOG_INFO("device id = 0x%08" PRIx32 "", *part_id);
215 return retu;
218 static int mini51_get_cpu_type(struct target *target, const struct mini51_cpu_type** cpu)
220 uint32_t part_id;
221 int status;
223 status = mini51_get_part_id(target, &part_id);
224 ENSURE_OK(status);
226 for (size_t i = 0; i < sizeof(mini51_cpu)/sizeof(mini51_cpu[0]); i++) {
227 if (part_id == mini51_cpu[i].ppid) {
228 *cpu = &mini51_cpu[i];
229 LOG_INFO("device name = %s", (*cpu)->name);
230 return ERROR_OK;
234 return ERROR_FLASH_OPERATION_FAILED;
237 static int mini51_get_flash_size(struct flash_bank *bank, const struct mini51_cpu_type *cpu, uint32_t *flash_size)
239 for (size_t i = 0; i < cpu->n_banks; i++) {
240 if (bank->base == cpu->bank[i].base) {
241 *flash_size = cpu->bank[i].size;
242 LOG_INFO("bank base = 0x%08" PRIx32 ", size = 0x%08" PRIx32 "", bank->base, *flash_size);
243 return ERROR_OK;
246 return ERROR_FLASH_OPERATION_FAILED;
249 static int mini51_isp_execute(struct target *target)
251 int status;
252 uint32_t ispcon;
253 int timeout;
254 uint32_t isptrg;
256 /* start ISP operation */
257 status = target_write_u32(target, ISPTRG, ISPTRG_ISPGO);
258 ENSURE_OK(status);
260 /* Wait for for command to finish executing */
261 timeout = MINI51_TIMEOUT;
262 do {
263 target_read_u32(target, ISPTRG, &isptrg);
264 timeout--;
265 } while ((isptrg & ISPTRG_ISPGO) && (timeout > 0));
266 if (timeout == 0) {
267 LOG_WARNING("Mini51 flash driver: Timeout executing flash command\n");
268 return ERROR_FLASH_OPERATION_FAILED;
271 /* Check for errors */
272 status = target_read_u32(target, ISPCON, &ispcon);
273 ENSURE_OK(status);
274 if (ispcon & ISPCON_ISPFF) {
275 LOG_WARNING("Mini51 flash driver: operation failed\n");
276 return ERROR_FLASH_OPERATION_FAILED;
278 return status;
281 static int mini51_isp_execute_cmd(struct target *target, uint32_t cmd, uint32_t address, uint32_t data)
283 int status;
284 status = target_write_u32(target, ISPDAT, data);
285 ENSURE_OK(status);
286 status = target_write_u32(target, ISPADR, address);
287 ENSURE_OK(status);
288 status = target_write_u32(target, ISPCMD, cmd);
289 ENSURE_OK(status);
291 status = mini51_isp_execute(target);
292 return status;
295 static int mini51_isp_execute_cmd_read(struct target *target, uint32_t cmd, uint32_t address, uint32_t *data)
297 int status;
298 status = target_write_u32(target, ISPADR, address);
299 ENSURE_OK(status);
300 status = target_write_u32(target, ISPCMD, cmd);
301 ENSURE_OK(status);
303 status = mini51_isp_execute(target);
304 ENSURE_OK(status);
306 status = target_read_u32(target, ISPDAT, data);
307 ENSURE_OK(status);
309 return status;
312 static int mini51_isp_enable(struct target *target)
314 int status;
315 uint32_t ispcon;
317 if (target->state != TARGET_HALTED) {
318 LOG_ERROR("Target not halted");
319 return ERROR_TARGET_NOT_HALTED;
322 status = mini51_unlock_reg(target);
323 ENSURE_OK(status);
324 status = target_read_u32(target, ISPCON, &ispcon);
325 ENSURE_OK(status);
326 ispcon |= ISPCON_ISPEN | ISPCON_LDUEN | ISPCON_APUEN | ISPCON_CFGUEN;
327 status = target_write_u32(target, ISPCON, ispcon);
328 return status;
331 /* Public (API) methods */
333 FLASH_BANK_COMMAND_HANDLER(mini51_flash_bank_command)
335 struct mini51_flash_bank *mini51_info;
336 mini51_info = malloc(sizeof(struct mini51_flash_bank));
337 mini51_info->probed = false;
338 bank->driver_priv = mini51_info;
340 return ERROR_OK;
343 static int mini51_protect_check(struct flash_bank *bank)
345 LOG_WARNING("Mini51 flash driver: protect_check not implemented yet\n");
347 return ERROR_FLASH_OPERATION_FAILED;
350 static int mini51_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
352 int status;
353 uint32_t ispdat;
354 struct target *target = bank->target;
356 if ((offset & 0x3) || (count & 0x3)) {
357 LOG_WARNING("Mini51 flash driver: unaligned access not supported\n");
358 return ERROR_FLASH_OPERATION_FAILED;
361 status = mini51_isp_enable(target);
362 ENSURE_OK(status);
364 for (uint32_t i = offset; i < offset + count; i += 4) {
365 status = mini51_isp_execute_cmd_read(target, ISPCMD_READ, bank->base + i, &ispdat);
366 memcpy(buffer, &ispdat, sizeof(ispdat));
367 ENSURE_OK(status);
368 buffer += sizeof(ispdat);
371 return ERROR_OK;
375 static int mini51_erase(struct flash_bank *bank, int first, int last)
377 int status;
378 struct target *target = bank->target;
380 /* Enable ISP */
381 status = mini51_isp_enable(target);
382 ENSURE_OK(status);
384 for (int page_start = first; page_start <= last; page_start++) {
385 /* Set up erase command */
386 uint32_t address = bank->base + page_start*MINI51_PAGE_SIZE;
387 status = mini51_isp_execute_cmd(target, ISPCMD_ERASE, address, 0);
388 ENSURE_OK(status);
391 return ERROR_OK;
394 static int mini51_protect(struct flash_bank *bank, int set, int first, int last)
396 LOG_WARNING("Mini51 flash driver: protect operation not implemented yet\n");
398 return ERROR_FLASH_OPERATION_FAILED;
401 static int mini51_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
403 int status;
404 uint32_t ispdat;
405 struct target *target = bank->target;
407 if ((offset & 0x3) || (count & 0x3)) {
408 LOG_WARNING("Mini51 flash driver: unaligned access not supported\n");
409 return ERROR_FLASH_OPERATION_FAILED;
412 status = mini51_isp_enable(target);
413 ENSURE_OK(status);
415 for (uint32_t i = offset; i < offset + count; i += 4) {
416 memcpy(&ispdat, buffer, sizeof(ispdat));
417 status = mini51_isp_execute_cmd(target, ISPCMD_PROGRAM, bank->base + i, ispdat);
418 ENSURE_OK(status);
419 buffer += sizeof(ispdat);
422 return ERROR_OK;
425 static int mini51_probe(struct flash_bank *bank)
427 uint32_t flash_size;
428 int status;
429 int num_pages;
430 uint32_t offset = 0;
431 const struct mini51_cpu_type *cpu;
432 struct target *target = bank->target;
434 status = mini51_get_cpu_type(target, &cpu);
435 if (status != ERROR_OK) {
436 LOG_WARNING("Mini51 flash driver: Failed to detect a known part\n");
437 return ERROR_FLASH_OPERATION_FAILED;
440 status = mini51_get_flash_size(bank, cpu, &flash_size);
441 if (status != ERROR_OK) {
442 LOG_WARNING("Mini51 flash driver: Failed to detect flash size\n");
443 return ERROR_FLASH_OPERATION_FAILED;
446 num_pages = flash_size / MINI51_PAGE_SIZE;
448 bank->num_sectors = num_pages;
449 bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
450 bank->size = flash_size;
452 for (int i = 0; i < num_pages; i++) {
453 bank->sectors[i].offset = offset;
454 bank->sectors[i].size = MINI51_PAGE_SIZE;
455 bank->sectors[i].is_erased = -1;
456 bank->sectors[i].is_protected = 0;
457 offset += MINI51_PAGE_SIZE;
460 struct mini51_flash_bank *mini51_info = bank->driver_priv;
461 mini51_info->probed = true;
462 mini51_info->cpu = cpu;
464 return ERROR_OK;
467 static int mini51_auto_probe(struct flash_bank *bank)
469 struct mini51_flash_bank *mini51_info = bank->driver_priv;
470 if (mini51_info->probed)
471 return ERROR_OK;
472 return mini51_probe(bank);
475 COMMAND_HANDLER(mini51_handle_read_isp_command)
477 uint32_t address;
478 uint32_t ispdat;
479 int status;
481 if (CMD_ARGC != 1)
482 return ERROR_COMMAND_SYNTAX_ERROR;
484 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
486 struct target *target = get_current_target(CMD_CTX);
488 status = mini51_isp_enable(target);
489 ENSURE_OK(status);
490 status = mini51_isp_execute_cmd_read(target, ISPCMD_READ, address, &ispdat);
491 ENSURE_OK(status);
492 LOG_INFO("0x%08" PRIx32 ": 0x%08" PRIx32, address, ispdat);
493 return ERROR_OK;
496 COMMAND_HANDLER(mini51_handle_write_isp_command)
498 uint32_t address;
499 uint32_t ispdat;
500 int status;
502 if (CMD_ARGC != 2)
503 return ERROR_COMMAND_SYNTAX_ERROR;
505 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
506 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], ispdat);
508 struct target *target = get_current_target(CMD_CTX);
510 status = mini51_isp_enable(target);
511 ENSURE_OK(status);
512 status = mini51_isp_execute_cmd(target, ISPCMD_PROGRAM, address, ispdat);
513 ENSURE_OK(status);
514 LOG_INFO("0x%08" PRIx32 ": 0x%08" PRIx32, address, ispdat);
515 return ERROR_OK;
518 COMMAND_HANDLER(mini51_handle_chip_erase_command)
520 int status;
521 if (CMD_ARGC != 0)
522 return ERROR_COMMAND_SYNTAX_ERROR;
524 struct target *target = get_current_target(CMD_CTX);
526 status = mini51_isp_enable(target);
527 ENSURE_OK(status);
528 /* Write one to undocumented flash control register */
529 status = target_write_u32(target, ISPUNKNOWN, 1);
530 ENSURE_OK(status);
532 status = mini51_isp_execute_cmd(target, ISPCMD_CHIP_ERASE, 0, 0);
533 ENSURE_OK(status);
534 return ERROR_OK;
537 static const struct command_registration mini51_exec_command_handlers[] = {
539 .name = "read_isp",
540 .handler = mini51_handle_read_isp_command,
541 .usage = "address",
542 .mode = COMMAND_EXEC,
543 .help = "read flash through ISP.",
546 .name = "write_isp",
547 .handler = mini51_handle_write_isp_command,
548 .usage = "address value",
549 .mode = COMMAND_EXEC,
550 .help = "write flash through ISP.",
553 .name = "chip_erase",
554 .handler = mini51_handle_chip_erase_command,
555 .mode = COMMAND_EXEC,
556 .help = "chip erase.",
558 COMMAND_REGISTRATION_DONE
561 static const struct command_registration mini51_command_handlers[] = {
563 .name = "mini51",
564 .mode = COMMAND_ANY,
565 .help = "mini51 flash command group",
566 .usage = "",
567 .chain = mini51_exec_command_handlers,
569 COMMAND_REGISTRATION_DONE
572 struct flash_driver mini51_flash = {
573 .name = "mini51",
574 .commands = mini51_command_handlers,
575 .flash_bank_command = mini51_flash_bank_command,
576 .erase = mini51_erase,
577 .protect = mini51_protect,
578 .write = mini51_write,
579 .read = mini51_read,
580 .probe = mini51_probe,
581 .auto_probe = mini51_auto_probe,
582 .erase_check = default_flash_blank_check,
583 .protect_check = mini51_protect_check,