⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libftdi.c

📁 UrJTAG package is free software, covered by the GNU General Public License, and you are welcome to
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: libftdi.c 1354 2008-09-06 20:10:31Z arniml $ * * Link driver for accessing FTDI devices via libftdi * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * * Written by Arnim Laeuger, 2008 * */#include "sysdep.h"#include <fcntl.h>#if __CYGWIN__ || __MINGW32__#include <windows.h>#endif#include <stdio.h>#include <string.h>#ifdef HAVE_STROPTS_H#include <stropts.h>#endif#include <stdlib.h>#include <stdint.h>#include <unistd.h>#include <ftdi.h>#include "cable.h"#include "usbconn.h"#include "usbconn/libftdx.h"typedef struct {  /* USB device information */  unsigned int vid;  unsigned int pid;  struct ftdi_context *fc;  char *serial;  /* send and receive buffer handling */  uint32_t  send_buf_len;  uint32_t  send_buffered;  uint8_t  *send_buf;  uint32_t  recv_buf_len;  uint32_t  to_recv;  uint32_t  recv_write_idx;  uint32_t  recv_read_idx;  uint8_t  *recv_buf;} ftdi_param_t;usbconn_driver_t usbconn_ftdi_driver;usbconn_driver_t usbconn_ftdi_mpsse_driver;static int usbconn_ftdi_common_open( usbconn_t *conn, int printerr );static void usbconn_ftdi_free( usbconn_t *conn );/* ---------------------------------------------------------------------- */static intusbconn_ftdi_flush( ftdi_param_t *p ){  int xferred;  int recvd = 0;  if (!p->fc)    return -1;  if (p->send_buffered == 0)    return 0;  if ((xferred = ftdi_write_data( p->fc, p->send_buf, p->send_buffered )) < 0)    printf( _("%s(): ftdi_write_data() failed: %s\n"),            __FUNCTION__, ftdi_get_error_string( p->fc ) );  if (xferred < p->send_buffered)  {    printf( _("%s(): Written fewer bytes than requested.\n"), __FUNCTION__ );    return -1;  }  p->send_buffered = 0;  /* now read all scheduled receive bytes */  if (p->to_recv)  {    if (p->recv_write_idx + p->to_recv > p->recv_buf_len)    {      /* extend receive buffer */      p->recv_buf_len = p->recv_write_idx + p->to_recv;      if (p->recv_buf)        p->recv_buf = (uint8_t *)realloc( p->recv_buf, p->recv_buf_len );    }    if (!p->recv_buf)    {      printf( _("%s(): Receive buffer does not exist.\n"), __FUNCTION__ );      return -1;    }    while (recvd == 0)      if ((recvd = ftdi_read_data( p->fc, &(p->recv_buf[p->recv_write_idx]),                                   p->to_recv )) < 0)        printf( _("%s(): Error from ftdi_read_data(): %s\n"),                __FUNCTION__, ftdi_get_error_string( p->fc ) );    if (recvd < p->to_recv)      printf( _("%s(): Received less bytes than requested.\n"),              __FUNCTION__ );    p->to_recv        -= recvd;    p->recv_write_idx += recvd;  }  return xferred < 0 ? -1 : xferred;}/* ---------------------------------------------------------------------- */static intusbconn_ftdi_read( usbconn_t *conn, uint8_t *buf, int len ){  ftdi_param_t *p = conn->params;  int cpy_len;  int recvd = 0;  if (!p->fc)    return -1;  /* flush send buffer to get all scheduled receive bytes */  if (usbconn_ftdi_flush( p ) < 0)    return -1;  if (len == 0)    return 0;  /* check for number of remaining bytes in receive buffer */  cpy_len = p->recv_write_idx - p->recv_read_idx;  if (cpy_len > len)    cpy_len = len;  len -= cpy_len;  if (cpy_len > 0)  {    /* get data from the receive buffer */    memcpy( buf, &(p->recv_buf[p->recv_read_idx]), cpy_len );    p->recv_read_idx += cpy_len;    if (p->recv_read_idx == p->recv_write_idx)      p->recv_read_idx = p->recv_write_idx = 0;  }  if (len > 0)  {    /* need to get more data directly from the device */    while (recvd == 0)      if ((recvd = ftdi_read_data( p->fc, &(buf[cpy_len]), len )) < 0)        printf( _("%s(): Error from ftdi_read_data(): %s\n"),                __FUNCTION__, ftdi_get_error_string( p->fc ) );  }  return recvd < 0 ? -1 : cpy_len + len;}/* ---------------------------------------------------------------------- */static intusbconn_ftdi_write( usbconn_t *conn, uint8_t *buf, int len, int recv ){  ftdi_param_t *p = conn->params;  int xferred = 0;  if (!p->fc)    return -1;  /* this write function will try to buffer write data     buffering will be ceased and a flush triggered in two cases. */  /* Case A: max number of scheduled receive bytes will be exceeded             with this write     Case B: max number of scheduled send bytes has been reached */  if ((p->to_recv + recv > FTDI_MAXRECV)      || ((p->send_buffered > FTDX_MAXSEND) && (p->to_recv == 0)))    xferred = usbconn_ftdi_flush( p );  if (xferred < 0)    return -1;  /* now buffer this write */  if (p->send_buffered + len > p->send_buf_len)  {    p->send_buf_len = p->send_buffered + len;    if (p->send_buf)      p->send_buf = (uint8_t *)realloc( p->send_buf, p->send_buf_len);  }  if (p->send_buf)  {    memcpy( &(p->send_buf[p->send_buffered]), buf, len );    p->send_buffered += len;    if (recv > 0)      p->to_recv     += recv;    if (recv < 0)    {      /* immediate write requested, so flush the buffered data */      xferred = usbconn_ftdi_flush( p );    }    return xferred < 0 ? -1 : len;  }  else  {    printf( _("%s(): Send buffer does not exist.\n"), __FUNCTION__ );    return -1;  }}/* ---------------------------------------------------------------------- */usbconn_t *usbconn_ftdi_connect( const char **param, int paramc, usbconn_cable_t *template ){  usbconn_t *c            = malloc( sizeof( usbconn_t ) );  ftdi_param_t *p         = malloc( sizeof( ftdi_param_t ) );  struct ftdi_context *fc = malloc( sizeof( struct ftdi_context ) );  if (p)  {    p->send_buf_len   = FTDX_MAXSEND;    p->send_buffered  = 0;    p->send_buf       = (uint8_t *)malloc( p->send_buf_len );    p->recv_buf_len   = FTDI_MAXRECV;    p->to_recv        = 0;    p->recv_write_idx = 0;    p->recv_read_idx  = 0;    p->recv_buf       = (uint8_t *)malloc( p->recv_buf_len );  }  if (!p || !c || !fc || !p->send_buf || !p->recv_buf)  {    printf( _("Out of memory\n") );    if (p->send_buf)      free( p->send_buf );    if (p->recv_buf)      free( p->recv_buf );    if (p)      free( p );    if (c)      free( c );    if (fc)      free( fc );    return NULL;  }  ftdi_init( fc );  p->fc     = fc;  p->pid    = template->pid;  p->vid    = template->vid;  p->serial = template->desc ? strdup( template->desc ) : NULL;  c->params = p;  c->driver = &usbconn_ftdi_driver;  c->cable  = NULL;  /* do a test open with the specified cable paramters,     alternatively we could use libusb to detect the presence of the     specified USB device */  if (usbconn_ftdi_common_open( c, 0 ) != 0)  {    usbconn_ftdi_free( c );    return NULL;  }  ftdi_usb_close( fc );  printf( _("Connected to libftdi driver.\n") );  return c;}usbconn_t *usbconn_ftdi_mpsse_connect( const char **param, int paramc, usbconn_cable_t *template ){  usbconn_t *conn = usbconn_ftdi_connect( param, paramc, template );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -