2e1009baa2eb74d5bd1692fea06f823834850f04
[openocd.git] / src / pld / ecp5.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 "ecp5.h"
13 #include "lattice.h"
14 #include "lattice_cmd.h"
15
16 #define ISC_PROGRAM_USERCODE 0xC2
17
18 #define STATUS_DONE_BIT 0x00000100
19 #define STATUS_ERROR_BITS 0x00020040
20 #define STATUS_FEA_OTP 0x00004000
21 #define STATUS_FAIL_FLAG 0x00002000
22 #define STATUS_BUSY_FLAG 0x00001000
23 #define REGISTER_ALL_BITS_1 0xffffffff
24
25 int lattice_ecp5_read_status(struct jtag_tap *tap, uint32_t *status, uint32_t out, bool do_idle)
26 {
27 return lattice_read_u32_register(tap, LSC_READ_STATUS, status, out, do_idle);
28 }
29
30 int lattice_ecp5_read_usercode(struct jtag_tap *tap, uint32_t *usercode, uint32_t out)
31 {
32 return lattice_read_u32_register(tap, READ_USERCODE, usercode, out, true);
33 }
34
35 int lattice_ecp5_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode)
36 {
37 struct jtag_tap *tap = lattice_device->tap;
38 if (!tap)
39 return ERROR_FAIL;
40
41 int retval = lattice_set_instr(tap, ISC_ENABLE, TAP_IDLE);
42 if (retval != ERROR_OK)
43 return retval;
44 jtag_add_runtest(5, TAP_IDLE);
45 jtag_add_sleep(20000);
46
47 retval = lattice_set_instr(tap, ISC_PROGRAM_USERCODE, TAP_IDLE);
48 if (retval != ERROR_OK)
49 return retval;
50
51 uint8_t buffer[4];
52 struct scan_field field;
53 h_u32_to_le(buffer, usercode);
54 field.num_bits = 32;
55 field.out_value = buffer;
56 field.in_value = NULL;
57 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
58 jtag_add_runtest(5, TAP_IDLE);
59 jtag_add_sleep(2000);
60
61 retval = lattice_set_instr(tap, ISC_DISABLE, TAP_IDLE);
62 if (retval != ERROR_OK)
63 return retval;
64 jtag_add_runtest(5, TAP_IDLE);
65 jtag_add_sleep(200000);
66
67 retval = jtag_execute_queue();
68 if (retval != ERROR_OK)
69 return retval;
70 return lattice_verify_usercode(lattice_device, 0x0, usercode, REGISTER_ALL_BITS_1);
71 }
72
73 static int lattice_ecp5_enable_sram_programming(struct jtag_tap *tap)
74 {
75 int retval = lattice_set_instr(tap, ISC_ENABLE, TAP_IDLE);
76 if (retval != ERROR_OK)
77 return retval;
78
79 struct scan_field field;
80 uint8_t buffer = 0x0;
81 field.num_bits = 8;
82 field.out_value = &buffer;
83 field.in_value = NULL;
84 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
85 jtag_add_runtest(2, TAP_IDLE);
86 jtag_add_sleep(10000);
87
88 return jtag_execute_queue();
89 }
90
91 static int lattice_ecp5_erase_sram(struct jtag_tap *tap)
92 {
93 int retval = lattice_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);
94 if (retval != ERROR_OK)
95 return retval;
96
97 struct scan_field field;
98 uint8_t buffer = 1;
99 field.num_bits = 8;
100 field.out_value = &buffer;
101 field.in_value = NULL;
102 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
103 jtag_add_runtest(2, TAP_IDLE);
104 jtag_add_sleep(200000);
105 return jtag_execute_queue();
106 }
107
108 static int lattice_ecp5_init_address(struct jtag_tap *tap)
109 {
110 int retval = lattice_set_instr(tap, LSC_INIT_ADDRESS, TAP_IDLE);
111 if (retval != ERROR_OK)
112 return retval;
113
114 struct scan_field field;
115 uint8_t buffer = 1;
116 field.num_bits = 8;
117 field.out_value = &buffer;
118 field.in_value = NULL;
119 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
120 jtag_add_runtest(2, TAP_IDLE);
121 jtag_add_sleep(10000);
122 return jtag_execute_queue();
123 }
124
125 static int lattice_ecp5_program_config_map(struct jtag_tap *tap, struct lattice_bit_file *bit_file)
126 {
127 int retval = lattice_set_instr(tap, LSC_BITSTREAM_BURST, TAP_IDLE);
128 if (retval != ERROR_OK)
129 return retval;
130 jtag_add_runtest(2, TAP_IDLE);
131 jtag_add_sleep(10000);
132
133 struct scan_field field;
134 field.num_bits = (bit_file->raw_bit.length - bit_file->offset) * 8;
135 field.out_value = bit_file->raw_bit.data + bit_file->offset;
136 field.in_value = NULL;
137 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
138 retval = lattice_set_instr(tap, BYPASS, TAP_IDLE);
139 if (retval != ERROR_OK)
140 return retval;
141 jtag_add_runtest(100, TAP_IDLE);
142 jtag_add_sleep(10000);
143
144 return jtag_execute_queue();
145 }
146
147 static int lattice_ecp5_exit_programming_mode(struct jtag_tap *tap)
148 {
149 int retval = lattice_set_instr(tap, ISC_DISABLE, TAP_IDLE);
150 if (retval != ERROR_OK)
151 return retval;
152 jtag_add_runtest(2, TAP_IDLE);
153 jtag_add_sleep(200000);
154 retval = lattice_set_instr(tap, BYPASS, TAP_IDLE);
155 if (retval != ERROR_OK)
156 return retval;
157 jtag_add_runtest(2, TAP_IDLE);
158 jtag_add_sleep(1000);
159 return jtag_execute_queue();
160 }
161
162 int lattice_ecp5_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file)
163 {
164 struct jtag_tap *tap = lattice_device->tap;
165 if (!tap)
166 return ERROR_FAIL;
167
168 int retval = lattice_preload(lattice_device);
169 if (retval != ERROR_OK)
170 return retval;
171
172 retval = lattice_ecp5_enable_sram_programming(tap);
173 if (retval != ERROR_OK)
174 return retval;
175
176 const uint32_t out = 0x0;
177 const uint32_t expected1 = 0x0;
178 const uint32_t mask1 = STATUS_ERROR_BITS | STATUS_FEA_OTP;
179 retval = lattice_verify_status_register_u32(lattice_device, out, expected1, mask1, true);
180 if (retval != ERROR_OK)
181 return retval;
182
183 retval = lattice_ecp5_erase_sram(tap);
184 if (retval != ERROR_OK)
185 return retval;
186
187 const uint32_t mask2 = STATUS_FAIL_FLAG | STATUS_BUSY_FLAG;
188 retval = lattice_verify_status_register_u32(lattice_device, out, expected1, mask2, false);
189 if (retval != ERROR_OK)
190 return retval;
191
192 retval = lattice_ecp5_init_address(tap);
193 if (retval != ERROR_OK)
194 return retval;
195
196 retval = lattice_ecp5_program_config_map(tap, bit_file);
197 if (retval != ERROR_OK)
198 return retval;
199
200 retval = lattice_ecp5_exit_programming_mode(tap);
201 if (retval != ERROR_OK)
202 return retval;
203
204 const uint32_t expected2 = STATUS_DONE_BIT;
205 const uint32_t mask3 = STATUS_DONE_BIT | STATUS_FAIL_FLAG;
206 return lattice_verify_status_register_u32(lattice_device, out, expected2, mask3, false);
207 }

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)