desktop

Curso para iniciarse con FPGAs

Hola Walter, estoy de acuerdo que todo se debe simular bien antes de cargar en placa...pero una vez que simulas y compruebas que todo esta ok,ya quieres cargar el firmware y ver por ejemplo la pantalla LCD funcionando como programaste (sobre todo si es la primera vez que lo haces). Un saludo
 
mi mensaje último dije que no hay apoyo a linux, pero encontré este: http://clippy.cz.cc/index.php?show=120
Código:
/*
 *   Clone of usb blaster driver
 *
 *   Copyright (C) 2009 Setec Astronomy Project - who are not aware of the donation of this code
 *   to their cause, but can be notified by sending this file to them.
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as
 *   published by the Free Software Foundation, either version 3 of the
 *   License, or (at your option) any later version, with the exception of
 *   any individual providing services to a corporation, or the corporation itself,
 *   if the name of the corporation starts with:
 *
 *        "ARR" or "ALTER"
 *
 *   These corporations and their employees, assigns, contractors, shareholders,
 *   rightsholders, attorneys and associates are specifically excluded by this
 *   license. This is not discriminatory; they can obtain software to perform
 *   interoperability and necessary functionality by pursuing internal licensing
 *   within their corporations or with all relevant rightsholders.
 *
 *   Copyright infringement by the above corporations and their employees, assigns,
 *   contractors, shareholders, rightsholders, attorneys and associates will be
 *   prosecuted to the fullest extent of the law. This license shall be governed
 *   by the laws of the State of California. If any part of this license
 *   is deemed to be invalid under applicable law, the remainder of the license
 *   shall be deemed severable and remain in force.
 *
 *   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 Affero General Public License for more details.
 *
 *
 *   Please read to the bottom of the file for instructions on how to use this.
 */

#include <string.h>
#include <dlfcn.h>

/*
 * The following section is pasted verbatim from libftdi.h, part of the package
 * libftdi-0.18
 *
 * If you prefer, you can use the file installed on your system using:
 * #include "libftdi-0.18.h"
 *
 * libftdi.so must also be installed from the same package. It is dynamically loaded
 * below.
 *
 * The following is Copyright (C) 2003 by Intra2net AG, and is licensed under
 * the GNU Lesser General Public License.
 *
 * The derived work, namely, the whole of this file, is governed by the copyright above,
 * under the compatible but more restrictive GNU Affero General Public License.
 */

/***************************************************************************
                          ftdi.h  -  description
                             -------------------
    begin                : Fri Apr 4 2003
    copyright            : (C) 2003 by Intra2net AG
    email                : opensource@intra2net.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License           *
 *   version 2.1 as published by the Free Software Foundation;             *
 *                                                                         *
 ***************************************************************************/

#ifndef __libftdi_h__
#define __libftdi_h__

#include <usb.h>

#define FTDI_DEFAULT_EEPROM_SIZE 128

/** FTDI chip type */
enum ftdi_chip_type { TYPE_AM=0, TYPE_BM=1, TYPE_2232C=2, TYPE_R=3, TYPE_2232H=4, TYPE_4232H=5 };
/** Parity mode for ftdi_set_line_property() */
enum ftdi_parity_type { NONE=0, ODD=1, EVEN=2, MARK=3, SPACE=4 };
/** Number of stop bits for ftdi_set_line_property() */
enum ftdi_stopbits_type { STOP_BIT_1=0, STOP_BIT_15=1, STOP_BIT_2=2 };
/** Number of bits for ftdi_set_line_property() */
enum ftdi_bits_type { BITS_7=7, BITS_8=8 };
/** Break type for ftdi_set_line_property2() */
enum ftdi_break_type { BREAK_OFF=0, BREAK_ON=1 };

/** MPSSE bitbang modes */
enum ftdi_mpsse_mode
{
    BITMODE_RESET  = 0x00,    /**< switch off bitbang mode, back to regular serial/FIFO */
    BITMODE_BITBANG= 0x01,    /**< classical asynchronous bitbang mode, introduced with B-type chips */
    BITMODE_MPSSE  = 0x02,    /**< MPSSE mode, available on 2232x chips */
    BITMODE_SYNCBB = 0x04,    /**< synchronous bitbang mode, available on 2232x and R-type chips  */
    BITMODE_MCU    = 0x08,    /**< MCU Host Bus Emulation mode, available on 2232x chips */
                              /* CPU-style fifo mode gets set via EEPROM */
    BITMODE_OPTO   = 0x10,    /**< Fast Opto-Isolated Serial Interface Mode, available on 2232x chips  */
    BITMODE_CBUS   = 0x20,    /**< Bitbang on CBUS pins of R-type chips, configure in EEPROM before */
    BITMODE_SYNCFF = 0x40,    /**< Single Channel Synchronous FIFO mode, available on 2232H chips */
};

/** Port interface for chips with multiple interfaces */
enum ftdi_interface
{
    INTERFACE_ANY = 0,
    INTERFACE_A   = 1,
    INTERFACE_B   = 2,
    INTERFACE_C   = 3,
    INTERFACE_D   = 4
};

/* Shifting commands IN MPSSE Mode*/
#define MPSSE_WRITE_NEG 0x01   /* Write TDI/DO on negative TCK/SK edge*/
#define MPSSE_BITMODE   0x02   /* Write bits, not bytes */
#define MPSSE_READ_NEG  0x04   /* Sample TDO/DI on negative TCK/SK edge */
#define MPSSE_LSB       0x08   /* LSB first */
#define MPSSE_DO_WRITE  0x10   /* Write TDI/DO */
#define MPSSE_DO_READ   0x20   /* Read TDO/DI */
#define MPSSE_WRITE_TMS 0x40   /* Write TMS/CS */

/* FTDI MPSSE commands */
#define SET_BITS_LOW   0x80
/*BYTE DATA*/
/*BYTE Direction*/
#define SET_BITS_HIGH  0x82
/*BYTE DATA*/
/*BYTE Direction*/
#define GET_BITS_LOW   0x81
#define GET_BITS_HIGH  0x83
#define LOOPBACK_START 0x84
#define LOOPBACK_END   0x85
#define TCK_DIVISOR    0x86
/* Value Low */
/* Value HIGH */ /*rate is 12000000/((1+value)*2) */
#define DIV_VALUE(rate) (rate > 6000000)?0:((6000000/rate -1) > 0xffff)? 0xffff: (6000000/rate -1)

/* Commands in MPSSE and Host Emulation Mode */
#define SEND_IMMEDIATE 0x87
#define WAIT_ON_HIGH   0x88
#define WAIT_ON_LOW    0x89

/* Commands in Host Emulation Mode */
#define READ_SHORT     0x90
/* Address_Low */
#define READ_EXTENDED  0x91
/* Address High */
/* Address Low  */
#define WRITE_SHORT    0x92
/* Address_Low */
#define WRITE_EXTENDED 0x93
/* Address High */
/* Address Low  */

/* Definitions for flow control */
#define SIO_RESET          0 /* Reset the port */
#define SIO_MODEM_CTRL     1 /* Set the modem control register */
#define SIO_SET_FLOW_CTRL  2 /* Set flow control register */
#define SIO_SET_BAUD_RATE  3 /* Set baud rate */
#define SIO_SET_DATA       4 /* Set the data characteristics of the port */

#define FTDI_DEVICE_OUT_REQTYPE (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT)
#define FTDI_DEVICE_IN_REQTYPE (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN)

/* Requests */
#define SIO_RESET_REQUEST             SIO_RESET
#define SIO_SET_BAUDRATE_REQUEST      SIO_SET_BAUD_RATE
#define SIO_SET_DATA_REQUEST          SIO_SET_DATA
#define SIO_SET_FLOW_CTRL_REQUEST     SIO_SET_FLOW_CTRL
#define SIO_SET_MODEM_CTRL_REQUEST    SIO_MODEM_CTRL
#define SIO_POLL_MODEM_STATUS_REQUEST 0x05
#define SIO_SET_EVENT_CHAR_REQUEST    0x06
#define SIO_SET_ERROR_CHAR_REQUEST    0x07
#define SIO_SET_LATENCY_TIMER_REQUEST 0x09
#define SIO_GET_LATENCY_TIMER_REQUEST 0x0A
#define SIO_SET_BITMODE_REQUEST       0x0B
#define SIO_READ_PINS_REQUEST         0x0C
#define SIO_READ_EEPROM_REQUEST       0x90
#define SIO_WRITE_EEPROM_REQUEST      0x91
#define SIO_ERASE_EEPROM_REQUEST      0x92


#define SIO_RESET_SIO 0
#define SIO_RESET_PURGE_RX 1
#define SIO_RESET_PURGE_TX 2

#define SIO_DISABLE_FLOW_CTRL 0x0
#define SIO_RTS_CTS_HS (0x1 << 8)
#define SIO_DTR_DSR_HS (0x2 << 8)
#define SIO_XON_XOFF_HS (0x4 << 8)

#define SIO_SET_DTR_MASK 0x1
#define SIO_SET_DTR_HIGH ( 1 | ( SIO_SET_DTR_MASK  << 8))
#define SIO_SET_DTR_LOW  ( 0 | ( SIO_SET_DTR_MASK  << 8))
#define SIO_SET_RTS_MASK 0x2
#define SIO_SET_RTS_HIGH ( 2 | ( SIO_SET_RTS_MASK << 8 ))
#define SIO_SET_RTS_LOW ( 0 | ( SIO_SET_RTS_MASK << 8 ))

#define SIO_RTS_CTS_HS (0x1 << 8)

/* marker for unused usb urb structures
   (taken from libusb) */
#define FTDI_URB_USERCONTEXT_COOKIE ((void *)0x1)

#ifdef __GNUC__
    #define DEPRECATED(func) func __attribute__ ((deprecated))
#elif defined(_MSC_VER)
    #define DEPRECATED(func) __declspec(deprecated) func
#else
    #pragma message("WARNING: You need to implement DEPRECATED for this compiler")
    #define DEPRECATED(func) func
#endif


/**
    \brief Main context structure for all libftdi functions.

    Do not access directly if possible.
*/
struct ftdi_context
{
    /* USB specific */
    /** libusb's usb_dev_handle */
    struct usb_dev_handle *usb_dev;
    /** usb read timeout */
    int usb_read_timeout;
    /** usb write timeout */
    int usb_write_timeout;

    /* FTDI specific */
    /** FTDI chip type */
    enum ftdi_chip_type type;
    /** baudrate */
    int baudrate;
    /** bitbang mode state */
    unsigned char bitbang_enabled;
    /** pointer to read buffer for ftdi_read_data */
    unsigned char *readbuffer;
    /** read buffer offset */
    unsigned int readbuffer_offset;
    /** number of remaining data in internal read buffer */
    unsigned int readbuffer_remaining;
    /** read buffer chunk size */
    unsigned int readbuffer_chunksize;
    /** write buffer chunk size */
    unsigned int writebuffer_chunksize;
    /** maximum packet size. Needed for filtering modem status bytes every n packets. */
    unsigned int max_packet_size;

    /* FTDI FT2232C requirecments */
    /** FT2232C interface number: 0 or 1 */
    int interface;   /* 0 or 1 */
    /** FT2232C index number: 1 or 2 */
    int index;       /* 1 or 2 */
    /* Endpoints */
    /** FT2232C end points: 1 or 2 */
    int in_ep;
    int out_ep;      /* 1 or 2 */

