737bc010cfe1b97f86072a55f84652d5387d5943
[ecpprog.git] / ecpprog / jtag_tap.c
1 /**
2 * Code adapted from Arduino-JTAG;
3 * portions copyright (c) 2015 Marcelo Roberto Jimenez <marcelo.jimenez (at) gmail (dot) com>.
4 * portions copyright (c) 2019 Katherine J. Temkin <kate@ktemkin.com>
5 * portions copyright (c) 2019 Great Scott Gadgets <ktemkin@greatscottgadgets.com>
6 */
7
8 #include <ftdi.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include <stdint.h>
12 #include <stdbool.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15
16 #include "mpsse.h"
17 #include "jtag.h"
18
19 void jtag_state_ack(bool tms);
20
21 /*
22 * Low nibble : TMS == 0
23 * High nibble: TMS == 1
24 */
25
26 #define TMS_T(TMS_HIGH_STATE, TMS_LOW_STATE) (((TMS_HIGH_STATE) << 4) | (TMS_LOW_STATE))
27
28 static const uint8_t tms_transitions[] = {
29 /* STATE_TEST_LOGIC_RESET */ TMS_T(STATE_TEST_LOGIC_RESET, STATE_RUN_TEST_IDLE),
30 /* STATE_RUN_TEST_IDLE */ TMS_T(STATE_SELECT_DR_SCAN, STATE_RUN_TEST_IDLE),
31 /* STATE_SELECT_DR_SCAN */ TMS_T(STATE_SELECT_IR_SCAN, STATE_CAPTURE_DR),
32 /* STATE_CAPTURE_DR */ TMS_T(STATE_EXIT1_DR, STATE_SHIFT_DR),
33 /* STATE_SHIFT_DR */ TMS_T(STATE_EXIT1_DR, STATE_SHIFT_DR),
34 /* STATE_EXIT1_DR */ TMS_T(STATE_UPDATE_DR, STATE_PAUSE_DR),
35 /* STATE_PAUSE_DR */ TMS_T(STATE_EXIT2_DR, STATE_PAUSE_DR),
36 /* STATE_EXIT2_DR */ TMS_T(STATE_UPDATE_DR, STATE_SHIFT_DR),
37 /* STATE_UPDATE_DR */ TMS_T(STATE_SELECT_DR_SCAN, STATE_RUN_TEST_IDLE),
38 /* STATE_SELECT_IR_SCAN */ TMS_T(STATE_TEST_LOGIC_RESET, STATE_CAPTURE_IR),
39 /* STATE_CAPTURE_IR */ TMS_T(STATE_EXIT1_IR, STATE_SHIFT_IR),
40 /* STATE_SHIFT_IR */ TMS_T(STATE_EXIT1_IR, STATE_SHIFT_IR),
41 /* STATE_EXIT1_IR */ TMS_T(STATE_UPDATE_IR, STATE_PAUSE_IR),
42 /* STATE_PAUSE_IR */ TMS_T(STATE_EXIT2_IR, STATE_PAUSE_IR),
43 /* STATE_EXIT2_IR */ TMS_T(STATE_UPDATE_IR, STATE_SHIFT_IR),
44 /* STATE_UPDATE_IR */ TMS_T(STATE_SELECT_DR_SCAN, STATE_RUN_TEST_IDLE),
45 };
46
47 #define BITSTR(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) ( \
48 ((uint16_t)(A) << 15) | \
49 ((uint16_t)(B) << 14) | \
50 ((uint16_t)(C) << 13) | \
51 ((uint16_t)(D) << 12) | \
52 ((uint16_t)(E) << 11) | \
53 ((uint16_t)(F) << 10) | \
54 ((uint16_t)(G) << 9) | \
55 ((uint16_t)(H) << 8) | \
56 ((uint16_t)(I) << 7) | \
57 ((uint16_t)(J) << 6) | \
58 ((uint16_t)(K) << 5) | \
59 ((uint16_t)(L) << 4) | \
60 ((uint16_t)(M) << 3) | \
61 ((uint16_t)(N) << 2) | \
62 ((uint16_t)(O) << 1) | \
63 ((uint16_t)(P) << 0) )
64
65 /*
66 * The index of this vector is the current state. The i-th bit tells you the
67 * value TMS must assume in order to go to state "i".
68
69 ------------------------------------------------------------------------------------------------------------
70 | | || F | E | D | C || B | A | 9 | 8 || 7 | 6 | 5 | 4 || 3 | 2 | 1 | 0 || HEX |
71 ------------------------------------------------------------------------------------------------------------
72 | STATE_TEST_LOGIC_RESET | 0 || 0 | 0 | 0 | 0 || 0 | 0 | 0 | 0 || 0 | 0 | 0 | 0 || 0 | 0 | 0 | 1 || 0x0001 |
73 | STATE_RUN_TEST_IDLE | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 0 | 1 || 0xFFFD |
74 | STATE_SELECT_DR_SCAN | 2 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 0 || 0 | 0 | 0 | 0 || 0 | x | 1 | 1 || 0xFE03 |
75 | STATE_CAPTURE_DR | 3 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 0 || x | 1 | 1 | 1 || 0xFFE7 |
76 | STATE_SHIFT_DR | 4 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 0 || 1 | 1 | 1 | 1 || 0xFFEF |
77 | STATE_EXIT1_DR | 5 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 0 | 0 | x | 0 || 1 | 1 | 1 | 1 || 0xFF0F |
78 | STATE_PAUSE_DR | 6 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 0 | 1 | 1 || 1 | 1 | 1 | 1 || 0xFFBF |
79 | STATE_EXIT2_DR | 7 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || x | 0 | 0 | 0 || 1 | 1 | 1 | 1 || 0xFF0F |
80 | STATE_UPDATE_DR | 8 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | x || 1 | 1 | 1 | 1 || 1 | 1 | 0 | 1 || 0xFEFD |
81 | STATE_SELECT_IR_SCAN | 9 || 0 | 0 | 0 | 0 || 0 | 0 | x | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 0x01FF |
82 | STATE_CAPTURE_IR | A || 1 | 1 | 1 | 1 || 0 | x | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 0xF3FF |
83 | STATE_SHIFT_IR | B || 1 | 1 | 1 | 1 || 0 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 0xF7FF |
84 | STATE_EXIT1_IR | C || 1 | 0 | 0 | x || 0 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 0x87FF |
85 | STATE_PAUSE_IR | D || 1 | 1 | 0 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 0xDFFF |
86 | STATE_EXIT2_IR | E || 1 | x | 0 | 0 || 0 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 0x87FF |
87 | STATE_UPDATE_IR | F || x | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 0 | 1 || 0x7FFD |
88 ------------------------------------------------------------------------------------------------------------
89
90 */
91 static const uint16_t tms_map[] = {
92 /* STATE_TEST_LOGIC_RESET */ BITSTR( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ),
93 /* STATE_RUN_TEST_IDLE */ BITSTR( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1 ),
94 /* STATE_SELECT_DR_SCAN */ BITSTR( 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1 ),
95 /* STATE_CAPTURE_DR */ BITSTR( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 ),
96 /* STATE_SHIFT_DR */ BITSTR( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 ),
97 /* STATE_EXIT1_DR */ BITSTR( 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 ),
98 /* STATE_PAUSE_DR */ BITSTR( 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 ),
99 /* STATE_EXIT2_DR */ BITSTR( 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 ),
100 /* STATE_UPDATE_DR */ BITSTR( 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1 ),
101 /* STATE_SELECT_IR_SCAN */ BITSTR( 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 ),
102 /* STATE_CAPTURE_IR */ BITSTR( 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ),
103 /* STATE_SHIFT_IR */ BITSTR( 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ),
104 /* STATE_EXIT1_IR */ BITSTR( 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ),
105 /* STATE_PAUSE_IR */ BITSTR( 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ),
106 /* STATE_EXIT2_IR */ BITSTR( 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ),
107 /* STATE_UPDATE_IR */ BITSTR( 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1 ),
108 };
109
110 static uint8_t current_state;
111
112 uint8_t jtag_current_state(void)
113 {
114 return current_state;
115 }
116
117 void jtag_set_current_state(uint8_t state)
118 {
119 current_state = state;
120 }
121
122 void jtag_error(int status){
123 mpsse_error(status);
124 }
125
126 void jtag_deinit(){
127 mpsse_close();
128 }
129
130 /**
131 * Performs any start-of-day tasks necessary to talk JTAG to our FPGA.
132 */
133 void jtag_init(int ifnum, const char *devstr, bool slow_clock)
134 {
135 mpsse_init(ifnum, devstr, slow_clock);
136
137 jtag_set_current_state(STATE_TEST_LOGIC_RESET);
138 jtag_go_to_state(STATE_TEST_LOGIC_RESET);
139 }
140
141 uint8_t data[32*1024];
142 uint8_t* ptr;
143 uint16_t rx_cnt;
144
145 extern struct ftdi_context mpsse_ftdic;
146
147 static inline void jtag_pulse_clock_and_read_tdo(bool tms, bool tdi)
148 {
149 *ptr++ = MC_DATA_TMS | MC_DATA_IN | MC_DATA_LSB | MC_DATA_BITS | MC_DATA_OCN;
150 *ptr++ = 0;
151 *ptr++ = (tdi ? 0x80 : 0) | (tms ? 0x01 : 0);
152 rx_cnt++;
153 }
154
155 static void _jtag_tap_shift(
156 uint8_t *input_data,
157 uint8_t *output_data,
158 uint32_t data_bits,
159 bool must_end)
160 {
161
162 //printf("_jtag_tap_shift(0x%08x,0x%08x,%u,%s);\n",input_data, output_data, data_bits, must_end ? "true" : "false");
163 uint32_t bit_count = data_bits;
164 uint32_t byte_count = (data_bits + 7) / 8;
165 rx_cnt = 0;
166 ptr = data;
167
168 for (uint32_t i = 0; i < byte_count; ++i) {
169 uint8_t byte_out = input_data[i];
170 for (int j = 0; j < 8 && bit_count-- > 0; ++j) {
171 bool tms = false;
172 if (bit_count == 0 && must_end) {
173 tms = true;
174 jtag_state_ack(1);
175 }
176 jtag_pulse_clock_and_read_tdo(tms, byte_out & 1);
177 byte_out >>= 1;
178 }
179 }
180
181 mpsse_xfer(data, ptr-data, rx_cnt);
182
183 /* Data out from the FTDI is actually from an internal shift register
184 * Instead of reconstructing the bitpattern, we can just take every 8th byte.*/
185 for(int i = 0; i < rx_cnt/8; i++)
186 output_data[i] = data[7+i*8];
187 }
188
189
190 static void jtag_shift_bytes(
191 uint8_t *input_data,
192 uint8_t *output_data,
193 uint32_t data_bits,
194 bool must_end)
195 {
196
197 /* Sanity check */
198 if(data_bits % 8 != 0){
199 printf("Error %u is not a byte multiple\n", data_bits);
200 }
201 //printf("jtag_shift_bytes(0x%08x,0x%08x,%u,%s);\n",input_data, output_data, data_bits, must_end ? "true" : "false");
202 uint32_t byte_count = data_bits / 8;
203
204
205
206 data[0] = MC_DATA_OUT | MC_DATA_IN | MC_DATA_LSB | MC_DATA_OCN;
207 data[1] = (byte_count - 1);
208 data[2] = (byte_count - 1) >> 8;
209 memcpy(data + 3, input_data, byte_count);
210
211 mpsse_xfer(data, byte_count + 3, byte_count);
212
213 memcpy(output_data, data, byte_count);
214 }
215
216
217 #define MIN(a,b) ((a) < (b)) ? (a) : (b)
218
219 void jtag_tap_shift(
220 uint8_t *input_data,
221 uint8_t *output_data,
222 uint32_t data_bits,
223 bool must_end)
224 {
225 /* if 'must_end' the send last byte seperately
226 * This way we toggle TMS on the last clock cycle */
227 if(must_end)
228 data_bits -= 8;
229
230 uint32_t data_bits_sent = 0;
231 if(data_bits){
232 while(data_bits_sent != data_bits){
233
234 uint32_t _data_bits = MIN(4096 + 2048, data_bits - data_bits_sent);
235
236 jtag_shift_bytes(
237 input_data + data_bits_sent/8,
238 output_data + data_bits_sent/8,
239 _data_bits,
240 false
241 );
242 data_bits_sent += _data_bits;
243 }
244 }
245
246 /* Send our last byte */
247 if(must_end){
248 _jtag_tap_shift(
249 input_data + data_bits_sent/8,
250 output_data + data_bits_sent/8,
251 8,
252 must_end
253 );
254 }
255 }
256
257 void jtag_state_ack(bool tms)
258 {
259 if (tms) {
260 jtag_set_current_state((tms_transitions[jtag_current_state()] >> 4) & 0xf);
261 } else {
262 jtag_set_current_state(tms_transitions[jtag_current_state()] & 0xf);
263 }
264 }
265
266 void jtag_go_to_state(unsigned state)
267 {
268
269 if (state == STATE_TEST_LOGIC_RESET) {
270 for (int i = 0; i < 5; ++i) {
271 jtag_state_ack(true);
272 }
273
274 uint8_t data[3] = {
275 MC_DATA_TMS | MC_DATA_LSB | MC_DATA_BITS,
276 5 - 1,
277 0b11111
278 };
279 mpsse_xfer(data, 3, 0);
280
281 } else {
282 while (jtag_current_state() != state) {
283 uint8_t data[3] = {
284 MC_DATA_TMS | MC_DATA_LSB | MC_DATA_ICN | MC_DATA_BITS,
285 0,
286 (tms_map[jtag_current_state()] >> state) & 1
287 };
288
289 jtag_state_ack((tms_map[jtag_current_state()] >> state) & 1);
290 mpsse_xfer(data, 3, 0);
291 }
292 }
293 }
294
295 void jtag_wait_time(uint32_t microseconds)
296 {
297 uint16_t bytes = microseconds / 8;
298 uint8_t remain = microseconds % 8;
299
300 uint8_t data[3] = {
301 MC_CLK_N8,
302 bytes & 0xFF,
303 (bytes >> 8) & 0xFF
304 };
305 mpsse_xfer(data, 3, 0);
306
307 if(remain){
308 data[0] = MC_CLK_N;
309 data[1] = remain;
310 mpsse_xfer(data, 2, 0);
311 }
312 }
313