📄 libftdi.c
字号:
if (conn) conn->driver = &usbconn_ftdi_mpsse_driver; return conn;}/* ---------------------------------------------------------------------- */static intusbconn_ftdi_common_open( usbconn_t *conn, int printerr ){ ftdi_param_t *p = conn->params; struct ftdi_context *fc = p->fc; int status; /* use command line string for desc= as serial number and try to open a matching device */ status = ftdi_usb_open_desc( fc, p->vid, p->pid, NULL, p->serial ); if (status < 0) /* try again with matching the string against the description */ status = ftdi_usb_open_desc( fc, p->vid, p->pid, p->serial, NULL ); if (status < 0) { if (printerr) printf( _("%s() failed: %s\n"), __FUNCTION__, ftdi_get_error_string( fc ) ); ftdi_deinit( fc ); /* mark ftdi layer as not initialized */ p->fc = NULL; /* TODO: disconnect? */ return -1; } return 0;}/* ---------------------------------------------------------------------- */#undef LIBFTDI_UNIMPLEMENTEDstatic intseq_purge( struct ftdi_context *fc, int purge_rx, int purge_tx ){ int r; unsigned char buf;#ifndef LIBFTDI_UNIMPLEMENTED if ((r = ftdi_usb_purge_buffers( fc )) < 0) printf( _("%s(): ftdi_usb_purge_buffers() failed: %s\n"), __FUNCTION__, ftdi_get_error_string( fc ) ); if (r >= 0) if ((r = ftdi_read_data( fc, &buf, 1 )) < 0) printf( _("%s(): ftdi_read_data() failed: %s\n"), __FUNCTION__, ftdi_get_error_string( fc ) );#else /* not yet available */ { int rx_loop; if (purge_rx) for (rx_loop = 0; (rx_loop < 6) && (r >= 0); rx_loop++) if ((r = ftdi_usb_purge_rx_buffer( fc )) < 0) printf( _("%s(): ftdi_usb_purge_rx_buffer() failed: %s\n"), __FUNCTION__, ftdi_get_error_string( fc ) ); if (purge_tx) if (r >= 0) if ((r = ftdi_usb_purge_tx_buffer( fc )) < 0) printf( _("%s(): ftdi_usb_purge_tx_buffer() failed: %s\n"), __FUNCTION__, ftdi_get_error_string( fc ) ); if (r >= 0) if ((r = ftdi_read_data( fc, &buf, 1 )) < 0) printf( _("%s(): ftdi_read_data() failed: %s\n"), __FUNCTION__, ftdi_get_error_string( fc ) ); }#endif return r < 0 ? -1 : 0;}static intseq_reset( struct ftdi_context *fc ){ int r;#ifdef LIBFTDI_UNIMPLEMENTED /* not yet available */ { unsigned short status; if ((r = ftdi_poll_status( fc, &status )) < 0) printf( _("%s(): ftdi_poll_status() failed: %s\n"), __FUNCTION__, ftdi_get_error_string( fc ) ); }#endif if ((r = ftdi_usb_reset( fc )) < 0) printf( _("%s(): ftdi_usb_reset() failed: %s\n"), __FUNCTION__, ftdi_get_error_string( fc ) ); if (r >= 0) r = seq_purge( fc, 1, 1 ); return r < 0 ? -1 : 0;}/* ---------------------------------------------------------------------- */static intusbconn_ftdi_open( usbconn_t *conn ){ ftdi_param_t *p = conn->params; struct ftdi_context *fc = p->fc; int r; if (usbconn_ftdi_common_open( conn, 1 ) < 0) return -1; r = seq_reset( fc ); if (r >= 0) r = seq_purge( fc, 1, 0 ); if (r >= 0) if ((r = ftdi_disable_bitbang( fc )) < 0) printf( _("%s(): ftdi_disable_bitbang() failed: %s\n"), __FUNCTION__, ftdi_get_error_string( fc ) ); if (r >= 0) if ((r = ftdi_set_latency_timer( fc, 2 )) < 0) printf( _("%s(): ftdi_set_latency_timer() failed: %s\n"), __FUNCTION__, ftdi_get_error_string( fc ) );#if 0 /* libftdi 0.6 doesn't allow high baudrates, so we send the control message outselves */ if (r >= 0) if (usb_control_msg( fc->usb_dev, 0x40, 3, 1, 0, NULL, 0, fc->usb_write_timeout ) != 0) { printf( "Can't set max baud rate.\n" ); r = -1; }#else if (r >= 0) if ((r = ftdi_set_baudrate( fc, 3E6 )) < 0) printf( _("%s(): ftdi_set_baudrate() failed: %s\n"), __FUNCTION__, ftdi_get_error_string( fc ) );#endif if (r < 0) { ftdi_usb_close( fc ); ftdi_deinit( fc ); /* mark ftdi layer as not initialized */ p->fc = NULL; } return r < 0 ? -1 : 0;}/* ---------------------------------------------------------------------- */static intusbconn_ftdi_mpsse_open( usbconn_t *conn ){ ftdi_param_t *p = conn->params; struct ftdi_context *fc = p->fc; int r; if (usbconn_ftdi_common_open( conn, 1 ) < 0) return -1; /* This sequence might seem weird and containing superfluous stuff. However, it's built after the description of JTAG_InitDevice Ref. FTCJTAGPG10.pdf Intermittent problems will occur when certain steps are skipped. */ r = seq_reset( fc ); if (r >= 0) r = seq_purge( fc, 1, 0 );#ifdef LIBFTDI_UNIMPLEMENTED if (r >= 0) if ((r = ftdi_set_event_char( fc, 0, 0 )) < 0) puts( ftdi_get_error_string( fc ) ); if (r >= 0) if ((r = ftdi_set_error_char( fc, 0, 0 )) < 0) puts( ftdi_get_error_string( fc ) );#endif /* set a reasonable latency timer value if this value is too low then the chip will send intermediate result data in short packets (suboptimal performance) */ if (r >= 0) if ((r = ftdi_set_latency_timer( fc, 16 )) < 0) printf( _("%s(): ftdi_set_latency_timer() failed: %s\n"), __FUNCTION__, ftdi_get_error_string( fc ) ); if (r >= 0) if ((r = ftdi_disable_bitbang( fc )) < 0) printf( _("%s(): ftdi_disable_bitbang() failed: %s\n"), __FUNCTION__, ftdi_get_error_string( fc ) ); if (r >= 0) if ((r = ftdi_set_bitmode( fc, 0x0b, BITMODE_MPSSE )) < 0) printf( _("%s(): ftdi_set_bitmode() failed: %s\n"), __FUNCTION__, ftdi_get_error_string( fc ) ); if (r >= 0) if ((r = ftdi_usb_reset( fc )) < 0) printf( _("%s(): ftdi_usb_reset() failed: %s\n"), __FUNCTION__, ftdi_get_error_string( fc ) ); if (r >= 0) r = seq_purge( fc, 1, 0 ); /* set TCK Divisor */ if (r >= 0) { uint8_t buf[3] = {TCK_DIVISOR, 0x00, 0x00}; r = usbconn_ftdi_write( conn, buf, 3, 0 ); } /* switch off loopback */ if (r >= 0) { uint8_t buf[1] = {LOOPBACK_END}; r = usbconn_ftdi_write( conn, buf, 1, 0 ); } if (r >= 0) r = usbconn_ftdi_read( conn, NULL, 0 ); if (r >= 0) if ((r = ftdi_usb_reset( fc )) < 0) printf( _("%s(): ftdi_usb_reset() failed: %s\n"), __FUNCTION__, ftdi_get_error_string( fc ) ); if (r >= 0) r = seq_purge( fc, 1, 0 ); if (r < 0) { ftdi_usb_close( fc ); ftdi_deinit( fc ); /* mark ftdi layer as not initialized */ p->fc = NULL; } return r < 0 ? -1 : 0;}/* ---------------------------------------------------------------------- */static intusbconn_ftdi_close( usbconn_t *conn ){ ftdi_param_t *p = conn->params; if (p->fc) { ftdi_disable_bitbang( p->fc ); ftdi_usb_close( p->fc ); ftdi_deinit( p->fc ); p->fc = NULL; } return 0;}/* ---------------------------------------------------------------------- */static voidusbconn_ftdi_free( usbconn_t *conn ){ ftdi_param_t *p = conn->params; if (p->send_buf) free( p->send_buf ); if (p->recv_buf) free( p->recv_buf ); if (p->fc) free( p->fc ); if (p->serial) free( p->serial ); free( conn->params ); free( conn );}/* ---------------------------------------------------------------------- */usbconn_driver_t usbconn_ftdi_driver = { "ftdi", usbconn_ftdi_connect, usbconn_ftdi_free, usbconn_ftdi_open, usbconn_ftdi_close, usbconn_ftdi_read, usbconn_ftdi_write};usbconn_driver_t usbconn_ftdi_mpsse_driver = { "ftdi-mpsse", usbconn_ftdi_mpsse_connect, usbconn_ftdi_free, usbconn_ftdi_mpsse_open, usbconn_ftdi_close, usbconn_ftdi_read, usbconn_ftdi_write};/* Local Variables: mode:C c-default-style:gnu indent-tabs-mode:nil End:*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -