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)},
469 {"UNKNOWN", 0x00000000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 16 * 1024, 8)},
472 /* Private bank information for NuMicro. */
473 struct numicro_flash_bank
{
474 struct working_area
*write_algorithm
;
476 const struct numicro_cpu_type
*cpu
;
479 /* Private methods */
480 static int numicro_reg_unlock(struct target
*target
)
482 uint32_t is_protected
;
483 int retval
= ERROR_OK
;
485 /* Check to see if NUC is register unlocked or not */
486 retval
= target_read_u32(target
, NUMICRO_SYS_WRPROT
, &is_protected
);
487 if (retval
!= ERROR_OK
)
490 LOG_DEBUG("protected = 0x%08" PRIx32
"", is_protected
);
491 if (is_protected
== 0) { /* means protected - so unlock it */
492 /* unlock flash registers */
493 retval
= target_write_u32(target
, NUMICRO_SYS_WRPROT
, REG_KEY1
);
494 if (retval
!= ERROR_OK
)
496 retval
= target_write_u32(target
, NUMICRO_SYS_WRPROT
, REG_KEY2
);
497 if (retval
!= ERROR_OK
)
499 retval
= target_write_u32(target
, NUMICRO_SYS_WRPROT
, REG_KEY3
);
500 if (retval
!= ERROR_OK
)
503 /* Check that unlock worked */
504 retval
= target_read_u32(target
, NUMICRO_SYS_WRPROT
, &is_protected
);
505 if (retval
!= ERROR_OK
)
508 if (is_protected
== 1) { /* means unprotected */
509 LOG_DEBUG("protection removed");
511 LOG_DEBUG("still protected!!");
517 static int numicro_init_isp(struct target
*target
)
520 int retval
= ERROR_OK
;
522 if (target
->state
!= TARGET_HALTED
) {
523 LOG_ERROR("Target not halted");
524 return ERROR_TARGET_NOT_HALTED
;
527 retval
= numicro_reg_unlock(target
);
528 if (retval
!= ERROR_OK
)
531 /* Enable ISP/SRAM/TICK Clock */
532 retval
= target_read_u32(target
, NUMICRO_SYSCLK_AHBCLK
, ®_stat
);
533 if (retval
!= ERROR_OK
)
536 reg_stat
|= AHBCLK_ISP_EN
| AHBCLK_SRAM_EN
| AHBCLK_TICK_EN
;
537 retval
= target_write_u32(target
, NUMICRO_SYSCLK_AHBCLK
, reg_stat
);
538 if (retval
!= ERROR_OK
)
542 retval
= target_read_u32(target
, NUMICRO_FLASH_ISPCON
, ®_stat
);
543 if (retval
!= ERROR_OK
)
546 reg_stat
|= ISPCON_ISPFF
| ISPCON_LDUEN
| ISPCON_APUEN
| ISPCON_CFGUEN
| ISPCON_ISPEN
;
547 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPCON
, reg_stat
);
548 if (retval
!= ERROR_OK
)
551 /* Write one to undocumented flash control register */
552 retval
= target_write_u32(target
, NUMICRO_FLASH_CHEAT
, 1);
553 if (retval
!= ERROR_OK
)
559 static uint32_t numicro_fmc_cmd(struct target
*target
, uint32_t cmd
, uint32_t addr
, uint32_t wdata
, uint32_t *rdata
)
561 uint32_t timeout
, status
;
562 int retval
= ERROR_OK
;
564 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPCMD
, cmd
);
565 if (retval
!= ERROR_OK
)
568 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPDAT
, wdata
);
569 if (retval
!= ERROR_OK
)
572 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPADR
, addr
);
573 if (retval
!= ERROR_OK
)
576 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPTRG
, ISPTRG_ISPGO
);
577 if (retval
!= ERROR_OK
)
580 /* Wait for busy to clear - check the GO flag */
583 retval
= target_read_u32(target
, NUMICRO_FLASH_ISPTRG
, &status
);
584 if (retval
!= ERROR_OK
)
586 LOG_DEBUG("status: 0x%" PRIx32
"", status
);
587 if ((status
& (ISPTRG_ISPGO
)) == 0)
589 if (timeout
-- <= 0) {
590 LOG_DEBUG("timed out waiting for flash");
593 busy_sleep(1); /* can use busy sleep for short times. */
596 retval
= target_read_u32(target
, NUMICRO_FLASH_ISPDAT
, rdata
);
597 if (retval
!= ERROR_OK
)
604 /* NuMicro Program-LongWord Microcodes */
605 static const uint8_t numicro_flash_write_code
[] = {
607 * r0 - workarea buffer / result
608 * r1 - target address
618 /* for(register uint32_t i=0;i<wcount;i++){ */
619 0x04, 0x1C, /* mov r4, r0 */
620 0x00, 0x23, /* mov r3, #0 */
622 0x0D, 0x1A, /* sub r5, r1, r0 */
623 0x67, 0x19, /* add r7, r4, r7 */
624 0x93, 0x42, /* cmp r3, r2 */
625 0x0C, 0xD0, /* beq .L7 */
627 /* NUMICRO_FLASH_ISPADR = faddr; */
628 0x08, 0x4E, /* ldr r6, .L8 */
629 0x37, 0x60, /* str r7, [r6] */
630 /* NUMICRO_FLASH_ISPDAT = *pLW; */
631 0x80, 0xCC, /* ldmia r4!, {r7} */
632 0x08, 0x4D, /* ldr r5, .L8+4 */
633 0x2F, 0x60, /* str r7, [r5] */
636 /* Trigger write action */
637 /* NUMICRO_FLASH_ISPTRG = ISPTRG_ISPGO; */
638 0x08, 0x4D, /* ldr r5, .L8+8 */
639 0x01, 0x26, /* mov r6, #1 */
640 0x2E, 0x60, /* str r6, [r5] */
642 /* while((NUMICRO_FLASH_ISPTRG & ISPTRG_ISPGO) == ISPTRG_ISPGO){}; */
643 0x2F, 0x68, /* ldr r7, [r5] */
644 0xFF, 0x07, /* lsl r7, r7, #31 */
645 0xFC, 0xD4, /* bmi .L3 */
647 0x01, 0x33, /* add r3, r3, #1 */
648 0xEE, 0xE7, /* b .L2 */
650 /* return (NUMICRO_FLASH_ISPCON & ISPCON_ISPFF); */
651 0x05, 0x4B, /* ldr r3, .L8+12 */
652 0x18, 0x68, /* ldr r0, [r3] */
653 0x40, 0x21, /* mov r1, #64 */
654 0x08, 0x40, /* and r0, r1 */
656 0x00, 0xBE, /* bkpt #0 */
658 0x04, 0xC0, 0x00, 0x50,/* .word 1342226436 */
659 0x08, 0xC0, 0x00, 0x50,/* .word 1342226440 */
660 0x10, 0xC0, 0x00, 0x50,/* .word 1342226448 */
661 0x00, 0xC0, 0x00, 0x50 /* .word 1342226432 */
663 /* Program LongWord Block Write */
664 static int numicro_writeblock(struct flash_bank
*bank
, const uint8_t *buffer
,
665 uint32_t offset
, uint32_t count
)
667 struct target
*target
= bank
->target
;
668 uint32_t buffer_size
= 1024; /* Default minimum value */
669 struct working_area
*write_algorithm
;
670 struct working_area
*source
;
671 uint32_t address
= bank
->base
+ offset
;
672 struct reg_param reg_params
[3];
673 struct armv7m_algorithm armv7m_info
;
674 int retval
= ERROR_OK
;
677 * r0 - workarea buffer / result
678 * r1 - target address
687 /* Increase buffer_size if needed */
688 if (buffer_size
< (target
->working_area_size
/2))
689 buffer_size
= (target
->working_area_size
/2);
691 /* check code alignment */
693 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
694 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
697 /* allocate working area with flash programming code */
698 if (target_alloc_working_area(target
, sizeof(numicro_flash_write_code
),
699 &write_algorithm
) != ERROR_OK
) {
700 LOG_WARNING("no working area available, can't do block memory writes");
701 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
704 retval
= target_write_buffer(target
, write_algorithm
->address
,
705 sizeof(numicro_flash_write_code
), numicro_flash_write_code
);
706 if (retval
!= ERROR_OK
)
710 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
) {
712 if (buffer_size
<= 256) {
713 /* free working area, write algorithm already allocated */
714 target_free_working_area(target
, write_algorithm
);
716 LOG_WARNING("No large enough working area available, can't do block memory writes");
717 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
721 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
722 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
724 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
); /* *pLW (*buffer) */
725 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* faddr */
726 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* number of words to program */
728 /* write code buffer and use Flash programming code within NuMicro */
729 /* Set breakpoint to 0 with time-out of 1000 ms */
731 uint32_t thisrun_count
= (count
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : count
;
733 retval
= target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
734 if (retval
!= ERROR_OK
)
737 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
738 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
739 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
741 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
742 write_algorithm
->address
, 0, 100000, &armv7m_info
);
743 if (retval
!= ERROR_OK
) {
744 LOG_ERROR("Error executing NuMicro Flash programming algorithm");
745 retval
= ERROR_FLASH_OPERATION_FAILED
;
749 buffer
+= thisrun_count
* 4;
750 address
+= thisrun_count
* 4;
751 count
-= thisrun_count
;
754 target_free_working_area(target
, source
);
755 target_free_working_area(target
, write_algorithm
);
757 destroy_reg_param(®_params
[0]);
758 destroy_reg_param(®_params
[1]);
759 destroy_reg_param(®_params
[2]);
764 /* Flash Lock checking - examines the lock bit. */
765 static int numicro_protect_check(struct flash_bank
*bank
)
767 struct target
*target
= bank
->target
;
768 uint32_t set
, config
[2];
769 int retval
= ERROR_OK
;
771 if (target
->state
!= TARGET_HALTED
) {
772 LOG_ERROR("Target not halted");
773 return ERROR_TARGET_NOT_HALTED
;
776 LOG_INFO("Nuvoton NuMicro: Flash Lock Check...");
778 retval
= numicro_init_isp(target
);
779 if (retval
!= ERROR_OK
)
782 /* Read CONFIG0,CONFIG1 */
783 numicro_fmc_cmd(target
, ISPCMD_READ
, NUMICRO_CONFIG0
, 0 , &config
[0]);
784 numicro_fmc_cmd(target
, ISPCMD_READ
, NUMICRO_CONFIG1
, 0 , &config
[1]);
786 LOG_DEBUG("CONFIG0: 0x%" PRIx32
",CONFIG1: 0x%" PRIx32
"", config
[0], config
[1]);
788 if ((config
[0] & (1<<7)) == 0)
789 LOG_INFO("CBS=0: Boot From LPROM");
791 LOG_INFO("CBS=1: Boot From APROM");
793 if ((config
[0] & CONFIG0_LOCK_MASK
) == 0) {
795 LOG_INFO("Flash is secure locked!");
796 LOG_INFO("TO UNLOCK FLASH,EXECUTE chip_erase COMMAND!!");
799 LOG_INFO("Flash is not locked!");
803 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++)
804 bank
->sectors
[i
].is_protected
= set
;
810 static int numicro_erase(struct flash_bank
*bank
, unsigned int first
,
813 struct target
*target
= bank
->target
;
814 uint32_t timeout
, status
;
815 int retval
= ERROR_OK
;
817 if (target
->state
!= TARGET_HALTED
) {
818 LOG_ERROR("Target not halted");
819 return ERROR_TARGET_NOT_HALTED
;
822 LOG_INFO("Nuvoton NuMicro: Sector Erase ... (%u to %u)", first
, last
);
824 retval
= numicro_init_isp(target
);
825 if (retval
!= ERROR_OK
)
828 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPCMD
, ISPCMD_ERASE
);
829 if (retval
!= ERROR_OK
)
832 for (unsigned int i
= first
; i
<= last
; i
++) {
833 LOG_DEBUG("erasing sector %u at address " TARGET_ADDR_FMT
, i
,
834 bank
->base
+ bank
->sectors
[i
].offset
);
835 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPADR
, bank
->base
+ bank
->sectors
[i
].offset
);
836 if (retval
!= ERROR_OK
)
838 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPTRG
, ISPTRG_ISPGO
); /* This is the only bit available */
839 if (retval
!= ERROR_OK
)
842 /* wait for busy to clear - check the GO flag */
845 retval
= target_read_u32(target
, NUMICRO_FLASH_ISPTRG
, &status
);
846 if (retval
!= ERROR_OK
)
848 LOG_DEBUG("status: 0x%" PRIx32
"", status
);
851 if (timeout
-- <= 0) {
852 LOG_DEBUG("timed out waiting for flash");
855 busy_sleep(1); /* can use busy sleep for short times. */
858 /* check for failure */
859 retval
= target_read_u32(target
, NUMICRO_FLASH_ISPCON
, &status
);
860 if (retval
!= ERROR_OK
)
862 if ((status
& ISPCON_ISPFF
) != 0) {
863 LOG_DEBUG("failure: 0x%" PRIx32
"", status
);
864 /* if bit is set, then must write to it to clear it. */
865 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPCON
, (status
| ISPCON_ISPFF
));
866 if (retval
!= ERROR_OK
)
872 LOG_DEBUG("Erase done.");
877 /* The write routine stub. */
878 static int numicro_write(struct flash_bank
*bank
, const uint8_t *buffer
,
879 uint32_t offset
, uint32_t count
)
881 struct target
*target
= bank
->target
;
882 uint32_t timeout
, status
;
883 int retval
= ERROR_OK
;
885 if (target
->state
!= TARGET_HALTED
) {
886 LOG_ERROR("Target not halted");
887 return ERROR_TARGET_NOT_HALTED
;
890 LOG_INFO("Nuvoton NuMicro: Flash Write ...");
892 retval
= numicro_init_isp(target
);
893 if (retval
!= ERROR_OK
)
896 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPCMD
, ISPCMD_WRITE
);
897 if (retval
!= ERROR_OK
)
900 assert(offset
% 4 == 0);
901 assert(count
% 4 == 0);
903 uint32_t words_remaining
= count
/ 4;
905 /* try using a block write */
906 retval
= numicro_writeblock(bank
, buffer
, offset
, words_remaining
);
908 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
) {
909 /* if block write failed (no sufficient working area),
910 * we use normal (slow) single word accesses */
911 LOG_WARNING("couldn't use block writes, falling back to single "
914 /* program command */
915 for (uint32_t i
= 0; i
< count
; i
+= 4) {
917 LOG_DEBUG("write longword @ %08" PRIX32
, offset
+ i
);
919 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPADR
, bank
->base
+ offset
+ i
);
920 if (retval
!= ERROR_OK
)
922 retval
= target_write_memory(target
, NUMICRO_FLASH_ISPDAT
, 4, 1, buffer
+ i
);
923 if (retval
!= ERROR_OK
)
925 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPTRG
, ISPTRG_ISPGO
);
926 if (retval
!= ERROR_OK
)
929 /* wait for busy to clear - check the GO flag */
932 retval
= target_read_u32(target
, NUMICRO_FLASH_ISPTRG
, &status
);
933 if (retval
!= ERROR_OK
)
935 LOG_DEBUG("status: 0x%" PRIx32
"", status
);
938 if (timeout
-- <= 0) {
939 LOG_DEBUG("timed out waiting for flash");
942 busy_sleep(1); /* can use busy sleep for short times. */
948 /* check for failure */
949 retval
= target_read_u32(target
, NUMICRO_FLASH_ISPCON
, &status
);
950 if (retval
!= ERROR_OK
)
952 if ((status
& ISPCON_ISPFF
) != 0) {
953 LOG_DEBUG("failure: 0x%" PRIx32
"", status
);
954 /* if bit is set, then must write to it to clear it. */
955 retval
= target_write_u32(target
, NUMICRO_FLASH_ISPCON
, (status
| ISPCON_ISPFF
));
956 if (retval
!= ERROR_OK
)
959 LOG_DEBUG("Write OK");
963 LOG_DEBUG("Write done.");
968 static int numicro_get_cpu_type(struct target
*target
, const struct numicro_cpu_type
**cpu
)
971 int retval
= ERROR_OK
;
973 /* Read NuMicro PartID */
974 retval
= target_read_u32(target
, NUMICRO_SYS_BASE
, &part_id
);
975 if (retval
!= ERROR_OK
) {
976 LOG_WARNING("NuMicro flash driver: Failed to Get PartID\n");
977 return ERROR_FLASH_OPERATION_FAILED
;
980 LOG_INFO("Device ID: 0x%08" PRIx32
"", part_id
);
981 /* search part numbers */
982 for (size_t i
= 0; i
< ARRAY_SIZE(numicro_parts
); i
++) {
983 if (part_id
== numicro_parts
[i
].partid
) {
984 *cpu
= &numicro_parts
[i
];
985 LOG_INFO("Device Name: %s", (*cpu
)->partname
);
993 static int numicro_get_flash_size(struct flash_bank
*bank
, const struct numicro_cpu_type
*cpu
, uint32_t *flash_size
)
995 for (size_t i
= 0; i
< cpu
->n_banks
; i
++) {
996 if (bank
->base
== cpu
->bank
[i
].base
) {
997 *flash_size
= cpu
->bank
[i
].size
;
998 LOG_INFO("bank base = " TARGET_ADDR_FMT
", size = 0x%08"
999 PRIx32
, bank
->base
, *flash_size
);
1003 return ERROR_FLASH_OPERATION_FAILED
;
1006 static int numicro_probe(struct flash_bank
*bank
)
1008 uint32_t flash_size
, offset
= 0;
1010 const struct numicro_cpu_type
*cpu
;
1011 struct target
*target
= bank
->target
;
1012 int retval
= ERROR_OK
;
1014 retval
= numicro_get_cpu_type(target
, &cpu
);
1015 if (retval
!= ERROR_OK
) {
1016 LOG_WARNING("NuMicro flash driver: Failed to detect a known part\n");
1017 return ERROR_FLASH_OPERATION_FAILED
;
1020 retval
= numicro_get_flash_size(bank
, cpu
, &flash_size
);
1021 if (retval
!= ERROR_OK
) {
1022 LOG_WARNING("NuMicro flash driver: Failed to detect flash size\n");
1023 return ERROR_FLASH_OPERATION_FAILED
;
1026 num_pages
= flash_size
/ NUMICRO_PAGESIZE
;
1028 bank
->num_sectors
= num_pages
;
1029 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_pages
);
1030 bank
->size
= flash_size
;
1032 for (int i
= 0; i
< num_pages
; i
++) {
1033 bank
->sectors
[i
].offset
= offset
;
1034 bank
->sectors
[i
].size
= NUMICRO_PAGESIZE
;
1035 bank
->sectors
[i
].is_erased
= -1;
1036 bank
->sectors
[i
].is_protected
= 0;
1037 offset
+= NUMICRO_PAGESIZE
;
1040 struct numicro_flash_bank
*numicro_info
= bank
->driver_priv
;
1041 numicro_info
->probed
= true;
1042 numicro_info
->cpu
= cpu
;
1043 LOG_DEBUG("Nuvoton NuMicro: Probed ...");
1048 /* Standard approach to autoprobing. */
1049 static int numicro_auto_probe(struct flash_bank
*bank
)
1051 struct numicro_flash_bank
*numicro_info
= bank
->driver_priv
;
1052 if (numicro_info
->probed
)
1054 return numicro_probe(bank
);
1058 /* This is the function called in the config file. */
1059 FLASH_BANK_COMMAND_HANDLER(numicro_flash_bank_command
)
1061 struct numicro_flash_bank
*bank_info
;
1064 return ERROR_COMMAND_SYNTAX_ERROR
;
1066 LOG_DEBUG("add flash_bank numicro %s", bank
->name
);
1068 bank_info
= malloc(sizeof(struct numicro_flash_bank
));
1070 memset(bank_info
, 0, sizeof(struct numicro_flash_bank
));
1072 bank
->driver_priv
= bank_info
;
1073 bank
->write_start_alignment
= bank
->write_end_alignment
= 4;
1079 COMMAND_HANDLER(numicro_handle_read_isp_command
)
1083 int retval
= ERROR_OK
;
1086 return ERROR_COMMAND_SYNTAX_ERROR
;
1088 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1090 struct target
*target
= get_current_target(CMD_CTX
);
1092 retval
= numicro_init_isp(target
);
1093 if (retval
!= ERROR_OK
)
1096 retval
= numicro_fmc_cmd(target
, ISPCMD_READ
, address
, 0, &ispdat
);
1097 if (retval
!= ERROR_OK
)
1100 LOG_INFO("0x%08" PRIx32
": 0x%08" PRIx32
, address
, ispdat
);
1105 COMMAND_HANDLER(numicro_handle_write_isp_command
)
1108 uint32_t ispdat
, rdat
;
1109 int retval
= ERROR_OK
;
1112 return ERROR_COMMAND_SYNTAX_ERROR
;
1114 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1115 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], ispdat
);
1117 struct target
*target
= get_current_target(CMD_CTX
);
1119 retval
= numicro_init_isp(target
);
1120 if (retval
!= ERROR_OK
)
1123 retval
= numicro_fmc_cmd(target
, ISPCMD_WRITE
, address
, ispdat
, &rdat
);
1124 if (retval
!= ERROR_OK
)
1127 LOG_INFO("0x%08" PRIx32
": 0x%08" PRIx32
, address
, ispdat
);
1131 COMMAND_HANDLER(numicro_handle_chip_erase_command
)
1133 int retval
= ERROR_OK
;
1137 return ERROR_COMMAND_SYNTAX_ERROR
;
1139 struct target
*target
= get_current_target(CMD_CTX
);
1141 retval
= numicro_init_isp(target
);
1142 if (retval
!= ERROR_OK
)
1145 retval
= numicro_fmc_cmd(target
, ISPCMD_CHIPERASE
, 0, 0, &rdat
);
1146 if (retval
!= ERROR_OK
) {
1147 command_print(CMD
, "numicro chip_erase failed");
1151 command_print(CMD
, "numicro chip_erase complete");
1156 static const struct command_registration numicro_exec_command_handlers
[] = {
1159 .handler
= numicro_handle_read_isp_command
,
1161 .mode
= COMMAND_EXEC
,
1162 .help
= "read flash through ISP.",
1165 .name
= "write_isp",
1166 .handler
= numicro_handle_write_isp_command
,
1167 .usage
= "address value",
1168 .mode
= COMMAND_EXEC
,
1169 .help
= "write flash through ISP.",
1172 .name
= "chip_erase",
1173 .handler
= numicro_handle_chip_erase_command
,
1174 .mode
= COMMAND_EXEC
,
1175 .help
= "chip erase through ISP.",
1178 COMMAND_REGISTRATION_DONE
1181 static const struct command_registration numicro_command_handlers
[] = {
1184 .mode
= COMMAND_ANY
,
1185 .help
= "numicro flash command group",
1187 .chain
= numicro_exec_command_handlers
,
1189 COMMAND_REGISTRATION_DONE
1192 const struct flash_driver numicro_flash
= {
1194 .commands
= numicro_command_handlers
,
1195 .flash_bank_command
= numicro_flash_bank_command
,
1196 .erase
= numicro_erase
,
1197 .write
= numicro_write
,
1198 .read
= default_flash_read
,
1199 .probe
= numicro_probe
,
1200 .auto_probe
= numicro_auto_probe
,
1201 .erase_check
= default_flash_blank_check
,
1202 .protect_check
= numicro_protect_check
,
1203 .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)