1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2011 by James K. Larson *
5 * jlarson@pacifier.com *
7 * Copyright (C) 2013 Cosmin Gorgovan *
8 * cosmin [at] linux-geek [dot] org *
10 * Copyright (C) 2014 Pawel Si *
11 * stawel+openocd@gmail.com *
13 * Copyright (C) 2015 Nemui Trinomius *
14 * nemuisan_kawausogasuki@live.jp *
16 * Copyright (C) 2017 Zale Yu *
19 * Copyright (C) 2022 Jian-Hong Pan *
20 * chienhung.pan@gmail.com *
21 ***************************************************************************/
28 #include <helper/binarybuffer.h>
29 #include <target/algorithm.h>
30 #include <target/armv7m.h>
31 #include <target/cortex_m.h>
33 /* Nuvoton NuMicro register locations */
34 #define NUMICRO_SYS_BASE 0x50000000
35 #define NUMICRO_SYS_WRPROT 0x50000100
36 #define NUMICRO_SYS_IPRSTC1 0x50000008
38 #define NUMICRO_SYSCLK_BASE 0x50000200
39 #define NUMICRO_SYSCLK_PWRCON 0x50000200
40 #define NUMICRO_SYSCLK_CLKSEL0 0x50000210
41 #define NUMICRO_SYSCLK_CLKDIV 0x50000218
42 #define NUMICRO_SYSCLK_AHBCLK 0x50000204
44 #define NUMICRO_FLASH_BASE 0x5000C000
45 #define NUMICRO_FLASH_ISPCON 0x5000C000
46 #define NUMICRO_FLASH_ISPADR 0x5000C004
47 #define NUMICRO_FLASH_ISPDAT 0x5000C008
48 #define NUMICRO_FLASH_ISPCMD 0x5000C00C
49 #define NUMICRO_FLASH_ISPTRG 0x5000C010
50 #define NUMICRO_FLASH_CHEAT 0x5000C01C /* Undocumented isp register(may be cheat register) */
52 #define NUMICRO_SCS_BASE 0xE000E000
53 #define NUMICRO_SCS_AIRCR 0xE000ED0C
54 #define NUMICRO_SCS_DHCSR 0xE000EDF0
55 #define NUMICRO_SCS_DEMCR 0xE000EDFC
57 #define NUMICRO_APROM_BASE 0x00000000
58 #define NUMICRO_DATA_BASE 0x0001F000
59 #define NUMICRO_LDROM_BASE 0x00100000
60 #define NUMICRO_CONFIG_BASE 0x00300000
62 #define NUMICRO_CONFIG0 0x5000C000
63 #define NUMICRO_CONFIG1 0x5000C004
65 /* Command register bits */
66 #define PWRCON_OSC22M (1 << 2)
67 #define PWRCON_XTL12M (1 << 0)
69 #define IPRSTC1_CPU_RST (1 << 1)
70 #define IPRSTC1_CHIP_RST (1 << 0)
72 #define AHBCLK_ISP_EN (1 << 2)
73 #define AHBCLK_SRAM_EN (1 << 4)
74 #define AHBCLK_TICK_EN (1 << 5)
76 #define ISPCON_ISPEN (1 << 0)
77 #define ISPCON_BS_AP (0 << 1)
78 #define ISPCON_BS_LP (1 << 1)
79 #define ISPCON_BS_MASK (1 << 1)
80 #define ISPCON_APUEN (1 << 3)
81 #define ISPCON_CFGUEN (1 << 4)
82 #define ISPCON_LDUEN (1 << 5)
83 #define ISPCON_ISPFF (1 << 6)
85 #define CONFIG0_LOCK_MASK (1 << 1)
88 #define ISPCMD_READ 0x00
89 #define ISPCMD_WRITE 0x21
90 #define ISPCMD_ERASE 0x22
91 #define ISPCMD_CHIPERASE 0x26 /* Undocumented isp "Chip-Erase" command */
92 #define ISPCMD_READ_CID 0x0B
93 #define ISPCMD_READ_DID 0x0C
94 #define ISPCMD_READ_UID 0x04
95 #define ISPCMD_VECMAP 0x2E
96 #define ISPTRG_ISPGO (1 << 0)
98 /* access unlock keys */
100 #define REG_KEY2 0x16
101 #define REG_KEY3 0x88
102 #define REG_LOCK 0x00
104 /* flash pagesizes */
105 #define NUMICRO_PAGESIZE 512
106 /* flash MAX banks */
107 #define NUMICRO_MAX_FLASH_BANKS 4
109 /* flash bank structs */
110 struct numicro_flash_bank_type
{
116 struct numicro_cpu_type
{
119 unsigned int n_banks
;
120 struct numicro_flash_bank_type bank
[NUMICRO_MAX_FLASH_BANKS
];
123 /* If DataFlash size equals zero, it means the actual size depends on config settings. */
124 #define NUMICRO_BANKS_GENERAL(aprom_size, data_size, ldrom_size, config_size) \
126 {{NUMICRO_APROM_BASE, (aprom_size)}, \
127 {NUMICRO_DATA_BASE, (data_size)}, \
128 {NUMICRO_LDROM_BASE, (ldrom_size)}, \
129 {NUMICRO_CONFIG_BASE, (config_size)}}
131 static const struct numicro_cpu_type numicro_parts
[] = {
132 /*PART NO*/ /*PART ID*/ /*Banks*/
134 {"M052LAN", 0x00005200, NUMICRO_BANKS_GENERAL(8 * 1024, 4 * 1024, 4 * 1024, 4)},
135 {"M054LAN", 0x00005400, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)},
136 {"M058LAN", 0x00005800, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},
137 {"M0516LAN", 0x00005A00, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},
138 {"M052ZAN", 0x00005203, NUMICRO_BANKS_GENERAL(8 * 1024, 4 * 1024, 4 * 1024, 4)},
139 {"M054ZAN", 0x00005403, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)},
140 {"M058ZAN", 0x00005803, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},
141 {"M0516ZAN", 0x00005A03, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},
144 {"M052LBN", 0x10005200, NUMICRO_BANKS_GENERAL(8 * 1024, 4 * 1024, 4 * 1024, 4)},
145 {"M054LBN", 0x10005400, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)},
146 {"M058LBN", 0x10005800, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},
147 {"M0516LBN", 0x10005A00, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},
148 {"M052ZBN", 0x10005203, NUMICRO_BANKS_GENERAL(8 * 1024, 4 * 1024, 4 * 1024, 4)},
149 {"M054ZBN", 0x10005403, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)},
150 {"M058ZBN", 0x10005803, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},
151 {"M0516ZBN", 0x10005A03, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},
154 {"M0516LDN", 0x20005A00, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},
155 {"M0516ZDN", 0x20005A03, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},
156 {"M052LDN", 0x20005200, NUMICRO_BANKS_GENERAL(8 * 1024, 4 * 1024, 4 * 1024, 4)},
157 {"M052ZDN", 0x20005203, NUMICRO_BANKS_GENERAL(8 * 1024, 4 * 1024, 4 * 1024, 4)},
158 {"M054LDN", 0x20005400, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)},
159 {"M054ZDN", 0x20005403, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)},
160 {"M058LDN", 0x20005800, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},
161 {"M058ZDN", 0x20005803, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},
164 {"M0516LDE", 0x30005A00, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},
165 {"M0516ZDE", 0x30005A03, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},
166 {"M052LDE", 0x30005200, NUMICRO_BANKS_GENERAL(8 * 1024, 4 * 1024, 4 * 1024, 4)},
167 {"M052ZDE", 0x30005203, NUMICRO_BANKS_GENERAL(8 * 1024, 4 * 1024, 4 * 1024, 4)},
168 {"M054LDE", 0x30005400, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)},
169 {"M054ZDE", 0x30005403, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)},
170 {"M058LDE", 0x30005800, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},
171 {"M058ZDE", 0x30005803, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},
174 {"M0518LC2AE", 0x10051803, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
175 {"M0518LD2AE", 0x10051800, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
176 {"M0518SC2AE", 0x10051813, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
177 {"M0518SD2AE", 0x10051810, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
180 {"M0519LD3AE", 0x00051902, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 8 * 1024, 8)},
181 {"M0519LE3AE", 0x00051900, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},
182 {"M0519SD3AE", 0x00051922, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 8 * 1024, 8)},
183 {"M0519SE3AE", 0x00051920, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},
184 {"M0519VE3AE", 0x00051930, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},
187 {"M058SFAN", 0x00005818, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
188 {"M058SLAN", 0x00005810, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
189 {"M058SSAN", 0x00005816, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
190 {"M058SZAN", 0x00005813, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
193 {"MINI51LAN", 0x00205100, NUMICRO_BANKS_GENERAL(4 * 1024, 0 * 1024, 2 * 1024, 8)},
194 {"MINI51TAN", 0x00205104, NUMICRO_BANKS_GENERAL(4 * 1024, 0 * 1024, 2 * 1024, 8)},
195 {"MINI51ZAN", 0x00205103, NUMICRO_BANKS_GENERAL(4 * 1024, 0 * 1024, 2 * 1024, 8)},
196 {"MINI52LAN", 0x00205200, NUMICRO_BANKS_GENERAL(8 * 1024, 0 * 1024, 2 * 1024, 8)},
197 {"MINI52TAN", 0x00205204, NUMICRO_BANKS_GENERAL(8 * 1024, 0 * 1024, 2 * 1024, 8)},
198 {"MINI52ZAN", 0x00205203, NUMICRO_BANKS_GENERAL(8 * 1024, 0 * 1024, 2 * 1024, 8)},
199 {"MINI54LAN", 0x00205400, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},
200 {"MINI54TAN", 0x00205404, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},
201 {"MINI54ZAN", 0x00205403, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},
204 {"MINI51FDE", 0x20205105, NUMICRO_BANKS_GENERAL(4 * 1024, 0 * 1024, 2 * 1024, 8)},
205 {"MINI51LDE", 0x20205100, NUMICRO_BANKS_GENERAL(4 * 1024, 0 * 1024, 2 * 1024, 8)},
206 {"MINI51TDE", 0x20205104, NUMICRO_BANKS_GENERAL(4 * 1024, 0 * 1024, 2 * 1024, 8)},
207 {"MINI51ZDE", 0x20205103, NUMICRO_BANKS_GENERAL(4 * 1024, 0 * 1024, 2 * 1024, 8)},
208 {"MINI52FDE", 0x20205205, NUMICRO_BANKS_GENERAL(8 * 1024, 0 * 1024, 2 * 1024, 8)},
209 {"MINI52LDE", 0x20205200, NUMICRO_BANKS_GENERAL(8 * 1024, 0 * 1024, 2 * 1024, 8)},
210 {"MINI52TDE", 0x20205204, NUMICRO_BANKS_GENERAL(8 * 1024, 0 * 1024, 2 * 1024, 8)},
211 {"MINI52ZDE", 0x20205203, NUMICRO_BANKS_GENERAL(8 * 1024, 0 * 1024, 2 * 1024, 8)},
212 {"MINI54FDE", 0x20205405, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},
213 {"MINI54LDE", 0x20205400, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},
214 {"MINI54TDE", 0x20205404, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},
215 {"MINI54ZDE", 0x20205403, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},
218 {"MINI55LDE", 0x00505500, NUMICRO_BANKS_GENERAL(35 * 512, 0 * 1024, 2 * 1024, 8)},
219 {"MINI55ZDE", 0x00505503, NUMICRO_BANKS_GENERAL(35 * 512, 0 * 1024, 2 * 1024, 8)},
222 {"MINI58FDE", 0x00A05805, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 5 * 512, 8)},
223 {"MINI58LDE", 0x00A05800, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 5 * 512, 8)},
224 {"MINI58TDE", 0x00A05804, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 5 * 512, 8)},
225 {"MINI58ZDE", 0x00A05803, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 5 * 512, 8)},
228 {"NANO100LC2AN", 0x00110025, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
229 {"NANO100LD2AN", 0x00110019, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
230 {"NANO100LD3AN", 0x00110018, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
231 {"NANO100SC2AN", 0x00110023, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
232 {"NANO100SD2AN", 0x00110016, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
233 {"NANO100SD3AN", 0x00110015, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
234 {"NANO100VD2AN", 0x00110013, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
235 {"NANO100VD3AN", 0x00110012, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
236 {"NANO100ZC2AN", 0x00110029, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
237 {"NANO100ZD2AN", 0x00110028, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
238 {"NANO100ZD3AN", 0x00110027, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
239 {"NANO120LC2AN", 0x00112025, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
240 {"NANO120LD2AN", 0x00112019, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
241 {"NANO120LD3AN", 0x00112018, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
242 {"NANO120SC2AN", 0x00112023, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
243 {"NANO120SD2AN", 0x00112016, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
244 {"NANO120SD3AN", 0x00112015, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
245 {"NANO120VD2AN", 0x00112013, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
246 {"NANO120VD3AN", 0x00112012, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
247 {"NANO120ZC2AN", 0x00112029, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
248 {"NANO120ZD2AN", 0x00112028, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
249 {"NANO120ZD3AN", 0x00112027, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
252 {"NANO100KC2BN", 0x00110040, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
253 {"NANO100KD2BN", 0x00110039, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
254 {"NANO100KD3BN", 0x00110038, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
255 {"NANO100KE3BN", 0x00110030, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},
256 {"NANO100LC2BN", 0x00110043, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
257 {"NANO100LD2BN", 0x0011003F, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
258 {"NANO100LD3BN", 0x0011003E, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
259 {"NANO100LE3BN", 0x00110036, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},
260 {"NANO100ND2BN", 0x00110046, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
261 {"NANO100ND3BN", 0x00110045, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
262 {"NANO100NE3BN", 0x00110044, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},
263 {"NANO100SC2BN", 0x00110042, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
264 {"NANO100SD2BN", 0x0011003D, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
265 {"NANO100SD3BN", 0x0011003C, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
266 {"NANO100SE3BN", 0x00110034, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},
267 {"NANO110KC2BN", 0x00111040, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
268 {"NANO110KD2BN", 0x00111039, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
269 {"NANO110KD3BN", 0x00111038, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
270 {"NANO110KE3BN", 0x00111030, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},
271 {"NANO110RC2BN", 0x00111043, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
272 {"NANO110RD2BN", 0x00111044, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
273 {"NANO110RD3BN", 0x00111045, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
274 {"NANO110SC2BN", 0x00111042, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
275 {"NANO110SD2BN", 0x0011103D, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
276 {"NANO110SD3BN", 0x0011103C, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
277 {"NANO110SE3BN", 0x00111034, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},
278 {"NANO120KC2BN", 0x00112040, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
279 {"NANO120KD2BN", 0x00112039, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
280 {"NANO120KD3BN", 0x00112038, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
281 {"NANO120KE3BN", 0x00112030, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},
282 {"NANO120LC2BN", 0x00112043, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
283 {"NANO120LD2BN", 0x0011203F, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
284 {"NANO120LD3BN", 0x0011203E, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
285 {"NANO120LE3BN", 0x00112036, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},
286 {"NANO120SC2BN", 0x00112042, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
287 {"NANO120SD2BN", 0x0011203D, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
288 {"NANO120SD3BN", 0x0011203C, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
289 {"NANO120SE3BN", 0x00112034, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},
290 {"NANO130KC2BN", 0x00113040, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
291 {"NANO130KD2BN", 0x00113039, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
292 {"NANO130KD3BN", 0x00113038, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
293 {"NANO130KE3BN", 0x00113030, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},
294 {"NANO130SC2BN", 0x00113042, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
295 {"NANO130SD2BN", 0x0011303D, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
296 {"NANO130SD3BN", 0x0011303C, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
297 {"NANO130SE3BN", 0x00113034, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},
300 {"NANO103SD3AE", 0x00110301, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
301 {"NANO103LD3AE", 0x00110304, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
302 {"NANO103ZD3AE", 0x00110307, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},
305 {"NANO102LB1AN", 0x00110206, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 4 * 1024, 8)},
306 {"NANO102LC2AN", 0x00110208, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
307 {"NANO102SC2AN", 0x00110212, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
308 {"NANO102ZB1AN", 0x00110202, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 4 * 1024, 8)},
309 {"NANO102ZC2AN", 0x00110204, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
310 {"NANO112LB1AN", 0x00111202, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 4 * 1024, 8)},
311 {"NANO112LC2AN", 0x00111204, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
312 {"NANO112RB1AN", 0x00111210, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 4 * 1024, 8)},
313 {"NANO112RC2AN", 0x00111212, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
314 {"NANO112SB1AN", 0x00111206, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 4 * 1024, 8)},
315 {"NANO112SC2AN", 0x00111208, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
316 {"NANO112VC2AN", 0x00111216, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},
319 {"NUC029LAN", 0x00295A00, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},
320 {"NUC029TAN", 0x00295804, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},
323 {"NUC029FAE", 0x00295415, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},
326 {"NUC100LD3AN", 0x00010003, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
327 {"NUC100LE3AN", 0x00010000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
328 {"NUC100RD3AN", 0x00010012, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
329 {"NUC100RE3AN", 0x00010009, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
330 {"NUC100VD2AN", 0x00010022, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
331 {"NUC100VD3AN", 0x00010021, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
332 {"NUC100VE3AN", 0x00100018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
333 {"NUC120LD3AN", 0x00012003, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
334 {"NUC120LE3AN", 0x00120000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
335 {"NUC120RD3AN", 0x00012012, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
336 {"NUC120RE3AN", 0x00012009, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
337 {"NUC120VD2AN", 0x00012022, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
338 {"NUC120VD3AN", 0x00012021, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
339 {"NUC120VE3AN", 0x00012018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
342 {"NUC100LC1BN", 0x10010008, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
343 {"NUC100LD1BN", 0x10010005, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
344 {"NUC100LD2BN", 0x10010004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
345 {"NUC100RC1BN", 0x10010017, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
346 {"NUC100RD1BN", 0x10010014, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
347 {"NUC100RD2BN", 0x10010013, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
348 {"NUC120LC1BN", 0x10012008, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
349 {"NUC120LD1BN", 0x10012005, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
350 {"NUC120LD2BN", 0x10012004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
351 {"NUC120RC1BN", 0x10012017, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
352 {"NUC120RD1BN", 0x10012014, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
353 {"NUC120RD2BN", 0x10012013, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
356 {"NUC130LC1CN", 0x20013008, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
357 {"NUC130LD2CN", 0x20013004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
358 {"NUC130LE3CN", 0x20013000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
359 {"NUC130RC1CN", 0x20013017, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
360 {"NUC130RD2CN", 0x20013013, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
361 {"NUC130RE3CN", 0x20013009, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
362 {"NUC130VE3CN", 0x20013018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
363 {"NUC140LC1CN", 0x20014008, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
364 {"NUC140LD2CN", 0x20014004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
365 {"NUC140LE3CN", 0x20014000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
366 {"NUC140RC1CN", 0x20014017, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
367 {"NUC140RD2CN", 0x20014013, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
368 {"NUC140RE3CN", 0x20014009, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
369 {"NUC140VE3CN", 0x20014018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
372 {"NUC100LC1DN", 0x30010008, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
373 {"NUC100LD1DN", 0x30010005, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
374 {"NUC100LD2DN", 0x30010004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
375 {"NUC100LD3DN", 0x30010003, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
376 {"NUC100LE3DN", 0x30010000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
377 {"NUC100RC1DN", 0x30010017, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
378 {"NUC100RD1DN", 0x30010014, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
379 {"NUC100RD2DN", 0x30010013, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
380 {"NUC100RD3DN", 0x30010012, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
381 {"NUC100RE3DN", 0x30010009, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
382 {"NUC100VD2DN", 0x30010022, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
383 {"NUC100VD3DN", 0x30010021, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
384 {"NUC100VE3DN", 0x30010018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
385 {"NUC120LC1DN", 0x30012008, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
386 {"NUC120LD1DN", 0x30012005, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
387 {"NUC120LD2DN", 0x30012004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
388 {"NUC120LD3DN", 0x30012003, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
389 {"NUC120LE3DN", 0x30012000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
390 {"NUC120RC1DN", 0x30012035, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
391 {"NUC120RD1DN", 0x30012032, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
392 {"NUC120RD2DN", 0x30012031, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
393 {"NUC120RD3DN", 0x30012030, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
394 {"NUC120RE3DN", 0x30012027, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
395 {"NUC120VD2DN", 0x30012022, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
396 {"NUC120VD3DN", 0x30012021, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
397 {"NUC120VE3DN", 0x30012018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
400 {"NUC121SC2AE", 0x00012105, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)},
401 {"NUC121LC2AE", 0x00012125, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)},
402 {"NUC121ZC2AE", 0x00012145, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)},
403 {"NUC125SC2AE", 0x00012505, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)},
404 {"NUC125LC2AE", 0x00012525, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)},
405 {"NUC125ZC2AE", 0x00012545, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)},
408 {"NUC122LC1AN", 0x00012208, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
409 {"NUC122LD2AN", 0x00012204, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
410 {"NUC122SC1AN", 0x00012226, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
411 {"NUC122SD2AN", 0x00012222, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
412 {"NUC122ZC1AN", 0x00012235, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
413 {"NUC122ZD2AN", 0x00012231, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
416 {"NUC123LC2AN1", 0x00012325, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
417 {"NUC123LD4AN0", 0x00012335, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
418 {"NUC123SC2AN1", 0x00012305, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
419 {"NUC123SD4AN0", 0x00012315, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
420 {"NUC123ZC2AN1", 0x00012345, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
421 {"NUC123ZD4AN0", 0x00012355, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
424 {"NUC123LC2AE1", 0x10012325, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
425 {"NUC123LD4AE0", 0x10012335, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
426 {"NUC123SC2AE1", 0x10012305, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
427 {"NUC123SD4AE0", 0x10012315, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
428 {"NUC123ZC2AE1", 0x10012345, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
429 {"NUC123ZD4AE0", 0x10012355, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
432 {"NUC131LC2AE", 0x10013103, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
433 {"NUC131LD2AE", 0x10013100, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
434 {"NUC131SC2AE", 0x10013113, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
435 {"NUC131SD2AE", 0x10013110, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
438 {"NUC200LC2AN", 0x00020007, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
439 {"NUC200LD2AN", 0x00020004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
440 {"NUC200LE3AN", 0x00020000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
441 {"NUC200SC2AN", 0x00020034, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
442 {"NUC200SD2AN", 0x00020031, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
443 {"NUC200SE3AN", 0x00020027, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
444 {"NUC200VE3AN", 0x00020018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
445 {"NUC220LC2AN", 0x00022007, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
446 {"NUC220LD2AN", 0x00022004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
447 {"NUC220LE3AN", 0x00022000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
448 {"NUC220SC2AN", 0x00022034, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},
449 {"NUC220SD2AN", 0x00022031, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},
450 {"NUC220SE3AN", 0x00022027, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
451 {"NUC220VE3AN", 0x00022018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
454 {"NUC230LC2AE", 0x10023007, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 8 * 1024, 8)},
455 {"NUC230LD2AE", 0x10023004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 8 * 1024, 8)},
456 {"NUC230LE3AE", 0x10023000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},
457 {"NUC230SC2AE", 0x10023034, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 8 * 1024, 8)},
458 {"NUC230SD2AE", 0x10023031, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 8 * 1024, 8)},
459 {"NUC230SE3AE", 0x10023027, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},
460 {"NUC230VE3AE", 0x10023018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},
461 {"NUC240LC2AE", 0x10024007, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 8 * 1024, 8)},
462 {"NUC240LD2AE", 0x10024004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 8 * 1024, 8)},
463 {"NUC240LE3AE", 0x10024000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},
464 {"NUC240SC2AE", 0x10024034, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 8 * 1024, 8)},
465 {"NUC240SD2AE", 0x10024031, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 8 * 1024, 8)},
466 {"NUC240SE3AE", 0x10024027, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},
467 {"NUC240VE3AE", 0x10024018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},
470 {"M451LC3AE", 0x00945101, NUMICRO_BANKS_GENERAL(40 * 1024, 0 * 1024, 4 * 1024, 8)},
471 {"M451LD3AE", 0x00945100, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)},
472 {"M451LE6AE", 0x00845101, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
473 {"M451LG6AE", 0x00845100, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},
474 {"M451MLC3AE", 0x00945001, NUMICRO_BANKS_GENERAL(40 * 1024, 0 * 1024, 4 * 1024, 8)},
475 {"M451MLD3AE", 0x00945000, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)},
476 {"M451MLE6AE", 0x00845001, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
477 {"M451MLG6AE", 0x00845000, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},
478 {"M451MSC3AE", 0x00945011, NUMICRO_BANKS_GENERAL(40 * 1024, 0 * 1024, 4 * 1024, 8)},
479 {"M451MSD3AE", 0x00945010, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)},
480 {"M451RC3AE", 0x00945121, NUMICRO_BANKS_GENERAL(40 * 1024, 0 * 1024, 4 * 1024, 8)},
481 {"M451RD3AE", 0x00945120, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)},
482 {"M451RE6AE", 0x00845121, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
483 {"M451RG6AE", 0x00845120, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},
484 {"M451VE6AE", 0x00845131, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
485 {"M451VG6AE", 0x00845130, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},
486 {"M452LC3AE", 0x00945201, NUMICRO_BANKS_GENERAL(40 * 1024, 0 * 1024, 4 * 1024, 8)},
487 {"M452LD3AE", 0x00945200, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)},
488 {"M452LE6AE", 0x00845201, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
489 {"M452LG6AE", 0x00845200, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},
490 {"M452RD3AE", 0x00945220, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)},
491 {"M452RE6AE", 0x00845221, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
492 {"M452RG6AE", 0x00845220, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},
493 {"M453LC3AE", 0x00945301, NUMICRO_BANKS_GENERAL(40 * 1024, 0 * 1024, 4 * 1024, 8)},
494 {"M453LD3AE", 0x00945300, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)},
495 {"M453LE6AE", 0x00845301, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
496 {"M453LG6AE", 0x00845300, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},
497 {"M453RD3AE", 0x00945320, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)},
498 {"M453RE6AE", 0x00845321, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
499 {"M453RG6AE", 0x00845320, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},
500 {"M453VD3AE", 0x00945330, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)},
501 {"M453VE6AE", 0x00845331, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
502 {"M453VG6AE", 0x00845330, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},
503 {"M4TKVG6AE", 0x00845430, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},
504 {"M4TKVE6AE", 0x00845431, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
505 {"M4TKRG6AE", 0x00845420, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},
506 {"M4TKRE6AE", 0x00845421, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
507 {"M4TKLG6AE", 0x00845400, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},
508 {"M4TKLE6AE", 0x00845401, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},
511 {"NUC442JG8AE", 0x00044203, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)},
512 {"NUC442JI8AE", 0x00044201, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)},
513 {"NUC442KG8AE", 0x00044206, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)},
514 {"NUC442KI8AE", 0x00044204, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)},
515 {"NUC442RG8AE", 0x00044212, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)},
516 {"NUC442RI8AE", 0x00044210, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)},
517 {"NUC442VG8AE", 0x00044209, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)},
518 {"NUC442VI8AE", 0x00044207, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)},
519 {"NUC472HG8AE", 0x00047203, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)},
520 {"NUC472HI8AE", 0x00047201, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)},
521 {"NUC472JG8AE", 0x00047206, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)},
522 {"NUC472JI8AE", 0x00047204, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)},
523 {"NUC472KG8AE", 0x00047209, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)},
524 {"NUC472KI8AE", 0x00047207, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)},
525 {"NUC472VG8AE", 0x00047212, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)},
526 {"NUC472VI8AE", 0x00047210, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)},
528 {"UNKNOWN", 0x00000000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 16 * 1024, 8)},
531 /* Private bank information for NuMicro. */
532 struct numicro_flash_bank
{
533 struct working_area
*write_algorithm
;
535 const struct numicro_cpu_type
*cpu
;
538 /* Private variables */
539 static uint32_t m_page_size
= NUMICRO_PAGESIZE
;
540 static uint32_t m_address_bias_offset
;
542 /* Private methods */
543 static int numicro_get_arm_arch(struct target
*target
)
545 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
547 if (armv7m
->arm
.arch
!= ARM_ARCH_V6M
) {
548 LOG_DEBUG("NuMicro arm architecture: armv7m\n");
549 m_page_size
= NUMICRO_PAGESIZE
* 4;
550 m_address_bias_offset
= 0x10000000;
552 LOG_DEBUG("NuMicro arm architecture: armv6m\n");
553 m_page_size
= NUMICRO_PAGESIZE
;
554 m_address_bias_offset
= 0x0;
560 static int numicro_reg_unlock(struct target
*target
)
562 uint32_t is_protected
;
563 int retval
= ERROR_OK
;
565 /* Check to see if NUC is register unlocked or not */
566 retval
= target_read_u32(target
, NUMICRO_SYS_WRPROT
- m_address_bias_offset
, &is_protected
);
567 if (retval
!= ERROR_OK
)
570 LOG_DEBUG("protected = 0x%08" PRIx32
"", is_protected
);
571 if (is_protected
== 0) { /* means protected - so unlock it */
572 /* unlock flash registers */
573 retval
= target_write_u32(target
, NUMICRO_SYS_WRPROT
- m_address_bias_offset
, REG_KEY1
);
574 if (retval
!= ERROR_OK
)
576 retval
= target_write_u32(target
, NUMICRO_SYS_WRPROT
- m_address_bias_offset
, REG_KEY2
);
577 if (retval
!= ERROR_OK
)
579 retval
= target_write_u32(target
, NUMICRO_SYS_WRPROT
- m_address_bias_offset
, REG_KEY3
);
580 if (retval
!= ERROR_OK
)
583 /* Check that unlock worked */
584 retval
= target_read_u32(target
, NUMICRO_SYS_WRPROT
- m_address_bias_offset
, &is_protected
);
585 if (retval
!= ERROR_OK
)
588 if (is_protected
== 1) { /* means unprotected */
589 LOG_DEBUG("protection removed");
591 LOG_DEBUG("still protected!!");
597 static int numicro_init_isp(struct target
*target
)
600 int retval
= ERROR_OK
;
602 if (target
->state
!= TARGET_HALTED
) {
603 LOG_ERROR("Target not halted");
604 return ERROR_TARGET_NOT_HALTED
;
607 retval
= numicro_reg_unlock(target
);
608 if (retval
!= ERROR_OK
)
611 /* Enable ISP/SRAM/TICK Clock */
612 retval
= target_read_u32(target
, NUMICRO_SYSCLK_AHBCLK
- m_address_bias_offset
, ®_stat
);
613 if (retval
!= ERROR_OK
)
616 reg_stat
|= AHBCLK_ISP_EN
| AHBCLK_SRAM_EN
| AHBCLK_TICK_EN
;
617 retval
= target_write_u32(target
, NUMICRO_SYSCLK_AHBCLK
- m_address_bias_offset
, reg_stat
);
618 if (retval
!= ERROR_OK
)
622 retval
= target_read_u32(target
, NUMICRO_FLASH_ISPCON
- m_address_bias_offset
, ®_stat
);
623 if (retval
!= ERROR_OK
)
626 reg_stat
|= ISPCON_ISPFF
| ISPCON_LDUEN
| ISPCON_APUEN
| ISPCON_CFGUEN
| ISPCON_ISPEN
;
627 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPCON
- m_address_bias_offset
, reg_stat
);
628 if (retval
!= ERROR_OK
)
631 /* Write one to undocumented flash control register */
632 retval
= target_write_u32(target
, NUMICRO_FLASH_CHEAT
- m_address_bias_offset
, 1);
633 if (retval
!= ERROR_OK
)
639 static uint32_t numicro_fmc_cmd(struct target
*target
, uint32_t cmd
, uint32_t addr
, uint32_t wdata
, uint32_t *rdata
)
641 uint32_t timeout
, status
;
642 int retval
= ERROR_OK
;
644 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPCMD
- m_address_bias_offset
, cmd
);
645 if (retval
!= ERROR_OK
)
648 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPDAT
- m_address_bias_offset
, wdata
);
649 if (retval
!= ERROR_OK
)
652 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPADR
- m_address_bias_offset
, addr
);
653 if (retval
!= ERROR_OK
)
656 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPTRG
- m_address_bias_offset
, ISPTRG_ISPGO
);
657 if (retval
!= ERROR_OK
)
660 /* Wait for busy to clear - check the GO flag */
663 retval
= target_read_u32(target
, NUMICRO_FLASH_ISPTRG
- m_address_bias_offset
, &status
);
664 if (retval
!= ERROR_OK
)
666 if ((status
& (ISPTRG_ISPGO
)) == 0)
668 if (timeout
-- <= 0) {
669 LOG_DEBUG("timed out waiting for flash");
672 busy_sleep(1); /* can use busy sleep for short times. */
675 retval
= target_read_u32(target
, NUMICRO_FLASH_ISPDAT
- m_address_bias_offset
, rdata
);
676 if (retval
!= ERROR_OK
)
682 /* NuMicro Program-LongWord Microcodes */
683 static const uint8_t numicro_flash_write_code
[] = {
684 #include "../../../contrib/loaders/flash/numicro/numicro_m0.inc"
687 static const uint8_t numicro_m4_flash_write_code
[] = {
688 #include "../../../contrib/loaders/flash/numicro/numicro_m4.inc"
691 /* Program LongWord Block Write */
692 static int numicro_writeblock(struct flash_bank
*bank
, const uint8_t *buffer
,
693 uint32_t offset
, uint32_t count
)
695 struct target
*target
= bank
->target
;
696 uint32_t buffer_size
= 1024; /* Default minimum value */
697 struct working_area
*write_algorithm
;
698 struct working_area
*source
;
699 uint32_t address
= bank
->base
+ offset
;
700 struct reg_param reg_params
[3];
701 struct armv7m_algorithm armv7m_info
;
702 int retval
= ERROR_OK
;
705 * r0 - workarea buffer / result
706 * r1 - target address
715 /* Increase buffer_size if needed */
716 if (buffer_size
< (target
->working_area_size
/2))
717 buffer_size
= (target
->working_area_size
/2);
719 /* check code alignment */
721 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
722 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
724 /* Difference between M0 and M4 */
725 if (m_page_size
== NUMICRO_PAGESIZE
) {
726 /* allocate working area with flash programming code */
727 if (target_alloc_working_area(target
, sizeof(numicro_flash_write_code
),
728 &write_algorithm
) != ERROR_OK
) {
729 LOG_WARNING("no working area available, can't do block memory writes");
730 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
733 retval
= target_write_buffer(target
, write_algorithm
->address
,
734 sizeof(numicro_flash_write_code
), numicro_flash_write_code
);
735 if (retval
!= ERROR_OK
)
737 } else { /* for M4 */
738 /* allocate working area with flash programming code */
739 if (target_alloc_working_area(target
, sizeof(numicro_m4_flash_write_code
),
740 &write_algorithm
) != ERROR_OK
) {
741 LOG_WARNING("no working area available, can't do block memory writes");
742 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
745 retval
= target_write_buffer(target
, write_algorithm
->address
,
746 sizeof(numicro_m4_flash_write_code
), numicro_m4_flash_write_code
);
747 if (retval
!= ERROR_OK
)
750 buffer_size
= m_page_size
;
754 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
) {
756 if (buffer_size
<= 256) {
757 /* free working area, write algorithm already allocated */
758 target_free_working_area(target
, write_algorithm
);
760 LOG_WARNING("No large enough working area available, can't do block memory writes");
761 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
765 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
766 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
768 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
); /* *pLW (*buffer) */
769 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* faddr */
770 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* number of words to program */
772 /* write code buffer and use Flash programming code within NuMicro */
773 /* Set breakpoint to 0 with time-out of 1000 ms */
775 uint32_t thisrun_count
= (count
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : count
;
777 retval
= target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
778 if (retval
!= ERROR_OK
)
781 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
782 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
783 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
785 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
786 write_algorithm
->address
, 0, 100000, &armv7m_info
);
787 if (retval
!= ERROR_OK
) {
788 LOG_ERROR("Error executing NuMicro Flash programming algorithm");
789 retval
= ERROR_FLASH_OPERATION_FAILED
;
793 buffer
+= thisrun_count
* 4;
794 address
+= thisrun_count
* 4;
795 count
-= thisrun_count
;
798 target_free_working_area(target
, source
);
799 target_free_working_area(target
, write_algorithm
);
801 destroy_reg_param(®_params
[0]);
802 destroy_reg_param(®_params
[1]);
803 destroy_reg_param(®_params
[2]);
808 /* Flash Lock checking - examines the lock bit. */
809 static int numicro_protect_check(struct flash_bank
*bank
)
811 struct target
*target
= bank
->target
;
812 uint32_t set
, config
[2];
813 int retval
= ERROR_OK
;
815 if (target
->state
!= TARGET_HALTED
) {
816 LOG_ERROR("Target not halted");
817 return ERROR_TARGET_NOT_HALTED
;
820 LOG_INFO("Nuvoton NuMicro: Flash Lock Check...");
822 numicro_get_arm_arch(target
);
823 retval
= numicro_init_isp(target
);
824 if (retval
!= ERROR_OK
)
827 /* Read CONFIG0,CONFIG1 */
828 numicro_fmc_cmd(target
, ISPCMD_READ
, NUMICRO_CONFIG0
- m_address_bias_offset
, 0, &config
[0]);
829 numicro_fmc_cmd(target
, ISPCMD_READ
, NUMICRO_CONFIG1
- m_address_bias_offset
, 0, &config
[1]);
831 LOG_DEBUG("CONFIG0: 0x%" PRIx32
",CONFIG1: 0x%" PRIx32
"", config
[0], config
[1]);
833 if ((config
[0] & (1<<7)) == 0)
834 LOG_INFO("CBS=0: Boot From LPROM");
836 LOG_INFO("CBS=1: Boot From APROM");
838 if ((config
[0] & CONFIG0_LOCK_MASK
) == 0) {
840 LOG_INFO("Flash is secure locked!");
841 LOG_INFO("TO UNLOCK FLASH,EXECUTE chip_erase COMMAND!!");
844 LOG_INFO("Flash is not locked!");
848 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++)
849 bank
->sectors
[i
].is_protected
= set
;
855 static int numicro_erase(struct flash_bank
*bank
, unsigned int first
,
858 struct target
*target
= bank
->target
;
859 uint32_t timeout
, status
;
860 int retval
= ERROR_OK
;
862 if (target
->state
!= TARGET_HALTED
) {
863 LOG_ERROR("Target not halted");
864 return ERROR_TARGET_NOT_HALTED
;
867 LOG_INFO("Nuvoton NuMicro: Sector Erase ... (%u to %u)", first
, last
);
869 numicro_get_arm_arch(target
);
870 retval
= numicro_init_isp(target
);
871 if (retval
!= ERROR_OK
)
874 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPCMD
- m_address_bias_offset
, ISPCMD_ERASE
);
875 if (retval
!= ERROR_OK
)
878 for (unsigned int i
= first
; i
<= last
; i
++) {
879 LOG_DEBUG("erasing sector %u at address " TARGET_ADDR_FMT
, i
, bank
->base
+ bank
->sectors
[i
].offset
);
880 retval
= target_write_u32(target
,
881 NUMICRO_FLASH_ISPADR
- m_address_bias_offset
,
882 bank
->base
+ bank
->sectors
[i
].offset
);
883 if (retval
!= ERROR_OK
)
885 retval
= target_write_u32(target
,
886 NUMICRO_FLASH_ISPTRG
- m_address_bias_offset
,
887 ISPTRG_ISPGO
); /* This is the only bit available */
888 if (retval
!= ERROR_OK
)
891 /* wait for busy to clear - check the GO flag */
894 retval
= target_read_u32(target
, NUMICRO_FLASH_ISPTRG
- m_address_bias_offset
, &status
);
895 if (retval
!= ERROR_OK
)
899 if (timeout
-- <= 0) {
900 LOG_DEBUG("timed out waiting for flash");
903 busy_sleep(1); /* can use busy sleep for short times. */
906 /* check for failure */
907 retval
= target_read_u32(target
, NUMICRO_FLASH_ISPCON
- m_address_bias_offset
, &status
);
908 if (retval
!= ERROR_OK
)
910 if ((status
& ISPCON_ISPFF
) != 0) {
911 LOG_DEBUG("failure: 0x%" PRIx32
"", status
);
912 /* if bit is set, then must write to it to clear it. */
913 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPCON
- m_address_bias_offset
, (status
| ISPCON_ISPFF
));
914 if (retval
!= ERROR_OK
)
920 LOG_DEBUG("Erase done.");
925 /* The write routine stub. */
926 static int numicro_write(struct flash_bank
*bank
, const uint8_t *buffer
,
927 uint32_t offset
, uint32_t count
)
929 struct target
*target
= bank
->target
;
930 uint32_t timeout
, status
;
931 int retval
= ERROR_OK
;
933 if (target
->state
!= TARGET_HALTED
) {
934 LOG_ERROR("Target not halted");
935 return ERROR_TARGET_NOT_HALTED
;
938 LOG_INFO("Nuvoton NuMicro: Flash Write ...");
940 numicro_get_arm_arch(target
);
941 retval
= numicro_init_isp(target
);
942 if (retval
!= ERROR_OK
)
945 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPCMD
- m_address_bias_offset
, ISPCMD_WRITE
);
946 if (retval
!= ERROR_OK
)
949 assert(offset
% 4 == 0);
950 assert(count
% 4 == 0);
952 uint32_t words_remaining
= count
/ 4;
954 /* try using a block write */
955 retval
= numicro_writeblock(bank
, buffer
, offset
, words_remaining
);
957 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
) {
958 /* if block write failed (no sufficient working area),
959 * we use normal (slow) single word accesses */
960 LOG_WARNING("couldn't use block writes, falling back to single "
963 /* program command */
964 for (uint32_t i
= 0; i
< count
; i
+= 4) {
965 /* write 4 bytes each time with 0xff padding to avoid unaligned case */
966 uint8_t padding
[4] = {0xff, 0xff, 0xff, 0xff};
967 memcpy(padding
, buffer
+ i
, MIN(4, count
- i
));
969 retval
= target_write_u32(target
,
970 NUMICRO_FLASH_ISPADR
- m_address_bias_offset
,
971 bank
->base
+ offset
+ i
);
972 if (retval
!= ERROR_OK
)
974 retval
= target_write_memory(target
,
975 NUMICRO_FLASH_ISPDAT
- m_address_bias_offset
,
977 if (retval
!= ERROR_OK
)
979 retval
= target_write_u32(target
,
980 NUMICRO_FLASH_ISPTRG
- m_address_bias_offset
,
982 if (retval
!= ERROR_OK
)
985 /* wait for busy to clear - check the GO flag */
988 retval
= target_read_u32(target
,
989 NUMICRO_FLASH_ISPTRG
- m_address_bias_offset
,
991 if (retval
!= ERROR_OK
)
995 if (timeout
-- <= 0) {
996 LOG_DEBUG("timed out waiting for flash");
999 busy_sleep(1); /* can use busy sleep for short times. */
1005 /* check for failure */
1006 retval
= target_read_u32(target
, NUMICRO_FLASH_ISPCON
- m_address_bias_offset
, &status
);
1007 if (retval
!= ERROR_OK
)
1009 if ((status
& ISPCON_ISPFF
) != 0) {
1010 LOG_DEBUG("failure: 0x%" PRIx32
"", status
);
1011 /* if bit is set, then must write to it to clear it. */
1012 retval
= target_write_u32(target
,
1013 NUMICRO_FLASH_ISPCON
- m_address_bias_offset
,
1014 (status
| ISPCON_ISPFF
));
1015 if (retval
!= ERROR_OK
)
1018 LOG_DEBUG("Write OK");
1022 LOG_DEBUG("Write done.");
1027 static int numicro_get_cpu_type(struct target
*target
, const struct numicro_cpu_type
**cpu
)
1030 int retval
= ERROR_OK
;
1032 numicro_get_arm_arch(target
);
1033 /* Read NuMicro PartID */
1034 retval
= target_read_u32(target
, NUMICRO_SYS_BASE
- m_address_bias_offset
, &part_id
);
1035 if (retval
!= ERROR_OK
) {
1036 LOG_WARNING("NuMicro flash driver: Failed to Get PartID\n");
1037 return ERROR_FLASH_OPERATION_FAILED
;
1040 LOG_INFO("Device ID: 0x%08" PRIx32
"", part_id
);
1041 /* search part numbers */
1042 for (size_t i
= 0; i
< ARRAY_SIZE(numicro_parts
); i
++) {
1043 if (part_id
== numicro_parts
[i
].partid
) {
1044 *cpu
= &numicro_parts
[i
];
1045 LOG_INFO("Device Name: %s", (*cpu
)->partname
);
1053 static int numicro_get_flash_size(struct flash_bank
*bank
, const struct numicro_cpu_type
*cpu
, uint32_t *flash_size
)
1055 for (size_t i
= 0; i
< cpu
->n_banks
; i
++) {
1056 if (bank
->base
== cpu
->bank
[i
].base
) {
1057 *flash_size
= cpu
->bank
[i
].size
;
1058 LOG_INFO("bank base = " TARGET_ADDR_FMT
", size = 0x%08"
1059 PRIx32
, bank
->base
, *flash_size
);
1063 return ERROR_FLASH_OPERATION_FAILED
;
1066 static int numicro_probe(struct flash_bank
*bank
)
1068 uint32_t flash_size
, offset
= 0;
1070 const struct numicro_cpu_type
*cpu
;
1071 struct target
*target
= bank
->target
;
1072 int retval
= ERROR_OK
;
1074 retval
= numicro_get_cpu_type(target
, &cpu
);
1075 if (retval
!= ERROR_OK
) {
1076 LOG_WARNING("NuMicro flash driver: Failed to detect a known part\n");
1077 return ERROR_FLASH_OPERATION_FAILED
;
1080 retval
= numicro_get_flash_size(bank
, cpu
, &flash_size
);
1081 if (retval
!= ERROR_OK
) {
1082 LOG_WARNING("NuMicro flash driver: Failed to detect flash size\n");
1083 return ERROR_FLASH_OPERATION_FAILED
;
1086 num_pages
= flash_size
/ m_page_size
;
1088 bank
->num_sectors
= num_pages
;
1089 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_pages
);
1090 bank
->size
= flash_size
;
1092 for (int i
= 0; i
< num_pages
; i
++) {
1093 bank
->sectors
[i
].offset
= offset
;
1094 bank
->sectors
[i
].size
= m_page_size
;
1095 bank
->sectors
[i
].is_erased
= -1;
1096 bank
->sectors
[i
].is_protected
= 0;
1097 offset
+= m_page_size
;
1100 struct numicro_flash_bank
*numicro_info
= bank
->driver_priv
;
1101 numicro_info
->probed
= true;
1102 numicro_info
->cpu
= cpu
;
1103 LOG_DEBUG("Nuvoton NuMicro: Probed ...");
1108 /* Standard approach to autoprobing. */
1109 static int numicro_auto_probe(struct flash_bank
*bank
)
1111 struct numicro_flash_bank
*numicro_info
= bank
->driver_priv
;
1112 if (numicro_info
->probed
)
1114 return numicro_probe(bank
);
1118 /* This is the function called in the config file. */
1119 FLASH_BANK_COMMAND_HANDLER(numicro_flash_bank_command
)
1121 struct numicro_flash_bank
*bank_info
;
1124 return ERROR_COMMAND_SYNTAX_ERROR
;
1126 LOG_DEBUG("add flash_bank numicro %s", bank
->name
);
1128 bank_info
= malloc(sizeof(struct numicro_flash_bank
));
1130 memset(bank_info
, 0, sizeof(struct numicro_flash_bank
));
1132 bank
->driver_priv
= bank_info
;
1133 bank
->write_start_alignment
= bank
->write_end_alignment
= 4;
1138 COMMAND_HANDLER(numicro_handle_read_isp_command
)
1142 int retval
= ERROR_OK
;
1145 return ERROR_COMMAND_SYNTAX_ERROR
;
1147 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1149 struct target
*target
= get_current_target(CMD_CTX
);
1151 numicro_get_arm_arch(target
);
1152 retval
= numicro_init_isp(target
);
1153 if (retval
!= ERROR_OK
)
1156 retval
= numicro_fmc_cmd(target
, ISPCMD_READ
, address
, 0, &ispdat
);
1157 if (retval
!= ERROR_OK
)
1160 LOG_INFO("0x%08" PRIx32
": 0x%08" PRIx32
, address
, ispdat
);
1165 COMMAND_HANDLER(numicro_handle_write_isp_command
)
1168 uint32_t ispdat
, rdat
;
1169 int retval
= ERROR_OK
;
1172 return ERROR_COMMAND_SYNTAX_ERROR
;
1174 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1175 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], ispdat
);
1177 struct target
*target
= get_current_target(CMD_CTX
);
1179 numicro_get_arm_arch(target
);
1180 retval
= numicro_init_isp(target
);
1181 if (retval
!= ERROR_OK
)
1184 retval
= numicro_fmc_cmd(target
, ISPCMD_WRITE
, address
, ispdat
, &rdat
);
1185 if (retval
!= ERROR_OK
)
1188 LOG_INFO("0x%08" PRIx32
": 0x%08" PRIx32
, address
, ispdat
);
1192 COMMAND_HANDLER(numicro_handle_chip_erase_command
)
1194 int retval
= ERROR_OK
;
1198 return ERROR_COMMAND_SYNTAX_ERROR
;
1200 struct target
*target
= get_current_target(CMD_CTX
);
1202 numicro_get_arm_arch(target
);
1203 retval
= numicro_init_isp(target
);
1204 if (retval
!= ERROR_OK
)
1207 retval
= numicro_fmc_cmd(target
, ISPCMD_CHIPERASE
, 0, 0, &rdat
);
1208 if (retval
!= ERROR_OK
) {
1209 command_print(CMD
, "numicro chip_erase failed");
1213 command_print(CMD
, "numicro chip_erase complete");
1218 static const struct command_registration numicro_exec_command_handlers
[] = {
1221 .handler
= numicro_handle_read_isp_command
,
1223 .mode
= COMMAND_EXEC
,
1224 .help
= "read flash through ISP.",
1227 .name
= "write_isp",
1228 .handler
= numicro_handle_write_isp_command
,
1229 .usage
= "address value",
1230 .mode
= COMMAND_EXEC
,
1231 .help
= "write flash through ISP.",
1234 .name
= "chip_erase",
1235 .handler
= numicro_handle_chip_erase_command
,
1236 .mode
= COMMAND_EXEC
,
1237 .help
= "chip erase through ISP.",
1240 COMMAND_REGISTRATION_DONE
1243 static const struct command_registration numicro_command_handlers
[] = {
1246 .mode
= COMMAND_ANY
,
1247 .help
= "numicro flash command group",
1249 .chain
= numicro_exec_command_handlers
,
1251 COMMAND_REGISTRATION_DONE
1254 const struct flash_driver numicro_flash
= {
1256 .commands
= numicro_command_handlers
,
1257 .flash_bank_command
= numicro_flash_bank_command
,
1258 .erase
= numicro_erase
,
1259 .write
= numicro_write
,
1260 .read
= default_flash_read
,
1261 .probe
= numicro_probe
,
1262 .auto_probe
= numicro_auto_probe
,
1263 .erase_check
= default_flash_blank_check
,
1264 .protect_check
= numicro_protect_check
,
1265 .free_driver_priv
= default_flash_free_driver_priv
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)