    /** Bitbang mode. 1: (default) Normal bitbang mode, 2: FT2232C SPI bitbang mode */
    unsigned char bitbang_mode;

    /** EEPROM size. Default is 128 bytes for 232BM and 245BM chips */
    int eeprom_size;

    /** String representation of last error */
    char *error_str;

    /** Buffer needed for async communication */
    char *async_usb_buffer;
    /** Number of URB-structures we can buffer */
    unsigned int async_usb_buffer_size;
};

/**
    \brief list of usb devices created by ftdi_usb_find_all()
*/
struct ftdi_device_list
{
    /** pointer to next entry */
    struct ftdi_device_list *next;
    /** pointer to libusb's usb_device */
    struct usb_device *dev;
};

/**
    \brief FTDI eeprom structure
*/
struct ftdi_eeprom
{
    /** vendor id */
    int vendor_id;
    /** product id */
    int product_id;

    /** self powered */
    int self_powered;
    /** remote wakeup */
    int remote_wakeup;
    /** chip type */
    int BM_type_chip;

    /** input in isochronous transfer mode */
    int in_is_isochronous;
    /** output in isochronous transfer mode */
    int out_is_isochronous;
    /** suspend pull downs */
    int suspend_pull_downs;

    /** use serial */
    int use_serial;
    /** fake usb version */
    int change_usb_version;
    /** usb version */
    int usb_version;
    /** maximum power */
    int max_power;

    /** manufacturer name */
    char *manufacturer;
    /** product name */
    char *product;
    /** serial number */
    char *serial;

    /** eeprom size in bytes. This doesn't get stored in the eeprom
        but is the only way to pass it to ftdi_eeprom_build. */
    int size;
};

#ifdef __cplusplus
extern "C"
{
#endif

    int ftdi_init(struct ftdi_context *ftdi);
    struct ftdi_context *ftdi_new(void);
    int ftdi_set_interface(struct ftdi_context *ftdi, enum ftdi_interface interface);

    void ftdi_deinit(struct ftdi_context *ftdi);
    void ftdi_free(struct ftdi_context *ftdi);
    void ftdi_set_usbdev (struct ftdi_context *ftdi, usb_dev_handle *usbdev);

    int ftdi_usb_find_all(struct ftdi_context *ftdi, struct ftdi_device_list **devlist,
                          int vendor, int product);
    void ftdi_list_free(struct ftdi_device_list **devlist);
    void ftdi_list_free2(struct ftdi_device_list *devlist);
    int ftdi_usb_get_strings(struct ftdi_context *ftdi, struct usb_device *dev,
                             char * manufacturer, int mnf_len,
                             char * description, int desc_len,
                             char * serial, int serial_len);

    int ftdi_usb_open(struct ftdi_context *ftdi, int vendor, int product);
    int ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product,
                           const char* description, const char* serial);
    int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int vendor, int product,
                           const char* description, const char* serial, unsigned int index);
    int ftdi_usb_open_dev(struct ftdi_context *ftdi, struct usb_device *dev);
    int ftdi_usb_open_string(struct ftdi_context *ftdi, const char* description);

    int ftdi_usb_close(struct ftdi_context *ftdi);
    int ftdi_usb_reset(struct ftdi_context *ftdi);
    int ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi);
    int ftdi_usb_purge_tx_buffer(struct ftdi_context *ftdi);
    int ftdi_usb_purge_buffers(struct ftdi_context *ftdi);

    int ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate);
    int ftdi_set_line_property(struct ftdi_context *ftdi, enum ftdi_bits_type bits,
                               enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity);
    int ftdi_set_line_property2(struct ftdi_context *ftdi, enum ftdi_bits_type bits,
                                enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity,
                                enum ftdi_break_type break_type);

    int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size);
    int ftdi_read_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize);
    int ftdi_read_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize);

    int ftdi_write_data(struct ftdi_context *ftdi, unsigned char *buf, int size);
    int ftdi_write_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize);
    int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize);

    int ftdi_write_data_async(struct ftdi_context *ftdi, unsigned char *buf, int size);
    void ftdi_async_complete(struct ftdi_context *ftdi, int wait_for_more);

    int DEPRECATED(ftdi_enable_bitbang(struct ftdi_context *ftdi, unsigned char bitmask));
    int ftdi_disable_bitbang(struct ftdi_context *ftdi);
    int ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned char bitmask, unsigned char mode);
    int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins);

    int ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency);
    int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency);

    int ftdi_poll_modem_status(struct ftdi_context *ftdi, unsigned short *status);

    /* flow control */
    int ftdi_setflowctrl(struct ftdi_context *ftdi, int flowctrl);
    int ftdi_setdtr_rts(struct ftdi_context *ftdi, int dtr, int rts);
    int ftdi_setdtr(struct ftdi_context *ftdi, int state);
    int ftdi_setrts(struct ftdi_context *ftdi, int state);

    int ftdi_set_event_char(struct ftdi_context *ftdi, unsigned char eventch, unsigned char enable);
    int ftdi_set_error_char(struct ftdi_context *ftdi, unsigned char errorch, unsigned char enable);

    /* set eeprom size */
    void ftdi_eeprom_setsize(struct ftdi_context *ftdi, struct ftdi_eeprom *eeprom, int size);

    /* init and build eeprom from ftdi_eeprom structure */
    void ftdi_eeprom_initdefaults(struct ftdi_eeprom *eeprom);
    void ftdi_eeprom_free(struct ftdi_eeprom *eeprom);
    int ftdi_eeprom_build(struct ftdi_eeprom *eeprom, unsigned char *output);
    int ftdi_eeprom_decode(struct ftdi_eeprom *eeprom, unsigned char *output, int size);

    /* "eeprom" needs to be valid 128 byte eeprom (generated by the eeprom generator)
       the checksum of the eeprom is valided */
    int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom);
    int ftdi_read_chipid(struct ftdi_context *ftdi, unsigned int *chipid);
    int ftdi_read_eeprom_getsize(struct ftdi_context *ftdi, unsigned char *eeprom, int maxsize);
    int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom);
    int ftdi_erase_eeprom(struct ftdi_context *ftdi);

    int ftdi_read_eeprom_location (struct ftdi_context *ftdi, int eeprom_addr, unsigned short *eeprom_val);
    int ftdi_write_eeprom_location(struct ftdi_context *ftdi, int eeprom_addr, unsigned short eeprom_val);

    char *ftdi_get_error_string(struct ftdi_context *ftdi);

