numicro: Integrate Nuvoton NuMicro flash driver. 94/2794/3
authorNemui Trinomius <nemuisan_kawausogasuki@live.jp>
Wed, 3 Jun 2015 15:27:56 +0000 (00:27 +0900)
committerSpencer Oliver <spen@spen-soft.co.uk>
Wed, 30 Sep 2015 21:12:39 +0000 (22:12 +0100)
Flash driver "mini51.c" and "nuc1x.c" are same target MCU.
This patch integrates each driver and functions,
and makes into new "NuMicro" flash driver.

Change-Id: Ifff5c1cfdd265acca0f489631695be9194fa144c
Signed-off-by: Nemui Trinomius <nemuisan_kawausogasuki@live.jp>
Reviewed-on: http://openocd.zylin.com/2794
Tested-by: jenkins
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
src/flash/nor/Makefile.am
src/flash/nor/drivers.c
src/flash/nor/mini51.c [deleted file]
src/flash/nor/nuc1x.c [deleted file]
src/flash/nor/numicro.c [new file with mode: 0644]
tcl/target/m051.cfg [deleted file]
tcl/target/numicro.cfg [new file with mode: 0644]

index 4d11436cd8807528df74131a2b5edc23714f5e1a..3027dc73ddc41af5745196cdd7268062dd20993b 100644 (file)
@@ -43,8 +43,7 @@ NOR_DRIVERS = \
        fm3.c \
        dsp5680xx_flash.c \
        kinetis.c \
-       mini51.c \
-       nuc1x.c \
+       numicro.c \
        nrf51.c \
        mrvlqspi.c \
        psoc4.c \
index ef95f7b152fb842e3dcdfab8df54d84edc08a3c3..e527ddd03f204504bbbaa03a572389054b6ca262 100644 (file)
@@ -54,8 +54,7 @@ extern struct flash_driver fm3_flash;
 extern struct flash_driver kinetis_flash;
 extern struct flash_driver efm32_flash;
 extern struct flash_driver mdr_flash;
-extern struct flash_driver mini51_flash;
-extern struct flash_driver nuc1x_flash;
+extern struct flash_driver numicro_flash;
 extern struct flash_driver nrf51_flash;
 extern struct flash_driver mrvlqspi_flash;
 extern struct flash_driver psoc4_flash;
