initial commit, start with iceprog as a base
[ecpprog.git] / mpsse.c
1 /*
2 * iceprog -- simple programming tool for FTDI-based Lattice iCE programmers
3 *
4 * Copyright (C) 2015 Clifford Wolf <clifford@clifford.at>
5 * Copyright (C) 2018 Piotr Esden-Tempski <piotr@esden.net>
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 * Relevant Documents:
20 * -------------------
21 * http://www.ftdichip.com/Support/Documents/AppNotes/AN_108_Command_Processor_for_MPSSE_and_MCU_Host_Bus_Emulation_Modes.pdf
22 */
23
24 #define _GNU_SOURCE
25
26 #include <ftdi.h>
27 #include <stdio.h>
28 #include <stdint.h>
29 #include <stdbool.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32
33 #include "mpsse.h"
34
35 // ---------------------------------------------------------
36 // MPSSE / FTDI definitions
37 // ---------------------------------------------------------
38
39 /* FTDI bank pinout typically used for iCE dev boards
40 * BUS IO | Signal | Control
41 * -------+--------+--------------
42 * xDBUS0 | SCK | MPSSE
43 * xDBUS1 | MOSI | MPSSE
44 * xDBUS2 | MISO | MPSSE
45 * xDBUS3 | nc |
46 * xDBUS4 | CS | GPIO
47 * xDBUS5 | nc |
48 * xDBUS6 | CDONE | GPIO
49 * xDBUS7 | CRESET | GPIO
50 */
51
52 struct ftdi_context mpsse_ftdic;
53 bool mpsse_ftdic_open = false;
54 bool mpsse_ftdic_latency_set = false;
55 unsigned char mpsse_ftdi_latency;
56
57
58 enum jtag_states
59 {
60 JTAG_INVALID = 0,
61 JTAG_TEST_LOGIC_RESET,
62 JTAG_RUN_TEST_IDLE,
63 JTAG_SELECT_DR_SCAN,
64 JTAG_CAPTURE_DR,
65 JTAG_SHIFT_DR,
66 JTAG_EXIT_1_DR,
67 JTAG_PAUSE_DR,
68 JTAG_EXIT_2_DR,
69 JTAG_UPDATE_DR,
70 JTAG_SELECT_IR_SCAN,
71 JTAG_CAPTURE_IR,
72 JTAG_SHIFT_IR,
73 JTAG_EXIT_1_IR,
74 JTAG_PAUSE_IR,
75 JTAG_EXIT_2_IR,
76 JTAG_UPDATE_IR,
77 };
78 enum jtag_states jtag_state = JTAG_INVALID;
79
80 /* MPSSE engine command definitions */
81 enum mpsse_cmd
82 {
83 /* Mode commands */
84 MC_SETB_LOW = 0x80, /* Set Data bits LowByte */
85 MC_READB_LOW = 0x81, /* Read Data bits LowByte */
86 MC_SETB_HIGH = 0x82, /* Set Data bits HighByte */
87 MC_READB_HIGH = 0x83, /* Read data bits HighByte */
88 MC_LOOPBACK_EN = 0x84, /* Enable loopback */
89 MC_LOOPBACK_DIS = 0x85, /* Disable loopback */
90 MC_SET_CLK_DIV = 0x86, /* Set clock divisor */
91 MC_FLUSH = 0x87, /* Flush buffer fifos to the PC. */
92 MC_WAIT_H = 0x88, /* Wait on GPIOL1 to go high. */
93 MC_WAIT_L = 0x89, /* Wait on GPIOL1 to go low. */
94 MC_TCK_X5 = 0x8A, /* Disable /5 div, enables 60MHz master clock */
95 MC_TCK_D5 = 0x8B, /* Enable /5 div, backward compat to FT2232D */
96 MC_EN_3PH_CLK = 0x8C, /* Enable 3 phase clk, DDR I2C */
97 MC_DIS_3PH_CLK = 0x8D, /* Disable 3 phase clk */
98 MC_CLK_N = 0x8E, /* Clock every bit, used for JTAG */
99 MC_CLK_N8 = 0x8F, /* Clock every byte, used for JTAG */
100 MC_CLK_TO_H = 0x94, /* Clock until GPIOL1 goes high */
101 MC_CLK_TO_L = 0x95, /* Clock until GPIOL1 goes low */
102 MC_EN_ADPT_CLK = 0x96, /* Enable adaptive clocking */
103 MC_DIS_ADPT_CLK = 0x97, /* Disable adaptive clocking */
104 MC_CLK8_TO_H = 0x9C, /* Clock until GPIOL1 goes high, count bytes */
105 MC_CLK8_TO_L = 0x9D, /* Clock until GPIOL1 goes low, count bytes */
106 MC_TRI = 0x9E, /* Set IO to only drive on 0 and tristate on 1 */
107 /* CPU mode commands */
108 MC_CPU_RS = 0x90, /* CPUMode read short address */
109 MC_CPU_RE = 0x91, /* CPUMode read extended address */
110 MC_CPU_WS = 0x92, /* CPUMode write short address */
111 MC_CPU_WE = 0x93, /* CPUMode write extended address */
112 };
113
114 /* Transfer Command bits */
115
116 /* All byte based commands consist of:
117 * - Command byte
118 * - Length lsb
119 * - Length msb
120 *
121 * If data out is enabled the data follows after the above command bytes,
122 * otherwise no additional data is needed.
123 * - Data * n
124 *
125 * All bit based commands consist of:
126 * - Command byte
127 * - Length
128 *
129 * If data out is enabled a byte containing bitst to transfer follows.
130 * Otherwise no additional data is needed. Only up to 8 bits can be transferred
131 * per transaction when in bit mode.
132 */
133
134 /* b 0000 0000
135 * |||| |||`- Data out negative enable. Update DO on negative clock edge.
136 * |||| ||`-- Bit count enable. When reset count represents bytes.
137 * |||| |`--- Data in negative enable. Latch DI on negative clock edge.
138 * |||| `---- LSB enable. When set clock data out LSB first.
139 * ||||
140 * |||`------ Data out enable
141 * ||`------- Data in enable
142 * |`-------- TMS mode enable
143 * `--------- Special command mode enable. See mpsse_cmd enum.
144 */
145
146 #define MC_DATA_TMS (0x40) /* When set use TMS mode */
147 #define MC_DATA_IN (0x20) /* When set read data (Data IN) */
148 #define MC_DATA_OUT (0x10) /* When set write data (Data OUT) */
149 #define MC_DATA_LSB (0x08) /* When set input/output data LSB first. */
150 #define MC_DATA_ICN (0x04) /* When set receive data on negative clock edge */
151 #define MC_DATA_BITS (0x02) /* When set count bits not bytes */
152 #define MC_DATA_OCN (0x01) /* When set update data on negative clock edge */
153
154 // ---------------------------------------------------------
155 // MPSSE / FTDI function implementations
156 // ---------------------------------------------------------
157
158 void mpsse_check_rx()
159 {
160 while (1) {
161 uint8_t data;
162 int rc = ftdi_read_data(&mpsse_ftdic, &data, 1);
163 if (rc <= 0)
164 break;
165 fprintf(stderr, "unexpected rx byte: %02X\n", data);
166 }
167 }
168
169 void mpsse_error(int status)
170 {
171 mpsse_check_rx();
172 fprintf(stderr, "ABORT.\n");
173 if (mpsse_ftdic_open) {
174 if (mpsse_ftdic_latency_set)
175 ftdi_set_latency_timer(&mpsse_ftdic, mpsse_ftdi_latency);
176 ftdi_usb_close(&mpsse_ftdic);
177 }
178 ftdi_deinit(&mpsse_ftdic);
179 exit(status);
180 }
181
182 uint8_t mpsse_recv_byte()
183 {
184 uint8_t data;
185 while (1) {
186 int rc = ftdi_read_data(&mpsse_ftdic, &data, 1);
187 if (rc < 0) {
188 fprintf(stderr, "Read error.\n");
189 mpsse_error(2);
190 }
191 if (rc == 1)
192 break;
193 usleep(100);
194 }
195 return data;
196 }
197
198 void mpsse_send_byte(uint8_t data)
199 {
200 int rc = ftdi_write_data(&mpsse_ftdic, &data, 1);
201 if (rc != 1) {
202 fprintf(stderr, "Write error (single byte, rc=%d, expected %d).\n", rc, 1);
203 mpsse_error(2);
204 }
205 }
206
207 void mpsse_send_spi(uint8_t *data, int n)
208 {
209 if (n < 1)
210 return;
211
212 /* Output only, update data on negative clock edge. */
213 mpsse_send_byte(MC_DATA_OUT | MC_DATA_OCN);
214 mpsse_send_byte(n - 1);
215 mpsse_send_byte((n - 1) >> 8);
216
217 int rc = ftdi_write_data(&mpsse_ftdic, data, n);
218 if (rc != n) {
219 fprintf(stderr, "Write error (chunk, rc=%d, expected %d).\n", rc, n);
220 mpsse_error(2);
221 }
222 }
223
224 void mpsse_xfer_spi(uint8_t *data, int n)
225 {
226 if (n < 1)
227 return;
228
229 /* Input and output, update data on negative edge read on positive. */
230 mpsse_send_byte(MC_DATA_IN | MC_DATA_OUT | MC_DATA_OCN);
231 mpsse_send_byte(n - 1);
232 mpsse_send_byte((n - 1) >> 8);
233
234 int rc = ftdi_write_data(&mpsse_ftdic, data, n);
235 if (rc != n) {
236 fprintf(stderr, "Write error (chunk, rc=%d, expected %d).\n", rc, n);
237 mpsse_error(2);
238 }
239
240 for (int i = 0; i < n; i++)
241 data[i] = mpsse_recv_byte();
242 }
243
244 uint8_t mpsse_xfer_spi_bits(uint8_t data, int n)
245 {
246 if (n < 1)
247 return 0;
248
249 /* Input and output, update data on negative edge read on positive, bits. */
250 mpsse_send_byte(MC_DATA_IN | MC_DATA_OUT | MC_DATA_OCN | MC_DATA_BITS);
251 mpsse_send_byte(n - 1);
252 mpsse_send_byte(data);
253
254 return mpsse_recv_byte();
255 }
256
257 void mpsse_set_gpio(uint8_t gpio, uint8_t direction)
258 {
259 mpsse_send_byte(MC_SETB_LOW);
260 mpsse_send_byte(gpio); /* Value */
261 mpsse_send_byte(direction); /* Direction */
262 }
263
264 int mpsse_readb_low(void)
265 {
266 uint8_t data;
267 mpsse_send_byte(MC_READB_LOW);
268 data = mpsse_recv_byte();
269 return data;
270 }
271
272 int mpsse_readb_high(void)
273 {
274 uint8_t data;
275 mpsse_send_byte(MC_READB_HIGH);
276 data = mpsse_recv_byte();
277 return data;
278 }
279
280 void mpsse_send_dummy_bytes(uint8_t n)
281 {
282 // add 8 x count dummy bits (aka n bytes)
283 mpsse_send_byte(MC_CLK_N8);
284 mpsse_send_byte(n - 1);
285 mpsse_send_byte(0x00);
286
287 }
288
289 void mpsse_send_dummy_bit(void)
290 {
291 // add 1 dummy bit
292 mpsse_send_byte(MC_CLK_N);
293 mpsse_send_byte(0x00);
294 }
295
296 void mpsse_jtag_init(){
297 mpsse_send_byte(MC_SETB_LOW);
298 mpsse_send_byte(0x08); /* Value */
299 mpsse_send_byte(0x0B); /* Direction */
300
301 /* Reset JTAG State machine */
302 mpsse_jtag_tms(6, 0b111111);
303
304 jtag_state = JTAG_TEST_LOGIC_RESET;
305 }
306
307 void mpsse_jtag_tms(uint8_t bits, uint8_t pattern){
308 mpsse_send_byte(MC_DATA_TMS | MC_DATA_IN | MC_DATA_LSB | MC_DATA_BITS);
309 mpsse_send_byte(bits-1);
310 mpsse_send_byte(pattern);
311 }
312
313 void mpsse_jtag_idcode(){
314 mpsse_send_byte(MC_SETB_LOW);
315 mpsse_send_byte(0x08); /* Value */
316 mpsse_send_byte(0x0B); /* Direction */
317
318 /* Reset JTAG State machine */
319 mpsse_jtag_tms(6, 0b000000);
320 mpsse_jtag_tms(6, 0b000000);
321
322 jtag_state = JTAG_TEST_LOGIC_RESET;
323 }
324
325 void mpsse_jtag_scan_dr(uint16_t len, uint8_t* data_out){
326 uint8_t data;
327 enter_jtag_state_shift_dr();
328
329 mpsse_send_byte(MC_DATA_IN | MC_DATA_LSB);
330 mpsse_send_byte(4);
331 data = mpsse_recv_byte();
332 data = mpsse_recv_byte();
333
334 uint32_t idcode = 0;
335
336 for(int i = 0; i < 4; i++)
337 {
338 mpsse_send_byte(0);
339 idcode = mpsse_recv_byte() << 24 | idcode >> 8;
340 }
341
342 fprintf(stderr, "idcode: 0x%08x\n", idcode);
343
344 mpsse_jtag_tms(6, 0b111111);
345
346
347 }
348
349 void enter_jtag_state_shift_dr(){
350 switch(jtag_state){
351 case JTAG_TEST_LOGIC_RESET:
352 mpsse_jtag_tms(4, 0b0010);
353 break;
354
355 default:
356 case JTAG_INVALID:
357 fprintf(stderr, "JTAG statemachine in INVALID State\n");
358 break;
359 }
360 }
361
362 void mpsse_init(int ifnum, const char *devstr, bool slow_clock)
363 {
364 enum ftdi_interface ftdi_ifnum = INTERFACE_A;
365
366 switch (ifnum) {
367 case 0:
368 ftdi_ifnum = INTERFACE_A;
369 break;
370 case 1:
371 ftdi_ifnum = INTERFACE_B;
372 break;
373 case 2:
374 ftdi_ifnum = INTERFACE_C;
375 break;
376 case 3:
377 ftdi_ifnum = INTERFACE_D;
378 break;
379 default:
380 ftdi_ifnum = INTERFACE_A;
381 break;
382 }
383
384 ftdi_init(&mpsse_ftdic);
385 ftdi_set_interface(&mpsse_ftdic, ftdi_ifnum);
386
387 if (devstr != NULL) {
388 if (ftdi_usb_open_string(&mpsse_ftdic, devstr)) {
389 fprintf(stderr, "Can't find iCE FTDI USB device (device string %s).\n", devstr);
390 mpsse_error(2);
391 }
392 } else {
393 if (ftdi_usb_open(&mpsse_ftdic, 0x0403, 0x6010) && ftdi_usb_open(&mpsse_ftdic, 0x0403, 0x6014)) {
394 fprintf(stderr, "Can't find iCE FTDI USB device (vendor_id 0x0403, device_id 0x6010 or 0x6014).\n");
395 mpsse_error(2);
396 }
397 }
398
399 mpsse_ftdic_open = true;
400
401 if (ftdi_usb_reset(&mpsse_ftdic)) {
402 fprintf(stderr, "Failed to reset iCE FTDI USB device.\n");
403 mpsse_error(2);
404 }
405
406 if (ftdi_usb_purge_buffers(&mpsse_ftdic)) {
407 fprintf(stderr, "Failed to purge buffers on iCE FTDI USB device.\n");
408 mpsse_error(2);
409 }
410
411 if (ftdi_get_latency_timer(&mpsse_ftdic, &mpsse_ftdi_latency) < 0) {
412 fprintf(stderr, "Failed to get latency timer (%s).\n", ftdi_get_error_string(&mpsse_ftdic));
413 mpsse_error(2);
414 }
415
416 /* 1 is the fastest polling, it means 1 kHz polling */
417 if (ftdi_set_latency_timer(&mpsse_ftdic, 1) < 0) {
418 fprintf(stderr, "Failed to set latency timer (%s).\n", ftdi_get_error_string(&mpsse_ftdic));
419 mpsse_error(2);
420 }
421
422 mpsse_ftdic_latency_set = true;
423
424 /* Enter MPSSE (Multi-Protocol Synchronous Serial Engine) mode. Set all pins to output. */
425 if (ftdi_set_bitmode(&mpsse_ftdic, 0xff, BITMODE_MPSSE) < 0) {
426 fprintf(stderr, "Failed to set BITMODE_MPSSE on iCE FTDI USB device.\n");
427 mpsse_error(2);
428 }
429
430 // enable clock divide by 5
431 mpsse_send_byte(MC_TCK_D5);
432
433 if (slow_clock) {
434 // set 50 kHz clock
435 mpsse_send_byte(MC_SET_CLK_DIV);
436 mpsse_send_byte(119);
437 mpsse_send_byte(0x00);
438 } else {
439 // set 6 MHz clock
440 mpsse_send_byte(MC_SET_CLK_DIV);
441 mpsse_send_byte(0x00);
442 mpsse_send_byte(0x00);
443 }
444 }
445
446 void mpsse_close(void)
447 {
448 ftdi_set_latency_timer(&mpsse_ftdic, mpsse_ftdi_latency);
449 ftdi_disable_bitbang(&mpsse_ftdic);
450 ftdi_usb_close(&mpsse_ftdic);
451 ftdi_deinit(&mpsse_ftdic);
452 }