#ifdef __cplusplus
}
#endif

#endif /* __libftdi_h__ */


/* end of libftdi.h */




#include <stdint.h>
#include <stdio.h>

#define ATTR_CDECL      __attribute__((cdecl))

struct ftdi_so_st {	/* pointers to libftdi.so */
	ATTR_CDECL int (* p_ftdi_init)(struct ftdi_context *ftdi);
	ATTR_CDECL uint32_t (* p_ftdi_interface_write)(void * unused_void, unsigned long const * buf, unsigned long count);
	ATTR_CDECL int (* p_ftdi_set_interface)(struct ftdi_context *ftdi, enum ftdi_interface interface);
	ATTR_CDECL void (* p_ftdi_deinit)(struct ftdi_context *ftdi);
	ATTR_CDECL int (* p_ftdi_usb_open)(struct ftdi_context *ftdi, int vendor, int product);
	ATTR_CDECL char (* p_ftdi_interface_close)(void * unused_void);
	ATTR_CDECL int (* p_ftdi_usb_close)(struct ftdi_context *ftdi);
	ATTR_CDECL int (* p_ftdi_usb_reset)(struct ftdi_context *ftdi);
	ATTR_CDECL int (* p_ftdi_usb_purge_buffers)(struct ftdi_context *ftdi);
	ATTR_CDECL int (* p_ftdi_read_data)(struct ftdi_context *ftdi, unsigned char *buf, int size);
	ATTR_CDECL int (* p_ftdi_read_data_set_chunksize)(struct ftdi_context *ftdi, unsigned int chunksize);
	ATTR_CDECL int (* p_ftdi_write_data)(struct ftdi_context *ftdi, unsigned char *buf, int size);
	ATTR_CDECL int (* p_ftdi_write_data_set_chunksize)(struct ftdi_context *ftdi, unsigned int chunksize);
	ATTR_CDECL int (* p_ftdi_write_data_get_chunksize)(struct ftdi_context *ftdi, unsigned int *chunksize);
	ATTR_CDECL int (* p_ftdi_set_bitmode)(struct ftdi_context *ftdi, unsigned char bitmask, unsigned char mode);
	ATTR_CDECL char * (* p_ftdi_get_error_string)(struct ftdi_context *ftdi);
	void * handle;	/* handle to libftdi DSO returned from dlopen() */
	unsigned chunksize;	/* cached from ftdi_write_data_get_chunksize */
};

typedef ATTR_CDECL char (* fn_find_devs)(uint32_t dev_index, char * out_desc, uint32_t api_ver);
typedef ATTR_CDECL char (* fn_find_descriptions)(const char * description);
typedef ATTR_CDECL int (* fn_init_dev)(uint32_t * p_exit_status, const char * desc, struct ftdi_so_st * s_server_ops, void * parent);
typedef ATTR_CDECL void (* fn_close)(void * unused_void);
typedef ATTR_CDECL void (* fn_pkt_wr_pattern)(void * unused_void, uint32_t jtag_tms, uint32_t v, unsigned long len);
typedef ATTR_CDECL void (* fn_pkt_wr_bits)(void * unused_void, unsigned jtag_tms, unsigned long * p_bits, unsigned long len, unsigned long field_144_minus_len);
typedef ATTR_CDECL char (* fn_do_flush)(void * unused_void, int bool_val, uint32_t index_val);
struct virtual_fns_st {	/* ABI to pass data in and out of driver */
	uint32_t             st_size;	/* to check ABI compatibility */
	char                 dev_description[32];
	uint32_t             st_flags;
	void *               reserved01[2];
	fn_find_devs         p_find_devs;
	fn_find_descriptions p_find_descriptions;
	fn_init_dev          p_init_dev;
	fn_close             p_close;
	void *               reserved02[3];
	fn_pkt_wr_pattern    p_pkt_wr_pattern;
	fn_pkt_wr_bits       p_pkt_wr_bits;
	void *               reserved03[1];
	fn_do_flush          p_do_flush;
	void *               reserved04[5];
};

struct driver_st
{
	uint32_t num_devs;
	struct virtual_fns_st vfns;
	struct ftdi_so_st ffns, str_fns;
	struct ftdi_context dev_info;
	void * parent;
	uint8_t w_buf[0x10000];	/* FT2232D can receive up to 64KB in one USB transfer */
	uint32_t w_buf_use, want_read, last_tms, last_cmd, chain_3d;
	uint8_t r_buf_2[0x10000], r_nbits[0x10000];
};
extern struct driver_st d;

int do_ftdi_write(uint8_t * c, size_t s)
{
	if (!d.ffns.chunksize) return 1;
	int r;
	if (d.ffns.chunksize < ((s + 0xff) & ~0xff)) {
		if ((r = d.ffns.p_ftdi_write_data_set_chunksize(&d.dev_info, (s + 0xff) & ~0xff)) < 0) return 1;
	}
	size_t i;
	if ((r = d.ffns.p_ftdi_write_data(&d.dev_info, c, s)) < 0) return 1;
	if (!d.want_read) return 0;
	unsigned got_read;
	for (got_read = 0, i = 0; got_read < d.want_read; got_read += r, i++) {
		if ((r = d.ffns.p_ftdi_read_data(&d.dev_info, &d.r_buf_2[got_read], sizeof(d.r_buf_2)/sizeof(d.r_buf_2[0]) - got_read)) < 0) return 1;
		if (i >= 10) return 1;
	}
	return 0;
}

