aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNemui Trinomius <nemuisan_kawausogasuki@live.jp>2015-06-04 00:27:56 +0900
committerSpencer Oliver <spen@spen-soft.co.uk>2015-09-30 22:12:39 +0100
commit33e406824c5d522703829189bb0f55967b887ec5 (patch)
tree80e6e5628c327b83f17a3fe499589a4ec70a921c /src
parent03f46e368830c7293f83186658268a6cd4557b20 (diff)
downloadriscv-openocd-33e406824c5d522703829189bb0f55967b887ec5.zip
riscv-openocd-33e406824c5d522703829189bb0f55967b887ec5.tar.gz
riscv-openocd-33e406824c5d522703829189bb0f55967b887ec5.tar.bz2
numicro: Integrate Nuvoton NuMicro flash driver.
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>
Diffstat (limited to 'src')
-rw-r--r--src/flash/nor/Makefile.am3
-rw-r--r--src/flash/nor/drivers.c6
-rw-r--r--src/flash/nor/mini51.c584
-rw-r--r--src/flash/nor/nuc1x.c640
-rw-r--r--src/flash/nor/numicro.c1880
5 files changed, 1883 insertions, 1230 deletions
diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am
index 4d11436..3027dc7 100644
--- a/src/flash/nor/Makefile.am
+++ b/src/flash/nor/Makefile.am
@@ -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 \
diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c
index ef95f7b..e527ddd 100644
--- a/src/flash/nor/drivers.c
+++ b/src/flash/nor/drivers.c
@@ -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
index df6e7ce..0000000
--- a/src/flash/nor/mini51.c
+++ /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
index 3f39a05..0000000
--- a/src/flash/nor/nuc1x.c
+++ /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
index 0000000..8d8ed6e
--- /dev/null
+++ b/src/flash/nor/numicro.c
@@ -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,
+};