some more jtag speedups
[ecpprog.git] / 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 <stdio.h>
10 #include <stdint.h>
11 #include <stdbool.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14
15 #include "mpsse.h"
16 #include "jtag.h"
17
18 void jtag_state_ack(bool tms);
19
20 /*
21 * Low nibble : TMS == 0
22 * High nibble: TMS == 1
23 */
24
25 #define TMS_T(TMS_HIGH_STATE, TMS_LOW_STATE) (((TMS_HIGH_STATE) << 4) | (TMS_LOW_STATE))
26
27 static const uint8_t tms_transitions[] = {
28 /* STATE_TEST_LOGIC_RESET */ TMS_T(STATE_TEST_LOGIC_RESET, STATE_RUN_TEST_IDLE),
29 /* STATE_RUN_TEST_IDLE */ TMS_T(STATE_SELECT_DR_SCAN, STATE_RUN_TEST_IDLE),
30 /* STATE_SELECT_DR_SCAN */ TMS_T(STATE_SELECT_IR_SCAN, STATE_CAPTURE_DR),
31 /* STATE_CAPTURE_DR */ TMS_T(STATE_EXIT1_DR, STATE_SHIFT_DR),
32 /* STATE_SHIFT_DR */ TMS_T(STATE_EXIT1_DR, STATE_SHIFT_DR),
33 /* STATE_EXIT1_DR */ TMS_T(STATE_UPDATE_DR, STATE_PAUSE_DR),
34 /* STATE_PAUSE_DR */ TMS_T(STATE_EXIT2_DR, STATE_PAUSE_DR),
35 /* STATE_EXIT2_DR */ TMS_T(STATE_UPDATE_DR, STATE_SHIFT_DR),
36 /* STATE_UPDATE_DR */ TMS_T(STATE_SELECT_DR_SCAN, STATE_RUN_TEST_IDLE),
37 /* STATE_SELECT_IR_SCAN */ TMS_T(STATE_TEST_LOGIC_RESET, STATE_CAPTURE_IR),
38 /* STATE_CAPTURE_IR */ TMS_T(STATE_EXIT1_IR, STATE_SHIFT_IR),
39 /* STATE_SHIFT_IR */ TMS_T(STATE_EXIT1_IR, STATE_SHIFT_IR),
40 /* STATE_EXIT1_IR */ TMS_T(STATE_UPDATE_IR, STATE_PAUSE_IR),
41 /* STATE_PAUSE_IR */ TMS_T(STATE_EXIT2_IR, STATE_PAUSE_IR),
42 /* STATE_EXIT2_IR */ TMS_T(STATE_UPDATE_IR, STATE_SHIFT_IR),
43 /* STATE_UPDATE_IR */ TMS_T(STATE_SELECT_DR_SCAN, STATE_RUN_TEST_IDLE),
44 };
45
46 #define BITSTR(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) ( \
47 ((uint16_t)(A) << 15) | \
48 ((uint16_t)(B) << 14) | \
49 ((uint16_t)(C) << 13) | \
50 ((uint16_t)(D) << 12) | \
51 ((uint16_t)(E) << 11) | \
52 ((uint16_t)(F) << 10) | \
53 ((uint16_t)(G) << 9) | \
54 ((uint16_t)(H) << 8) | \
55 ((uint16_t)(I) << 7) | \
56 ((uint16_t)(J) << 6) | \
57 ((uint16_t)(K) << 5) | \
58 ((uint16_t)(L) << 4) | \
59 ((uint16_t)(M) << 3) | \
60 ((uint16_t)(N) << 2) | \
61 ((uint16_t)(O) << 1) | \
62 ((uint16_t)(P) << 0) )
63
64 /*
65 * The index of this vector is the current state. The i-th bit tells you the
66 * value TMS must assume in order to go to state "i".
67
68 ------------------------------------------------------------------------------------------------------------
69 | | || F | E | D | C || B | A | 9 | 8 || 7 | 6 | 5 | 4 || 3 | 2 | 1 | 0 || HEX |
70 ------------------------------------------------------------------------------------------------------------
71 | STATE_TEST_LOGIC_RESET | 0 || 0 | 0 | 0 | 0 || 0 | 0 | 0 | 0 || 0 | 0 | 0 | 0 || 0 | 0 | 0 | 1 || 0x0001 |
72 | STATE_RUN_TEST_IDLE | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 0 | 1 || 0xFFFD |
73 | STATE_SELECT_DR_SCAN | 2 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 0 || 0 | 0 | 0 | 0 || 0 | x | 1 | 1 || 0xFE03 |
74 | STATE_CAPTURE_DR | 3 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 0 || x | 1 | 1 | 1 || 0xFFE7 |
75 | STATE_SHIFT_DR | 4 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 0 || 1 | 1 | 1 | 1 || 0xFFEF |
76 | STATE_EXIT1_DR | 5 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 0 | 0 | x | 0 || 1 | 1 | 1 | 1 || 0xFF0F |
77 | STATE_PAUSE_DR | 6 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 0 | 1 | 1 || 1 | 1 | 1 | 1 || 0xFFBF |
78 | STATE_EXIT2_DR | 7 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || x | 0 | 0 | 0 || 1 | 1 | 1 | 1 || 0xFF0F |
79 | STATE_UPDATE_DR | 8 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | x || 1 | 1 | 1 | 1 || 1 | 1 | 0 | 1 || 0xFEFD |
80 | STATE_SELECT_IR_SCAN | 9 || 0 | 0 | 0 | 0 || 0 | 0 | x | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 0x01FF |
81 | STATE_CAPTURE_IR | A || 1 | 1 | 1 | 1 || 0 | x | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 0xF3FF |
82 | STATE_SHIFT_IR | B || 1 | 1 | 1 | 1 || 0 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 0xF7FF |
83 | STATE_EXIT1_IR | C || 1 | 0 | 0 | x || 0 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 0x87FF |
84 | STATE_PAUSE_IR | D || 1 | 1 | 0 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 0xDFFF |
85 | STATE_EXIT2_IR | E || 1 | x | 0 | 0 || 0 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 0x87FF |
86 | STATE_UPDATE_IR | F || x | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 1 | 1 || 1 | 1 | 0 | 1 || 0x7FFD |
87 ------------------------------------------------------------------------------------------------------------
88
89 */
90 static const uint16_t tms_map[] = {
91 /* STATE_TEST_LOGIC_RESET */ BITSTR( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ),
92 /* STATE_RUN_TEST_IDLE */ BITSTR( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1 ),
93 /* STATE_SELECT_DR_SCAN */ BITSTR( 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1 ),
94 /* STATE_CAPTURE_DR */ BITSTR( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 ),
95 /* STATE_SHIFT_DR */ BITSTR( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 ),
96 /* STATE_EXIT1_DR */ BITSTR( 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 ),
97 /* STATE_PAUSE_DR */ BITSTR( 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 ),
98 /* STATE_EXIT2_DR */ BITSTR( 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 ),
99 /* STATE_UPDATE_DR */ BITSTR( 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1 ),
100 /* STATE_SELECT_IR_SCAN */ BITSTR( 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 ),
101 /* STATE_CAPTURE_IR */ BITSTR( 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ),
102 /* STATE_SHIFT_IR */ BITSTR( 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ),
103 /* STATE_EXIT1_IR */ BITSTR( 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ),
104 /* STATE_PAUSE_IR */ BITSTR( 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ),
105 /* STATE_EXIT2_IR */ BITSTR( 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ),
106 /* STATE_UPDATE_IR */ BITSTR( 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1 ),
107 };
108
109 static uint8_t current_state;
110
111 uint8_t jtag_current_state(void)
112 {
113 return current_state;
114 }
115
116 void jtag_set_current_state(uint8_t state)
117 {
118 current_state = state;
119 }
120
121
122 /**
123 * Hook for any per-platform initialization that needs to occur.
124 */
125 __attribute__((weak)) void jtag_platform_init(void)
126 {
127
128 }
129
130
131 /**
132 * Performs any start-of-day tasks necessary to talk JTAG to our FPGA.
133 */
134 void jtag_init(void)
135 {
136 jtag_platform_init();
137 jtag_set_current_state(STATE_TEST_LOGIC_RESET);
138 jtag_go_to_state(STATE_TEST_LOGIC_RESET);
139 }
140
141
142 static inline void jtag_pulse_clock(void)
143 {
144 //mpsse_send_byte(MC_CLK_N);
145 //mpsse_send_byte(0x00);
146 mpsse_send_byte(MC_DATA_TMS | MC_DATA_IN | MC_DATA_LSB | MC_DATA_BITS);
147 mpsse_send_byte(0);
148 mpsse_send_byte(0);
149 }
150
151 uint8_t data[512];
152 uint8_t* ptr;
153 uint8_t rx_cnt;
154
155 extern struct ftdi_context mpsse_ftdic;
156
157 static inline uint8_t jtag_pulse_clock_and_read_tdo(bool tms, bool tdi)
158 {
159 uint8_t ret;
160 *ptr++ = MC_DATA_TMS | MC_DATA_IN | MC_DATA_LSB | MC_DATA_BITS;
161 *ptr++ = 0;
162
163 uint8_t data0 = 0;
164 if(tdi)
165 data0 |= 0x80;
166 if(tms)
167 data0 |= 0x01;
168
169 *ptr++ = data0;
170 rx_cnt++;
171 //ret = mpsse_recv_byte();
172
173 //return (ret >> 7) & 1;
174 }
175
176
177 void jtag_tap_shift(
178 uint8_t *input_data,
179 uint8_t *output_data,
180 uint32_t data_bits,
181 bool must_end)
182 {
183
184
185 mpsse_purge();
186
187 uint32_t bit_count = data_bits;
188 uint32_t byte_count = (data_bits + 7) / 8;
189
190 for (uint32_t i = 0; i < byte_count; ++i) {
191 uint8_t byte_out = input_data[i];
192 uint8_t tdo_byte = 0;
193
194 rx_cnt = 0;
195 ptr = data;
196
197
198 for (int j = 0; j < 8 && bit_count-- > 0; ++j) {
199 bool tms = false;
200 bool tdi = false;
201 if (bit_count == 0 && must_end) {
202 tms = true;
203 jtag_state_ack(1);
204 }
205 if (byte_out & 1) {
206 tdi = true;
207 } else {
208 tdi = false;
209 }
210 byte_out >>= 1;
211 bool tdo = jtag_pulse_clock_and_read_tdo(tms, tdi);
212 tdo_byte |= tdo << j;
213 }
214 printf(" Tx: %u, Rx: %u\n", ptr-data, rx_cnt);
215 int rc = ftdi_write_data(&mpsse_ftdic, &data, ptr-data);
216 if (rc != (ptr-data)) {
217 fprintf(stderr, "Write error (single byte, rc=%d, expected %d).\n", rc, 1);
218 mpsse_error(2);
219 }
220
221
222 rc = ftdi_read_data(&mpsse_ftdic, &data, rx_cnt);
223 if (rc < 0) {
224 fprintf(stderr, "Read error.\n");
225 mpsse_error(2);
226 }
227 output_data[i] = data[rx_cnt-1];
228 }
229 }
230
231 void jtag_state_ack(bool tms)
232 {
233 if (tms) {
234 jtag_set_current_state((tms_transitions[jtag_current_state()] >> 4) & 0xf);
235 } else {
236 jtag_set_current_state(tms_transitions[jtag_current_state()] & 0xf);
237 }
238 }
239
240 void jtag_state_step(bool tms)
241 {
242
243 //mpsse_send_byte(MC_DATA_TMS | MC_DATA_LSB | MC_DATA_BITS);
244 //mpsse_send_byte(0);
245 if (tms) {
246 // mpsse_send_byte(1);
247 } else {
248 // mpsse_send_byte(0);
249 }
250
251 jtag_state_ack(tms);
252 }
253
254
255 uint8_t bit_reverse(uint8_t);
256
257 void jtag_go_to_state(unsigned state)
258 {
259 mpsse_purge();
260
261 if (state == STATE_TEST_LOGIC_RESET) {
262 for (int i = 0; i < 5; ++i) {
263 jtag_state_step(true);
264 }
265 mpsse_send_byte(MC_DATA_TMS | MC_DATA_LSB | MC_DATA_BITS);
266 mpsse_send_byte(5 - 1);
267 mpsse_send_byte(0b11111);
268
269 } else {
270 uint8_t d = 0;
271 uint8_t count = 0;
272 while (jtag_current_state() != state) {
273 d = (d >> 1) & ~0x80;
274 if((tms_map[jtag_current_state()] >> state) & 1){
275 d |= 0x80;
276 }
277 count++;
278
279 jtag_state_step((tms_map[jtag_current_state()] >> state) & 1);
280 }
281 mpsse_send_byte(MC_DATA_TMS | MC_DATA_LSB | MC_DATA_BITS);
282 mpsse_send_byte(count - 1);
283 mpsse_send_byte(d >> (8-count));
284
285 }
286 }
287
288 void jtag_wait_time(uint32_t microseconds)
289 {
290 while (microseconds--) {
291 jtag_pulse_clock();
292 }
293 }
294