ATTR_CDECL char find_devs(uint32_t dev_index, char * out_desc, uint32_t api_ver)
{
	if (api_ver < 4) return 0;
	if (dev_index >= d.num_devs) return 0;
	strcpy(out_desc, "bus-instance");
	return 1;
}

ATTR_CDECL char find_descriptions(const char * description)
{
	return !strcmp(description, "bus-instance");
}

inline void init_w_buf_red_on()
{
	d.w_buf[0] = 0x80;
	d.w_buf[1] = 0x10;
	d.w_buf[2] = 0x9b;
	d.w_buf_use = 3;
	d.last_tms = 0;
	d.last_cmd = 0;
	d.chain_3d = 0;
	d.want_read = 0;
}

ATTR_CDECL int init_dev(uint32_t * p_exit_status, const char * desc, struct ftdi_so_st * s_server_ops, void * parent)
{
	if (!parent) return 1;
	if (strcmp(desc, "bus-instance") != 0) return 1;
	init_w_buf_red_on();
	if (d.ffns.chunksize) return 1;
	memset(&d.str_fns, 0, sizeof(d.str_fns));
	d.str_fns.p_ftdi_interface_write = s_server_ops->p_ftdi_interface_write;
	d.str_fns.p_ftdi_interface_close = s_server_ops->p_ftdi_interface_close;
	d.parent = parent;
	if (d.ffns.chunksize) return 1;
	if (d.ffns.p_ftdi_write_data_get_chunksize(&d.dev_info, &d.ffns.chunksize) < 0 || d.ffns.p_ftdi_set_bitmode(&d.dev_info, 0x0b, 2) < 0) return 1;
	d.want_read = 0;
	uint8_t cmd[] = { 0x80, 0x90, 0x9b, 0x82, 0x07, 0x07, 0x86, 0, 0, 0x85, };
	if (do_ftdi_write(cmd, sizeof(cmd)) || d.ffns.p_ftdi_usb_purge_buffers(&d.dev_info) < 0) return 1;
	*p_exit_status = 1;
	return 0;
}

ATTR_CDECL void do_close(void * unused_void)
{
}

ATTR_CDECL char do_flush(void * unused_void, int bool_val, uint32_t index_val)
{
	if (!d.num_devs) return 1;
	uint8_t * wp = &d.w_buf[d.w_buf_use];
	*(wp++) = 0x80;	*(wp++) = 0x10;	*(wp++) = 0x9b;	*(wp++) = 0x87;
	do_ftdi_write(&d.w_buf[0], d.w_buf_use + 3);
	unsigned ulout_use = 0, bit = 0, i, q;
	for (i = 0; i < d.want_read; i++) {
		uint8_t bv = d.r_buf_2[i];
		for (q = 0; q < d.r_nbits[i]; q++) {
			if (!bit) d.r_buf_2[ulout_use] = 0;	/* prepare next byte to receive bits */
			if (bv & (0x80 >> (d.r_nbits[i] - q - 1))) d.r_buf_2[ulout_use] |= 1 << bit;
			bit++;
			if (bit & 8) {
				bit = 0;
				ulout_use++;
			}
		}
	}
	if (d.str_fns.p_ftdi_interface_write) d.str_fns.p_ftdi_interface_write(d.parent, (unsigned long *) d.r_buf_2, ulout_use * 8 + bit);
	if (d.str_fns.p_ftdi_interface_close) d.str_fns.p_ftdi_interface_close(d.parent);
	init_w_buf_red_on();
	return 1;
}

void send_bit(unsigned tms, unsigned v)
{
	if (d.last_tms != tms) {
		if (d.last_cmd == 0 && d.w_buf_use == 3) d.w_buf_use = 0;
		/* datasheet: TMS should be asserted before rising edge of first clock */
		d.w_buf[d.w_buf_use++] = 0x80;	d.w_buf[d.w_buf_use++] = 0x10 | (tms ? 0x08 : 0);	d.w_buf[d.w_buf_use++] = 0x9b;
		d.last_tms = !!tms;
		d.chain_3d = 0;
	} else if (d.w_buf_use > 3 && d.w_buf[d.last_cmd] == 0x3e) {
		if (d.w_buf[d.last_cmd + 1] < 6) {
			d.w_buf[d.last_cmd + 2] |= (v ? 1 : 0) << (++d.w_buf[d.last_cmd + 1]);
			d.r_nbits[d.want_read - 1]++;
		} else {
			if (!d.chain_3d) {
				d.w_buf[d.last_cmd] = 0x3d;
				d.w_buf[d.w_buf_use] = d.w_buf[d.w_buf_use - 1] | (v ? 0x80 : 0);	d.w_buf[d.w_buf_use - 1] = 0x00;	d.w_buf[d.w_buf_use - 2] = 0x00;
				d.w_buf_use++;
				d.r_nbits[d.want_read - 1]++;
				d.chain_3d = d.last_cmd;
			} else {
				unsigned chain = (d.w_buf[d.chain_3d + 1] | (d.w_buf[d.chain_3d + 2] << 8)) + 1;
				d.w_buf[d.chain_3d + 1] = chain & 0xff;	d.w_buf[d.chain_3d + 2] = (chain >> 8) & 0xff;	d.w_buf[d.chain_3d + 3 + chain] = d.w_buf[d.last_cmd + 2] | (v ? 0x80 : 0);
				d.w_buf_use = d.chain_3d + chain + 4;
				d.last_cmd = d.chain_3d;
				d.r_nbits[d.want_read - 1]++;
			}
		}
		return;
	}
	d.last_cmd = d.w_buf_use;
	d.w_buf[d.w_buf_use++] = 0x3e;	d.w_buf[d.w_buf_use++] = 0x00;	d.w_buf[d.w_buf_use++] = (v ? 1 : 0);
	d.r_nbits[d.want_read++] = 1;
	if (d.want_read > 128) do_flush(0, 0, 0);
}

