Documentation: fix warning "unbalanced square brackets"
[openocd.git] / src / pld / certus.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2022 by Daniel Anselmi *
5 * danselmi@gmx.ch *
6 ***************************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include "certus.h"
13 #include "lattice.h"
14 #include "lattice_cmd.h"
15
16 #define LSC_ENABLE_X 0x74
17 #define LSC_REFRESH 0x79
18 #define LSC_DEVICE_CTRL 0x7D
19
20 int lattice_certus_read_status(struct jtag_tap *tap, uint64_t *status, uint64_t out)
21 {
22 return lattice_read_u64_register(tap, LSC_READ_STATUS, status, out);
23 }
24
25 int lattice_certus_read_usercode(struct jtag_tap *tap, uint32_t *usercode, uint32_t out)
26 {
27 return lattice_read_u32_register(tap, READ_USERCODE, usercode, out, false);
28 }
29
30 int lattice_certus_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode)
31 {
32 LOG_ERROR("Not supported to write usercode on certus devices");
33 return ERROR_FAIL;
34 }
35
36 static int lattice_certus_enable_transparent_mode(struct jtag_tap *tap)
37 {
38 struct scan_field field;
39
40 int retval = lattice_set_instr(tap, LSC_ENABLE_X, TAP_IDLE);
41 if (retval != ERROR_OK)
42 return retval;
43
44 uint8_t buffer = 0x0;
45 field.num_bits = 8;
46 field.out_value = &buffer;
47 field.in_value = NULL;
48 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
49 jtag_add_runtest(2, TAP_IDLE);
50
51 return jtag_execute_queue();
52 }
53
54 static int lattice_certus_erase_device(struct lattice_pld_device *lattice_device)
55 {
56 struct jtag_tap *tap = lattice_device->tap;
57 if (!tap)
58 return ERROR_FAIL;
59
60 int retval = lattice_set_instr(tap, LSC_DEVICE_CTRL, TAP_IRPAUSE);
61 if (retval != ERROR_OK)
62 return retval;
63
64 struct scan_field field;
65 uint8_t buffer = 8;
66 field.num_bits = 8;
67 field.out_value = &buffer;
68 field.in_value = NULL;
69 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
70 jtag_add_runtest(2, TAP_IDLE);
71 retval = jtag_execute_queue();
72 if (retval != ERROR_OK)
73 return retval;
74
75 retval = lattice_set_instr(tap, LSC_DEVICE_CTRL, TAP_IDLE);
76 if (retval != ERROR_OK)
77 return retval;
78 buffer = 0;
79 field.num_bits = 8;
80 field.out_value = &buffer;
81 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
82 jtag_add_runtest(2, TAP_IDLE);
83 retval = jtag_execute_queue();
84 if (retval != ERROR_OK)
85 return retval;
86
87 retval = lattice_set_instr(tap, ISC_ERASE, TAP_IDLE);
88 if (retval != ERROR_OK)
89 return retval;
90 buffer = 0;
91 field.num_bits = 8;
92 field.out_value = &buffer;
93 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
94 jtag_add_runtest(100, TAP_IDLE);
95 jtag_add_sleep(5000);
96 retval = jtag_execute_queue();
97 if (retval != ERROR_OK)
98 return retval;
99
100 /* check done is cleared and fail is cleared */
101 const uint64_t status_done_flag = 0x100;
102 const uint64_t status_fail_flag = 0x2000;
103 return lattice_verify_status_register_u64(lattice_device, 0x0, 0x0, status_done_flag | status_fail_flag);
104 }
105
106 static int lattice_certus_enable_programming(struct jtag_tap *tap)
107 {
108 struct scan_field field;
109
110 int retval = lattice_set_instr(tap, LSC_REFRESH, TAP_IDLE);
111 if (retval != ERROR_OK)
112 return retval;
113 jtag_add_runtest(2, TAP_IDLE);
114 retval = jtag_execute_queue();
115 if (retval != ERROR_OK)
116 return retval;
117
118 retval = lattice_set_instr(tap, ISC_ENABLE, TAP_IDLE);
119 if (retval != ERROR_OK)
120 return retval;
121 uint8_t buffer = 0;
122 field.num_bits = 8;
123 field.out_value = &buffer;
124 field.in_value = NULL;
125 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
126 jtag_add_runtest(2, TAP_IDLE);
127 return jtag_execute_queue();
128 }
129
130 static int lattice_certus_init_address(struct jtag_tap *tap)
131 {
132 int retval = lattice_set_instr(tap, LSC_INIT_ADDRESS, TAP_IDLE);
133 if (retval != ERROR_OK)
134 return retval;
135 jtag_add_runtest(2, TAP_IDLE);
136 return jtag_execute_queue();
137 }
138
139 static int lattice_certus_exit_programming_mode(struct jtag_tap *tap)
140 {
141 int retval = lattice_set_instr(tap, ISC_DISABLE, TAP_IDLE);
142 if (retval != ERROR_OK)
143 return retval;
144 jtag_add_runtest(2, TAP_IDLE);
145 retval = lattice_set_instr(tap, BYPASS, TAP_IDLE);
146 if (retval != ERROR_OK)
147 return retval;
148 jtag_add_runtest(100, TAP_IDLE);
149 return jtag_execute_queue();
150 }
151
152 static int lattice_certus_program_config_map(struct jtag_tap *tap, struct lattice_bit_file *bit_file)
153 {
154 struct scan_field field;
155
156 int retval = lattice_set_instr(tap, LSC_BITSTREAM_BURST, TAP_IDLE);
157 if (retval != ERROR_OK)
158 return retval;
159
160 field.num_bits = (bit_file->raw_bit.length - bit_file->offset) * 8;
161 field.out_value = bit_file->raw_bit.data + bit_file->offset;
162 field.in_value = NULL;
163 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
164
165 return jtag_execute_queue();
166 }
167
168 int lattice_certus_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file)
169 {
170 struct jtag_tap *tap = lattice_device->tap;
171 if (!tap)
172 return ERROR_FAIL;
173
174 int retval = lattice_preload(lattice_device);
175 if (retval != ERROR_OK)
176 return retval;
177
178 /* check password protection is disabled */
179 const uint64_t status_pwd_protection = 0x20000;
180 retval = lattice_verify_status_register_u64(lattice_device, 0x0, 0x0, status_pwd_protection);
181 if (retval != ERROR_OK) {
182 LOG_ERROR("Password protection is set");
183 return retval;
184 }
185
186 retval = lattice_certus_enable_transparent_mode(tap);
187 if (retval != ERROR_OK)
188 return retval;
189
190 /* Check the SRAM Erase Lock */
191 const uint64_t status_otp = 0x40;
192 retval = lattice_verify_status_register_u64(lattice_device, 0x0, status_otp, status_otp);
193 if (retval != ERROR_OK) {
194 LOG_ERROR("NV User Feature Sector OTP is Set");
195 return retval;
196 }
197
198 /* Check the SRAM Lock */
199 const uint64_t status_write_protected = 0x400;
200 retval = lattice_verify_status_register_u64(lattice_device, 0x0, 0x0, status_write_protected);
201 if (retval != ERROR_OK) {
202 LOG_ERROR("NV User Feature Sector OTP is Set");
203 return retval;
204 }
205
206 retval = lattice_certus_enable_programming(tap);
207 if (retval != ERROR_OK) {
208 LOG_ERROR("failed to enable programming mode");
209 return retval;
210 }
211
212 retval = lattice_certus_erase_device(lattice_device);
213 if (retval != ERROR_OK) {
214 LOG_ERROR("erasing device failed");
215 return retval;
216 }
217
218 retval = lattice_certus_init_address(tap);
219 if (retval != ERROR_OK)
220 return retval;
221
222 retval = lattice_certus_program_config_map(tap, bit_file);
223 if (retval != ERROR_OK)
224 return retval;
225 const uint32_t expected = 0x100; // done
226 const uint32_t mask = expected |
227 0x3000 | // Busy Flag and Fail Flag
228 0xf000000; // BSE Error
229 retval = lattice_verify_status_register_u64(lattice_device, 0x0, 0x100, mask);
230 if (retval != ERROR_OK)
231 return retval;
232
233 return lattice_certus_exit_programming_mode(tap);
234 }
235
236 int lattice_certus_connect_spi_to_jtag(struct lattice_pld_device *pld_device_info)
237 {
238 if (!pld_device_info)
239 return ERROR_FAIL;
240
241 struct jtag_tap *tap = pld_device_info->tap;
242 if (!tap)
243 return ERROR_FAIL;
244
245 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) == PROGRAM_SPI)
246 return ERROR_OK;
247
248 // erase configuration
249 int retval = lattice_preload(pld_device_info);
250 if (retval != ERROR_OK)
251 return retval;
252
253 retval = lattice_certus_enable_programming(tap);
254 if (retval != ERROR_OK)
255 return retval;
256
257 retval = lattice_certus_erase_device(pld_device_info);
258 if (retval != ERROR_OK) {
259 LOG_ERROR("erasing device failed");
260 return retval;
261 }
262
263 retval = lattice_certus_exit_programming_mode(tap);
264 if (retval != ERROR_OK)
265 return retval;
266
267 // connect jtag to spi pins
268 retval = lattice_set_instr(tap, PROGRAM_SPI, TAP_IDLE);
269 if (retval != ERROR_OK)
270 return retval;
271
272 struct scan_field field;
273 uint8_t buffer[2] = {0xfe, 0x68};
274 field.num_bits = 16;
275 field.out_value = buffer;
276 field.in_value = NULL;
277 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
278
279 return jtag_execute_queue();
280 }
281
282 int lattice_certus_disconnect_spi_from_jtag(struct lattice_pld_device *pld_device_info)
283 {
284 if (!pld_device_info)
285 return ERROR_FAIL;
286
287 struct jtag_tap *tap = pld_device_info->tap;
288 if (!tap)
289 return ERROR_FAIL;
290
291 /* Connecting it again takes way too long to do it multiple times for writing
292 a bitstream (ca. 0.4s each access).
293 We just leave it connected since SCS will not be active when not in shift_dr state.
294 So there is no need to change instruction, just make sure we are not in shift dr state. */
295 jtag_add_runtest(2, TAP_IDLE);
296 return jtag_execute_queue();
297 }
298
299 int lattice_certus_get_facing_read_bits(struct lattice_pld_device *pld_device_info, unsigned int *facing_read_bits)
300 {
301 if (!pld_device_info)
302 return ERROR_FAIL;
303
304 *facing_read_bits = 0;
305
306 return ERROR_OK;
307 }
308
309 int lattice_certus_refresh(struct lattice_pld_device *lattice_device)
310 {
311 struct jtag_tap *tap = lattice_device->tap;
312 if (!tap)
313 return ERROR_FAIL;
314
315 int retval = lattice_preload(lattice_device);
316 if (retval != ERROR_OK)
317 return retval;
318
319 retval = lattice_set_instr(tap, LSC_REFRESH, TAP_IDLE);
320 if (retval != ERROR_OK)
321 return retval;
322 jtag_add_runtest(2, TAP_IDLE);
323 jtag_add_sleep(200000);
324 retval = lattice_set_instr(tap, BYPASS, TAP_IDLE);
325 if (retval != ERROR_OK)
326 return retval;
327 jtag_add_runtest(100, TAP_IDLE);
328 jtag_add_sleep(1000);
329
330 return jtag_execute_queue();
331 }

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)