@@ -99,8 +98,7 @@ static struct flash_driver *flash_drivers[] = {
        &kinetis_flash,
        &efm32_flash,
        &mdr_flash,
-       &mini51_flash,
-       &nuc1x_flash,
+       &numicro_flash,
        &nrf51_flash,
        &mrvlqspi_flash,
        &psoc4_flash,
diff --git a/src/flash/nor/mini51.c b/src/flash/nor/mini51.c
deleted file mode 100644 (file)
index df6e7ce..0000000
+++ /dev/null
@@ -1,584 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2013 Cosmin Gorgovan                                    *
- *   cosmin [at] linux-geek [dot] org                                      *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
- ***************************************************************************/
-
-/*
-       Flash driver for the Nuvoton NuMicro Mini51 and M051 series microcontrollers
-
-       Part             |APROM Size |Part ID (at 0x5000_0000)
-       ----------------------------------------------
-       MINI51LAN        4 KB                   0x00205100
-       MINI51ZAN        4 KB                   0x00205103
-       MINI51TAN        4 KB                   0x00205104
-       MINI52LAN        8 KB                   0x00205200
-       MINI52ZAN        8 KB                   0x00205203
-       MINI52TAN        8 KB                   0x00205204
-       MINI54LAN        16 KB           0x00205400
-       MINI54ZAN        16 KB           0x00205403
-       MINI54TAN        16 KB           0x00205404
-       M052LBN           8 KB           0x10005200
-       M054LBN          16 KB           0x10005400
-       M058LBN          32 KB           0x10005800
-       M0516LBN         64 KB           0x10005A00
-       M052ZBN           8 KB           0x10005203
-       M054ZBN          16 KB           0x10005403
-       M058ZBN          32 KB           0x10005803
-       M0516ZBN         64 KB           0x10005A03
-       M052LDN           8 KB           0x20005200
-       M054LDN          16 KB           0x20005400
-       M058LDN          32 KB           0x20005800
-       M0516LDN         64 KB           0x20005A00
-       M052ZDN           8 KB           0x20005203
-       M054ZDN          16 KB           0x20005403
-       M058ZDN          32 KB           0x20005803
-       M0516ZDN         64 KB           0x20005A03
-       M052LDE           8 KB           0x30005200
-       M054LDE          16 KB           0x30005400
-       M058LDE          32 KB           0x30005800
-       M0516LDE         64 KB           0x30005A00
-       M052ZDE           8 KB           0x30005203
-       M054ZDE          16 KB           0x30005403
-       M058ZDE          32 KB           0x30005803
-       M0516ZDE         64 KB           0x30005A03
-
-       Datasheet & TRM
-       ---------------
-
-       The ISP flash programming procedure is described on pages 130 and 131 of the (not very verbose) TRM.
-
-       http://www.keil.com/dd/docs/datashts/nuvoton/mini51/da00-mini51_52_54c1.pdf
-
-       M051 ISP datasheet pages 190-206:
-       http://www.nuvoton.com/hq/resource-download.jsp?tp_GUID=DA05-M052-54-58-516
-
-       This driver
-       -----------
-
-       * chip_erase, erase, read and write operations have been implemented;
-       * All operations support APROM, LDROM, FLASH DATA and CONFIG;
-
-       Flash access limitations
-       ------------------------
-
-       For implementing the read operation, please note that the APROM isn't memory mapped when booted from LDROM.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "imp.h"
-
-#define PART_ID_REG     0x50000000
-#define IPRSTC1         0x50000008
-#define REGLOCKADDR     0x50000100
-#define ISPCON          0x5000C000
-#define ISPADR          0x5000C004
-#define ISPDAT          0x5000C008
-#define ISPCMD          0x5000C00C
-#define ISPTRG          0x5000C010
-/* Undocumented isp register */
-#define ISPUNKNOWN      0x5000C01C
-
-#define IPRSTC_CPU_RST      0x02
-
-#define ISPCON_ISPFF        0x40
-#define ISPCON_LDUEN        0x20
-#define ISPCON_CFGUEN       0x10
-#define ISPCON_APUEN        0x08
-#define ISPCON_BS_LDROM     0x02
-#define ISPCON_ISPEN        0x01
-
-#define ISPCMD_READ         0x00
-#define ISPCMD_PROGRAM      0x21
-#define ISPCMD_ERASE        0x22
-#define ISPCMD_CHIP_ERASE   0x26
-
-#define ISPTRG_ISPGO        0x01
-
-#define MINI51_APROM_BASE  0x00000000
-#define MINI51_DATA_BASE   0x0001F000
-#define MINI51_LDROM_BASE  0x00100000
-#define MINI51_CONFIG_BASE 0x00300000
-
-#define MINI51_KB          1024
-#define MINI51_PAGE_SIZE   512
-#define MINI51_TIMEOUT     1000
-
-
-#define ENSURE_OK(status) if (status != ERROR_OK) return status
-
-#define MINI51_MAX_FLASH_BANKS 4
-
-struct mini51_flash_bank_type {
-       uint32_t base;
-       uint32_t size;
-};
-
-struct mini51_cpu_type {
-       char *name;
-       uint32_t ppid;
-       unsigned n_banks;
-       struct mini51_flash_bank_type bank[MINI51_MAX_FLASH_BANKS];
-};
-
-#define MINI51_BANKS_MINI51(aprom_size) \
-       .n_banks = 3, \
-       { {MINI51_APROM_BASE, (aprom_size)}, {MINI51_LDROM_BASE, 2*1024}, {MINI51_CONFIG_BASE, 512} }
-
-#define MINI51_BANKS_M051(aprom_size) \
-       .n_banks = 4, \
-       { {MINI51_APROM_BASE, (aprom_size)}, {MINI51_DATA_BASE, 4*1024}, {MINI51_LDROM_BASE, 4*1024}, \
-       {MINI51_CONFIG_BASE, 1024} }
-
-static const struct mini51_cpu_type mini51_cpu[] = {
-       { "MINI51LAN", 0x00205100, MINI51_BANKS_MINI51(4*1024) },
-       { "MINI51ZAN", 0x00205103, MINI51_BANKS_MINI51(4*1024) },
-       { "MINI51TAN", 0x00205104, MINI51_BANKS_MINI51(4*1024) },
-       { "MINI52LAN", 0x00205200, MINI51_BANKS_MINI51(8*1024) },
-       { "MINI52ZAN", 0x00205203, MINI51_BANKS_MINI51(8*1024) },
-       { "MINI52TAN", 0x00205204, MINI51_BANKS_MINI51(8*1024) },
-       { "MINI54LAN", 0x00205400, MINI51_BANKS_MINI51(16*1024) },
-       { "MINI54ZAN", 0x00205403, MINI51_BANKS_MINI51(16*1024) },
-       { "MINI54TAN", 0x00205404, MINI51_BANKS_MINI51(16*1024) },
-
-       { "M052LBN",   0x10005200, MINI51_BANKS_M051(8*1024) },
-       { "M054LBN",   0x10005400, MINI51_BANKS_M051(16*1024) },
-       { "M058LBN",   0x10005800, MINI51_BANKS_M051(32*1024) },
-       { "M0516LBN",  0x10005A00, MINI51_BANKS_M051(64*1024) },
-       { "M052ZBN",   0x10005203, MINI51_BANKS_M051(8*1024) },
-       { "M054ZBN",   0x10005403, MINI51_BANKS_M051(16*1024) },
-       { "M058ZBN",   0x10005803, MINI51_BANKS_M051(32*1024) },
-       { "M0516ZBN",  0x10005A03, MINI51_BANKS_M051(64*1024) },
-       { "M052LDN",   0x20005200, MINI51_BANKS_M051(8*1024) },
-       { "M054LDN",   0x20005400, MINI51_BANKS_M051(16*1024) },
-       { "M058LDN",   0x20005800, MINI51_BANKS_M051(32*1024) },
-       { "M0516LDN",  0x20005A00, MINI51_BANKS_M051(64*1024) },
-       { "M052ZDN",   0x20005203, MINI51_BANKS_M051(8*1024) },
-       { "M054ZDN",   0x20005403, MINI51_BANKS_M051(16*1024) },
-       { "M058ZDN",   0x20005803, MINI51_BANKS_M051(32*1024) },
-       { "M0516ZDN",  0x20005A03, MINI51_BANKS_M051(64*1024) },
-       { "M052LDE",   0x30005200, MINI51_BANKS_M051(8*1024) },
-       { "M054LDE",   0x30005400, MINI51_BANKS_M051(16*1024) },
-       { "M058LDE",   0x30005800, MINI51_BANKS_M051(32*1024) },
-       { "M0516LDE",  0x30005A00, MINI51_BANKS_M051(64*1024) },
-       { "M052ZDE",   0x30005203, MINI51_BANKS_M051(8*1024) },
-       { "M054ZDE",   0x30005403, MINI51_BANKS_M051(16*1024) },
-       { "M058ZDE",   0x30005803, MINI51_BANKS_M051(32*1024) },
-       { "M0516ZDE",  0x30005A03, MINI51_BANKS_M051(64*1024) },
-};
-
-struct mini51_flash_bank {
-       bool probed;
-       const struct mini51_cpu_type *cpu;
-};
-
-/* Private methods */
-
-static int mini51_unlock_reg(struct target *target)
-{
-       int status;
-       status = target_write_u32(target, REGLOCKADDR, 0x59);
-       if (status != ERROR_OK)
-               return status;
-       status = target_write_u32(target, REGLOCKADDR, 0x16);
-       if (status != ERROR_OK)
-               return status;
-       status = target_write_u32(target, REGLOCKADDR, 0x88);
-       if (status != ERROR_OK)
-               return status;
-
-       return ERROR_OK;
-}
-
-
-static int mini51_get_part_id(struct target *target, uint32_t *part_id)
-{
-       int retu = target_read_u32(target, PART_ID_REG, part_id);
-       LOG_INFO("device id = 0x%08" PRIx32 "", *part_id);
-       return retu;
-}
-
-static int mini51_get_cpu_type(struct target *target, const struct mini51_cpu_type** cpu)
-{
-       uint32_t part_id;
-       int status;
-
-       status = mini51_get_part_id(target, &part_id);
-       ENSURE_OK(status);
-
-       for (size_t i = 0; i < sizeof(mini51_cpu)/sizeof(mini51_cpu[0]); i++) {
-               if (part_id == mini51_cpu[i].ppid) {
-                       *cpu = &mini51_cpu[i];
-                       LOG_INFO("device name = %s", (*cpu)->name);
-                       return ERROR_OK;
-               }
-       }
-
-       return ERROR_FLASH_OPERATION_FAILED;
-}
-
-static int mini51_get_flash_size(struct flash_bank *bank, const struct mini51_cpu_type *cpu, uint32_t *flash_size)
-{
-       for (size_t i = 0; i < cpu->n_banks; i++) {
-               if (bank->base == cpu->bank[i].base) {
-                       *flash_size = cpu->bank[i].size;
-                       LOG_INFO("bank base = 0x%08" PRIx32 ", size = 0x%08" PRIx32 "", bank->base, *flash_size);
-                       return ERROR_OK;
-               }
-       }
-       return ERROR_FLASH_OPERATION_FAILED;
-}
-
-static int mini51_isp_execute(struct target *target)
-{
-       int status;
-       uint32_t ispcon;
-       int timeout;
-       uint32_t isptrg;
-
-       /* start ISP operation */
-       status = target_write_u32(target, ISPTRG, ISPTRG_ISPGO);
-       ENSURE_OK(status);
-
-       /* Wait for for command to finish executing */
-       timeout = MINI51_TIMEOUT;
-       do {
-               target_read_u32(target, ISPTRG, &isptrg);
-               timeout--;
-       } while ((isptrg & ISPTRG_ISPGO) && (timeout > 0));
-       if (timeout == 0) {
-               LOG_WARNING("Mini51 flash driver: Timeout executing flash command\n");
-               return ERROR_FLASH_OPERATION_FAILED;
-       }
-
-       /* Check for errors */
-       status = target_read_u32(target, ISPCON, &ispcon);
-       ENSURE_OK(status);
-       if (ispcon & ISPCON_ISPFF) {
-               LOG_WARNING("Mini51 flash driver: operation failed\n");
-               return ERROR_FLASH_OPERATION_FAILED;
-       }
-       return status;
-}
-
-static int mini51_isp_execute_cmd(struct target *target, uint32_t cmd, uint32_t address, uint32_t data)
-{
-       int status;
-       status = target_write_u32(target, ISPDAT, data);
-       ENSURE_OK(status);
-       status = target_write_u32(target, ISPADR, address);
-       ENSURE_OK(status);
-       status = target_write_u32(target, ISPCMD, cmd);
-       ENSURE_OK(status);
-
-       status = mini51_isp_execute(target);
-       return status;
-}
-
-static int mini51_isp_execute_cmd_read(struct target *target, uint32_t cmd, uint32_t address, uint32_t *data)
-{
-       int status;
-       status = target_write_u32(target, ISPADR, address);
-       ENSURE_OK(status);
-       status = target_write_u32(target, ISPCMD, cmd);
-       ENSURE_OK(status);
-
-       status = mini51_isp_execute(target);
-       ENSURE_OK(status);
-
-       status = target_read_u32(target, ISPDAT, data);
-       ENSURE_OK(status);
-
-       return status;
-}
-
-static int mini51_isp_enable(struct target *target)
-{
-       int status;
-       uint32_t ispcon;
-
-       if (target->state != TARGET_HALTED) {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
-       status = mini51_unlock_reg(target);
-       ENSURE_OK(status);
-       status = target_read_u32(target, ISPCON, &ispcon);
-       ENSURE_OK(status);
-       ispcon |= ISPCON_ISPEN | ISPCON_LDUEN | ISPCON_APUEN | ISPCON_CFGUEN;
-       status = target_write_u32(target, ISPCON, ispcon);
-       return status;
-}
-
-/* Public (API) methods */
-
-FLASH_BANK_COMMAND_HANDLER(mini51_flash_bank_command)
-{
-       struct mini51_flash_bank *mini51_info;
-       mini51_info = malloc(sizeof(struct mini51_flash_bank));
-       mini51_info->probed = false;
-       bank->driver_priv = mini51_info;
-
-       return ERROR_OK;
-}
-
-static int mini51_protect_check(struct flash_bank *bank)
-{
-       LOG_WARNING("Mini51 flash driver: protect_check not implemented yet\n");
-
-       return ERROR_FLASH_OPERATION_FAILED;
-}
-
-static int mini51_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
-{
-       int status;
-       uint32_t ispdat;
-       struct target *target = bank->target;
-
-       if ((offset & 0x3) || (count & 0x3)) {
-               LOG_WARNING("Mini51 flash driver: unaligned access not supported\n");
-               return ERROR_FLASH_OPERATION_FAILED;
-       }
-
-       status = mini51_isp_enable(target);
-       ENSURE_OK(status);
-
-       for (uint32_t i = offset; i < offset + count; i += 4) {
-               status = mini51_isp_execute_cmd_read(target, ISPCMD_READ, bank->base + i, &ispdat);
-               memcpy(buffer, &ispdat, sizeof(ispdat));
-               ENSURE_OK(status);
-               buffer += sizeof(ispdat);
-       }
-
-       return ERROR_OK;
-}
-
-
-static int mini51_erase(struct flash_bank *bank, int first, int last)
-{
-       int status;
-       struct target *target = bank->target;
-
-       /* Enable ISP */
-       status = mini51_isp_enable(target);
-       ENSURE_OK(status);
-
-       for (int page_start = first; page_start <= last; page_start++) {
-               /* Set up erase command */
-               uint32_t address = bank->base + page_start*MINI51_PAGE_SIZE;
-               status = mini51_isp_execute_cmd(target, ISPCMD_ERASE, address, 0);
-               ENSURE_OK(status);
-       }
-
-       return ERROR_OK;
-}
-
-static int mini51_protect(struct flash_bank *bank, int set, int first, int last)
-{
-       LOG_WARNING("Mini51 flash driver: protect operation not implemented yet\n");
-
-       return ERROR_FLASH_OPERATION_FAILED;
-}
-
-static int mini51_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
-{
-       int status;
-       uint32_t ispdat;
-       struct target *target = bank->target;
-
-       if ((offset & 0x3) || (count & 0x3)) {
-               LOG_WARNING("Mini51 flash driver: unaligned access not supported\n");
-               return ERROR_FLASH_OPERATION_FAILED;
-       }
-
-       status = mini51_isp_enable(target);
-       ENSURE_OK(status);
-
-       for (uint32_t i = offset; i < offset + count; i += 4) {
-               memcpy(&ispdat, buffer, sizeof(ispdat));
-               status = mini51_isp_execute_cmd(target, ISPCMD_PROGRAM, bank->base + i, ispdat);
-               ENSURE_OK(status);
-               buffer += sizeof(ispdat);
-       }
-
-       return ERROR_OK;
-}
-
-static int mini51_probe(struct flash_bank *bank)
-{
-       uint32_t flash_size;
-       int status;
-       int num_pages;
-       uint32_t offset = 0;
-       const struct mini51_cpu_type *cpu;
-       struct target *target = bank->target;
-
-       status = mini51_get_cpu_type(target, &cpu);
-       if (status != ERROR_OK) {
-               LOG_WARNING("Mini51 flash driver: Failed to detect a known part\n");
-               return ERROR_FLASH_OPERATION_FAILED;
-       }
-
-       status = mini51_get_flash_size(bank, cpu, &flash_size);
-       if (status != ERROR_OK) {
-               LOG_WARNING("Mini51 flash driver: Failed to detect flash size\n");
-               return ERROR_FLASH_OPERATION_FAILED;
-       }
-
-       num_pages = flash_size / MINI51_PAGE_SIZE;
-
-       bank->num_sectors = num_pages;
-       bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
-       bank->size = flash_size;
-
-       for (int i = 0; i < num_pages; i++) {
-               bank->sectors[i].offset = offset;
-               bank->sectors[i].size = MINI51_PAGE_SIZE;
-               bank->sectors[i].is_erased = -1;
-               bank->sectors[i].is_protected = 0;
-               offset += MINI51_PAGE_SIZE;
-       }
-
-       struct mini51_flash_bank *mini51_info = bank->driver_priv;
-       mini51_info->probed = true;
-       mini51_info->cpu = cpu;
-
-       return ERROR_OK;
-}
-
-static int mini51_auto_probe(struct flash_bank *bank)
-{
-       struct mini51_flash_bank *mini51_info = bank->driver_priv;
-       if (mini51_info->probed)
-               return ERROR_OK;
-       return mini51_probe(bank);
-}
-
-COMMAND_HANDLER(mini51_handle_read_isp_command)
-{
-       uint32_t address;
-       uint32_t ispdat;
-       int status;
-
-       if (CMD_ARGC != 1)
-               return ERROR_COMMAND_SYNTAX_ERROR;
-
-       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
-
-       struct target *target = get_current_target(CMD_CTX);
-
-       status = mini51_isp_enable(target);
-       ENSURE_OK(status);
-       status = mini51_isp_execute_cmd_read(target, ISPCMD_READ, address, &ispdat);
-       ENSURE_OK(status);
-       LOG_INFO("0x%08" PRIx32 ": 0x%08" PRIx32, address, ispdat);
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(mini51_handle_write_isp_command)
-{
-       uint32_t address;
-       uint32_t ispdat;
-       int status;
-
-       if (CMD_ARGC != 2)
-               return ERROR_COMMAND_SYNTAX_ERROR;
-
-       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
-       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], ispdat);
-
-       struct target *target = get_current_target(CMD_CTX);
-
-       status = mini51_isp_enable(target);
-       ENSURE_OK(status);
-       status = mini51_isp_execute_cmd(target, ISPCMD_PROGRAM, address, ispdat);
-       ENSURE_OK(status);
-       LOG_INFO("0x%08" PRIx32 ": 0x%08" PRIx32, address, ispdat);
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(mini51_handle_chip_erase_command)
-{
-       int status;
-       if (CMD_ARGC != 0)
-               return ERROR_COMMAND_SYNTAX_ERROR;
-
-       struct target *target = get_current_target(CMD_CTX);
-
-       status = mini51_isp_enable(target);
-       ENSURE_OK(status);
-       /* Write one to undocumented flash control register */
-       status = target_write_u32(target, ISPUNKNOWN, 1);
-       ENSURE_OK(status);
-
-       status = mini51_isp_execute_cmd(target, ISPCMD_CHIP_ERASE, 0, 0);
-       ENSURE_OK(status);
-       return ERROR_OK;
-}
-
-static const struct command_registration mini51_exec_command_handlers[] = {
-       {
-               .name = "read_isp",
-               .handler = mini51_handle_read_isp_command,
-               .usage = "address",
-               .mode = COMMAND_EXEC,
-               .help = "read flash through ISP.",
-       },
-       {
-               .name = "write_isp",
-               .handler = mini51_handle_write_isp_command,
-               .usage = "address value",
-               .mode = COMMAND_EXEC,
-               .help = "write flash through ISP.",
-       },
-       {
-               .name = "chip_erase",
-               .handler = mini51_handle_chip_erase_command,
-               .mode = COMMAND_EXEC,
-               .help = "chip erase.",
-       },
-       COMMAND_REGISTRATION_DONE
-};
-
-static const struct command_registration mini51_command_handlers[] = {
-       {
-               .name = "mini51",
-               .mode = COMMAND_ANY,
-               .help = "mini51 flash command group",
-               .usage = "",
-               .chain = mini51_exec_command_handlers,
-       },
-       COMMAND_REGISTRATION_DONE
-};
-
-struct flash_driver mini51_flash = {
-       .name = "mini51",
-       .commands = mini51_command_handlers,
-       .flash_bank_command = mini51_flash_bank_command,
-       .erase = mini51_erase,
-       .protect = mini51_protect,
-       .write = mini51_write,
-       .read = mini51_read,
-       .probe = mini51_probe,
-       .auto_probe = mini51_auto_probe,
-       .erase_check = default_flash_blank_check,
-       .protect_check = mini51_protect_check,
-};
diff --git a/src/flash/nor/nuc1x.c b/src/flash/nor/nuc1x.c
deleted file mode 100644 (file)
index 3f39a05..0000000
+++ /dev/null
@@ -1,640 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2011 by James K. Larson                                 *
- *   jlarson@pacifier.com                                                  *
- *                                                                         *
- *   Copyright (C) 2013 Nemui Trinomius                                    *
- *   nemuisan_kawausogasuki@live.jp                                        *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
- ***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "imp.h"
-
-/* nuc1x register locations */
-#define NUC1X_SYS_BASE        0x50000000
-#define NUC1X_SYS_WRPROT      0x50000100
-#define NUC1X_SYS_IPRSTC1     0x50000008
-
-#define NUC1X_SYSCLK_BASE     0x50000200
-#define NUC1X_SYSCLK_PWRCON   0x50000200
-#define NUC1X_SYSCLK_CLKSEL0  0x50000210
-#define NUC1X_SYSCLK_CLKDIV   0x50000218
-#define NUC1X_SYSCLK_AHBCLK   0x50000204
-
-#define NUC1X_FLASH_BASE      0x5000C000
-#define NUC1X_FLASH_ISPCON    0x5000C000
-#define NUC1X_FLASH_ISPCMD    0x5000C00C
-#define NUC1X_FLASH_ISPADR    0x5000C004
-#define NUC1X_FLASH_ISPDAT    0x5000C008
-#define NUC1X_FLASH_ISPTRG    0x5000C010
-
-/* Command register bits */
-#define PWRCON_OSC22M         (1 << 2)
-#define PWRCON_XTL12M         (1 << 0)
-
-#define IPRSTC1_CPU_RST       (1<<1)
-#define IPRSTC1_CHIP_RST      (1<<0)
-
-#define AHBCLK_ISP_EN         (1 << 2)
-
-#define ISPCON_ISPEN          (1 << 0)
-#define ISPCON_BS_AP          (0 << 1)
-#define ISPCON_BS_LP          (1 << 1)
-#define ISPCON_CFGUEN         (1 << 4)
-#define ISPCON_LDUEN          (1 << 5)
-#define ISPCON_ISPFF          (1 << 6)
-
-/* isp commands */
-#define ISPCMD_FCTRL          (0x2)
-#define ISPCMD_FCEN           (1 << 4)
-#define ISPCMD_FOEN           (1 << 5)
-#define ISPCMD_ERASE          (0x2 | ISPCMD_FOEN)
-#define ISPCMD_WRITE          (0x1 | ISPCMD_FOEN)
-#define ISPTRG_ISPGO          (1 << 0)
-
-/* access unlock keys */
-#define KEY1 0x59
-#define KEY2 0x16
-#define KEY3 0x88
-#define LOCK 0x00
-
-/* part structs */
-static const struct {
-       const char *partname;
-       uint32_t partno;
-       uint16_t num_page;
-}
-NuMicroParts[] = {
-       /*PART NO*/   /*PART ID*/   /*NUM PAGE*/
-       {"NUC100LC1", 0x00010008,   64},
-       {"NUC100LD1", 0x00010005,   128},
-       {"NUC100LD2", 0x00010004,   128},
-       {"NUC100RC1", 0x00010017,   64},
-       {"NUC100RD1", 0x00010014,   128},
-       {"NUC100RD2", 0x00010013,   128},
-
-       {"NUC100LD3", 0x00010003,   128},
-       {"NUC100LE3", 0x00010000,   256},
-       {"NUC100RD3", 0x00010012,   128},
-       {"NUC100RE3", 0x00010009,   256},
-       {"NUC100VD2", 0x00010022,   128},
-       {"NUC100VD3", 0x00010021,   128},
-       {"NUC100VE3", 0x00010018,   256},
-
-       {"NUC120LC1", 0x00012008,   64},
-       {"NUC120LD1", 0x00012005,   128},
-       {"NUC120LD2", 0x00012004,   128},
-       {"NUC120RC1", 0x00012017,   64},
-       {"NUC120RD1", 0x00012014,   128},
-       {"NUC120RD2", 0x00012013,   128},
-
-       {"NUC120LD3", 0x00012003,   128},
-       {"NUC120LE3", 0x00012000,   256},
-       {"NUC120RD3", 0x00012012,   128},
-       {"NUC120RE3", 0x00012009,   256},
-       {"NUC120VD2", 0x00012022,   128},
-       {"NUC120VD3", 0x00012021,   128},
-       {"NUC120VE3", 0x00012018,   256},
-
-       {"NUC122ZD2", 0x00012231,   128},
-       {"NUC122ZC1", 0x00012235,   64},
-       {"NUC122LD2", 0x00012204,   128},
-       {"NUC122LC1", 0x00012208,   64},
-       {"NUC122RD2", 0x00012213,   128},
-       {"NUC122RC1", 0x00012217,   64},
-
-       {"NUC123ZD4", 0x00012255,   136},
-       {"NUC123ZC2", 0x00012245,   68},
-       {"NUC123LD4", 0x00012235,   136},
-       {"NUC123LC2", 0x00012225,   68},
-       {"NUC123SD4", 0x00012215,   136},
-       {"NUC123SC2", 0x00012205,   68},
-
-       {"NUC130LC1", 0x00013008,   64},
-       {"NUC130LD2", 0x00013004,   128},
-       {"NUC130LE3", 0x00013000,   256},
-       {"NUC130RC1", 0x00013017,   64},
-       {"NUC130RD2", 0x00013013,   128},
-       {"NUC130RE3", 0x00013009,   256},
-       {"NUC130VE3", 0x00013018,   256},
-
-       {"M052L",     0x00005200,   16},
-       {"M052Z",     0x00005203,   16},
-       {"M054L",     0x00005400,   32},
-       {"M054Z",     0x00005403,   32},
-       {"M058L",     0x00005800,   64},
-       {"M058Z",     0x00005803,   64},
-       {"M0516L",    0x00005A00,   128},
-       {"M0516Z",    0x00005A03,   128},
-
-       {"MINI51L",   0x00205100,   8},
-       {"MINI51Z",   0x00205103,   8},
-       {"MINI52L",   0x00205200,   16},
-       {"MINI52Z",   0x00205203,   16},
-       {"MINI54L",   0x00205400,   32},
-       {"MINI54Z",   0x00205403,   32},
-
-       {"UNKNOWN",   0x00000000,   256},
-};
-
-static int nuc1x_unlock(struct flash_bank *bank)
-{
-       uint32_t is_protected;
-       struct target *target = bank->target;
-
-       /* Check to see if Nuc is unlocked or not */
-       int retval = target_read_u32(target, NUC1X_SYS_WRPROT, &is_protected);
-       if (retval != ERROR_OK)
-               return retval;
-
-       LOG_DEBUG("protected = 0x%08" PRIx32 "", is_protected);
-       if (is_protected == 0) {        /* means protected - so unlock it */
-               /* unlock flash registers */
-               retval = target_write_u32(target, NUC1X_SYS_WRPROT, KEY1);
-               if (retval != ERROR_OK)
-                       return retval;
-               retval = target_write_u32(target, NUC1X_SYS_WRPROT, KEY2);
-               if (retval != ERROR_OK)
-                       return retval;
-               retval = target_write_u32(target, NUC1X_SYS_WRPROT, KEY3);
-               if (retval != ERROR_OK)
-                       return retval;
-       }
-       /* Check that unlock worked */
-       retval = target_read_u32(target, NUC1X_SYS_WRPROT, &is_protected);
-       if (retval != ERROR_OK)
-               return retval;
-
-       if (is_protected == 1) {        /* means unprotected */
-               LOG_DEBUG("protection removed");
-       } else {
-               LOG_DEBUG("still protected!!");
-       }
-
-       return ERROR_OK;
-}
-
-static int nuc1x_reset(struct flash_bank *bank)
-{
-       struct target *target = bank->target;
-
-       nuc1x_unlock(bank);
-
-       int retval = target_write_u32(target, NUC1X_SYS_IPRSTC1, IPRSTC1_CPU_RST);
-       if (retval != ERROR_OK)
-               return retval;
-
-       return ERROR_OK;
-}
-
-static int nuc1x_reset2lprom(struct flash_bank *bank)
-{
-       struct target *target = bank->target;
-
-       nuc1x_unlock(bank);
-       int retval = target_write_u32(target, NUC1X_FLASH_ISPCON, ISPCON_BS_LP);
-       if (retval != ERROR_OK)
-               return retval;
-
-       nuc1x_reset(bank);
-
-       return ERROR_OK;
-}
-
-static int nuc1x_init_iap(struct flash_bank *bank)
-{
-       struct target *target = bank->target;
-
-       if (target->state != TARGET_HALTED) {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
-       int retval = nuc1x_unlock(bank);
-       if (retval != ERROR_OK)
-               return retval;
-
-       /* enable isp clock and ispen bit */
-       retval = target_write_u32(target, NUC1X_SYSCLK_AHBCLK, AHBCLK_ISP_EN);
-       if (retval != ERROR_OK)
-               return retval;
-
-       retval = target_write_u32(target, NUC1X_FLASH_ISPCON, ISPCON_ISPFF | ISPCON_LDUEN | ISPCON_CFGUEN | ISPCON_ISPEN);
-       if (retval != ERROR_OK)
-               return retval;
-
-       return ERROR_OK;
-}
-
-/* Private bank information for nuc1x. */
-struct  nuc1x_flash_bank {
-       struct working_area *write_algorithm;
-       int probed;
-};
-
-/* This is the function called in the config file. */
-FLASH_BANK_COMMAND_HANDLER(nuc1x_flash_bank_command)
-{
-       struct nuc1x_flash_bank *bank_info;
-
-       if (CMD_ARGC < 6)
-               return ERROR_COMMAND_SYNTAX_ERROR;
-
-       LOG_INFO("add flash_bank nuc1x %s", bank->name);
-
-       bank_info = malloc(sizeof(struct nuc1x_flash_bank));
-
-       memset(bank_info, 0, sizeof(struct nuc1x_flash_bank));
-
-       bank->driver_priv = bank_info;
-
-       return ERROR_OK;
-
-}
-
-/* Protection checking - examines the lock bit. */
-static int nuc1x_protect_check(struct flash_bank *bank)
-{
-       uint32_t is_protected, set;
-       struct target *target = bank->target;
-       int i;
-
-       if (target->state != TARGET_HALTED) {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
-       /* Check to see if Nuc is unlocked or not */
-       int retval = target_read_u32(target, NUC1X_SYS_WRPROT, &is_protected);
-       if (retval != ERROR_OK)
-               return retval;
-
-       LOG_INFO("is_protected = 0x%08" PRIx32 "", is_protected);
-       if (is_protected == 0) {        /* means protected */
-               set = 1;
-       } else {
-               set = 0;
-       }
-       for (i = 0; i < bank->num_sectors; i++)
-               bank->sectors[i].is_protected = set;
-
-       return ERROR_OK;
-}
-
-static int nuc1x_erase(struct flash_bank *bank, int first, int last)
-{
-       struct target *target = bank->target;
-       uint32_t timeout, status;
-       int i;
-
-       if (bank->target->state != TARGET_HALTED) {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
-       LOG_INFO("Nuvoton NUC: Sector Erase ... (%d to %d)", first, last);
-
-       int retval = nuc1x_reset2lprom(bank);
-       if (retval != ERROR_OK)
-               return retval;
-
-       retval = nuc1x_init_iap(bank);
-       if (retval != ERROR_OK)
-               return retval;
-
-       retval = nuc1x_unlock(bank);
-       if (retval != ERROR_OK)
-               return retval;
-
-       retval = target_write_u32(target, NUC1X_FLASH_ISPCMD, ISPCMD_ERASE);
-       if (retval != ERROR_OK)
-               return retval;
-
-       for (i = first; i <= last; i++) {
-               LOG_DEBUG("erasing sector %d at address 0x%" PRIx32 "", i, bank->base + bank->sectors[i].offset);
-               retval = target_write_u32(target, NUC1X_FLASH_ISPADR, bank->base + bank->sectors[i].offset);
-               if (retval != ERROR_OK)
-                       return retval;
-               retval = target_write_u32(target, NUC1X_FLASH_ISPTRG, ISPTRG_ISPGO); /* This is the only bit available */
-               if (retval != ERROR_OK)
-                       return retval;
-
-               /* wait for busy to clear - check the GO flag */
-               timeout = 100;
-               for (;;) {
-                       retval = target_read_u32(target, NUC1X_FLASH_ISPTRG, &status);
-                       if (retval != ERROR_OK)
-                               return retval;
-                               LOG_DEBUG("status: 0x%" PRIx32 "", status);
-                       if (status == 0)
-                               break;
-                       if (timeout-- <= 0) {
-                               LOG_DEBUG("timed out waiting for flash");
-                               return ERROR_FAIL;
-                       }
-                       busy_sleep(1);  /* can use busy sleep for short times. */
-               }
-
-               /* check for failure */
-               retval = target_read_u32(target, NUC1X_FLASH_ISPCON, &status);
-               if (retval != ERROR_OK)
-                       return retval;
-               if ((status & ISPCON_ISPFF) != 0) {
-                       LOG_DEBUG("failure: 0x%" PRIx32 "", status);
-                       /* if bit is set, then must write to it to clear it. */
-                       retval = target_write_u32(target, NUC1X_FLASH_ISPCON, ISPCON_ISPFF);
-                       if (retval != ERROR_OK)
-                               return retval;
-               } else {
-                       bank->sectors[i].is_erased = 1;
-               }
-       }
-
-       retval = nuc1x_reset(bank);
-       if (retval != ERROR_OK)
-               return retval;
-
-       /* done, */
-       LOG_DEBUG("Erase done.");
-
-       return ERROR_OK;
-}
-
-/* The write routine stub. */
-static int nuc1x_write(struct flash_bank *bank, const uint8_t *buffer,
-               uint32_t offset, uint32_t count)
-{
-       struct target *target = bank->target;
-       uint32_t i, timeout, status;
-
-       if (bank->target->state != TARGET_HALTED) {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
-       LOG_INFO("Nuvoton NUC: FLASH Write ...");
-
-       int retval = nuc1x_reset2lprom(bank);
-       if (retval != ERROR_OK)
-               return retval;
-
-       retval = nuc1x_init_iap(bank);
-       if (retval != ERROR_OK)
-               return retval;
-
-       retval = nuc1x_unlock(bank);
-       if (retval != ERROR_OK)
-               return retval;
-
-       retval = target_write_u32(target, NUC1X_FLASH_ISPCMD, ISPCMD_WRITE);
-       if (retval != ERROR_OK)
-               return retval;
-
-       /* program command */
-       for (i = 0; i < count; i += 4) {
-
-               LOG_DEBUG("write longword @ %08" PRIX32, (uint32_t)(offset + i));
-
-               uint8_t padding[4] = {0xff, 0xff, 0xff, 0xff};
-               memcpy(padding, buffer + i, MIN(4, count-i));
-
-               retval = target_write_u32(target, NUC1X_FLASH_ISPADR, bank->base + offset + i);
-               if (retval != ERROR_OK)
-                       return retval;
-               retval = target_write_memory(target, NUC1X_FLASH_ISPDAT, 4, 1, padding);
-               if (retval != ERROR_OK)
-                       return retval;
-               retval = target_write_u32(target, NUC1X_FLASH_ISPTRG, ISPTRG_ISPGO);
-               if (retval != ERROR_OK)
-                       return retval;
-
-               /* wait for busy to clear - check the GO flag */
-               timeout = 100;
-               for (;;) {
-                       retval = target_read_u32(target, NUC1X_FLASH_ISPTRG, &status);
-                       if (retval != ERROR_OK)
-                               return retval;
-                               LOG_DEBUG("status: 0x%" PRIx32 "", status);
-                       if (status == 0)
-                               break;
-                       if (timeout-- <= 0) {
-                               LOG_DEBUG("timed out waiting for flash");
-                               return ERROR_FAIL;
-                       }
-                       busy_sleep(1);  /* can use busy sleep for short times. */
-               }
-
-               /* check for failure */
-               retval = target_read_u32(target, NUC1X_FLASH_ISPCON, &status);
-               if (retval != ERROR_OK)
-                       return retval;
-               if ((status & ISPCON_ISPFF) != 0) {
-                       LOG_DEBUG("failure: 0x%" PRIx32 "", status);
-                       /* if bit is set, then must write to it to clear it. */
-                       retval = target_write_u32(target, NUC1X_FLASH_ISPCON, ISPCON_ISPFF);
-                       if (retval != ERROR_OK)
-                               return retval;
-               } else {
-                       LOG_DEBUG("Write OK");
-               }
-       }
-
-       retval = nuc1x_reset(bank);
-       if (retval != ERROR_OK)
-               return retval;
-
-       /* done, */
-       LOG_DEBUG("Write done.");
-
-       return ERROR_OK;
-}
-
-/* The probe routine for the nuc. Only recognizes the nuc120 right now. */
-static int nuc1x_probe(struct flash_bank *bank)
-{
-       struct target *target = bank->target;
-       struct nuc1x_flash_bank *nuc1x_info = bank->driver_priv;
-       int i;
-       uint16_t num_pages;
-       uint32_t device_id;
-       int page_size;
-       uint32_t base_address = 0x00000000;
-
-       nuc1x_info->probed = 0;
-
-       /* read nuc1x device id register */
-       int retval = target_read_u32(target, 0x50000000, &device_id);
-       if (retval != ERROR_OK)
-               return retval;
-
-       page_size = 512;        /* all nuc parts has 512 byte per sector */
-
-       /* search part numbers */
-       for (i = 0; NuMicroParts[i].partno; i++) {
-               if (NuMicroParts[i].partno == (device_id & 0x0FFFFFFF)) {
-                       num_pages = NuMicroParts[i].num_page;
-                       break;
-               }
-       }
-       if (!(NuMicroParts[i].partno == 0x00000000)) {
-               LOG_INFO("DeviceID : 0x%08" PRIx32 "", device_id);
-               LOG_INFO("Detect %s%cN!", NuMicroParts[i].partname, (char)('A'+(device_id>>28)));
-       } else {
-               LOG_INFO("No NUC Device Detected...");
-               return ERROR_FAIL;
-       }
-
-       if (bank->sectors) {
-               free(bank->sectors);
-               bank->sectors = NULL;
-       }
-
-       bank->base = base_address;
-       bank->size = (num_pages * page_size);
-       bank->num_sectors = num_pages;
-       bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
-
-       for (i = 0; i < num_pages; i++) {
-               bank->sectors[i].offset = i * page_size;
-               bank->sectors[i].size = page_size;
-               bank->sectors[i].is_erased = -1;
-               bank->sectors[i].is_protected = 1;
-       }
-
-       nuc1x_info->probed = 1;
-
-       LOG_DEBUG("Nuvoton NUC: Probed ...");
-
-       return ERROR_OK;
-}
-
-/* Standard approach to autoprobing. */
-static int nuc1x_auto_probe(struct flash_bank *bank)
-{
-       struct nuc1x_flash_bank *nuc1x_info = bank->driver_priv;
-       if (nuc1x_info->probed)
-               return ERROR_OK;
-       return nuc1x_probe(bank);
-}
-
-/* Info doesn't really add much, but works correctly. */
-static int get_nuc1x_info(struct flash_bank *bank, char *buf, int buf_size)
-{
-       struct target *target = bank->target;
-       uint32_t i, device_id;
-
-       /* read nuc1x device id register */
-       int retval = target_read_u32(target, 0x50000000, &device_id);
-       if (retval != ERROR_OK)
-               return retval;
-
-       /* search part numbers */
-       for (i = 0; NuMicroParts[i].partno; i++) {
-               if (NuMicroParts[i].partno == (device_id & 0x0FFFFFFF))
-                       break;
-       }
-       if (!(NuMicroParts[i].partno == 0x00000000)) {
-               LOG_INFO("DeviceID : 0x%08" PRIx32 "", device_id);
-               LOG_INFO("Detect %s%cN!", NuMicroParts[i].partname, (char)('A'+(device_id>>28)));
-       } else {
-               LOG_INFO("No NUC Device Detected...");
-               return ERROR_FAIL;
-       }
-
-       return ERROR_OK;
-}
-
-/* The nuc120 doesn't support mass erase, so this will probably be removed soon.
- * The structure is left for now until I am sure I don't want to add any custom
- * commands. */
-static int nuc1x_mass_erase(struct flash_bank *bank)
-{
-       struct target *target = bank->target;
-       int retval = ERROR_OK;
-
-       if (target->state != TARGET_HALTED) {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
-       LOG_INFO("Nuvoton NUC: Chip Erase ... (may take several seconds)");
-
-       return retval;
-}
-
-COMMAND_HANDLER(nuc1x_handle_mass_erase_command)
-{
-       int i; /* for erasing sectors */
-       if (CMD_ARGC < 1) {
-               command_print(CMD_CTX, "nuc1x mass_erase <bank>");
-               return ERROR_OK;
-       }
-
-       struct flash_bank *bank;
-       int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
-       if (ERROR_OK != retval)
-               return retval;
-
-       retval = nuc1x_mass_erase(bank);
-       if (retval == ERROR_OK) {
-               /* set all sectors as erased */
-               for (i = 0; i < bank->num_sectors; i++)
-                       bank->sectors[i].is_erased = 1;
-
-               command_print(CMD_CTX, "nuc1x mass erase complete");
-       } else
-               command_print(CMD_CTX, "nuc1x mass erase failed");
-
-       return retval;
-}
-
-static const struct command_registration nuc1x_exec_command_handlers[] = {
-       {
-               .name = "mass_erase",
-               .handler = nuc1x_handle_mass_erase_command,
-               .mode = COMMAND_EXEC,
-               .usage = "bank_id",
-               .help = "Erase entire Flash device.",
-       },
-       COMMAND_REGISTRATION_DONE
-};
-
-static const struct command_registration nuc1x_command_handlers[] = {
-       {
-               .name = "nuc1x",
-               .mode = COMMAND_ANY,
-               .help = "nuc1x Flash command group",
-               .chain = nuc1x_exec_command_handlers,
-       },
-       COMMAND_REGISTRATION_DONE
-};
-struct flash_driver nuc1x_flash = {
-       .name = "nuc1x",
-       .commands = nuc1x_command_handlers,
-       .flash_bank_command = nuc1x_flash_bank_command,
-       .erase = nuc1x_erase,
-       .write = nuc1x_write,
-       .read = default_flash_read,
-       .probe = nuc1x_probe,
-       .auto_probe = nuc1x_auto_probe,
-       .erase_check = default_flash_blank_check,
-       .protect_check = nuc1x_protect_check,
-       .info = get_nuc1x_info,
-};
diff --git a/src/flash/nor/numicro.c b/src/flash/nor/numicro.c
new file mode 100644 (file)
index 0000000..8d8ed6e
--- /dev/null
@@ -0,0 +1,1880 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by James K. Larson                                 *
+ *   jlarson@pacifier.com                                                  *
+ *                                                                         *
+ *   Copyright (C) 2013 Cosmin Gorgovan                                    *
+ *   cosmin [at] linux-geek [dot] org                                      *
+ *                                                                         *
+ *   Copyright (C) 2014 Pawel Si                                           *
+ *   stawel+openocd@gmail.com                                              *
+ *                                                                         *
+ *   Copyright (C) 2015 Nemui Trinomius                                    *
+ *   nemuisan_kawausogasuki@live.jp                                        *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "imp.h"
+#include <helper/binarybuffer.h>
+#include <target/algorithm.h>
+#include <target/armv7m.h>
+#include <target/cortex_m.h>
+
+/* Nuvoton NuMicro register locations */
+#define NUMICRO_SYS_BASE        0x50000000
+#define NUMICRO_SYS_WRPROT      0x50000100
+#define NUMICRO_SYS_IPRSTC1     0x50000008
+
+#define NUMICRO_SYSCLK_BASE     0x50000200
+#define NUMICRO_SYSCLK_PWRCON   0x50000200
+#define NUMICRO_SYSCLK_CLKSEL0  0x50000210
+#define NUMICRO_SYSCLK_CLKDIV   0x50000218
+#define NUMICRO_SYSCLK_AHBCLK   0x50000204
+
+#define NUMICRO_FLASH_BASE      0x5000C000
+#define NUMICRO_FLASH_ISPCON    0x5000C000
+#define NUMICRO_FLASH_ISPADR    0x5000C004
+#define NUMICRO_FLASH_ISPDAT    0x5000C008
+#define NUMICRO_FLASH_ISPCMD    0x5000C00C
+#define NUMICRO_FLASH_ISPTRG    0x5000C010
+#define NUMICRO_FLASH_CHEAT      0x5000C01C    /* Undocumented isp register(may be cheat register) */
+
+#define NUMICRO_SCS_BASE        0xE000E000
+#define NUMICRO_SCS_AIRCR       0xE000ED0C
+#define NUMICRO_SCS_DHCSR       0xE000EDF0
+#define NUMICRO_SCS_DEMCR       0xE000EDFC
+
+#define NUMICRO_APROM_BASE      0x00000000
+#define NUMICRO_DATA_BASE       0x0001F000
+#define NUMICRO_LDROM_BASE      0x00100000
+#define NUMICRO_CONFIG_BASE     0x00300000
+
+#define NUMICRO_CONFIG0         0x5000C000
+#define NUMICRO_CONFIG1         0x5000C004
+
+/* Command register bits */
+#define PWRCON_OSC22M         (1 << 2)
+#define PWRCON_XTL12M         (1 << 0)
+
+#define IPRSTC1_CPU_RST       (1 << 1)
+#define IPRSTC1_CHIP_RST      (1 << 0)
+
+#define AHBCLK_ISP_EN         (1 << 2)
+#define AHBCLK_SRAM_EN        (1 << 4)
+#define AHBCLK_TICK_EN        (1 << 5)
+
+#define ISPCON_ISPEN          (1 << 0)
+#define ISPCON_BS_AP          (0 << 1)
+#define ISPCON_BS_LP          (1 << 1)
+#define ISPCON_BS_MASK        (1 << 1)
+#define ISPCON_APUEN          (1 << 3)
+#define ISPCON_CFGUEN         (1 << 4)
+#define ISPCON_LDUEN          (1 << 5)
+#define ISPCON_ISPFF          (1 << 6)
+
+#define CONFIG0_LOCK_MASK        (1 << 1)
+
+/* isp commands */
+#define ISPCMD_READ           0x00
+#define ISPCMD_WRITE          0x21
+#define ISPCMD_ERASE          0x22
+#define ISPCMD_CHIPERASE      0x26   /* Undocumented isp "Chip-Erase" command */
+#define ISPCMD_READ_CID       0x0B
+#define ISPCMD_READ_DID       0x0C
+#define ISPCMD_READ_UID       0x04
+#define ISPCMD_VECMAP         0x2E
+#define ISPTRG_ISPGO          (1 << 0)
+
+/* access unlock keys */
+#define REG_KEY1              0x59
+#define REG_KEY2              0x16
+#define REG_KEY3              0x88
+#define REG_LOCK              0x00
+
+/* flash pagesizes */
+#define NUMICRO_PAGESIZE        512
+/* flash MAX banks */
+#define NUMICRO_MAX_FLASH_BANKS 4
+
+/* flash bank structs */
+struct numicro_flash_bank_type {
+       uint32_t base;
+       uint32_t size;
+};
+
+/* part structs */
+struct numicro_cpu_type {
+       char *partname;
+       uint32_t partid;
+       unsigned int n_banks;
+       struct numicro_flash_bank_type bank[NUMICRO_MAX_FLASH_BANKS];
+};
+
+/* TODO : Support variable DataFlash region for 128kB Flash model */
+#define NUMICRO_BANKS_NUC100(aprom_size) \
+       .n_banks = 4, \
+       { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_DATA_BASE, 4*1024}, {NUMICRO_LDROM_BASE, 4*1024}, \
+       {NUMICRO_CONFIG_BASE, 1024} }
+
+#define NUMICRO_BANKS_M051(aprom_size) \
+       .n_banks = 4, \
+       { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_DATA_BASE, 4*1024}, {NUMICRO_LDROM_BASE, 4*1024}, \
+       {NUMICRO_CONFIG_BASE, 1024} }
+
+#define NUMICRO_BANKS_MINI51(aprom_size) \
+       .n_banks = 3, \
+       { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_LDROM_BASE, 2*1024}, {NUMICRO_CONFIG_BASE, 512} }
+
+#define NUMICRO_BANKS_NANO(aprom_size) \
+       .n_banks = 4, \
+       { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_DATA_BASE, 4*1024}, {NUMICRO_LDROM_BASE, 4*1024}, \
+       {NUMICRO_CONFIG_BASE, 1024} }
+
+#define NUMICRO_BANKS_NUC400(aprom_size) \
+       .n_banks = 4, \
+       { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_DATA_BASE, 4*1024}, {NUMICRO_LDROM_BASE, 16*1024}, \
+       {NUMICRO_CONFIG_BASE, 1024} }
+
+
+static const struct numicro_cpu_type NuMicroParts[] = {
+       /*PART NO*/     /*PART ID*/ /*Banks*/
+       /* NUC100 Version B */
+       {"NUC100LD2BN", 0x10010004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100LD1BN", 0x10010005, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100LD0BN", 0x10010027, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100LC2BN", 0x10010007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100LC1BN", 0x10010008, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100LC0BN", 0x10010028, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100LB2BN", 0x10010029, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC100LB1BN", 0x10010030, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC100LB0BN", 0x10010031, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC100LA2BN", 0x10010032, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC100LA1BN", 0x10010033, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC100LA0BN", 0x10010034, NUMICRO_BANKS_NUC100(8*1024)},
+
+       {"NUC100RD2BN", 0x10010013, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100RD1BN", 0x10010014, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100RD0BN", 0x10010035, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100RC2BN", 0x10010016, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100RC1BN", 0x10010017, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100RC0BN", 0x10010036, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100RB2BN", 0x10010037, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC100RB1BN", 0x10010038, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC100RB0BN", 0x10010039, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC100RA2BN", 0x10010040, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC100RA1BN", 0x10010041, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC100RA0BN", 0x10010042, NUMICRO_BANKS_NUC100(8*1024)},
+
+    /* NUC100 Version C */
+       {"NUC100LE3CN", 0x20010000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100LE2CN", 0x20010001, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100LE1CN", 0x20010002, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100LD3CN", 0x20010003, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100LD2CN", 0x20010004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100LD1CN", 0x20010005, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100LC3CN", 0x20010006, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100LC2CN", 0x20010007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100LC1CN", 0x20010008, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100RE3CN", 0x20010009, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100RE2CN", 0x20010010, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100RE1CN", 0x20010011, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100RD3CN", 0x20010012, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100RD2CN", 0x20010013, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100RD1CN", 0x20010014, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100RC3CN", 0x20010015, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100RC2CN", 0x20010016, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100RC1CN", 0x20010017, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100VE3CN", 0x20010018, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100VE2CN", 0x20010019, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100VE1CN", 0x20010020, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100VD3CN", 0x20010021, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100VD2CN", 0x20010022, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100VD1CN", 0x20010023, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100VC3CN", 0x20010024, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100VC2CN", 0x20010025, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100VC1CN", 0x20010026, NUMICRO_BANKS_NUC100(32*1024)},
+
+    /* NUC100 Version B */
+       {"NUC101YD2BN", 0x10010143, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101YD1BN", 0x10010144, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101YD0BN", 0x10010145, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101YC2BN", 0x10010146, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101YC1BN", 0x10010147, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101YC0BN", 0x10010148, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101YB2BN", 0x10010149, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC101YB1BN", 0x10010150, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC101YB0BN", 0x10010151, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC101YA2BN", 0x10010152, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC101YA1BN", 0x10010153, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC101YA0BN", 0x10010154, NUMICRO_BANKS_NUC100(8*1024)},
+
+       {"NUC101LD2BN", 0x10010104, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101LD1BN", 0x10010105, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101LD0BN", 0x10010127, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101LC2BN", 0x10010107, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101LC1BN", 0x10010108, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101LC0BN", 0x10010128, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101LB2BN", 0x10010129, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC101LB1BN", 0x10010130, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC101LB0BN", 0x10010131, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC101LA2BN", 0x10010132, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC101LA1BN", 0x10010133, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC101LA0BN", 0x10010134, NUMICRO_BANKS_NUC100(8*1024)},
+
+       {"NUC101RD2BN", 0x10010113, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101RD1BN", 0x10010114, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101RD0BN", 0x10010135, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101RC2BN", 0x10010116, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101RC1BN", 0x10010117, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101RC0BN", 0x10010136, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101RB2BN", 0x10010137, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC101RB1BN", 0x10010138, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC101RB0BN", 0x10010139, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC101RA2BN", 0x10010140, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC101RA1BN", 0x10010141, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC101RA0BN", 0x10010142, NUMICRO_BANKS_NUC100(8*1024)},
+
+    /* NUC101 Version C */
+       {"NUC101LE3CN", 0x20010100, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101LE2CN", 0x20010101, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101LE1CN", 0x20010102, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101LD3CN", 0x20010103, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101LD2CN", 0x20010104, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101LD1CN", 0x20010105, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101LC3CN", 0x20010106, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101LC2CN", 0x20010107, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101LC1CN", 0x20010108, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101RE3CN", 0x20010109, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101RE2CN", 0x20010110, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101RE1CN", 0x20010111, NUMICRO_BANKS_NUC100(128*1024)},
+
+       {"NUC101RD3CN", 0x20010112, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101RD2CN", 0x20010113, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101RD1CN", 0x20010114, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101RC3CN", 0x20010115, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101RC2CN", 0x20010116, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101RC1CN", 0x20010117, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101VE3CN", 0x20010118, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101VE2CN", 0x20010119, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101VE1CN", 0x20010120, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101VD3CN", 0x20010121, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101VD2CN", 0x20010122, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101VD1CN", 0x20010123, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101VC3CN", 0x20010124, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101VC2CN", 0x20010125, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101VC1CN", 0x20010126, NUMICRO_BANKS_NUC100(32*1024)},
+
+    /* NUC102 Version A */
+       {"NUC102ZD2AN", 0x00010231, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC102ZC1AN", 0x00010235, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC102LD2AN", 0x00010204, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC102LC1AN", 0x00010208, NUMICRO_BANKS_NUC100(32*1024)},
+
+       {"NUC102RB3AN", 0x00010248, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC102RB2AN", 0x00010249, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC102RB1AN", 0x00010250, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC102RA3AN", 0x00010251, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC102RA2AN", 0x00010252, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC102RA1AN", 0x00010253, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC102VB3AN", 0x00010254, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC102VB2AN", 0x00010255, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC102VB1AN", 0x00010256, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC102VA3AN", 0x00010257, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC102VA2AN", 0x00010258, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC102VA1AN", 0x00010259, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC102LA0AN", 0x00010260, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC102LB0AN", 0x00010261, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC102LC0AN", 0x00010262, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC102LD0AN", 0x00010263, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC102RA0AN", 0x00010264, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC102RB0AN", 0x00010265, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC102RC0AN", 0x00010266, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC102RD0AN", 0x00010267, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC102VA0AN", 0x00010268, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC102VB0AN", 0x00010269, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC102VC0AN", 0x00010270, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC102VD0AN", 0x00010271, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC102ZA0AN", 0x00010272, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC102ZB0AN", 0x00010273, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC102ZC0AN", 0x00010274, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC102ZD0AN", 0x00010275, NUMICRO_BANKS_NUC100(64*1024)},
+
+    /* NUC102 Version A */
+       {"NUC122LD2AN", 0x00012204, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC122LD1AN", 0x00012205, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC122LC2AN", 0x00012207, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC122LC1AN", 0x00012208, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC122RD2AN", 0x00012213, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC122RD1AN", 0x00012214, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC122RC2AN", 0x00012216, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC122RC1AN", 0x00012217, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC122SD2AN", 0x00012222, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC122SD1AN", 0x00012223, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC122SC2AN", 0x00012225, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC122SC1AN", 0x00012226, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC122ZD2AN", 0x00012231, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC122ZD1AN", 0x00012232, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC122ZC2AN", 0x00012234, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC122ZC1AN", 0x00012235, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC122ZB2AN", 0x00012237, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC122ZB1AN", 0x00012238, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC122ZA2AN", 0x00012240, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC122ZA1AN", 0x00012241, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC122LB2AN", 0x00012243, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC122LB1AN", 0x00012244, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC122LA2AN", 0x00012246, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC122LA1AN", 0x00012247, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC122RB2AN", 0x00012249, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC122RB1AN", 0x00012250, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC122RA2AN", 0x00012252, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC122RA1AN", 0x00012253, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC122SB2AN", 0x00012255, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC122SB1AN", 0x00012256, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC122SA2AN", 0x00012258, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC122SA1AN", 0x00012259, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC122LA0AN", 0x00012260, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC122LB0AN", 0x00012261, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC122LC0AN", 0x00012262, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC122LD0AN", 0x00012263, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC122RA0AN", 0x00012264, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC122RB0AN", 0x00012265, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC122RC0AN", 0x00012266, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC122RD0AN", 0x00012267, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC122SA0AN", 0x00012268, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC122SB0AN", 0x00012269, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC122SC0AN", 0x00012270, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC122SD0AN", 0x00012271, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC122ZA0AN", 0x00012272, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC122ZB0AN", 0x00012273, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC122ZC0AN", 0x00012274, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC122ZD0AN", 0x00012275, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC122YD2AN", 0x00012277, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC122YD1AN", 0x00012278, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC122YD0AN", 0x00012279, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC122YC2AN", 0x00012281, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC122YC1AN", 0x00012282, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC122YC0AN", 0x00012283, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC122YB2AN", 0x00012285, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC122YB1AN", 0x00012286, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC122YB0AN", 0x00012287, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC122YA2AN", 0x00012289, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC122YA1AN", 0x00012290, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC122YA0AN", 0x00012291, NUMICRO_BANKS_NUC100(8*1024)},
+
+    /* NUC120 Version C */
+       {"NUC120LD2BN", 0x10012004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120LD1BN", 0x10012005, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120LD0BN", 0x10012027, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120LC2BN", 0x10012007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120LC1BN", 0x10012008, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120LC0BN", 0x10012028, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120LB2BN", 0x10012029, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC120LB1BN", 0x10012030, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC120LB0BN", 0x10012031, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC120LA2BN", 0x10012032, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC120LA1BN", 0x10012033, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC120LA0BN", 0x10012034, NUMICRO_BANKS_NUC100(8*1024)},
+
+       {"NUC120RD2BN", 0x10012013, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120RD1BN", 0x10012014, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120RD0BN", 0x10012035, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120RC2BN", 0x10012016, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120RC1BN", 0x10012017, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120RC0BN", 0x10012036, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120RB2BN", 0x10012037, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC120RB1BN", 0x10012038, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC120RB0BN", 0x10012039, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC120RA2BN", 0x10012040, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC120RA1BN", 0x10012041, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC120RA0BN", 0x10012042, NUMICRO_BANKS_NUC100(8*1024)},
+
+    /* NUC120 Version C */
+       {"NUC120LE3CN", 0x20012000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120LE2CN", 0x20012001, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120LE1CN", 0x20012002, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120LD3CN", 0x20012003, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120LD2CN", 0x20012004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120LD1CN", 0x20012005, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120LC3CN", 0x20012006, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120LC2CN", 0x20012007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120LC1CN", 0x20012008, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120RE3CN", 0x20012009, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120RE2CN", 0x20012010, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120RE1CN", 0x20012011, NUMICRO_BANKS_NUC100(128*1024)},
+
+       {"NUC120RD3CN", 0x20012012, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120RD2CN", 0x20012013, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120RD1CN", 0x20012014, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120RC3CN", 0x20012015, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120RC2CN", 0x20012016, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120RC1CN", 0x20012017, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120VE3CN", 0x20012018, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120VE2CN", 0x20012019, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120VE1CN", 0x20012020, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120VD3CN", 0x20012021, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120VD2CN", 0x20012022, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120VD1CN", 0x20012023, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120VC3CN", 0x20012024, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120VC2CN", 0x20012025, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120VC1CN", 0x20012026, NUMICRO_BANKS_NUC100(32*1024)},
+
+    /* NUC120 Version B */
+       {"NUC130LD2BN", 0x10013004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130LD1BN", 0x10013005, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130LD0BN", 0x10013027, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130LC2BN", 0x10013007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130LC1BN", 0x10013008, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130LC0BN", 0x10013028, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130LB2BN", 0x10013029, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC130LB1BN", 0x10013030, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC130LB0BN", 0x10013031, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC130LA2BN", 0x10013032, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC130LA1BN", 0x10013033, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC130LA0BN", 0x10013034, NUMICRO_BANKS_NUC100(8*1024)},
+
+       {"NUC130RD2BN", 0x10013013, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130RD1BN", 0x10013014, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130RD0BN", 0x10013035, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130RC2BN", 0x10013016, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130RC1BN", 0x10013017, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130RC0BN", 0x10013036, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130RB2BN", 0x10013037, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC130RB1BN", 0x10013038, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC130RB0BN", 0x10013039, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC130RA2BN", 0x10013040, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC130RA1BN", 0x10013041, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC130RA0BN", 0x10013042, NUMICRO_BANKS_NUC100(8*1024)},
+
+    /* NUC130 Version C */
+       {"NUC130LE3CN", 0x20013000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130LE2CN", 0x20013001, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130LE1CN", 0x20013002, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130LD3CN", 0x20013003, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130LD2CN", 0x20013004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130LD1CN", 0x20013005, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130LC3CN", 0x20013006, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130LC2CN", 0x20013007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130LC1CN", 0x20013008, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130RE3CN", 0x20013009, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130RE2CN", 0x20013010, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130RE1CN", 0x20013011, NUMICRO_BANKS_NUC100(128*1024)},
+
+       {"NUC130RD3CN", 0x20013012, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130RD2CN", 0x20013013, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130RD1CN", 0x20013014, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130RC3CN", 0x20013015, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130RC2CN", 0x20013016, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130RC1CN", 0x20013017, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130VE3CN", 0x20013018, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130VE2CN", 0x20013019, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130VE1CN", 0x20013020, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130VD3CN", 0x20013021, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130VD2CN", 0x20013022, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130VD1CN", 0x20013023, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130VC3CN", 0x20013024, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130VC2CN", 0x20013025, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130VC1CN", 0x20013026, NUMICRO_BANKS_NUC100(32*1024)},
+
+    /* NUC140 Version B */
+       {"NUC140LD2BN", 0x10014004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140LD1BN", 0x10014005, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140LD0BN", 0x10014027, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140LC2BN", 0x10014007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140LC1BN", 0x10014008, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140LC0BN", 0x10014028, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140LB2BN", 0x10014029, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC140LB1BN", 0x10014030, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC140LB0BN", 0x10014031, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC140LA2BN", 0x10014032, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC140LA1BN", 0x10014033, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC140LA0BN", 0x10014034, NUMICRO_BANKS_NUC100(8*1024)},
+
+       {"NUC140RD2BN", 0x10014013, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140RD1BN", 0x10014014, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140RD0BN", 0x10014035, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140RC2BN", 0x10014016, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140RC1BN", 0x10014017, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140RC0BN", 0x10014036, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140RB2BN", 0x10014037, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC140RB1BN", 0x10014038, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC140RB0BN", 0x10014039, NUMICRO_BANKS_NUC100(16*1024)},
+       {"NUC140RA2BN", 0x10014040, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC140RA1BN", 0x10014041, NUMICRO_BANKS_NUC100(8*1024)},
+       {"NUC140RA0BN", 0x10014042, NUMICRO_BANKS_NUC100(8*1024)},
+
+    /* NUC140 Version C */
+       {"NUC140LE3CN", 0x20014000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140LE2CN", 0x20014001, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140LE1CN", 0x20014002, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140LD3CN", 0x20014003, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140LD2CN", 0x20014004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140LD1CN", 0x20014005, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140LC3CN", 0x20014006, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140LC2CN", 0x20014007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140LC1CN", 0x20014008, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140RE3CN", 0x20014009, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140RE2CN", 0x20014010, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140RE1CN", 0x20014011, NUMICRO_BANKS_NUC100(128*1024)},
+
+       {"NUC140RD3CN", 0x20014012, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140RD2CN", 0x20014013, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140RD1CN", 0x20014014, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140RC3CN", 0x20014015, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140RC2CN", 0x20014016, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140RC1CN", 0x20014017, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140VE3CN", 0x20014018, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140VE2CN", 0x20014019, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140VE1CN", 0x20014020, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140VD3CN", 0x20014021, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140VD2CN", 0x20014022, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140VD1CN", 0x20014023, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140VC3CN", 0x20014024, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140VC2CN", 0x20014025, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140VC1CN", 0x20014026, NUMICRO_BANKS_NUC100(32*1024)},
+
+    /* NUC100 Version A */
+       {"NUC100LE3AN", 0x00010000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100LE2AN", 0x00010001, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100LE1AN", 0x00010002, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100LD3AN", 0x00010003, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100LD2AN", 0x00010004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100LD1AN", 0x00010005, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100LC3AN", 0x00010006, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100LC2AN", 0x00010007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100LC1AN", 0x00010008, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100RE3AN", 0x00010009, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100RE2AN", 0x00010010, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100RE1AN", 0x00010011, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100RD3AN", 0x00010012, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100RD2AN", 0x00010013, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100RD1AN", 0x00010014, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100RC3AN", 0x00010015, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100RC2AN", 0x00010016, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100RC1AN", 0x00010017, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100VE3AN", 0x00010018, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100VE2AN", 0x00010019, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100VE1AN", 0x00010020, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100VD3AN", 0x00010021, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100VD2AN", 0x00010022, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100VD1AN", 0x00010023, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100VC3AN", 0x00010024, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100VC2AN", 0x00010025, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100VC1AN", 0x00010026, NUMICRO_BANKS_NUC100(32*1024)},
+
+    /* NUC100 Version A */
+       {"NUC101LE3AN", 0x00010100, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101LE2AN", 0x00010101, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101LE1AN", 0x00010102, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101LD3AN", 0x00010103, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101LD2AN", 0x00010104, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101LD1AN", 0x00010105, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101LC3AN", 0x00010106, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101LC2AN", 0x00010107, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101LC1AN", 0x00010108, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101RE3AN", 0x00010109, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101RE2AN", 0x00010110, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101RE1AN", 0x00010111, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101RD3AN", 0x00010112, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101RD2AN", 0x00010113, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101RD1AN", 0x00010114, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101RC3AN", 0x00010115, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101RC2AN", 0x00010116, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101RC1AN", 0x00010117, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101VE3AN", 0x00010118, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101VE2AN", 0x00010119, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101VE1AN", 0x00010120, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC101VD3AN", 0x00010121, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101VD2AN", 0x00010122, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101VD1AN", 0x00010123, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC101VC3AN", 0x00010124, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101VC2AN", 0x00010125, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC101VC1AN", 0x00010126, NUMICRO_BANKS_NUC100(32*1024)},
+
+    /* NUC120 Version A */
+       {"NUC120LE3AN", 0x00012000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120LE2AN", 0x00012001, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120LE1AN", 0x00012002, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120LD3AN", 0x00012003, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120LD2AN", 0x00012004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120LD1AN", 0x00012005, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120LC3AN", 0x00012006, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120LC2AN", 0x00012007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120LC1AN", 0x00012008, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120RE3AN", 0x00012009, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120RE2AN", 0x00012010, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120RE1AN", 0x00012011, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120RD3AN", 0x00012012, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120RD2AN", 0x00012013, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120RD1AN", 0x00012014, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120RC3AN", 0x00012015, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120RC2AN", 0x00012016, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120RC1AN", 0x00012017, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120VE3AN", 0x00012018, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120VE2AN", 0x00012019, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120VE1AN", 0x00012020, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120VD3AN", 0x00012021, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120VD2AN", 0x00012022, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120VD1AN", 0x00012023, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120VC3AN", 0x00012024, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120VC2AN", 0x00012025, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120VC1AN", 0x00012026, NUMICRO_BANKS_NUC100(32*1024)},
+
+    /* NUC120 Version A */
+       {"NUC130LE3AN", 0x00013000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130LE2AN", 0x00013001, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130LE1AN", 0x00013002, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130LD3AN", 0x00013003, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130LD2AN", 0x00013004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130LD1AN", 0x00013005, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130LC3AN", 0x00013006, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130LC2AN", 0x00013007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130LC1AN", 0x00013008, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130RE3AN", 0x00013009, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130RE2AN", 0x00013010, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130RE1AN", 0x00013011, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130RD3AN", 0x00013012, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130RD2AN", 0x00013013, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130RD1AN", 0x00013014, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130RC3AN", 0x00013015, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130RC2AN", 0x00013016, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130RC1AN", 0x00013017, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130VE3AN", 0x00013018, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130VE2AN", 0x00013019, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130VE1AN", 0x00013020, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130VD3AN", 0x00013021, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130VD2AN", 0x00013022, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130VD1AN", 0x00013023, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC130VC3AN", 0x00013024, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130VC2AN", 0x00013025, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC130VC1AN", 0x00013026, NUMICRO_BANKS_NUC100(32*1024)},
+
+    /* NUC140 Version A */
+       {"NUC140LE3AN", 0x00014000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140LE2AN", 0x00014001, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140LE1AN", 0x00014002, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140LD3AN", 0x00014003, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140LD2AN", 0x00014004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140LD1AN", 0x00014005, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140LC3AN", 0x00014006, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140LC2AN", 0x00014007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140LC1AN", 0x00014008, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140RE3AN", 0x00014009, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140RE2AN", 0x00014010, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140RE1AN", 0x00014011, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140RD3AN", 0x00014012, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140RD2AN", 0x00014013, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140RD1AN", 0x00014014, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140RC3AN", 0x00014015, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140RC2AN", 0x00014016, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140RC1AN", 0x00014017, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140VE3AN", 0x00014018, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140VE2AN", 0x00014019, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140VE1AN", 0x00014020, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC140VD3AN", 0x00014021, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140VD2AN", 0x00014022, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140VD1AN", 0x00014023, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC140VC3AN", 0x00014024, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140VC2AN", 0x00014025, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC140VC1AN", 0x00014026, NUMICRO_BANKS_NUC100(32*1024)},
+
+
+       /* M052 */
+       {"M052LAN"  , 0x00005200, NUMICRO_BANKS_M051(8*1024)},
+       {"M052PAN"  , 0x00005201, NUMICRO_BANKS_M051(8*1024)},
+       {"M052YAN"  , 0x00005202, NUMICRO_BANKS_M051(8*1024)},
+       {"M052ZAN"  , 0x00005203, NUMICRO_BANKS_M051(8*1024)},
+
+    /* M054 */
+       {"M054LAN"  , 0x00005400, NUMICRO_BANKS_M051(16*1024)},
+       {"M054PAN"  , 0x00005401, NUMICRO_BANKS_M051(16*1024)},
+       {"M054YAN"  , 0x00005402, NUMICRO_BANKS_M051(16*1024)},
+       {"M054ZAN"  , 0x00005403, NUMICRO_BANKS_M051(16*1024)},
+
+    /* M058 */
+       {"M058LAN"  , 0x00005800, NUMICRO_BANKS_M051(32*1024)},
+       {"M058PAN"  , 0x00005801, NUMICRO_BANKS_M051(32*1024)},
+       {"M058YAN"  , 0x00005802, NUMICRO_BANKS_M051(32*1024)},
+       {"M058ZAN"  , 0x00005803, NUMICRO_BANKS_M051(32*1024)},
+
+    /* M0516 */
+       {"M0516LAN" , 0x00005A00, NUMICRO_BANKS_M051(64*1024)},
+       {"M0516PAN" , 0x00005A01, NUMICRO_BANKS_M051(64*1024)},
+       {"M0516YAN" , 0x00005A02, NUMICRO_BANKS_M051(64*1024)},
+       {"M0516ZAN" , 0x00005A03, NUMICRO_BANKS_M051(64*1024)},
+       {"M051LBN"  , 0x10005100, NUMICRO_BANKS_M051(4*1024)},
+       {"M051PBN"  , 0x10005101, NUMICRO_BANKS_M051(4*1024)},
+       {"M051YBN"  , 0x10005102, NUMICRO_BANKS_M051(4*1024)},
+       {"M051ZBN"  , 0x10005103, NUMICRO_BANKS_M051(4*1024)},
+       {"M052LBN"  , 0x10005200, NUMICRO_BANKS_M051(8*1024)},
+       {"M052PBN"  , 0x10005201, NUMICRO_BANKS_M051(8*1024)},
+       {"M052YBN"  , 0x10005202, NUMICRO_BANKS_M051(8*1024)},
+       {"M052ZBN"  , 0x10005203, NUMICRO_BANKS_M051(8*1024)},
+       {"M054LBN"  , 0x10005400, NUMICRO_BANKS_M051(16*1024)},
+       {"M054PBN"  , 0x10005401, NUMICRO_BANKS_M051(16*1024)},
+       {"M054YBN"  , 0x10005402, NUMICRO_BANKS_M051(16*1024)},
+       {"M054ZBN"  , 0x10005403, NUMICRO_BANKS_M051(16*1024)},
+       {"M058LBN"  , 0x10005800, NUMICRO_BANKS_M051(32*1024)},
+       {"M058PBN"  , 0x10005801, NUMICRO_BANKS_M051(32*1024)},
+       {"M058YBN"  , 0x10005802, NUMICRO_BANKS_M051(32*1024)},
+       {"M058ZBN"  , 0x10005803, NUMICRO_BANKS_M051(32*1024)},
+       {"M0516LBN" , 0x10005A00, NUMICRO_BANKS_M051(64*1024)},
+       {"M0516PBN" , 0x10005A01, NUMICRO_BANKS_M051(64*1024)},
+       {"M0516YBN" , 0x10005A02, NUMICRO_BANKS_M051(64*1024)},
+       {"M0516ZBN" , 0x10005A03, NUMICRO_BANKS_M051(64*1024)},
+       {"M052LDN"  , 0x20005200, NUMICRO_BANKS_M051(8*1024)},
+       {"M054LDN"  , 0x20005400, NUMICRO_BANKS_M051(16*1024)},
+       {"M058LDN"  , 0x20005800, NUMICRO_BANKS_M051(32*1024)},
+       {"M0516LDN" , 0x20005A00, NUMICRO_BANKS_M051(64*1024)},
+       {"M052ZDN"  , 0x20005203, NUMICRO_BANKS_M051(8*1024)},
+       {"M054ZDN"  , 0x20005403, NUMICRO_BANKS_M051(16*1024)},
+       {"M058ZDN"  , 0x20005803, NUMICRO_BANKS_M051(32*1024)},
+       {"M0516ZDN" , 0x20005A03, NUMICRO_BANKS_M051(64*1024)},
+       {"M052TDN"  , 0x20005204, NUMICRO_BANKS_M051(8*1024)},
+       {"M054TDN"  , 0x20005404, NUMICRO_BANKS_M051(16*1024)},
+       {"M058TDN"  , 0x20005804, NUMICRO_BANKS_M051(32*1024)},
+       {"M0516TDN" , 0x20005A04, NUMICRO_BANKS_M051(64*1024)},
+       {"M052XDN"  , 0x20005205, NUMICRO_BANKS_M051(8*1024)},
+       {"M054XDN"  , 0x20005405, NUMICRO_BANKS_M051(16*1024)},
+       {"M058XDN"  , 0x20005805, NUMICRO_BANKS_M051(32*1024)},
+       {"M0516XDN" , 0x20005A05, NUMICRO_BANKS_M051(64*1024)},
+       {"M052LDE"  , 0x30005200, NUMICRO_BANKS_M051(8*1024)},
+       {"M054LDE"  , 0x30005400, NUMICRO_BANKS_M051(16*1024)},
+       {"M058LDE"  , 0x30005800, NUMICRO_BANKS_M051(32*1024)},
+       {"M0516LDE" , 0x30005A00, NUMICRO_BANKS_M051(64*1024)},
+       {"M052ZDE"  , 0x30005203, NUMICRO_BANKS_M051(8*1024)},
+       {"M054ZDE"  , 0x30005403, NUMICRO_BANKS_M051(16*1024)},
+       {"M058ZDE"  , 0x30005803, NUMICRO_BANKS_M051(32*1024)},
+       {"M0516ZDE" , 0x30005A03, NUMICRO_BANKS_M051(64*1024)},
+       {"M052TDE"  , 0x30005204, NUMICRO_BANKS_M051(8*1024)},
+       {"M054TDE"  , 0x30005404, NUMICRO_BANKS_M051(16*1024)},
+       {"M058TDE"  , 0x30005804, NUMICRO_BANKS_M051(32*1024)},
+       {"M0516TDE" , 0x30005A04, NUMICRO_BANKS_M051(64*1024)},
+       {"M052XDE"  , 0x30005205, NUMICRO_BANKS_M051(8*1024)},
+       {"M054XDE"  , 0x30005405, NUMICRO_BANKS_M051(16*1024)},
+       {"M058XDE"  , 0x30005805, NUMICRO_BANKS_M051(32*1024)},
+       {"M0516XDE" , 0x30005A05, NUMICRO_BANKS_M051(64*1024)},
+
+       /* Mini51 */
+       {"MINI51LAN",  0x00205100, NUMICRO_BANKS_MINI51(4*1024)},
+       {"MINI51QAN",  0x00205101, NUMICRO_BANKS_MINI51(4*1024)},
+       {"MINI51   ",  0x00205102, NUMICRO_BANKS_MINI51(4*1024)},
+       {"MINI51ZAN",  0x00205103, NUMICRO_BANKS_MINI51(4*1024)},
+       {"MINI51TAN",  0x00205104, NUMICRO_BANKS_MINI51(4*1024)},
+       {"MINI52LAN",  0x00205200, NUMICRO_BANKS_MINI51(8*1024)},
+       {"MINI52QAN",  0x00205201, NUMICRO_BANKS_MINI51(8*1024)},
+       {"MINI52   ",  0x00205202, NUMICRO_BANKS_MINI51(8*1024)},
+       {"MINI52ZAN",  0x00205203, NUMICRO_BANKS_MINI51(8*1024)},
+       {"MINI52TAN",  0x00205204, NUMICRO_BANKS_MINI51(8*1024)},
+       {"MINI54LAN",  0x00205400, NUMICRO_BANKS_MINI51(16*1024)},
+       {"MINI54QAN",  0x00205401, NUMICRO_BANKS_MINI51(16*1024)},
+       {"MINI54   ",  0x00205402, NUMICRO_BANKS_MINI51(16*1024)},
+       {"MINI54ZAN",  0x00205403, NUMICRO_BANKS_MINI51(16*1024)},
+       {"MINI54TAN",  0x00205404, NUMICRO_BANKS_MINI51(16*1024)},
+       {"MINI51LBN",  0x10205100, NUMICRO_BANKS_MINI51(4*1024)},
+       {"MINI51QBN",  0x10205101, NUMICRO_BANKS_MINI51(4*1024)},
+       {"MINI51   ",  0x10205102, NUMICRO_BANKS_MINI51(4*1024)},
+       {"MINI51ZBN",  0x10205103, NUMICRO_BANKS_MINI51(4*1024)},
+       {"MINI51TBN",  0x10205104, NUMICRO_BANKS_MINI51(4*1024)},
+       {"MINI52LBN",  0x10205200, NUMICRO_BANKS_MINI51(8*1024)},
+       {"MINI52QBN",  0x10205201, NUMICRO_BANKS_MINI51(8*1024)},
+       {"MINI52   ",  0x10205202, NUMICRO_BANKS_MINI51(8*1024)},
+       {"MINI52ZBN",  0x10205203, NUMICRO_BANKS_MINI51(8*1024)},
+       {"MINI52TBN",  0x10205204, NUMICRO_BANKS_MINI51(8*1024)},
+       {"MINI54LBN",  0x10205400, NUMICRO_BANKS_MINI51(16*1024)},
+       {"MINI54QBN",  0x10205401, NUMICRO_BANKS_MINI51(16*1024)},
+       {"MINI54   ",  0x10205402, NUMICRO_BANKS_MINI51(16*1024)},
+       {"MINI54ZBN" , 0x10205403, NUMICRO_BANKS_MINI51(16*1024)},
+       {"MINI54TBN" , 0x10205404, NUMICRO_BANKS_MINI51(16*1024)},
+       {"MINI51LDE" , 0x20205100, NUMICRO_BANKS_MINI51(4*1024)},
+       {"MINI51QDE" , 0x20205101, NUMICRO_BANKS_MINI51(4*1024)},
+       {"MINI51   " , 0x20205102, NUMICRO_BANKS_MINI51(4*1024)},
+       {"MINI51ZDE" , 0x20205103, NUMICRO_BANKS_MINI51(4*1024)},
+       {"MINI51TDE" , 0x20205104, NUMICRO_BANKS_MINI51(4*1024)},
+       {"MINI51FDE" , 0x20205105, NUMICRO_BANKS_MINI51(4*1024)},
+       {"MINI52LDE" , 0x20205200, NUMICRO_BANKS_MINI51(8*1024)},
+       {"MINI52QDE" , 0x20205201, NUMICRO_BANKS_MINI51(8*1024)},
+       {"MINI52   " , 0x20205202, NUMICRO_BANKS_MINI51(8*1024)},
+       {"MINI52ZDE" , 0x20205203, NUMICRO_BANKS_MINI51(8*1024)},
+       {"MINI52TDE" , 0x20205204, NUMICRO_BANKS_MINI51(8*1024)},
+       {"MINI52FDE" , 0x20205205, NUMICRO_BANKS_MINI51(8*1024)},
+       {"MINI54LDE" , 0x20205400, NUMICRO_BANKS_MINI51(16*1024)},
+       {"MINI54QDE" , 0x20205401, NUMICRO_BANKS_MINI51(16*1024)},
+       {"MINI54   " , 0x20205402, NUMICRO_BANKS_MINI51(16*1024)},
+       {"MINI54ZDE" , 0x20205403, NUMICRO_BANKS_MINI51(16*1024)},
+       {"MINI54TDE" , 0x20205404, NUMICRO_BANKS_MINI51(16*1024)},
+       {"MINI54FDE" , 0x20205405, NUMICRO_BANKS_MINI51(16*1024)},
+       {"MINI55LDE" , 0x20205500, NUMICRO_BANKS_MINI51(16*1024)},
+
+       /* NANO100 */
+       {"NANO100VF3AN" , 0x00110000, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO100VF2AN" , 0x00110001, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO100RF3AN" , 0x00110002, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO100RF2AN" , 0x00110003, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO100LF3AN" , 0x00110004, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO100LF2AN" , 0x00110005, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO100VE3AN" , 0x00110006, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO100VE2AN" , 0x00110007, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO100RE3AN" , 0x00110008, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO100RE2AN" , 0x00110009, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO100LE3AN" , 0x00110010, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO100LE2AN" , 0x00110011, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO100VD3AN" , 0x00110012, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100VD2AN" , 0x00110013, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100VD1AN" , 0x00110014, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100RD3AN" , 0x00110015, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100RD2AN" , 0x00110016, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100RD1AN" , 0x00110017, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100LD3AN" , 0x00110018, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100LD2AN" , 0x00110019, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100LD1AN" , 0x00110020, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100VC2AN" , 0x00110021, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO100VC1AN" , 0x00110022, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO100RC2AN" , 0x00110023, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO100RC1AN" , 0x00110024, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO100LC2AN" , 0x00110025, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO100LC1AN" , 0x00110026, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO100VB1AN" , 0x00110027, NUMICRO_BANKS_NANO(16*1024)},
+       {"NANO100VB0AN" , 0x00110028, NUMICRO_BANKS_NANO(16*1024)},
+       {"NANO100RB1AN" , 0x00110029, NUMICRO_BANKS_NANO(16*1024)},
+
+       {"NANO110VF3AN" , 0x00111000, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO110VF2AN" , 0x00111001, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO110RF3AN" , 0x00111002, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO110RF2AN" , 0x00111003, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO110VE3AN" , 0x00111006, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO110VE2AN" , 0x00111007, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO110RE3AN" , 0x00111008, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO110RE2AN" , 0x00111009, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO110VD3AN" , 0x00111012, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO110VD2AN" , 0x00111013, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO110VD1AN" , 0x00111014, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO110RD3AN" , 0x00111015, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO110RD2AN" , 0x00111016, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO110RD1AN" , 0x00111017, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO110VC2AN" , 0x00111021, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO110VC1AN" , 0x00111022, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO110SC2AN" , 0x00111023, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO110SC1AN" , 0x00111024, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO120VF3AN" , 0x00112000, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO120VF2AN" , 0x00112001, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO120RF3AN" , 0x00112002, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO120RF2AN" , 0x00112003, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO120LF3AN" , 0x00112004, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO120LF2AN" , 0x00112005, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO120VE3AN" , 0x00112006, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO120VE2AN" , 0x00112007, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO120RE3AN" , 0x00112008, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO120RE2AN" , 0x00112009, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO120LE3AN" , 0x00112010, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO120LE2AN" , 0x00112011, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO120VD3AN" , 0x00112012, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120VD2AN" , 0x00112013, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120VD1AN" , 0x00112014, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120SD3AN" , 0x00112015, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120SD2AN" , 0x00112016, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120SD1AN" , 0x00112017, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120LD3AN" , 0x00112018, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120LD2AN" , 0x00112019, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120LD1AN" , 0x00112020, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120VC2AN" , 0x00112021, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO120VC1AN" , 0x00112022, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO120SC2AN" , 0x00112023, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO120SC1AN" , 0x00112024, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO120LC2AN" , 0x00112025, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO120LC1AN" , 0x00112026, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO130VF3AN" , 0x00113000, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO130VF2AN" , 0x00113001, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO130SF3AN" , 0x00113002, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO130SF2AN" , 0x00113003, NUMICRO_BANKS_NANO(256*1024)},
+       {"NANO130VE3AN" , 0x00113006, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO130VE2AN" , 0x00113007, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO130SE3AN" , 0x00113008, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO130SE2AN" , 0x00113009, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO130VD3AN" , 0x00113012, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO130VD2AN" , 0x00113013, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO130VD1AN" , 0x00113014, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO130SD3AN" , 0x00113015, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO130SD2AN" , 0x00113016, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO130SD1AN" , 0x00113017, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO130VC2AN" , 0x00113021, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO130VC1AN" , 0x00113022, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO130SC2AN" , 0x00113023, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO130SC1AN" , 0x00113024, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO100KE3BN" , 0x00110030, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO100KE2BN" , 0x00110031, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO100VE3BN" , 0x00110032, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO100VE2BN" , 0x00110033, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO100SE3BN" , 0x00110034, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO100SE2BN" , 0x00110035, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO100LE3BN" , 0x00110036, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO100LE2BN" , 0x00110037, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO100KD3BN" , 0x00110038, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100KD2BN" , 0x00110039, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100VD3BN" , 0x0011003A, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100VD2BN" , 0x0011003B, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100SD3BN" , 0x0011003C, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100SD2BN" , 0x0011003D, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100LD3BN" , 0x0011003E, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100LD2BN" , 0x0011003F, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO100KC2BN" , 0x00110040, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO100VC2BN" , 0x00110041, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO100SC2BN" , 0x00110042, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO100LC2BN" , 0x00110043, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO110KE3BN" , 0x00111030, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO110KE2BN" , 0x00111031, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO110VE3BN" , 0x00111032, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO110VE2BN" , 0x00111033, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO110SE3BN" , 0x00111034, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO110SE2BN" , 0x00111035, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO110KD3BN" , 0x00111038, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO110KD2BN" , 0x00111039, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO110VD3BN" , 0x0011103A, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO110VD2BN" , 0x0011103B, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO110SD3BN" , 0x0011103C, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO110SD2BN" , 0x0011103D, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO110KC2BN" , 0x00111040, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO110VC2BN" , 0x00111041, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO110SC2BN" , 0x00111042, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO120KE3BN" , 0x00112030, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO120KE2BN" , 0x00112031, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO120VE3BN" , 0x00112032, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO120VE2BN" , 0x00112033, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO120SE3BN" , 0x00112034, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO120SE2BN" , 0x00112035, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO120LE3BN" , 0x00112036, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO120LE2BN" , 0x00112037, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO120KD3BN" , 0x00112038, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120KD2BN" , 0x00112039, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120VD3BN" , 0x0011203A, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120VD2BN" , 0x0011203B, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120SD3BN" , 0x0011203C, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120SD2BN" , 0x0011203D, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120LD3BN" , 0x0011203E, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120LD2BN" , 0x0011203F, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO120KC2BN" , 0x00112040, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO120VC2BN" , 0x00112041, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO120SC2BN" , 0x00112042, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO120LC2BN" , 0x00112043, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO130KE3BN" , 0x00113030, NUMICRO_BANKS_NANO(123*1024)},
+       {"NANO130KE2BN" , 0x00113031, NUMICRO_BANKS_NANO(123*1024)},
+       {"NANO130VE3BN" , 0x00113032, NUMICRO_BANKS_NANO(123*1024)},
+       {"NANO130VE2BN" , 0x00113033, NUMICRO_BANKS_NANO(123*1024)},
+       {"NANO130SE3BN" , 0x00113034, NUMICRO_BANKS_NANO(123*1024)},
+       {"NANO130SE2BN" , 0x00113035, NUMICRO_BANKS_NANO(123*1024)},
+       {"NANO130KD3BN" , 0x00113038, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO130KD2BN" , 0x00113039, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO130VD3BN" , 0x0011303A, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO130VD2BN" , 0x0011303B, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO130SD3BN" , 0x0011303C, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO130SD2BN" , 0x0011303D, NUMICRO_BANKS_NANO(64*1024)},
+       {"NANO130KC2BN" , 0x00113040, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO130VC2BN" , 0x00113041, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO130SC2BN" , 0x00113042, NUMICRO_BANKS_NANO(32*1024)},
+       {"N512DC4"      , 0x00100000, NUMICRO_BANKS_NANO(64*1024)},
+       {"N512LC4"      , 0x00100001, NUMICRO_BANKS_NANO(64*1024)},
+       {"N512MC4"      , 0x00100003, NUMICRO_BANKS_NANO(64*1024)},
+
+       {"N512SC4"      , 0x00100005, NUMICRO_BANKS_NANO(64*1024)},
+       {"N512VD4"      , 0x00100008, NUMICRO_BANKS_NANO(128*1024)},
+       {"N512MD4"      , 0x00100009, NUMICRO_BANKS_NANO(128*1024)},
+       {"N512SD4"      , 0x00100010, NUMICRO_BANKS_NANO(128*1024)},
+       {"NANO110RC2BN" , 0x00111043, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO110RD3BN" , 0x00111045, NUMICRO_BANKS_NANO(64*1024)},
+       {"TX110VE3BN"   , 0x00111036, NUMICRO_BANKS_NANO(128*1024)},
+
+       /* NANO102/NANO112 */
+       {"NANO112LB0AN" , 0x00111201, NUMICRO_BANKS_NANO(16*1024)},
+       {"NANO112LB1AN" , 0x00111202, NUMICRO_BANKS_NANO(16*1024)},
+       {"NANO112LC1AN" , 0x00111203, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO112LC2AN" , 0x00111204, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO112SB0AN" , 0x00111205, NUMICRO_BANKS_NANO(16*1024)},
+       {"NANO112SB1AN" , 0x00111206, NUMICRO_BANKS_NANO(16*1024)},
+       {"NANO112SC1AN" , 0x00111207, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO112SC2AN" , 0x00111208, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO112RB0AN" , 0x00111209, NUMICRO_BANKS_NANO(16*1024)},
+       {"NANO112RB1AN" , 0x00111210, NUMICRO_BANKS_NANO(16*1024)},
+       {"NANO112RC1AN" , 0x00111211, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO112RC2AN" , 0x00111212, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO112VB0AN" , 0x00111213, NUMICRO_BANKS_NANO(16*1024)},
+       {"NANO112VB1AN" , 0x00111214, NUMICRO_BANKS_NANO(16*1024)},
+       {"NANO112VC1AN" , 0x00111215, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO112VC2AN" , 0x00111216, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO102ZB0AN" , 0x00110201, NUMICRO_BANKS_NANO(16*1024)},
+       {"NANO102ZB1AN" , 0x00110202, NUMICRO_BANKS_NANO(16*1024)},
+       {"NANO102ZC1AN" , 0x00110203, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO102ZC2AN" , 0x00110204, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO102LB0AN" , 0x00110205, NUMICRO_BANKS_NANO(16*1024)},
+       {"NANO102LB1AN" , 0x00110206, NUMICRO_BANKS_NANO(16*1024)},
+       {"NANO102LC1AN" , 0x00110207, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO102LC2AN" , 0x00110208, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO102SB0AN" , 0x00110209, NUMICRO_BANKS_NANO(16*1024)},
+       {"NANO102SB1AN" , 0x00110210, NUMICRO_BANKS_NANO(16*1024)},
+       {"NANO102SC1AN" , 0x00110211, NUMICRO_BANKS_NANO(32*1024)},
+       {"NANO102SC2AN" , 0x00110212, NUMICRO_BANKS_NANO(32*1024)},
+
+       /* NUC103/NUC105/NUC123 */
+       {"NUC123SC2AN" , 0x00012305, NUMICRO_BANKS_NUC100(36*1024)},
+       {"NUC123SD4AN" , 0x00012315, NUMICRO_BANKS_NUC100(68*1024)},
+       {"NUC123LC2AN" , 0x00012325, NUMICRO_BANKS_NUC100(36*1024)},
+       {"NUC103LC2AN" , 0x00010325, NUMICRO_BANKS_NUC100(36*1024)},
+       {"NUC105LC2AN" , 0x00010525, NUMICRO_BANKS_NUC100(36*1024)},
+       {"NUC123LD4AN" , 0x00012335, NUMICRO_BANKS_NUC100(68*1024)},
+       {"NUC103LD4AN" , 0x00010335, NUMICRO_BANKS_NUC100(68*1024)},
+       {"NUC105LD4AN" , 0x00010535, NUMICRO_BANKS_NUC100(68*1024)},
+       {"NUC123ZC2AN" , 0x00012345, NUMICRO_BANKS_NUC100(36*1024)},
+       {"NUC103ZC2AN" , 0x00010345, NUMICRO_BANKS_NUC100(36*1024)},
+       {"NUC105ZC2AN" , 0x00010545, NUMICRO_BANKS_NUC100(36*1024)},
+       {"NUC123ZD4AN" , 0x00012355, NUMICRO_BANKS_NUC100(68*1024)},
+       {"NUC103ZD4AN" , 0x00010355, NUMICRO_BANKS_NUC100(68*1024)},
+       {"NUC105ZD4AN" , 0x00010555, NUMICRO_BANKS_NUC100(68*1024)},
+
+       /* NUC200 */
+       {"NUC200LC2AN" , 0x00020007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC200LD2AN" , 0x00020004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC200LE3AN" , 0x00020000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC200SC1AN" , 0x00020035, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC200SD2AN" , 0x00020031, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC200SE3AN" , 0x00020027, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC200VE3AN" , 0x00020018, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC220LC2AN" , 0x00022007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC220LD2AN" , 0x00022004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC220LE3AN" , 0x00022000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC220SC1AN" , 0x00022035, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC220SD2AN" , 0x00022031, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC220SE3AN" , 0x00022027, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC220VE3AN" , 0x00022018, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC230LC2AN" , 0x00023007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC230LD2AN" , 0x00023004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC230LE3AN" , 0x00023000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC230SC1AN" , 0x00023035, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC230SD2AN" , 0x00023031, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC230SE3AN" , 0x00023027, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC230VE3AN" , 0x00023018, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC240LC2AN" , 0x00024007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC240LD2AN" , 0x00024004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC240LE3AN" , 0x00024000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC240SC1AN" , 0x00024035, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC240SD2AN" , 0x00024031, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC240SE3AN" , 0x00024027, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC240VE3AN" , 0x00024018, NUMICRO_BANKS_NUC100(128*1024)},
+
+       /* NUC200 NUC2XXAE */
+       {"NUC230RC1AE" , 0x40013017, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC200LC2AE" , 0x10020007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC200LD2AE" , 0x10020004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC200LE3AE" , 0x10020000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC200SC2AE" , 0x10020034, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC200SD2AE" , 0x10020031, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC200SE3AE" , 0x10020027, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC200VE3AE" , 0x10020018, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC230LC2AE" , 0x10023007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC230LD2AE" , 0x10023004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC230LE3AE" , 0x10023000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC230SC2AE" , 0x10023034, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC230SD2AE" , 0x10023031, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC230SE3AE" , 0x10023027, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC230VE3AE" , 0x10023018, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC240LC2AE" , 0x10024007, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC240LD2AE" , 0x10024004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC240LE3AE" , 0x10024000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC240SC2AE" , 0x10024034, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC240SD2AE" , 0x10024031, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC240SE3AE" , 0x10024027, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC240VE3AE" , 0x10024018, NUMICRO_BANKS_NUC100(128*1024)},
+
+       /* NUC100 Version D */
+       {"NUC100LC1DN" , 0x30010008, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100LD1DN" , 0x30010005, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100LD2DN" , 0x30010004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100RC1DN" , 0x30010017, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC100RD1DN" , 0x30010014, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100RD2DN" , 0x30010013, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100LD3DN" , 0x30010003, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100LE3DN" , 0x30010000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100RD3DN" , 0x30010012, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100RE3DN" , 0x30010009, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC100VD2DN" , 0x30010022, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100VD3DN" , 0x30010021, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC100VE3DN" , 0x30010018, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120LC1DN" , 0x30012008, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120LD1DN" , 0x30012005, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120LD2DN" , 0x30012004, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120RC1DN" , 0x30012017, NUMICRO_BANKS_NUC100(32*1024)},
+       {"NUC120RD1DN" , 0x30012014, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120RD2DN" , 0x30012013, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120LD3DN" , 0x30012003, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120LE3DN" , 0x30012000, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120RD3DN" , 0x30012012, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120RE3DN" , 0x30012009, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC120VD2DN" , 0x30012022, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120VD3DN" , 0x30012021, NUMICRO_BANKS_NUC100(64*1024)},
+       {"NUC120VE3DN" , 0x30012018, NUMICRO_BANKS_NUC100(128*1024)},
+       {"NUC130RC1DN" , 0x30013017, NUMICRO_BANKS_NUC100(32*1024)},
+
+       {"UNKNOWN"     , 0x00000000, NUMICRO_BANKS_NUC100(128*1024)},
+};
+
+/* Private bank information for NuMicro. */
+struct  numicro_flash_bank {
+       struct working_area *write_algorithm;
+       int probed;
+       const struct numicro_cpu_type *cpu;
+};
+
+/* Private methods */
+static int numicro_reg_unlock(struct target *target)
+{
+       uint32_t is_protected;
+       int retval = ERROR_OK;
+
+       /* Check to see if NUC is register unlocked or not */
+       retval = target_read_u32(target, NUMICRO_SYS_WRPROT, &is_protected);
+       if (retval != ERROR_OK)
+               return retval;
+
+       LOG_DEBUG("protected = 0x%08" PRIx32 "", is_protected);
+       if (is_protected == 0) {        /* means protected - so unlock it */
+               /* unlock flash registers */
+               retval = target_write_u32(target, NUMICRO_SYS_WRPROT, REG_KEY1);
+               if (retval != ERROR_OK)
+                       return retval;
+               retval = target_write_u32(target, NUMICRO_SYS_WRPROT, REG_KEY2);
+               if (retval != ERROR_OK)
+                       return retval;
+               retval = target_write_u32(target, NUMICRO_SYS_WRPROT, REG_KEY3);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
+       /* Check that unlock worked */
+       retval = target_read_u32(target, NUMICRO_SYS_WRPROT, &is_protected);
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (is_protected == 1) {        /* means unprotected */
+               LOG_DEBUG("protection removed");
+       } else {
+               LOG_DEBUG("still protected!!");
+       }
+
+       return ERROR_OK;
+}
+
+static int numicro_init_isp(struct target *target)
+{
+       uint32_t reg_stat;
+       int retval = ERROR_OK;
+
+       if (target->state != TARGET_HALTED) {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       retval = numicro_reg_unlock(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /* Enable ISP/SRAM/TICK Clock */
+       retval = target_read_u32(target, NUMICRO_SYSCLK_AHBCLK, &reg_stat);
+       if (retval != ERROR_OK)
+               return retval;
+
+       reg_stat |= AHBCLK_ISP_EN | AHBCLK_SRAM_EN | AHBCLK_TICK_EN;
+       retval = target_write_u32(target, NUMICRO_SYSCLK_AHBCLK, reg_stat);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /* Enable ISP */
+       retval = target_read_u32(target, NUMICRO_FLASH_ISPCON, &reg_stat);
+       if (retval != ERROR_OK)
+               return retval;
+
+       reg_stat |= ISPCON_ISPFF | ISPCON_LDUEN | ISPCON_APUEN | ISPCON_CFGUEN | ISPCON_ISPEN;
+       retval = target_write_u32(target, NUMICRO_FLASH_ISPCON, reg_stat);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /* Write one to undocumented flash control register */
+       retval = target_write_u32(target, NUMICRO_FLASH_CHEAT, 1);
+       if (retval != ERROR_OK)
+               return retval;
+
+       return ERROR_OK;
+}
+
+static uint32_t numicro_fmc_cmd(struct target *target, uint32_t cmd, uint32_t addr, uint32_t wdata, uint32_t* rdata)
+{
+       uint32_t timeout, status;
+       int retval = ERROR_OK;
+
+       retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD, cmd);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = target_write_u32(target, NUMICRO_FLASH_ISPDAT, wdata);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, addr);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /* Wait for busy to clear - check the GO flag */
+       timeout = 100;
+       for (;;) {
+               retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status);
+               if (retval != ERROR_OK)
+                       return retval;
+                       LOG_DEBUG("status: 0x%" PRIx32 "", status);
+               if ((status & (ISPTRG_ISPGO)) == 0)
+                       break;
+               if (timeout-- <= 0) {
+                       LOG_DEBUG("timed out waiting for flash");
+                       return ERROR_FAIL;
+               }
+               busy_sleep(1);  /* can use busy sleep for short times. */
+       }
+
+       retval = target_read_u32(target, NUMICRO_FLASH_ISPDAT, rdata);
+       if (retval != ERROR_OK)
+               return retval;
+
+       return ERROR_OK;
+}
+
+
+/* NuMicro Program-LongWord Microcodes */
+static const uint8_t numicro_flash_write_code[] = {
+                               /* Params:
+                                * r0 - workarea buffer / result
+                                * r1 - target address
+                                * r2 - wordcount
+                                * Clobbered:
+                                * r4 - tmp
+                                * r5 - tmp
+                                * r6 - tmp
+                                * r7 - tmp
+                                */
+
+                               /* .L1: */
+                                               /* for(register uint32_t i=0;i<wcount;i++){ */
+       0x04, 0x1C,                             /* mov    r4, r0          */
+       0x00, 0x23,                             /* mov    r3, #0          */
+                               /* .L2: */
+       0x0D, 0x1A,                             /* sub    r5, r1, r0      */
+       0x67, 0x19,                             /* add    r7, r4, r7      */
+       0x93, 0x42,                             /* cmp    r3, r2                  */
+       0x0C, 0xD0,                             /* beq    .L7             */
+                               /* .L4: */
+                                               /* NUMICRO_FLASH_ISPADR = faddr; */
+       0x08, 0x4E,                             /* ldr  r6, .L8           */
+       0x37, 0x60,                             /* str  r7, [r6]          */
+                                               /* NUMICRO_FLASH_ISPDAT = *pLW; */
+       0x80, 0xCC,                             /* ldmia        r4!, {r7}     */
+       0x08, 0x4D,                             /* ldr  r5, .L8+4         */
+       0x2F, 0x60,                             /* str  r7, [r5]                  */
+                                                       /* faddr += 4; */
+                                                       /* pLW++; */
+                                                       /*  Trigger write action  */
+                                               /* NUMICRO_FLASH_ISPTRG = ISPTRG_ISPGO; */
+       0x08, 0x4D,                             /* ldr  r5, .L8+8         */
+       0x01, 0x26,                             /* mov  r6, #1            */
+       0x2E, 0x60,                             /* str  r6, [r5]          */
+                               /* .L3: */
+                                               /* while((NUMICRO_FLASH_ISPTRG & ISPTRG_ISPGO) == ISPTRG_ISPGO){}; */
+       0x2F, 0x68,                             /* ldr  r7, [r5]          */
+       0xFF, 0x07,                             /* lsl  r7, r7, #31       */
+       0xFC, 0xD4,                             /* bmi  .L3               */
+
+       0x01, 0x33,                             /* add  r3, r3, #1        */
+       0xEE, 0xE7,                             /* b    .L2               */
+                               /* .L7: */
+                                               /* return (NUMICRO_FLASH_ISPCON & ISPCON_ISPFF); */
+       0x05, 0x4B,                             /* ldr  r3, .L8+12        */
+       0x18, 0x68,                             /* ldr  r0, [r3]          */
+       0x40, 0x21,                             /* mov  r1, #64           */
+       0x08, 0x40,                             /* and  r0, r1            */
+                               /* .L9: */
+       0x00, 0xBE,                             /* bkpt    #0             */
+                               /* .L8: */
+       0x04, 0xC0, 0x00, 0x50,/* .word 1342226436    */
+       0x08, 0xC0, 0x00, 0x50,/* .word 1342226440    */
+       0x10, 0xC0, 0x00, 0x50,/* .word 1342226448    */
+       0x00, 0xC0, 0x00, 0x50 /* .word 1342226432    */
+};
+/* Program LongWord Block Write */
+static int numicro_writeblock(struct flash_bank *bank, const uint8_t *buffer,
+               uint32_t offset, uint32_t count)
+{
+       struct target *target = bank->target;
+       uint32_t buffer_size = 1024;            /* Default minimum value */
+       struct working_area *write_algorithm;
+       struct working_area *source;
+       uint32_t address = bank->base + offset;
+       struct reg_param reg_params[3];
+       struct armv7m_algorithm armv7m_info;
+       int retval = ERROR_OK;
+
+       /* Params:
+        * r0 - workarea buffer / result
+        * r1 - target address
+        * r2 - wordcount
+        * Clobbered:
+        * r4 - tmp
+        * r5 - tmp
+        * r6 - tmp
+        * r7 - tmp
+        */
+
+       /* Increase buffer_size if needed */
+       if (buffer_size < (target->working_area_size/2))
+               buffer_size = (target->working_area_size/2);
+
+       /* check code alignment */
+       if (offset & 0x1) {
+               LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
+               return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
+       }
+
+       /* allocate working area with flash programming code */
+       if (target_alloc_working_area(target, sizeof(numicro_flash_write_code),
+                       &write_algorithm) != ERROR_OK) {
+               LOG_WARNING("no working area available, can't do block memory writes");
+               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+       }
+
+       retval = target_write_buffer(target, write_algorithm->address,
+               sizeof(numicro_flash_write_code), numicro_flash_write_code);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /* memory buffer */
+       while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) {
+               buffer_size /= 4;
+               if (buffer_size <= 256) {
+                       /* free working area, write algorithm already allocated */
+                       target_free_working_area(target, write_algorithm);
+
+                       LOG_WARNING("No large enough working area available, can't do block memory writes");
+                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+               }
+       }
+
+       armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+       armv7m_info.core_mode = ARM_MODE_THREAD;
+
+       init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* *pLW (*buffer) */
+       init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);    /* faddr */
+       init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);    /* number of words to program */
+
+       struct armv7m_common *armv7m = target_to_armv7m(target);
+       if (armv7m == NULL) {
+               /* something is very wrong if armv7m is NULL */
+               LOG_ERROR("unable to get armv7m target");
+               return retval;
+       }
+
+       /* write code buffer and use Flash programming code within NuMicro     */
+       /* Set breakpoint to 0 with time-out of 1000 ms                        */
+       while (count > 0) {
+               uint32_t thisrun_count = (count > (buffer_size / 4)) ? (buffer_size / 4) : count;
+
+               retval = target_write_buffer(target, source->address, thisrun_count * 4, buffer);
+               if (retval != ERROR_OK)
+                       break;
+
+               buf_set_u32(reg_params[0].value, 0, 32, source->address);
+               buf_set_u32(reg_params[1].value, 0, 32, address);
+               buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
+
+               retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
+                               write_algorithm->address, 0, 100000, &armv7m_info);
+               if (retval != ERROR_OK) {
+                       LOG_ERROR("Error executing NuMicro Flash programming algorithm");
+                       retval = ERROR_FLASH_OPERATION_FAILED;
+                       break;
+               }
+
+               buffer  += thisrun_count * 4;
+               address += thisrun_count * 4;
+               count   -= thisrun_count;
+       }
+
+       target_free_working_area(target, source);
+       target_free_working_area(target, write_algorithm);
+
+       destroy_reg_param(&reg_params[0]);
+       destroy_reg_param(&reg_params[1]);
+       destroy_reg_param(&reg_params[2]);
+
+       return retval;
+}
+
+/* Flash Lock checking - examines the lock bit. */
+static int numicro_protect_check(struct flash_bank *bank)
+{
+       struct target *target = bank->target;
+       uint32_t set, config[2];
+       int i, retval = ERROR_OK;
+
+       if (target->state != TARGET_HALTED) {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       LOG_INFO("Nuvoton NuMicro: Flash Lock Check...");
+
+       retval = numicro_init_isp(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /* Read CONFIG0,CONFIG1 */
+       numicro_fmc_cmd(target, ISPCMD_READ, NUMICRO_CONFIG0, 0 , &config[0]);
+       numicro_fmc_cmd(target, ISPCMD_READ, NUMICRO_CONFIG1, 0 , &config[1]);
+
+       LOG_DEBUG("CONFIG0: 0x%" PRIx32 ",CONFIG1: 0x%" PRIx32 "", config[0], config[1]);
+
+       if ((config[0] & (1<<7)) == 0)
+               LOG_INFO("CBS=0: Boot From LPROM");
+       else
+               LOG_INFO("CBS=1: Boot From APROM");
+
+       if ((config[0] & CONFIG0_LOCK_MASK) == 0) {
+
+               LOG_INFO("Flash is secure locked!");
+               LOG_INFO("TO UNLOCK FLASH,EXECUTE chip_erase COMMAND!!");
+               set = 1;
+       } else {
+               LOG_INFO("Flash is not locked!");
+           set = 0;
+       }
+
+       for (i = 0; i < bank->num_sectors; i++)
+               bank->sectors[i].is_protected = set;
+
+       return ERROR_OK;
+}
+
+
+static int numicro_erase(struct flash_bank *bank, int first, int last)
+{
+       struct target *target = bank->target;
+       uint32_t timeout, status;
+       int i, retval = ERROR_OK;
+
+       if (target->state != TARGET_HALTED) {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       LOG_INFO("Nuvoton NuMicro: Sector Erase ... (%d to %d)", first, last);
+
+       retval = numicro_init_isp(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD, ISPCMD_ERASE);
+       if (retval != ERROR_OK)
+               return retval;
+
+       for (i = first; i <= last; i++) {
+               LOG_DEBUG("erasing sector %d at address 0x%" PRIx32 "", i, bank->base + bank->sectors[i].offset);
+               retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, bank->base + bank->sectors[i].offset);
+               if (retval != ERROR_OK)
+                       return retval;
+               retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO); /* This is the only bit available */
+               if (retval != ERROR_OK)
+                       return retval;
+
+               /* wait for busy to clear - check the GO flag */
+               timeout = 100;
+               for (;;) {
+                       retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status);
+                       if (retval != ERROR_OK)
+                               return retval;
+                               LOG_DEBUG("status: 0x%" PRIx32 "", status);
+                       if (status == 0)
+                               break;
+                       if (timeout-- <= 0) {
+                               LOG_DEBUG("timed out waiting for flash");
+                               return ERROR_FAIL;
+                       }
+                       busy_sleep(1);  /* can use busy sleep for short times. */
+               }
+
+               /* check for failure */
+               retval = target_read_u32(target, NUMICRO_FLASH_ISPCON, &status);
+               if (retval != ERROR_OK)
+                       return retval;
+               if ((status & ISPCON_ISPFF) != 0) {
+                       LOG_DEBUG("failure: 0x%" PRIx32 "", status);
+                       /* if bit is set, then must write to it to clear it. */
+                       retval = target_write_u32(target, NUMICRO_FLASH_ISPCON, (status | ISPCON_ISPFF));
+                       if (retval != ERROR_OK)
+                               return retval;
+               } else {
+                       bank->sectors[i].is_erased = 1;
+               }
+       }
+
+       /* done, */
+       LOG_DEBUG("Erase done.");
+
+       return ERROR_OK;
+}
+
+/* The write routine stub. */
+static int numicro_write(struct flash_bank *bank, const uint8_t *buffer,
+               uint32_t offset, uint32_t count)
+{
+       struct target *target = bank->target;
+       uint32_t timeout, status;
+       uint8_t *new_buffer = NULL;
+       int retval = ERROR_OK;
+
+       if (target->state != TARGET_HALTED) {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       LOG_INFO("Nuvoton NuMicro: Flash Write ...");
+
+       retval = numicro_init_isp(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD, ISPCMD_WRITE);
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (count & 0x3) {
+               uint32_t old_count = count;
+               count = (old_count | 3) + 1;
+               new_buffer = malloc(count);
+               if (new_buffer == NULL) {
+                       LOG_ERROR("odd number of bytes to write and no memory "
+                               "for padding buffer");
+                       return ERROR_FAIL;
+               }
+               LOG_INFO("odd number of bytes to write (%d), extending to %d "
+                       "and padding with 0xff", old_count, count);
+               memset(new_buffer, 0xff, count);
+               buffer = memcpy(new_buffer, buffer, old_count);
+       }
+
+       uint32_t words_remaining = count / 4;
+
+       /* try using a block write */
+       retval = numicro_writeblock(bank, buffer, offset, words_remaining);
+
+       if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
+               /* if block write failed (no sufficient working area),
+                * we use normal (slow) single word accesses */
+               LOG_WARNING("couldn't use block writes, falling back to single "
+                       "memory accesses");
+
+               /* program command */
+               for (uint32_t i = 0; i < count; i += 4) {
+
+                       LOG_DEBUG("write longword @ %08X", offset + i);
+
+                       uint8_t padding[4] = {0xff, 0xff, 0xff, 0xff};
+                       memcpy(padding, buffer + i, MIN(4, count-i));
+
+                       retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, bank->base + offset + i);
+                       if (retval != ERROR_OK)
+                               return retval;
+                       retval = target_write_memory(target, NUMICRO_FLASH_ISPDAT, 4, 1, padding);
+                       if (retval != ERROR_OK)
+                               return retval;
+                       retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO);
+                       if (retval != ERROR_OK)
+                               return retval;
+
+                       /* wait for busy to clear - check the GO flag */
+                       timeout = 100;
+                       for (;;) {
+                               retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status);
+                               if (retval != ERROR_OK)
+                                       return retval;
+                                       LOG_DEBUG("status: 0x%" PRIx32 "", status);
+                               if (status == 0)
+                                       break;
+                               if (timeout-- <= 0) {
+                                       LOG_DEBUG("timed out waiting for flash");
+                                       return ERROR_FAIL;
+                               }
+                               busy_sleep(1);  /* can use busy sleep for short times. */
+                       }
+
+               }
+       }
+
+       /* check for failure */
+       retval = target_read_u32(target, NUMICRO_FLASH_ISPCON, &status);
+       if (retval != ERROR_OK)
+               return retval;
+       if ((status & ISPCON_ISPFF) != 0) {
+               LOG_DEBUG("failure: 0x%" PRIx32 "", status);
+               /* if bit is set, then must write to it to clear it. */
+               retval = target_write_u32(target, NUMICRO_FLASH_ISPCON, (status | ISPCON_ISPFF));
+               if (retval != ERROR_OK)
+                       return retval;
+       } else {
+               LOG_DEBUG("Write OK");
+       }
+
+       /* done. */
+       LOG_DEBUG("Write done.");
+
+       return ERROR_OK;
+}
+
+static int numicro_get_cpu_type(struct target *target, const struct numicro_cpu_type** cpu)
+{
+       uint32_t part_id;
+       int retval = ERROR_OK;
+
+       /* Read NuMicro PartID */
+       retval = target_read_u32(target, NUMICRO_SYS_BASE, &part_id);
+       if (retval != ERROR_OK) {
+               LOG_WARNING("NuMicro flash driver: Failed to Get PartID\n");
+               return ERROR_FLASH_OPERATION_FAILED;
+       }
+
+       LOG_INFO("Device ID: 0x%08" PRIx32 "", part_id);
+       /* search part numbers */
+       for (size_t i = 0; i < sizeof(NuMicroParts)/sizeof(NuMicroParts[0]); i++) {
+               if (part_id == NuMicroParts[i].partid) {
+                       *cpu = &NuMicroParts[i];
+                       LOG_INFO("Device Name: %s", (*cpu)->partname);
+                       return ERROR_OK;
+               }
+       }
+
+       return ERROR_FAIL;
+}
+
+static int numicro_get_flash_size(struct flash_bank *bank, const struct numicro_cpu_type *cpu, uint32_t *flash_size)
+{
+       for (size_t i = 0; i < cpu->n_banks; i++) {
+               if (bank->base == cpu->bank[i].base) {
+                       *flash_size = cpu->bank[i].size;
+                       LOG_INFO("bank base = 0x%08" PRIx32 ", size = 0x%08" PRIx32 "", bank->base, *flash_size);
+                       return ERROR_OK;
+               }
+       }
+       return ERROR_FLASH_OPERATION_FAILED;
+}
+
+static int numicro_probe(struct flash_bank *bank)
+{
+       uint32_t flash_size, offset = 0;
+       int num_pages;
+       const struct numicro_cpu_type *cpu;
+       struct target *target = bank->target;
+       int retval = ERROR_OK;
+
+       retval = numicro_get_cpu_type(target, &cpu);
+       if (retval != ERROR_OK) {
+               LOG_WARNING("NuMicro flash driver: Failed to detect a known part\n");
+               return ERROR_FLASH_OPERATION_FAILED;
+       }
+
+       retval = numicro_get_flash_size(bank, cpu, &flash_size);
+       if (retval != ERROR_OK) {
+               LOG_WARNING("NuMicro flash driver: Failed to detect flash size\n");
+               return ERROR_FLASH_OPERATION_FAILED;
+       }
+
+       num_pages = flash_size / NUMICRO_PAGESIZE;
+
+       bank->num_sectors = num_pages;
+       bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
+       bank->size = flash_size;
+
+       for (int i = 0; i < num_pages; i++) {
+               bank->sectors[i].offset = offset;
+               bank->sectors[i].size = NUMICRO_PAGESIZE;
+               bank->sectors[i].is_erased = -1;
+               bank->sectors[i].is_protected = 0;
+               offset += NUMICRO_PAGESIZE;
+       }
+
+       struct numicro_flash_bank *numicro_info = bank->driver_priv;
+       numicro_info->probed = true;
+       numicro_info->cpu = cpu;
+       LOG_DEBUG("Nuvoton NuMicro: Probed ...");
+
+       return ERROR_OK;
+}
+
+/* Standard approach to autoprobing. */
+static int numicro_auto_probe(struct flash_bank *bank)
+{
+       struct numicro_flash_bank *numicro_info = bank->driver_priv;
+       if (numicro_info->probed)
+               return ERROR_OK;
+       return numicro_probe(bank);
+}
+
+
+/* This is the function called in the config file. */
+FLASH_BANK_COMMAND_HANDLER(numicro_flash_bank_command)
+{
+       struct numicro_flash_bank *bank_info;
+
+       if (CMD_ARGC < 6)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       LOG_DEBUG("add flash_bank numicro %s", bank->name);
+
+       bank_info = malloc(sizeof(struct numicro_flash_bank));
+
+       memset(bank_info, 0, sizeof(struct numicro_flash_bank));
+
+       bank->driver_priv = bank_info;
+
+       return ERROR_OK;
+
+}
+
+COMMAND_HANDLER(numicro_handle_read_isp_command)
+{
+       uint32_t address;
+       uint32_t ispdat;
+       int retval = ERROR_OK;
+
+       if (CMD_ARGC != 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
+
+       struct target *target = get_current_target(CMD_CTX);
+
+       retval = numicro_init_isp(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = numicro_fmc_cmd(target, ISPCMD_READ, address, 0, &ispdat);
+       if (retval != ERROR_OK)
+               return retval;
+
+       LOG_INFO("0x%08" PRIx32 ": 0x%08" PRIx32, address, ispdat);
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(numicro_handle_write_isp_command)
+{
+       uint32_t address;
+       uint32_t ispdat, rdat;
+       int retval = ERROR_OK;
+
+       if (CMD_ARGC != 2)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], ispdat);
+
+       struct target *target = get_current_target(CMD_CTX);
+
+       retval = numicro_init_isp(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = numicro_fmc_cmd(target, ISPCMD_WRITE, address, ispdat, &rdat);
+       if (retval != ERROR_OK)
+               return retval;
+
+       LOG_INFO("0x%08" PRIx32 ": 0x%08" PRIx32, address, ispdat);
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(numicro_handle_chip_erase_command)
+{
+       int retval = ERROR_OK;
+       uint32_t rdat;
+
+       if (CMD_ARGC != 0)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       struct target *target = get_current_target(CMD_CTX);
+
+       retval = numicro_init_isp(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = numicro_fmc_cmd(target, ISPCMD_CHIPERASE, 0, 0, &rdat);
+       if (retval != ERROR_OK) {
+               command_print(CMD_CTX, "numicro chip_erase failed");
+               return retval;
+       }
+
+       command_print(CMD_CTX, "numicro chip_erase complete");
+
+       return ERROR_OK;
+}
+
+static const struct command_registration numicro_exec_command_handlers[] = {
+       {
+               .name = "read_isp",
+               .handler = numicro_handle_read_isp_command,
+               .usage = "address",
+               .mode = COMMAND_EXEC,
+               .help = "read flash through ISP.",
+       },
+       {
+               .name = "write_isp",
+               .handler = numicro_handle_write_isp_command,
+               .usage = "address value",
+               .mode = COMMAND_EXEC,
+               .help = "write flash through ISP.",
+       },
+       {
+               .name = "chip_erase",
+               .handler = numicro_handle_chip_erase_command,
+               .mode = COMMAND_EXEC,
+               .help = "chip erase through ISP.",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration numicro_command_handlers[] = {
+       {
+               .name = "numicro",
+               .mode = COMMAND_ANY,
+               .help = "numicro flash command group",
+               .usage = "",
+               .chain = numicro_exec_command_handlers,
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+struct flash_driver numicro_flash = {
+       .name = "numicro",
+       .commands = numicro_command_handlers,
+       .flash_bank_command = numicro_flash_bank_command,
+       .erase = numicro_erase,
+       .write = numicro_write,
+       .read = default_flash_read,
+       .probe = numicro_probe,
+       .auto_probe = numicro_auto_probe,
+       .erase_check = default_flash_blank_check,
+       .protect_check = numicro_protect_check,
+};
diff --git a/tcl/target/m051.cfg b/tcl/target/m051.cfg
deleted file mode 100644 (file)
index d065594..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-# script for nuvoton M051 family
-
-transport select hla_swd
-
-source [find target/swj-dp.tcl]
-
-if { [info exists CHIPNAME] } {
-   set _CHIPNAME $CHIPNAME
-} else {
-   set _CHIPNAME m051
-}
-
-if { [info exists ENDIAN] } {
-   set _ENDIAN $ENDIAN
-} else {
-   set _ENDIAN little
-}
-
-# Work-area is a space in RAM used for flash programming
-# By default use 4kB
-if { [info exists WORKAREASIZE] } {
-   set _WORKAREASIZE $WORKAREASIZE
-} else {
-   set _WORKAREASIZE 0x1000
-}
-
-if { [info exists CPUTAPID] } {
-   set _CPUTAPID $CPUTAPID
-} else {
-  # See STM Document RM0091
-  # Section 29.5.3
-   set _CPUTAPID 0x0bb11477
-}
-
-swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
-
-set _TARGETNAME $_CHIPNAME.cpu
-target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME
-
-$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
-
-# flash size will be probed
-set _FLASHNAME $_CHIPNAME.flash_aprom
-flash bank $_FLASHNAME mini51 0x00000000 0x4000 0 0 $_TARGETNAME
-set _FLASHNAME $_CHIPNAME.flash_data
-flash bank $_FLASHNAME mini51 0x0001F000 0x1000 0 0 $_TARGETNAME
-set _FLASHNAME $_CHIPNAME.flash_ldrom
-flash bank $_FLASHNAME mini51 0x00100000 0x1000 0 0 $_TARGETNAME
-set _FLASHNAME $_CHIPNAME.flash_conf
-flash bank $_FLASHNAME mini51 0x00300000 0x0100 0 0 $_TARGETNAME
-
-# adapter speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz
-adapter_khz 1000
-
-adapter_nsrst_delay 100
-
-if {![using_hla]} {
-   # if srst is not fitted use SYSRESETREQ to
-   # perform a soft reset
-   cortex_m reset_config sysresetreq
-}
diff --git a/tcl/target/numicro.cfg b/tcl/target/numicro.cfg
new file mode 100644 (file)
index 0000000..13d9654
--- /dev/null
@@ -0,0 +1,60 @@
+# script for Nuvoton MuMicro Cortex-M0 Series
+
+# Adapt based on what transport is active.
+source [find target/swj-dp.tcl]
+
+# Set Chipname
+if { [info exists CHIPNAME] } {
+       set _CHIPNAME $CHIPNAME
+} else {
+       set _CHIPNAME NuMicro
+}
+
+# SWD DP-ID Nuvoton NuMicro Cortex-M0 has SWD Transport only.
+if { [info exists CPUDAPID] } {
+       set _CPUDAPID $CPUDAPID
+} else {
+       set _CPUDAPID 0x0BB11477
+}
+
+# Work-area is a space in RAM used for flash programming
+# By default use 2kB
+if { [info exists WORKAREASIZE] } {
+   set _WORKAREASIZE $WORKAREASIZE
+} else {
+   set _WORKAREASIZE 0x800
+}
+
+
+# Debug Adapter Target Settings
+swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUDAPID
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME
+
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
+
+# flash bank <name> numicro <base> <size(autodetect,set to 0)> 0 0 <target#>
+#set _FLASHNAME $_CHIPNAME.flash
+#flash bank $_FLASHNAME numicro 0 $_FLASHSIZE 0 0 $_TARGETNAME
+# flash size will be probed
+set _FLASHNAME $_CHIPNAME.flash_aprom
+flash bank $_FLASHNAME numicro 0x00000000 0 0 0 $_TARGETNAME
+set _FLASHNAME $_CHIPNAME.flash_data
+flash bank $_FLASHNAME numicro 0x0001F000 0 0 0 $_TARGETNAME
+set _FLASHNAME $_CHIPNAME.flash_ldrom
+flash bank $_FLASHNAME numicro 0x00100000 0 0 0 $_TARGETNAME
+set _FLASHNAME $_CHIPNAME.flash_config
+flash bank $_FLASHNAME numicro 0x00300000 0 0 0 $_TARGETNAME
+
+# set default SWCLK frequency
+adapter_khz 1000
+
+# set default srst setting "none"
+reset_config none
+
+# HLA doesn't have cortex_m commands
+if {![using_hla]} {
+   # if srst is not fitted use SYSRESETREQ to
+   # perform a soft reset
+   cortex_m reset_config sysresetreq
+}

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)