ATTR_CDECL void pkt_wr_pattern(void * unused_void, uint32_t jtag_tms, uint32_t v, unsigned long len)
{
	if (!d.num_devs || len < 1) return;
	unsigned long i;
	for (i = 0; i < len; i++) send_bit(jtag_tms, v);
}

ATTR_CDECL void pkt_wr_bits(void * unused_void, unsigned jtag_tms, unsigned long * p_bits, unsigned long len, unsigned long field_144_minus_len)
{
	if (!d.num_devs || len < 1) return;
	unsigned long i;
	for (i = 0; i < len; i++) send_bit(jtag_tms, (p_bits[i / 32] >> (i & 31)) & 1);
}

int do_set_interface()
{
	if (d.ffns.p_ftdi_set_interface(&d.dev_info, INTERFACE_A) < 0 || d.ffns.p_ftdi_usb_open(&d.dev_info, Vendor, ProdID) < 0)
	{
		d.ffns.p_ftdi_deinit(&d.dev_info);
		return 1;
	}
	if (d.ffns.p_ftdi_usb_reset(&d.dev_info) < 0 || d.ffns.p_ftdi_read_data_set_chunksize(&d.dev_info, 65536) < 0)
	{
		d.ffns.p_ftdi_usb_close(&d.dev_info);
		d.ffns.p_ftdi_deinit(&d.dev_info);
		return 1;
	}
	return 0;
}

struct driver_st d = {
	.vfns = {
		.st_size             = sizeof(struct virtual_fns_st),
		.dev_description     = "usb-blaster-clone",
		.st_flags            = 0x800,
		.p_find_devs         = find_devs,
		.p_find_descriptions = find_descriptions,
		.p_init_dev          = init_dev,
		.p_close             = do_close,
		.p_pkt_wr_pattern    = pkt_wr_pattern,
		.p_pkt_wr_bits       = pkt_wr_bits,
		.p_do_flush          = do_flush,
	},
};

#define STRINGIFIER_DSO_METHOD_NAME(x) #x
#define STRINGIFY_DSO_METHOD_NAME(y) STRINGIFIER_DSO_METHOD_NAME(y)
#define STRING_DSO_METHOD_NAME STRINGIFY_DSO_METHOD_NAME(DSO_METHOD_NAME)

#define VISIBILITY_DEFAULT_EXTERN __attribute__((visibility("default"))) extern

VISIBILITY_DEFAULT_EXTERN struct virtual_fns_st * DSO_METHOD_NAME(uint32_t hw_type)
{
	if (hw_type != 0) return 0;
	if (d.ffns.handle) return &d.vfns;
	d.ffns.handle = dlopen("libftdi.so", RTLD_NOW);
	if (!d.ffns.handle) {
		#if 0
			If you have libftdi.so installed and you get this error, try a test:
			Create a file test.c:

			int main() { return 0; }

			Next, compile it with: gcc -o test -lftdi test.c

			Use google to fix any problems, then make sure libftdi.so is in /usr/lib

			As a last resort, change the call to dlopen() above so it has the full file path
		#endif
		return 0;
	}

	#define load_ffn(f) (!(d.ffns.p_##f = dlsym(d.ffns.handle, #f)))
	/* these can fail when the version is wrong. it must be libftdi-0.18 */
	if (load_ffn(ftdi_init) || load_ffn(ftdi_set_interface) || load_ffn(ftdi_deinit) ||
		load_ffn(ftdi_usb_open) || load_ffn(ftdi_usb_close) || load_ffn(ftdi_usb_reset) ||
		load_ffn(ftdi_usb_purge_buffers) || load_ffn(ftdi_read_data) ||
		load_ffn(ftdi_read_data_set_chunksize) || load_ffn(ftdi_write_data) ||
		load_ffn(ftdi_write_data_set_chunksize) || load_ffn(ftdi_write_data_get_chunksize) ||
		load_ffn(ftdi_set_bitmode) || load_ffn(ftdi_get_error_string) ||
		d.ffns.p_ftdi_init(&d.dev_info) < 0 || do_set_interface())
	{
		dlclose(d.ffns.handle);
		d.ffns.handle = 0;
		return 0;
	}
	d.num_devs = 1;
	return &d.vfns;
}





/*

TODO
multiple device support
use bulk usb transfer, programming speed can be a lot faster
mac os support


INSTRUCTIONS
------------
save this file as libjtag_hw_your_name_here.c
(yes, you can use any name after libjtag_hw_)

you must then plug in your hardware to detect the USB ID and compile it into the .so file
then compile it with this command:
(this is a very long line, and it must all be typed on the same line)

gcc -fPIC -fvisibility=hidden -DDSO_METHOD_NAME=`wget -qO - http://ubuntuforums.org/archive/index.php/t-142166.html | sed -e '/ial pro/p;d' | cut -d " " --output-delimiter=_ -sf 37-39 | sed -e 's/.$//'` `awk '/clone/{print gensub("=","=0x","g",gensub(".*(V[^ ]*) *(P[^ ]*).*","-D\\\\1 -D\\\\2","",Q))}{Q=P;P=$0}' /proc/bus/usb/devices` -shared -Wl,-soname,libjtag_hw_your_name_here.so -o libjtag_hw_your_name_here.so -ldl libjtag_hw_your_name_here.c

then check that compilation went ok by typing this command:

nm -CD *.so|md5sum|awk '{if ($1 == "9c9ae1be799a6ebda49a84a7a3b09104") print "ok"; else print "problem"}'

then copy the .so file to the directory that has other files named libjtag_hw_*,
note that there are two directories, you can copy the .so file into both for normal situations

*/
ahora funciona asi asi
 
