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