flash/nor/numicro: reorder the parts list
[openocd.git] / src / flash / nor / numicro.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2011 by James K. Larson *
5 * jlarson@pacifier.com *
6 * *
7 * Copyright (C) 2013 Cosmin Gorgovan *
8 * cosmin [at] linux-geek [dot] org *
9 * *
10 * Copyright (C) 2014 Pawel Si *
11 * stawel+openocd@gmail.com *
12 * *
13 * Copyright (C) 2015 Nemui Trinomius *
14 * nemuisan_kawausogasuki@live.jp *
15 * *
16 * Copyright (C) 2017 Zale Yu *
17 * CYYU@nuvoton.com *
18 * *
19 * Copyright (C) 2022 Jian-Hong Pan *
20 * chienhung.pan@gmail.com *
21 ***************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include "imp.h"
28 #include <helper/binarybuffer.h>
29 #include <target/algorithm.h>
30 #include <target/armv7m.h>
31 #include <target/cortex_m.h>
32
33 /* Nuvoton NuMicro register locations */
34 #define NUMICRO_SYS_BASE 0x50000000
35 #define NUMICRO_SYS_WRPROT 0x50000100
36 #define NUMICRO_SYS_IPRSTC1 0x50000008
37
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
43
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) */
51
52 #define NUMICRO_SCS_BASE 0xE000E000
53 #define NUMICRO_SCS_AIRCR 0xE000ED0C
54 #define NUMICRO_SCS_DHCSR 0xE000EDF0
55 #define NUMICRO_SCS_DEMCR 0xE000EDFC
56
57 #define NUMICRO_APROM_BASE 0x00000000
58 #define NUMICRO_DATA_BASE 0x0001F000
59 #define NUMICRO_LDROM_BASE 0x00100000
60 #define NUMICRO_CONFIG_BASE 0x00300000
61
62 #define NUMICRO_CONFIG0 0x5000C000
63 #define NUMICRO_CONFIG1 0x5000C004
64
65 /* Command register bits */
66 #define PWRCON_OSC22M (1 << 2)
67 #define PWRCON_XTL12M (1 << 0)
68
69 #define IPRSTC1_CPU_RST (1 << 1)
70 #define IPRSTC1_CHIP_RST (1 << 0)
71
72 #define AHBCLK_ISP_EN (1 << 2)
73 #define AHBCLK_SRAM_EN (1 << 4)
74 #define AHBCLK_TICK_EN (1 << 5)
75
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)
84
85 #define CONFIG0_LOCK_MASK (1 << 1)
86
87 /* isp commands */
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)
97
98 /* access unlock keys */
99 #define REG_KEY1 0x59
100 #define REG_KEY2 0x16
101 #define REG_KEY3 0x88
102 #define REG_LOCK 0x00
103
104 /* flash pagesizes */
105 #define NUMICRO_PAGESIZE 512
106 /* flash MAX banks */
107 #define NUMICRO_MAX_FLASH_BANKS 4
108
109 /* flash bank structs */
110 struct numicro_flash_bank_type {
111 uint32_t base;
112 uint32_t size;
113 };
114
115 /* part structs */
116 struct numicro_cpu_type {
117 char *partname;
118 uint32_t partid;
119 unsigned int n_banks;
120 struct numicro_flash_bank_type bank[NUMICRO_MAX_FLASH_BANKS];
121 };
122
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) \
125 .n_banks = 4, \
126 {{NUMICRO_APROM_BASE, (aprom_size)}, \
127 {NUMICRO_DATA_BASE, (data_size)}, \
128 {NUMICRO_LDROM_BASE, (ldrom_size)}, \
129 {NUMICRO_CONFIG_BASE, (config_size)}}
130
131 static const struct numicro_cpu_type numicro_parts[] = {
132 /*PART NO*/ /*PART ID*/ /*Banks*/
133 /* M051AN */
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)},
142
143 /* M051BN */
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)},
152
153 /* M051DN */
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)},
162
163 /* M051DE */
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)},
172
173 /* M0518 */
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)},
178
179 /* M0519 */
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)},
185
186 /* M058S */
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)},
191
192 /* MINI51AN */
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)},
202
203 /* MINI51DE */
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)},
216
217 /* MINI55 */
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)},
220
221 /* MINI58 */
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)},
226
227 /* NANO100AN */
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)},
250
251 /* NANO100BN */
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)},
298
299 /* NANO103 */
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)},
303
304 /* NANO112AN */
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)},
317
318 /* NUC029AN */
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)},
321
322 /* NUC029AE */
323 {"NUC029FAE", 0x00295415, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},
324
325 /* NUC100AN */
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)},
340
341 /* NUC100BN */
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)},
354
355 /* NUC100CN */
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)},
370
371 /* NUC100DN */
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)},
398
399 /* NUC121 */
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)},
406
407 /* NUC122 */
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)},
414
415 /* NUC123AN */
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)},
422
423 /* NUC123AE */
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)},
430
431 /* NUC131AE */
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)},
436
437 /* NUC200/220AN */
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)},
452
453 /* NUC230/240AE */
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)},
468
469 {"UNKNOWN", 0x00000000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 16 * 1024, 8)},
470 };
471
472 /* Private bank information for NuMicro. */
473 struct numicro_flash_bank {
474 struct working_area *write_algorithm;
475 bool probed;
476 const struct numicro_cpu_type *cpu;
477 };
478
479 /* Private methods */
480 static int numicro_reg_unlock(struct target *target)
481 {
482 uint32_t is_protected;
483 int retval = ERROR_OK;
484
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)
488 return retval;
489
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)
495 return retval;
496 retval = target_write_u32(target, NUMICRO_SYS_WRPROT, REG_KEY2);
497 if (retval != ERROR_OK)
498 return retval;
499 retval = target_write_u32(target, NUMICRO_SYS_WRPROT, REG_KEY3);
500 if (retval != ERROR_OK)
501 return retval;
502 }
503 /* Check that unlock worked */
504 retval = target_read_u32(target, NUMICRO_SYS_WRPROT, &is_protected);
505 if (retval != ERROR_OK)
506 return retval;
507
508 if (is_protected == 1) { /* means unprotected */
509 LOG_DEBUG("protection removed");
510 } else {
511 LOG_DEBUG("still protected!!");
512 }
513
514 return ERROR_OK;
515 }
516
517 static int numicro_init_isp(struct target *target)
518 {
519 uint32_t reg_stat;
520 int retval = ERROR_OK;
521
522 if (target->state != TARGET_HALTED) {
523 LOG_ERROR("Target not halted");
524 return ERROR_TARGET_NOT_HALTED;
525 }
526
527 retval = numicro_reg_unlock(target);
528 if (retval != ERROR_OK)
529 return retval;
530
531 /* Enable ISP/SRAM/TICK Clock */
532 retval = target_read_u32(target, NUMICRO_SYSCLK_AHBCLK, &reg_stat);
533 if (retval != ERROR_OK)
534 return retval;
535
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)
539 return retval;
540
541 /* Enable ISP */
542 retval = target_read_u32(target, NUMICRO_FLASH_ISPCON, &reg_stat);
543 if (retval != ERROR_OK)
544 return retval;
545
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)
549 return retval;
550
551 /* Write one to undocumented flash control register */
552 retval = target_write_u32(target, NUMICRO_FLASH_CHEAT, 1);
553 if (retval != ERROR_OK)
554 return retval;
555
556 return ERROR_OK;
557 }
558
559 static uint32_t numicro_fmc_cmd(struct target *target, uint32_t cmd, uint32_t addr, uint32_t wdata, uint32_t *rdata)
560 {
561 uint32_t timeout, status;
562 int retval = ERROR_OK;
563
564 retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD, cmd);
565 if (retval != ERROR_OK)
566 return retval;
567
568 retval = target_write_u32(target, NUMICRO_FLASH_ISPDAT, wdata);
569 if (retval != ERROR_OK)
570 return retval;
571
572 retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, addr);
573 if (retval != ERROR_OK)
574 return retval;
575
576 retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO);
577 if (retval != ERROR_OK)
578 return retval;
579
580 /* Wait for busy to clear - check the GO flag */
581 timeout = 100;
582 for (;;) {
583 retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status);
584 if (retval != ERROR_OK)
585 return retval;
586 LOG_DEBUG("status: 0x%" PRIx32 "", status);
587 if ((status & (ISPTRG_ISPGO)) == 0)
588 break;
589 if (timeout-- <= 0) {
590 LOG_DEBUG("timed out waiting for flash");
591 return ERROR_FAIL;
592 }
593 busy_sleep(1); /* can use busy sleep for short times. */
594 }
595
596 retval = target_read_u32(target, NUMICRO_FLASH_ISPDAT, rdata);
597 if (retval != ERROR_OK)
598 return retval;
599
600 return ERROR_OK;
601 }
602
603
604 /* NuMicro Program-LongWord Microcodes */
605 static const uint8_t numicro_flash_write_code[] = {
606 /* Params:
607 * r0 - workarea buffer / result
608 * r1 - target address
609 * r2 - wordcount
610 * Clobbered:
611 * r4 - tmp
612 * r5 - tmp
613 * r6 - tmp
614 * r7 - tmp
615 */
616
617 /* .L1: */
618 /* for(register uint32_t i=0;i<wcount;i++){ */
619 0x04, 0x1C, /* mov r4, r0 */
620 0x00, 0x23, /* mov r3, #0 */
621 /* .L2: */
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 */
626 /* .L4: */
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] */
634 /* faddr += 4; */
635 /* pLW++; */
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] */
641 /* .L3: */
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 */
646
647 0x01, 0x33, /* add r3, r3, #1 */
648 0xEE, 0xE7, /* b .L2 */
649 /* .L7: */
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 */
655 /* .L9: */
656 0x00, 0xBE, /* bkpt #0 */
657 /* .L8: */
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 */
662 };
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)
666 {
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;
675
676 /* Params:
677 * r0 - workarea buffer / result
678 * r1 - target address
679 * r2 - wordcount
680 * Clobbered:
681 * r4 - tmp
682 * r5 - tmp
683 * r6 - tmp
684 * r7 - tmp
685 */
686
687 /* Increase buffer_size if needed */
688 if (buffer_size < (target->working_area_size/2))
689 buffer_size = (target->working_area_size/2);
690
691 /* check code alignment */
692 if (offset & 0x1) {
693 LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
694 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
695 }
696
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;
702 }
703
704 retval = target_write_buffer(target, write_algorithm->address,
705 sizeof(numicro_flash_write_code), numicro_flash_write_code);
706 if (retval != ERROR_OK)
707 return retval;
708
709 /* memory buffer */
710 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) {
711 buffer_size /= 4;
712 if (buffer_size <= 256) {
713 /* free working area, write algorithm already allocated */
714 target_free_working_area(target, write_algorithm);
715
716 LOG_WARNING("No large enough working area available, can't do block memory writes");
717 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
718 }
719 }
720
721 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
722 armv7m_info.core_mode = ARM_MODE_THREAD;
723
724 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* *pLW (*buffer) */
725 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* faddr */
726 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* number of words to program */
727
728 /* write code buffer and use Flash programming code within NuMicro */
729 /* Set breakpoint to 0 with time-out of 1000 ms */
730 while (count > 0) {
731 uint32_t thisrun_count = (count > (buffer_size / 4)) ? (buffer_size / 4) : count;
732
733 retval = target_write_buffer(target, source->address, thisrun_count * 4, buffer);
734 if (retval != ERROR_OK)
735 break;
736
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);
740
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;
746 break;
747 }
748
749 buffer += thisrun_count * 4;
750 address += thisrun_count * 4;
751 count -= thisrun_count;
752 }
753
754 target_free_working_area(target, source);
755 target_free_working_area(target, write_algorithm);
756
757 destroy_reg_param(&reg_params[0]);
758 destroy_reg_param(&reg_params[1]);
759 destroy_reg_param(&reg_params[2]);
760
761 return retval;
762 }
763
764 /* Flash Lock checking - examines the lock bit. */
765 static int numicro_protect_check(struct flash_bank *bank)
766 {
767 struct target *target = bank->target;
768 uint32_t set, config[2];
769 int retval = ERROR_OK;
770
771 if (target->state != TARGET_HALTED) {
772 LOG_ERROR("Target not halted");
773 return ERROR_TARGET_NOT_HALTED;
774 }
775
776 LOG_INFO("Nuvoton NuMicro: Flash Lock Check...");
777
778 retval = numicro_init_isp(target);
779 if (retval != ERROR_OK)
780 return retval;
781
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]);
785
786 LOG_DEBUG("CONFIG0: 0x%" PRIx32 ",CONFIG1: 0x%" PRIx32 "", config[0], config[1]);
787
788 if ((config[0] & (1<<7)) == 0)
789 LOG_INFO("CBS=0: Boot From LPROM");
790 else
791 LOG_INFO("CBS=1: Boot From APROM");
792
793 if ((config[0] & CONFIG0_LOCK_MASK) == 0) {
794
795 LOG_INFO("Flash is secure locked!");
796 LOG_INFO("TO UNLOCK FLASH,EXECUTE chip_erase COMMAND!!");
797 set = 1;
798 } else {
799 LOG_INFO("Flash is not locked!");
800 set = 0;
801 }
802
803 for (unsigned int i = 0; i < bank->num_sectors; i++)
804 bank->sectors[i].is_protected = set;
805
806 return ERROR_OK;
807 }
808
809
810 static int numicro_erase(struct flash_bank *bank, unsigned int first,
811 unsigned int last)
812 {
813 struct target *target = bank->target;
814 uint32_t timeout, status;
815 int retval = ERROR_OK;
816
817 if (target->state != TARGET_HALTED) {
818 LOG_ERROR("Target not halted");
819 return ERROR_TARGET_NOT_HALTED;
820 }
821
822 LOG_INFO("Nuvoton NuMicro: Sector Erase ... (%u to %u)", first, last);
823
824 retval = numicro_init_isp(target);
825 if (retval != ERROR_OK)
826 return retval;
827
828 retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD, ISPCMD_ERASE);
829 if (retval != ERROR_OK)
830 return retval;
831
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)
837 return retval;
838 retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO); /* This is the only bit available */
839 if (retval != ERROR_OK)
840 return retval;
841
842 /* wait for busy to clear - check the GO flag */
843 timeout = 100;
844 for (;;) {
845 retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status);
846 if (retval != ERROR_OK)
847 return retval;
848 LOG_DEBUG("status: 0x%" PRIx32 "", status);
849 if (status == 0)
850 break;
851 if (timeout-- <= 0) {
852 LOG_DEBUG("timed out waiting for flash");
853 return ERROR_FAIL;
854 }
855 busy_sleep(1); /* can use busy sleep for short times. */
856 }
857
858 /* check for failure */
859 retval = target_read_u32(target, NUMICRO_FLASH_ISPCON, &status);
860 if (retval != ERROR_OK)
861 return retval;
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)
867 return retval;
868 }
869 }
870
871 /* done, */
872 LOG_DEBUG("Erase done.");
873
874 return ERROR_OK;
875 }
876
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)
880 {
881 struct target *target = bank->target;
882 uint32_t timeout, status;
883 int retval = ERROR_OK;
884
885 if (target->state != TARGET_HALTED) {
886 LOG_ERROR("Target not halted");
887 return ERROR_TARGET_NOT_HALTED;
888 }
889
890 LOG_INFO("Nuvoton NuMicro: Flash Write ...");
891
892 retval = numicro_init_isp(target);
893 if (retval != ERROR_OK)
894 return retval;
895
896 retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD, ISPCMD_WRITE);
897 if (retval != ERROR_OK)
898 return retval;
899
900 assert(offset % 4 == 0);
901 assert(count % 4 == 0);
902
903 uint32_t words_remaining = count / 4;
904
905 /* try using a block write */
906 retval = numicro_writeblock(bank, buffer, offset, words_remaining);
907
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 "
912 "memory accesses");
913
914 /* program command */
915 for (uint32_t i = 0; i < count; i += 4) {
916
917 LOG_DEBUG("write longword @ %08" PRIX32, offset + i);
918
919 retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, bank->base + offset + i);
920 if (retval != ERROR_OK)
921 return retval;
922 retval = target_write_memory(target, NUMICRO_FLASH_ISPDAT, 4, 1, buffer + i);
923 if (retval != ERROR_OK)
924 return retval;
925 retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO);
926 if (retval != ERROR_OK)
927 return retval;
928
929 /* wait for busy to clear - check the GO flag */
930 timeout = 100;
931 for (;;) {
932 retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status);
933 if (retval != ERROR_OK)
934 return retval;
935 LOG_DEBUG("status: 0x%" PRIx32 "", status);
936 if (status == 0)
937 break;
938 if (timeout-- <= 0) {
939 LOG_DEBUG("timed out waiting for flash");
940 return ERROR_FAIL;
941 }
942 busy_sleep(1); /* can use busy sleep for short times. */
943 }
944
945 }
946 }
947
948 /* check for failure */
949 retval = target_read_u32(target, NUMICRO_FLASH_ISPCON, &status);
950 if (retval != ERROR_OK)
951 return retval;
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)
957 return retval;
958 } else {
959 LOG_DEBUG("Write OK");
960 }
961
962 /* done. */
963 LOG_DEBUG("Write done.");
964
965 return ERROR_OK;
966 }
967
968 static int numicro_get_cpu_type(struct target *target, const struct numicro_cpu_type **cpu)
969 {
970 uint32_t part_id;
971 int retval = ERROR_OK;
972
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;
978 }
979
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);
986 return ERROR_OK;
987 }
988 }
989
990 return ERROR_FAIL;
991 }
992
993 static int numicro_get_flash_size(struct flash_bank *bank, const struct numicro_cpu_type *cpu, uint32_t *flash_size)
994 {
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);
1000 return ERROR_OK;
1001 }
1002 }
1003 return ERROR_FLASH_OPERATION_FAILED;
1004 }
1005
1006 static int numicro_probe(struct flash_bank *bank)
1007 {
1008 uint32_t flash_size, offset = 0;
1009 int num_pages;
1010 const struct numicro_cpu_type *cpu;
1011 struct target *target = bank->target;
1012 int retval = ERROR_OK;
1013
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;
1018 }
1019
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;
1024 }
1025
1026 num_pages = flash_size / NUMICRO_PAGESIZE;
1027
1028 bank->num_sectors = num_pages;
1029 bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
1030 bank->size = flash_size;
1031
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;
1038 }
1039
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 ...");
1044
1045 return ERROR_OK;
1046 }
1047
1048 /* Standard approach to autoprobing. */
1049 static int numicro_auto_probe(struct flash_bank *bank)
1050 {
1051 struct numicro_flash_bank *numicro_info = bank->driver_priv;
1052 if (numicro_info->probed)
1053 return ERROR_OK;
1054 return numicro_probe(bank);
1055 }
1056
1057
1058 /* This is the function called in the config file. */
1059 FLASH_BANK_COMMAND_HANDLER(numicro_flash_bank_command)
1060 {
1061 struct numicro_flash_bank *bank_info;
1062
1063 if (CMD_ARGC < 6)
1064 return ERROR_COMMAND_SYNTAX_ERROR;
1065
1066 LOG_DEBUG("add flash_bank numicro %s", bank->name);
1067
1068 bank_info = malloc(sizeof(struct numicro_flash_bank));
1069
1070 memset(bank_info, 0, sizeof(struct numicro_flash_bank));
1071
1072 bank->driver_priv = bank_info;
1073 bank->write_start_alignment = bank->write_end_alignment = 4;
1074
1075 return ERROR_OK;
1076
1077 }
1078
1079 COMMAND_HANDLER(numicro_handle_read_isp_command)
1080 {
1081 uint32_t address;
1082 uint32_t ispdat;
1083 int retval = ERROR_OK;
1084
1085 if (CMD_ARGC != 1)
1086 return ERROR_COMMAND_SYNTAX_ERROR;
1087
1088 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
1089
1090 struct target *target = get_current_target(CMD_CTX);
1091
1092 retval = numicro_init_isp(target);
1093 if (retval != ERROR_OK)
1094 return retval;
1095
1096 retval = numicro_fmc_cmd(target, ISPCMD_READ, address, 0, &ispdat);
1097 if (retval != ERROR_OK)
1098 return retval;
1099
1100 LOG_INFO("0x%08" PRIx32 ": 0x%08" PRIx32, address, ispdat);
1101
1102 return ERROR_OK;
1103 }
1104
1105 COMMAND_HANDLER(numicro_handle_write_isp_command)
1106 {
1107 uint32_t address;
1108 uint32_t ispdat, rdat;
1109 int retval = ERROR_OK;
1110
1111 if (CMD_ARGC != 2)
1112 return ERROR_COMMAND_SYNTAX_ERROR;
1113
1114 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
1115 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], ispdat);
1116
1117 struct target *target = get_current_target(CMD_CTX);
1118
1119 retval = numicro_init_isp(target);
1120 if (retval != ERROR_OK)
1121 return retval;
1122
1123 retval = numicro_fmc_cmd(target, ISPCMD_WRITE, address, ispdat, &rdat);
1124 if (retval != ERROR_OK)
1125 return retval;
1126
1127 LOG_INFO("0x%08" PRIx32 ": 0x%08" PRIx32, address, ispdat);
1128 return ERROR_OK;
1129 }
1130
1131 COMMAND_HANDLER(numicro_handle_chip_erase_command)
1132 {
1133 int retval = ERROR_OK;
1134 uint32_t rdat;
1135
1136 if (CMD_ARGC != 0)
1137 return ERROR_COMMAND_SYNTAX_ERROR;
1138
1139 struct target *target = get_current_target(CMD_CTX);
1140
1141 retval = numicro_init_isp(target);
1142 if (retval != ERROR_OK)
1143 return retval;
1144
1145 retval = numicro_fmc_cmd(target, ISPCMD_CHIPERASE, 0, 0, &rdat);
1146 if (retval != ERROR_OK) {
1147 command_print(CMD, "numicro chip_erase failed");
1148 return retval;
1149 }
1150
1151 command_print(CMD, "numicro chip_erase complete");
1152
1153 return ERROR_OK;
1154 }
1155
1156 static const struct command_registration numicro_exec_command_handlers[] = {
1157 {
1158 .name = "read_isp",
1159 .handler = numicro_handle_read_isp_command,
1160 .usage = "address",
1161 .mode = COMMAND_EXEC,
1162 .help = "read flash through ISP.",
1163 },
1164 {
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.",
1170 },
1171 {
1172 .name = "chip_erase",
1173 .handler = numicro_handle_chip_erase_command,
1174 .mode = COMMAND_EXEC,
1175 .help = "chip erase through ISP.",
1176 .usage = "",
1177 },
1178 COMMAND_REGISTRATION_DONE
1179 };
1180
1181 static const struct command_registration numicro_command_handlers[] = {
1182 {
1183 .name = "numicro",
1184 .mode = COMMAND_ANY,
1185 .help = "numicro flash command group",
1186 .usage = "",
1187 .chain = numicro_exec_command_handlers,
1188 },
1189 COMMAND_REGISTRATION_DONE
1190 };
1191
1192 const struct flash_driver numicro_flash = {
1193 .name = "numicro",
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,
1204 };

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)