Última edición:
Hola Faritron, es natural que lo quieras ver funcionar; cada cosa a su tiempo, por eso comenté que :

"Cuando el diseño funcione, recién en este momento necesitaras la placa para calmar los instintos naturales..."

Mi comentario trata de remarcar dos cosas,

1 La herramienta de verificación es el simulador.

2 El hecho de que un diseño funcione sobre una placa no quiere decir que el diseño este bien. Sobre todo si el diseño fue por decir de alguna forma "criado" sobre la placa.

Concuerdo contigo que para quienes nos gusta meter la mano en la masa es estimulante ver que mas no sea un LED parpadeando como queríamos. Claro que si no enciende el LED el haber simulado bien te da la seguridad necesaria para buscar el problema en el lugar adecuado.

Saludos,
 
Hola, ya me llego la placa de Spartan 3e 1600 , es tan bonita y le dedicare tanto tiempo... (mi novia me deja seguro jeje)

309hg60.jpg


Estaba haciendo el proyecto en una spartan 3AN, pero esta es mucho mas grande!!!
Un saludo
 
FARITRON,

Con calma, debería haber una ley que les obligue a indicar en la caja :

"ATENCIÓN : El contacto prolongado produce efectos secundarios, consulte a su soporte técnico. "

Buena suerte y a las ordenes.
 
Estoy Trabajando con una CPLD CoolRunner, la idea es implementar un registro de 21 bits PIPO que haga de contador por medio de un sumador mas uno; esto con el fin de incluir algunas acciones por medio de pulsadores a los cuales se les aplica un circuito antirebote previamente.

Necesito Ayuda con el codigo en VHDL ya que tengo un diagrama esquemático de bloques de lo que quiero que ocurra, pero no se como describirlo en este lenguaje.
 
PIPO: Paralel Input-Paralel Output.

de VHDL se lo básico, apenas puedo usarlo para crear los componentes básicos: Flip Flops, mux y registros y otras cosas; actualmente curso la materia de Sitemas Digitales en la Universidad.

lo que necesito es un tipo de contador que vaya desde 0 hasta completar 21 bits de "1"s, hecho a partir de un registro PIPO. en si el proyecto trata de crear un generador de direcciones para un reproductor de música, por tal razón necesito que la salida pueda detenerse, devolverse , pausarse, pasar a siguiente canción y a la anterior, estos comandos van implementados por medio de pulsadores con un sistema antirebote.
 
Supongo es tarea de la Universidad por eso no te daré toda la repuesta, es bueno aprender a pensar...

Necesitas declarar una señal

SIGNAL contador : unsigned(20 DOWNTO 0);

Y el contador lo haces con

contador <= contador + 1;

dentro de un PROCESS sincrono

Si quieres que pare cuando este todo el contador en '1' deberás incluir una sentencia del tipo

IF contador = "111....(21 unos) THEN ....
(se puede simplificar o usar otra técnica para evitar un comparador de 21 bits)

dentro del PROCESS

Walter
 
Última edición:
buenass, me he leido las 10 páginas de este hilo, y me gustaria saber a día de hoy, cualquier persona que quiera iniciarse en las fpgas ¿que placa le recomendais que se compre?

Gracias un saludo
 
Yo recomendaría ésta (de Altera, por supuesto): http://www.altera.com/products/devkits/altera/kit-cyc2-2C20N.html

La FPGA que trae es bastante grande ("cabe mucho"), tienes pulsadores, leds, conector de expansión, salidas de vídeo y audio, conexión de tarjeta SD...

Como habrás leído, para alguien que empieza con las FPGAs le recomendaría empezar con Altera y no con Xilinx, porque el entorno de desarrollo de Altera es muchísimo más amigable que el de Xilinx.
 
Muchas gracias por tu respuesta ferny, entonces ¿me recomiendas la cyclone II?¿por donde me recomiendas,ademas, que la adquiera?¿por su tienda o por un distribuidor?

Saludos
 
Personalmente no la he comprado, aunque sí usado. Para adquirirla yo creo que da igual, intenta con un distribuidor primero pero si no lo encuentras o bien te cobra más por la placa, pídela directamente a Altera, yo iría por la opción más económica.
 
el mejor sitio que he visto hasta ahora es este distribuidor,
farnell
pero he visto que hay muchos tipos de kits, ha diferentes precios, ¿cual me aconsejas? esque he visto por ahi la cyclon III

Un Saludo
 
Farnell es totalmente fiable, pero mira a ver cuántos gastos de envío te clavan ya que no son baratos.

Si eliminamos de esa búsqueda los que se han dejado de fabricar, los que valen casi 1000€ o más y los que son tarjetas para pinchar en un PC, nos quedan sólo el kit de la Cyclone II y el de la Cyclone III.

Si te fijas, el de la Cyclone III apenas trae periféricos (botones, switches, leds, etc.), los conectores de expansión que traen son muy incómodos de usar... Esta tarjeta la veo más pensada para desarrollar una aplicación con un microprocesador (Nios), ya que lo que sí trae es una memoria DDR de 32 MB. No la recomendaría para alguien que no sabe.

Sin embargo en la Cyclone II tienes varios botones, switches, leds, displays de 7 segmentos, puerto serie, puerto VGA, conectores de audio, memoria SD... también incluye una SDRAM de 8MB, y también se pueden montar una aplicación con un microprocesador dentro, por si eso es de tu interés. Creo que todos estos componentes son más útiles para alguien que empieza ¿no? Además, los conectores de expansión que tiene son bastante cómodos de usar, por si quieres conectar la tarjeta a otra que tú te hagas y meter por ejemplo un ADC o un DAC o lo que se te ocurra.

