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

📄 xpc.c

📁 UrJTAG package is free software, covered by the GNU General Public License, and you are welcome to
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: xpc.c,v 1.8 2003/08/19 08:42:20 telka Exp $ * * Xilinx Platform Cable USB Driver (slow GPIO only) * Copyright (C) 2008 Kolja Waschk * * Loosely based on Xilinx DLC5 JTAG Parallel Cable III Driver * Copyright (C) 2002, 2003 ETC s.r.o. * * 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. * */#include "sysdep.h"#include "cable.h"#include "chain.h"#include "generic.h"#include "generic_usbconn.h"#include "usbconn.h"#include "usbconn/libusb.h"#include <errno.h>#include <string.h>// #define VERBOSE 1#undef VERBOSEtypedef struct{	int last_tdo;}xpc_cable_params_t;static int last_tdo;/* Connectivity on Spartan-3E starter kit: * * = FX2 Port A = * *   IOA.0 => green LED (0=off) *   IOA.1 => red LED   (0=off) *   IOA.2 is tied to VCC via R25 on my board  *   IOA.3 isn't connected  *   IOA.4 => CPLD pin 85 (reset?) *   IOA.5 => CPLD pin 86, eventually OE?  *   IOA.6 => CPLD pin 83 (reset?) *   IOA.7 => CPLD pin 49 (reset?) *     * = FX2 Port C = * *   probably used as GPIFADR 0..7, to CPLD  *       * = FX2 Port E = * *   IOE.3 => CPLD TCK  *   IOE.4 => CPLD TMS  *   IOE.5 => CPLD TDO  *   IOE.6 => CPLD TDI  *//* ---------------------------------------------------------------------- */int xpcu_output_enable(struct usb_dev_handle *xpcu, int enable){    if(usb_control_msg(xpcu, 0x40, 0xB0, enable ? 0x18 : 0x10, 0, NULL, 0, 1000)<0)    {        perror("usb_control_msg(0x10/0x18)");        return -1;    }    return 0;}/* ---------------------------------------------------------------------- */int xpcu_bit_reverse(struct usb_dev_handle *xpcu, uint8_t bits_in, uint8_t *bits_out){    if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0020, bits_in, (char*)bits_out, 1, 1000)<0)    {        perror("usb_control_msg(0x20.x) (bit reverse)");        return -1;    }    return 0;}/* ----------------------------------------------------------------- */int xpcu_request_28(struct usb_dev_handle *xpcu, int value){    /* Typical values seen during autodetection of chain configuration: 0x11, 0x12 */    if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0028, value, NULL, 0, 1000)<0)    {        perror("usb_control_msg(0x28.x)");        return -1;    }    return 0;}/* ---------------------------------------------------------------------- */int xpcu_write_gpio(struct usb_dev_handle *xpcu, uint8_t bits){    if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0030, bits, NULL, 0, 1000)<0)    {        perror("usb_control_msg(0x30.0x00) (write port E)");        return -1;    }    return 0;}/* ---------------------------------------------------------------------- */int xpcu_read_gpio(struct usb_dev_handle *xpcu, uint8_t *bits){    if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0038, 0, (char*)bits, 1, 1000)<0)    {        perror("usb_control_msg(0x38.0x00) (read port E)");        return -1;    }    return 0;}/* ---------------------------------------------------------------------- */int xpcu_read_cpld_version(struct usb_dev_handle *xpcu, uint16_t *buf){    if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0050, 0x0001, (char*)buf, 2, 1000)<0)    {        perror("usb_control_msg(0x50.1) (read_cpld_version)");        return -1;    }    return 0;}/* ---------------------------------------------------------------------- */int xpcu_read_firmware_version(struct usb_dev_handle *xpcu, uint16_t *buf){    if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0050, 0x0000, (char*)buf, 2, 1000)<0)    {        perror("usb_control_msg(0x50.0) (read_firmware_version)");        return -1;    }    return 0;}/* ----------------------------------------------------------------- */int xpcu_select_gpio(struct usb_dev_handle *xpcu, int int_or_ext ){    if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0052, int_or_ext, NULL, 0, 1000)<0)    {        perror("usb_control_msg(0x52.x) (select gpio)");        return -1;    }    return 0;}/* ---------------------------------------------------------------------- *//* === A6 transfer (TDI/TMS/TCK/RDO) === * *   Vendor request 0xA6 initiates a quite universal shift operation. The data *   is passed directly to the CPLD as 16-bit words. * *   The argument N in the request specifies the number of state changes/bits. * *   State changes are described by the following bulk write. It consists *   of ceil(N/4) little-endian 16-bit words, each describing up to 4 changes: * *   Care has to be taken that N is NOT a multiple of 4. *   The CPLD doesn't seem to handle that well. * *   Bit 0: Value for first TDI to shift out. *   Bit 1: Second TDI. *   Bit 2: Third TDI. *   Bit 3: Fourth TDI. * *   Bit 4: Value for first TMS to shift out. *   Bit 5: Second TMS. *   Bit 6: Third TMS. *   Bit 7: Fourth TMS. * *   Bit 8: Whether to raise/lower TCK for first bit. *   Bit 9: Same for second bit. *   Bit 10: Third bit. *   Bit 11: Fourth bit. * *   Bit 12: Whether to read TDO for first bit *   Bit 13: Same for second bit. *   Bit 14: Third bit. *   Bit 15: Fourth bit. * *   After the bulk write, if any of the bits 12..15 was set in any word, a  *   bulk_read shall follow to collect the TDO data. * *   TDO data is shifted in from MSB. In a "full" word with 16 TDO bits, the *   earliest one reached bit 0. The earliest of 15 bits however would be bit 0, *   and if there's only one TDO bit, it arrives as the MSB of the word. */static intxpcu_shift(struct usb_dev_handle *xpcu, int reqno, int bits, int in_len, uint8_t *in, int out_len, uint8_t *out ){    if(usb_control_msg(xpcu, 0x40, 0xB0, reqno, bits, NULL, 0, 1000)<0)    {        perror("usb_control_msg(x.x) (shift)");        return -1;    }#if VERBOSE	{	int i;    printf("###\n");    printf("reqno = %02X\n", reqno);    printf("bits    = %d\n", bits);    printf("in_len  = %d, in_len*2  = %d\n", in_len, in_len * 2);    printf("out_len = %d, out_len*8 = %d\n", out_len, out_len * 8);    printf("a6_display(\"%02X\", \"", bits);    for(i=0;i<in_len;i++) printf("%02X%s", in[i], (i+1<in_len)?",":"");    printf("\", ");	}#endif    if(usb_bulk_write(xpcu, 0x02, (char*)in, in_len, 1000)<0)    {        printf("\nusb_bulk_write error(shift): %s\n", strerror(errno));        return -1;    }    if(out_len > 0 && out != NULL)    {      if(usb_bulk_read(xpcu, 0x86, (char*)out, out_len, 1000)<0)      {        printf("\nusb_bulk_read error(shift): %s\n", strerror(errno));        return -1;      }    }#if VERBOSE	{	int i;    printf("\"");    for(i=0;i<out_len;i++) printf("%02X%s", out[i], (i+1<out_len)?",":"");    printf("\")\n");	}#endif     return 0;}/* ---------------------------------------------------------------------- */static int xpcu_common_init( cable_t *cable ){    int r;    uint16_t buf;    struct usb_dev_handle *xpcu;    if (usbconn_open( cable->link.usb )) return -1;    xpcu = ((libusb_param_t*)(cable->link.usb->params))->handle;    r = xpcu_request_28(xpcu, 0x11);    if (r>=0) r = xpcu_write_gpio(xpcu, 8);    /* Read firmware version (constant embedded in firmware) */    if (r>=0) r = xpcu_read_firmware_version(xpcu, &buf);    if (r>=0)    {        printf("firmware version = 0x%04X (%u)\n", buf, buf);    };    /* Read CPLD version (via GPIF) */    if (r>=0) xpcu_read_cpld_version(xpcu, &buf);    if (r>=0)    {        printf("cable CPLD version = 0x%04X (%u)\n", buf, buf);        if(buf == 0)        {            printf("Warning: version '0' can't be correct. Please try resetting the cable\n");            r = -1;        };    };    if (r<0)    {        usb_close(xpcu);    };    return r;}static intxpc_int_init( cable_t *cable ){	struct usb_dev_handle *xpcu;	if (xpcu_common_init( cable )<0) return -1;	xpcu = ((libusb_param_t*)(cable->link.usb->params))->handle;	if (xpcu_select_gpio(xpcu, 0)<0) return -1;	return 0;}static intxpc_ext_init( cable_t *cable ){	struct usb_dev_handle *xpcu;	uint8_t zero[2] = {0,0};	int r;	free(cable->params);	cable->params = NULL;

⌨️ 快捷键说明

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