2 * iceprog -- simple programming tool for FTDI-based Lattice iCE programmers
4 * Copyright (C) 2015 Clifford Wolf <clifford@clifford.at>
5 * Copyright (C) 2018 Piotr Esden-Tempski <piotr@esden.net>
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.
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.
21 * http://www.ftdichip.com/Support/Documents/AppNotes/AN_108_Command_Processor_for_MPSSE_and_MCU_Host_Bus_Emulation_Modes.pdf
35 // ---------------------------------------------------------
36 // MPSSE / FTDI definitions
37 // ---------------------------------------------------------
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
48 * xDBUS6 | CDONE | GPIO
49 * xDBUS7 | CRESET | GPIO
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
;
58 // ---------------------------------------------------------
59 // MPSSE / FTDI function implementations
60 // ---------------------------------------------------------
67 int rc
= ftdi_read_data(&mpsse_ftdic
, &data
, 1);
70 fprintf(stderr
, "unexpected rx byte: %02X\n", data
);
78 void mpsse_error(int status
)
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
);
87 ftdi_deinit(&mpsse_ftdic
);
91 uint8_t mpsse_recv_byte()
95 int rc
= ftdi_read_data(&mpsse_ftdic
, &data
, 1);
97 fprintf(stderr
, "Read error.\n");
107 void mpsse_send_byte(uint8_t data
)
109 int rc
= ftdi_write_data(&mpsse_ftdic
, &data
, 1);
111 fprintf(stderr
, "Write error (single byte, rc=%d, expected %d)(%s).\n", rc
, 1, ftdi_get_error_string(&mpsse_ftdic
));
116 void mpsse_purge(void){
117 int rc
= ftdi_usb_purge_buffers(&mpsse_ftdic
);
119 fprintf(stderr
, "Purge error.\n");
124 void mpsse_send_spi(uint8_t *data
, int n
)
129 /* Output only, update data on negative clock edge. */
130 mpsse_send_byte(MC_DATA_OUT
| MC_DATA_OCN
);
131 mpsse_send_byte(n
- 1);
132 mpsse_send_byte((n
- 1) >> 8);
134 int rc
= ftdi_write_data(&mpsse_ftdic
, data
, n
);
136 fprintf(stderr
, "Write error (chunk, rc=%d, expected %d).\n", rc
, n
);
141 void mpsse_xfer_spi(uint8_t *data
, int n
)
146 /* Input and output, update data on negative edge read on positive. */
147 mpsse_send_byte(MC_DATA_IN
| MC_DATA_OUT
| MC_DATA_OCN
);
148 mpsse_send_byte(n
- 1);
149 mpsse_send_byte((n
- 1) >> 8);
151 int rc
= ftdi_write_data(&mpsse_ftdic
, data
, n
);
153 fprintf(stderr
, "Write error (chunk, rc=%d, expected %d).\n", rc
, n
);
157 for (int i
= 0; i
< n
; i
++)
158 data
[i
] = mpsse_recv_byte();
161 uint8_t mpsse_xfer_spi_bits(uint8_t data
, int n
)
166 /* Input and output, update data on negative edge read on positive, bits. */
167 mpsse_send_byte(MC_DATA_IN
| MC_DATA_OUT
| MC_DATA_OCN
| MC_DATA_BITS
);
168 mpsse_send_byte(n
- 1);
169 mpsse_send_byte(data
);
171 return mpsse_recv_byte();
174 void mpsse_set_gpio(uint8_t gpio
, uint8_t direction
)
176 mpsse_send_byte(MC_SETB_LOW
);
177 mpsse_send_byte(gpio
); /* Value */
178 mpsse_send_byte(direction
); /* Direction */
181 int mpsse_readb_low(void)
184 mpsse_send_byte(MC_READB_LOW
);
185 data
= mpsse_recv_byte();
189 int mpsse_readb_high(void)
192 mpsse_send_byte(MC_READB_HIGH
);
193 data
= mpsse_recv_byte();
197 void mpsse_send_dummy_bytes(uint8_t n
)
199 // add 8 x count dummy bits (aka n bytes)
200 mpsse_send_byte(MC_CLK_N8
);
201 mpsse_send_byte(n
- 1);
202 mpsse_send_byte(0x00);
206 void mpsse_send_dummy_bit(void)
209 mpsse_send_byte(MC_CLK_N
);
210 mpsse_send_byte(0x00);
213 void mpsse_jtag_init(){
214 mpsse_send_byte(MC_SETB_LOW
);
215 mpsse_send_byte(0x08); /* Value */
216 mpsse_send_byte(0x0B); /* Direction */
218 /* Reset JTAG State machine */
222 void mpsse_jtag_tms(uint8_t bits
, uint8_t pattern
){
223 mpsse_send_byte(MC_DATA_TMS
| MC_DATA_LSB
| MC_DATA_BITS
);
224 mpsse_send_byte(bits
-1);
225 mpsse_send_byte(pattern
);
228 void mpsse_init(int ifnum
, const char *devstr
, bool slow_clock
)
230 enum ftdi_interface ftdi_ifnum
= INTERFACE_A
;
234 ftdi_ifnum
= INTERFACE_A
;
237 ftdi_ifnum
= INTERFACE_B
;
240 ftdi_ifnum
= INTERFACE_C
;
243 ftdi_ifnum
= INTERFACE_D
;
246 ftdi_ifnum
= INTERFACE_A
;
250 ftdi_init(&mpsse_ftdic
);
251 ftdi_set_interface(&mpsse_ftdic
, ftdi_ifnum
);
253 if (devstr
!= NULL
) {
254 if (ftdi_usb_open_string(&mpsse_ftdic
, devstr
)) {
255 fprintf(stderr
, "Can't find iCE FTDI USB device (device string %s).\n", devstr
);
259 if (ftdi_usb_open(&mpsse_ftdic
, 0x0403, 0x6010) && ftdi_usb_open(&mpsse_ftdic
, 0x0403, 0x6014)) {
260 fprintf(stderr
, "Can't find iCE FTDI USB device (vendor_id 0x0403, device_id 0x6010 or 0x6014).\n");
265 mpsse_ftdic_open
= true;
267 if (ftdi_usb_reset(&mpsse_ftdic
)) {
268 fprintf(stderr
, "Failed to reset iCE FTDI USB device.\n");
272 if (ftdi_usb_purge_buffers(&mpsse_ftdic
)) {
273 fprintf(stderr
, "Failed to purge buffers on iCE FTDI USB device.\n");
277 if (ftdi_get_latency_timer(&mpsse_ftdic
, &mpsse_ftdi_latency
) < 0) {
278 fprintf(stderr
, "Failed to get latency timer (%s).\n", ftdi_get_error_string(&mpsse_ftdic
));
282 /* 1 is the fastest polling, it means 1 kHz polling */
283 if (ftdi_set_latency_timer(&mpsse_ftdic
, 1) < 0) {
284 fprintf(stderr
, "Failed to set latency timer (%s).\n", ftdi_get_error_string(&mpsse_ftdic
));
288 mpsse_ftdic_latency_set
= true;
290 /* Enter MPSSE (Multi-Protocol Synchronous Serial Engine) mode. Set all pins to output. */
291 if (ftdi_set_bitmode(&mpsse_ftdic
, 0xff, BITMODE_MPSSE
) < 0) {
292 fprintf(stderr
, "Failed to set BITMODE_MPSSE on FTDI USB device.\n");
296 int rc
= ftdi_usb_purge_buffers(&mpsse_ftdic
);
298 fprintf(stderr
, "Purge error.\n");
302 // enable clock divide by 5
303 //mpsse_send_byte(MC_TCK_D5);
307 mpsse_send_byte(MC_SET_CLK_DIV
);
308 mpsse_send_byte(119);
309 mpsse_send_byte(0x00);
312 mpsse_send_byte(MC_SET_CLK_DIV
);
314 mpsse_send_byte(0x00);
319 void mpsse_close(void)
321 ftdi_set_latency_timer(&mpsse_ftdic
, mpsse_ftdi_latency
);
322 ftdi_disable_bitbang(&mpsse_ftdic
);
323 ftdi_usb_close(&mpsse_ftdic
);
324 ftdi_deinit(&mpsse_ftdic
);