Te sigo recomendando la Cyclone II, es una placa muy buena en mi opinión, en mi trabajo la hemos usado para desarrollar prototipos y probar firmware antes de fabricarnos nuestras tarjetas hechas a medida.
 
enserio muchisimas gracias, me has resueltos todas las dudas, esta tarde la pido, en cuanto me llegue pondre unas fotos por si alguien le interesa.
Muchas gracias por todo ferny un saludo
 
Hola a todos

En mi trabajo entre otras cosas me dedico a desarrollar y probar firmware para FPGA's, por lo que si tenéis alguna duda concreta os puedo intentar echar una mano :)

Por otro lado he trabajado con FPGA's de Altera y de Xilinx, mi consejo si os queréis comprar una placa de evaluación para aprender su manejo es que os compréis una de Altera, más que nada (en mi opinión) porque el entorno de trabajo es mucho más amigable y sencillo de usar, además de ser más estable (el ISE de Xilinx se "cuelga" a veces...). En mi trabajo he usado la Cyclone II de altera y es una tarjeta muy sencilla de usar y mi preferida si alguna vez decido comprarla, además de ser de las más baratas... También he usado las tarjetas de evaluación Spartan 3A y Virtex II Pro de Xilinx y son unas tarjetas más completas que la de Altera, pero como ya dije su uso se complica algo más...

Quizá para desarrollar exclusivamente código VHDL la diferencia no sea tanta, porque al fin y al cabo lo "gordo" del proyecto es escribir el código, y para eso con el notepad de windows ya basta Donde he visto grandes ventajas de Altera sobre Xilinx es en el desarrollo de esquemáticos (pueden llegar a ser muy útiles para unir varios bloques de código VHDL que interactúen entre sí) y en la herramienta de análisis lógico (chipscope de xilinx y signaltap de altera, que te permiten visualizar en el PC el valor de señales internas de la FPGA, para saber su estado exacto en cada momento). Me pareció que las de Altera son más intuitivas de usar...

Para Altera basta que se bajen el Quartus Web Edition (creo que es gratuito), lo único que no soporta los modelos más avanzados de FPGA pero la Cyclone II de la tarjeta de evaluación sí funciona (además el Web Edition viene en el CD adjunto a la tarjeta que compren, por lo que ni siquiera tienen que bajarlo). Tiene un simulador de código VHDL que si bien no es muy completo, sí permite hacer casi todas las pruebas que uno puede necesitar durante el desarrollo de código. Una herramienta de simulación mucho más avanzada es el modelsim, creo que incluso tiene una versión gratuita (con sus limitaciones).

Espero que esta información os sirva

Un saludo


viendo que tienes gran experiencia en el manejo de estas tarjetas de desarrollo, te pediría un consejo y es que con unos compañeros de la universidad compraremos una fpga no sabemos aun si comprar la spartan 3E 1600 o la nexys 1200,, ay ciertas diferencias entre las dos tarjetas,., me gustaria saber su opinion de ello, y de igual forma si me puedes regalar un link e informacion de las tarjetas de desarrollo altera,...

y la verdad saber cual nos serviría mas para tratar con señales ya que queremos enfocarnos en comando de voz,.,.,. gracias por su atencion

Alguien puede darme una idea de algun ejemplo que se pueda hacer que sea sencillo de programar.


contador de 8 bits


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;



entity contador is
generic(m: integer :=8);
port( clk: in std_logic;
reset : in std_logic;

l:in std_logic;
ud : in std_logic;
load: in std_logic_vector(m downto 0);
cuenta:eek:ut std_logic_vector(m downto 0));

end contador;

architecture Behavioral of contador is
signal temp: std_logic_vector(m downto 0);
begin
process(clk,reset,ud,l)
variable temp:std_logic_vector(m downto 0);

begin
if clk'event and clk='1' then
if reset='1' then
temp:="000000000";
end if;
end if;
if l='1' then
temp:=load;
elsif ud='1' then
temp:= temp+1;
elsif ud = '0' then
temp:=temp-1;
end if;
cuenta<=temp;
end process;


end Behavioral;


bueno aquí les dejo un contador de 8 bits
 
Última edición:
La spartan 3E 1600 es más completa que la nexys 1200, tiene una FPGA más grande (1600 kpuertas frente a 1200 kpuertas), el doble de RAM (32MB frente a 16MB) que es muy útil si vas a implementar un microprocesador para tu aplicación, también tiene más periféricos (ethernet, LCD...)

Para una aplicación de audio, piensa cómo vas a "meter el audio" en la FPGA. La 1600 tiene un convertidor ADC, que te puede resultar muy útil para esto. La 1200 creo que no.
 
La spartan 3E 1600 es más completa que la nexys 1200, tiene una FPGA más grande (1600 kpuertas frente a 1200 kpuertas), el doble de RAM (32MB frente a 16MB) que es muy útil si vas a implementar un microprocesador para tu aplicación, también tiene más periféricos (ethernet, LCD...)

Para una aplicación de audio, piensa cómo vas a "meter el audio" en la FPGA. La 1600 tiene un convertidor ADC, que te puede resultar muy útil para esto. La 1200 creo que no.

gracias men por el dato,, espero la podamos conseguir, por medio de este ADC como se maneja dentro de la spartan 3E, o tienes algun circuito que resulte sencillo de entender donde este esta aplicacion,,.,.,. gracias por su atencion
 
No lo he usado nunca, pero al ser una placa bastante conocida es posible que buscando encuentres alguna aplicación donde se use el ADC. También es posible que con la documentación de la tarjeta te vengan archivos de ejemplo.
 
Atrás
Arriba