slight speedup to jtag-tap
[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 // ---------------------------------------------------------
59 // MPSSE / FTDI function implementations
60 // ---------------------------------------------------------
61
62 void mpsse_check_rx()
63 {
64 while (1) {
65 uint8_t data;
66 int rc = ftdi_read_data(&mpsse_ftdic, &data, 1);
67 if (rc <= 0)
68 break;
69 fprintf(stderr, "unexpected rx byte: %02X\n", data);
70 }
71 }
72
73 void mpsse_error(int status)
74 {
75 mpsse_check_rx();
76 fprintf(stderr, "ABORT.\n");
77 if (mpsse_ftdic_open) {
78 if (mpsse_ftdic_latency_set)
79 ftdi_set_latency_timer(&mpsse_ftdic, mpsse_ftdi_latency);
80 ftdi_usb_close(&mpsse_ftdic);
81 }
82 ftdi_deinit(&mpsse_ftdic);
83 exit(status);
84 }
85
86 uint8_t mpsse_recv_byte()
87 {
88 uint8_t data;
89 while (1) {
90 int rc = ftdi_read_data(&mpsse_ftdic, &data, 1);
91 if (rc < 0) {
92 fprintf(stderr, "Read error.\n");
93 mpsse_error(2);
94 }
95 if (rc == 1)
96 break;
97 usleep(100);
98 }
99 return data;
100 }
101
102 void mpsse_send_byte(uint8_t data)
103 {
104 int rc = ftdi_write_data(&mpsse_ftdic, &data, 1);
105 if (rc != 1) {
106 fprintf(stderr, "Write error (single byte, rc=%d, expected %d).\n", rc, 1);
107 mpsse_error(2);
108 }
109 }
110
111 void mpsse_purge(void){
112 int rc = ftdi_usb_purge_buffers(&mpsse_ftdic);
113 if (rc != 0) {
114 fprintf(stderr, "Purge error.\n");
115 mpsse_error(2);
116 }
117 }
118
119 void mpsse_send_spi(uint8_t *data, int n)
120 {
121 if (n < 1)
122 return;
123
124 /* Output only, update data on negative clock edge. */
125 mpsse_send_byte(MC_DATA_OUT | MC_DATA_OCN);
126 mpsse_send_byte(n - 1);
127 mpsse_send_byte((n - 1) >> 8);
128
129 int rc = ftdi_write_data(&mpsse_ftdic, data, n);
130 if (rc != n) {
131 fprintf(stderr, "Write error (chunk, rc=%d, expected %d).\n", rc, n);
132 mpsse_error(2);
133 }
134 }
135
136 void mpsse_xfer_spi(uint8_t *data, int n)
137 {
138 if (n < 1)
139 return;
140
141 /* Input and output, update data on negative edge read on positive. */
142 mpsse_send_byte(MC_DATA_IN | MC_DATA_OUT | MC_DATA_OCN);
143 mpsse_send_byte(n - 1);
144 mpsse_send_byte((n - 1) >> 8);
145
146 int rc = ftdi_write_data(&mpsse_ftdic, data, n);
147 if (rc != n) {
148 fprintf(stderr, "Write error (chunk, rc=%d, expected %d).\n", rc, n);
149 mpsse_error(2);
150 }
151
152 for (int i = 0; i < n; i++)
153 data[i] = mpsse_recv_byte();
154 }
155
156 uint8_t mpsse_xfer_spi_bits(uint8_t data, int n)
157 {
158 if (n < 1)
159 return 0;
160
161 /* Input and output, update data on negative edge read on positive, bits. */
162 mpsse_send_byte(MC_DATA_IN | MC_DATA_OUT | MC_DATA_OCN | MC_DATA_BITS);
163 mpsse_send_byte(n - 1);
164 mpsse_send_byte(data);
165
166 return mpsse_recv_byte();
167 }
168
169 void mpsse_set_gpio(uint8_t gpio, uint8_t direction)
170 {
171 mpsse_send_byte(MC_SETB_LOW);
172 mpsse_send_byte(gpio); /* Value */
173 mpsse_send_byte(direction); /* Direction */
174 }
175
176 int mpsse_readb_low(void)
177 {
178 uint8_t data;
179 mpsse_send_byte(MC_READB_LOW);
180 data = mpsse_recv_byte();
181 return data;
182 }
183
184 int mpsse_readb_high(void)
185 {
186 uint8_t data;
187 mpsse_send_byte(MC_READB_HIGH);
188 data = mpsse_recv_byte();
189 return data;
190 }
191
192 void mpsse_send_dummy_bytes(uint8_t n)
193 {
194 // add 8 x count dummy bits (aka n bytes)
195 mpsse_send_byte(MC_CLK_N8);
196 mpsse_send_byte(n - 1);
197 mpsse_send_byte(0x00);
198
199 }
200
201 void mpsse_send_dummy_bit(void)
202 {
203 // add 1 dummy bit
204 mpsse_send_byte(MC_CLK_N);
205 mpsse_send_byte(0x00);
206 }
207
208 void mpsse_jtag_init(){
209 mpsse_send_byte(MC_SETB_LOW);
210 mpsse_send_byte(0x08); /* Value */
211 mpsse_send_byte(0x0B); /* Direction */
212
213 /* Reset JTAG State machine */
214 jtag_init();
215 }
216
217 void mpsse_jtag_tms(uint8_t bits, uint8_t pattern){
218 mpsse_send_byte(MC_DATA_TMS | MC_DATA_LSB | MC_DATA_BITS);
219 mpsse_send_byte(bits-1);
220 mpsse_send_byte(pattern);
221 }
222
223 void mpsse_init(int ifnum, const char *devstr, bool slow_clock)
224 {
225 enum ftdi_interface ftdi_ifnum = INTERFACE_A;
226
227 switch (ifnum) {
228 case 0:
229 ftdi_ifnum = INTERFACE_A;
230 break;
231 case 1:
232 ftdi_ifnum = INTERFACE_B;
233 break;
234 case 2:
235 ftdi_ifnum = INTERFACE_C;
236 break;
237 case 3:
238 ftdi_ifnum = INTERFACE_D;
239 break;
240 default:
241 ftdi_ifnum = INTERFACE_A;
242 break;
243 }
244
245 ftdi_init(&mpsse_ftdic);
246 ftdi_set_interface(&mpsse_ftdic, ftdi_ifnum);
247
248 if (devstr != NULL) {
249 if (ftdi_usb_open_string(&mpsse_ftdic, devstr)) {
250 fprintf(stderr, "Can't find iCE FTDI USB device (device string %s).\n", devstr);
251 mpsse_error(2);
252 }
253 } else {
254 if (ftdi_usb_open(&mpsse_ftdic, 0x0403, 0x6010) && ftdi_usb_open(&mpsse_ftdic, 0x0403, 0x6014)) {
255 fprintf(stderr, "Can't find iCE FTDI USB device (vendor_id 0x0403, device_id 0x6010 or 0x6014).\n");
256 mpsse_error(2);
257 }
258 }
259
260 mpsse_ftdic_open = true;
261
262 if (ftdi_usb_reset(&mpsse_ftdic)) {
263 fprintf(stderr, "Failed to reset iCE FTDI USB device.\n");
264 mpsse_error(2);
265 }
266
267 if (ftdi_usb_purge_buffers(&mpsse_ftdic)) {
268 fprintf(stderr, "Failed to purge buffers on iCE FTDI USB device.\n");
269 mpsse_error(2);
270 }
271
272 if (ftdi_get_latency_timer(&mpsse_ftdic, &mpsse_ftdi_latency) < 0) {
273 fprintf(stderr, "Failed to get latency timer (%s).\n", ftdi_get_error_string(&mpsse_ftdic));
274 mpsse_error(2);
275 }
276
277 /* 1 is the fastest polling, it means 1 kHz polling */
278 if (ftdi_set_latency_timer(&mpsse_ftdic, 1) < 0) {
279 fprintf(stderr, "Failed to set latency timer (%s).\n", ftdi_get_error_string(&mpsse_ftdic));
280 mpsse_error(2);
281 }
282
283 mpsse_ftdic_latency_set = true;
284
285 /* Enter MPSSE (Multi-Protocol Synchronous Serial Engine) mode. Set all pins to output. */
286 if (ftdi_set_bitmode(&mpsse_ftdic, 0xff, BITMODE_MPSSE) < 0) {
287 fprintf(stderr, "Failed to set BITMODE_MPSSE on iCE FTDI USB device.\n");
288 mpsse_error(2);
289 }
290
291 // enable clock divide by 5
292 mpsse_send_byte(MC_TCK_D5);
293
294 if (slow_clock) {
295 // set 50 kHz clock
296 mpsse_send_byte(MC_SET_CLK_DIV);
297 mpsse_send_byte(119);
298 mpsse_send_byte(0x00);
299 } else {
300 // set 6 MHz clock
301 mpsse_send_byte(MC_SET_CLK_DIV);
302 mpsse_send_byte(0x00);
303 mpsse_send_byte(0x00);
304 }
305
306 int rc = ftdi_usb_purge_buffers(&mpsse_ftdic);
307 if (rc != 0) {
308 fprintf(stderr, "Purge error.\n");
309 mpsse_error(2);
310 }
311 }
312
313 void mpsse_close(void)
314 {
315 ftdi_set_latency_timer(&mpsse_ftdic, mpsse_ftdi_latency);
316 ftdi_disable_bitbang(&mpsse_ftdic);
317 ftdi_usb_close(&mpsse_ftdic);
318 ftdi_deinit(&mpsse_ftdic);
319 }