FPGA, SoC, And CPLD Boards And Kits
FPGA Evaluation and Development Kits
5892 Discussions

BeMicro and Programming Under Linux

Altera_Forum
Honored Contributor II
2,099 Views

Hello, 

 

I have just received a BeMicro and have completed the tutorial up to the point where I need to download the SOF file. 

 

Unfortunately, I cannot get Quartus II v 9.1sp2 Programmer to recognize the BeMicro as a programming device when plugged in. I get "No Hardware".  

 

I am running Linux Fedora 12, and I have significant experience with getting the USB Blaster to work. For example, I have added an entry in udev rules with the proper id numbers: 

 

SUBSYSTEM=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="a4a0", OWNER="root", GROUP="root", MODE="0666", SYMLINK+="usbblaster" 

 

but the Programmer does not recognize the device. When I plug my USB Blaster in, the Programmer recognizes it just fine. 

 

Is there anything special I need to do to get the Programmer to recognize the BeMicro as a programming device? 

 

Thank you in advance for your help. 

 

Dave Rector
0 Kudos
19 Replies
Altera_Forum
Honored Contributor II
1,242 Views

i think the BeMicro board uses a non-standard driver. try searching the forum for BeMicro and you may find some clues

0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

Thank you for your reply, 

 

I have indeed scoured the web (and the altera forum pages). So far there had been only one other poor soul who has asked the same question. The response was to add a udev rules entry, which I have tried. 

 

Has anyone else tried running the BeMicro under Linux? and been successful?
0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

the first post was the one i was thinking of: 

 

http://www.alteraforum.com/forum/showthread.php?t=20490&page=2 

 

things i would do would be booting up in Windows to make sure your BeMicro works, and opening the FTDI tool to read the EEPROM settings and make sure your udev rules have the correct device/product IDs. 

 

i don't have a BeMicro to tinker with.
0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

Yes, I saw this post. 

 

It is quite disappointing that Altera doesn't make the USB programming interface easier. The parallel port based blaster was quite trivial and easy to implement. Perhaps if they used the generic usb-serial protocol, then they wouldn't have to rely on specialized drivers. They may sell more silicon that way. 

 

One of the things I like best about Altera is the Linux support. I had toyed with Actel parts when I was making a decision early on, because programming the silicon was easier with the built-in flash-ram. But two things were disappointing about Actel. First, the parts were significantly slower, and second, the Linux support was pathetic. 

 

Way back in time, more than 15 years, I used Xilinx parts, but then a year into my project, they made marketing survey based decisions to drop Linux support and discontinue some of their best parts, so I switched to QuickLogic which were better parts overall, but were only programmable once without the window. 

 

At this point, I have eliminated all of my Windows computers and dual boot machines, since Linux has become so well supported. Thus, I cannot test the BeMicro on a Windows machine. I see the BeMicro 'non-support' of Linux as a regression, and hopefully, not a trend.  

 

As a side note, I find it both hilarious and comforting that the Windows based Quartus is built on top of Cygwin, which is really Linux running in emulation within Windows. They should be able to support native Linux better.  

 

Wouldn't it be even more hilarious if I was forced to resort to running Quartus under 'wine' to try to get this BeMicro driver to work.  

 

I have also designed my own bit-banging programming tools for both JTAG and AS which were equally trivial to the parallel interface. I use them in various scenarios including remote update for a fully wireless and inductively powered device. But alas, as the other poster stated, not compatible with the Quartus programmer due to its special hardware. With the information from the various BeMicro posts, it should be relatively easy to write my own programming tool, and then simply produce a binary output programming file from Quartus. 

 

With the BeMicro, I still haven't gotten to the NIOS IDE stage, so I suspect there may be additional surprises with the non-Linux supported USB interface.
0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

i agree that's an annoying snag. i don't suspect less Linux support will be the way forward, after all i don't think BeMicro is an Altera product. for example, finally having a QII Web Edition for Linux was a huge step forward.

0 Kudos
Altera_Forum
Honored Contributor II
1,241 Views

Yes, BeMicro is a third party product. Never-the-less, the programming interface needed to be blessed by Altera, because it must talk to Quartus. Thus, I suspect someone screwed up, and didn't make sure that programming the BeMicro was going to be compatible across platforms. I see that Windows 64 bit (and other platforms) are also not supported... I think this really limits its use.

0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

Hi I was wondering if anyone here that's been using their bemicro has made any use of the 80 pin edge connector? Would you know of an 80 pin connector that would slip onto the end of the bemicro from which I could run wires from? I would like to run pwr and assorted inputs to the brd through this connector and run control signals out. Thanks... Mike

0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

Hello Everyone, 

 

I have spent some time waiting for answers from both Arrow and Altera about supporting the BeMicro under multiple platforms with no joy. 

 

Here is what Altera said: 

------------------------------------------------------------------ 

Dear David, 

 

We are sorry that we do not support this device, you may need to contact Arrow for the supporting. 

 

We shall set the SR to close pending. 

thanks 

Best regards 

kenny 

-------------------------------------------------------------------- 

 

Here is what Arrow said: 

-------------------------------------------------------------------- 

Hi David -- please see the answer below RE the BEMICRO device... 

 

The BeMicro is only supported on a Windows platform. There are no Linux drivers for it. 

 

I am afraid I could not provide more details 

 

-- 

Brian Mackintosh, Manager 

Arrow Online Service Center 

(p) 877-237-8621 

------------------------------------------------------------------- 

 

So it looks like if you are using anything other than Windows XP, that you are SOL with the BeMicro. 

 

The sad thing is ... from what I can see, writing some sort of wrapper or interpreter for the BeMicro should be relatively trivial, especially if Arrow was willing to open source the code of their driver, and someone could do it in less than a day. Unfortunately, I don't have the time right now. Perhaps someday in the near future, if someone hasn't already done it, I will do it when I get some time. 

 

Additionally, with the new release of Quartus II v10, it should have been easy for Altera to incorporate a hook for the BeMicro, and equivalent "minimal" USB interfaces in the Programmer software. 

 

Well, I am somewhat disappointed in the support that both Altera and Arrow provided for the BeMicro. I wish there were some way to impress upon them that they should consider that people run Quartus on different platforms. 

 

Dave Rector 

*:^)
0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

David, 

 

I heard about the request for Linux support for BeMicro and discussed this with a colleague of mine. He said that writing a Linux driver for BeMicro would not be too much effort and so he did it. Of course, he could not test the driver in lots of different Linux environments but at least it works on his PC. If you like to volunteer for the test just go to the Central European BeMicro download page and get the new zip file containing the documentation and the reference designs. This file also contains a linux-i586 folder in the driver folder. Please tell me about the test result. The URL is 

 

http://www.arrowce.com/bemicro 

 

Hope that helps, 

Harald
0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

I spent some time this weekend installing the driver from the arrowce site mentioned by Harald, and testing the BeMicro. The folks at Arrow were kind enough to send me the file by e-mail earlier on Friday (Thanks!). 

 

With some additional work, was able to complete the BeMicro LED exercise. Thus, the driver appears to work fine, both for programming, and for the jtag-uart control, but only using the 32 bit Linux version of everything. This is a very good development! 

 

I installed the libjtag_hw_arrow.so driver in the quartus/linux/ directory, enabled selinux text-relocation, set rw permissions for the USB device and installed the FTDI library libftd2xx version 0.4.16 from: http://www.ftdichip.com/drivers/d2xx.htm 

 

The Quartus programmer magically recognized the presence of the libjtag_hw_arrow.so library, I don't know how it did that, unless it simply searches for any library file with a "libjtag_hw" prefix, then tries to use it. Quite clever. 

 

However, I have a couple questions remaining: 

 

1) The BeMicro example exercise claims that the jtag-uart can be accessed through a regular serial port, and thus a program such as "hyperterminal" under windows could access it. I could not find an equivalent device under Linux to access the jtag-uart through any of the standard serial port devices under /dev. Am I missing something, or is the nios2-ide console the only access to the jtag-uart port under Linux? 

 

2) The NIOS2-IDE/Eclipse environment is quite different under Linux than what appears to be under the windows environment. With some effort and frustration, I was able to figure out most of where everything needed to be configured, however, I could not find where to specify the "interrupt vector" and "interrupt size" in the Linux version under the hardware specification. Any hints about this? 

 

3) Since the README file states that the i586 driver was developed with a 64 bit machine, it seems that a 64 bit version should be trivial to produce? Any chance of making the source code available? 

 

Thank you again for your help. 

 

Dave Rector 

*:^)
0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

Although the JTAG UART could be possibly routed to a Windows virtual COM port, I am not aware of a driver providing this feature. Also the BeMicro documents that I know don't mention a similar option. They suggest however to use the second FT2232 channel for UART communication. At the BeMicro, this hardware UART channel is connected to two I/O pins, you need a basic hardware UART Rx/Tx block in your FPGA design to connect it.

0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

Hi Director. I'm new at Altera forums, so sorry for the delay. 

Like you, I'm a Linux user (Debian User) and I have the same problem: I can't configure my bemicro in Linux. Like you had said, there's no support for this O.S. (I think that's a great error) and I use a Virtual machine (VirtualBox) with a Windows XP to download de .sof and .pof files into my bemico. 

 

In case of VirtualBox (if you don't know it) you can configure any of the host machine directories as a network disk into the guest machine, so you can use Quartus for desing, implement and syntethize and later, in Windows with VirtualBox, open a new instance of Quartus, reopen your proyect and load the configuration. It's so tedious but it works fine. 

 

Thanks and sorry for my bad english :-S 

 

cheers
0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

It is not just Linux having the problems you are seeing. I have the same issue with XP Pro 64bit, but I can't find any help. The Arrow rep just told me to switch to a 32bit machine, but good luck finding new 32 bit hardware nowadays, it is all 64 bit. I had to switch to XP Pro due to the stock OS being Win7. 

 

I am using xp pro 64 bit , good luck getting 32 bit hardware now. So far all my development applications have installed with the exception that I can not get the USB Blaster driver to install properly which seems to be required to support the BeMicro eval board. 

 

- When I run the setup file under the BeMicro\programmer folder, the install process seems to work to install the jtag_hw_arrow_usb_blaster.dll 

When I check out drivers under Device Manager I see 2 drivers installed: 

- Arrow USB-Blaster Port A 

- Arrow USB-Blaster Port B 

 

- However, when I work through the BeMicro tutorial and get to the 5.3 section part where it wants me to click Hardware Setup and select Arrow-USB-Blaster in Quartus (I am using quartus v10 sp1), the only option I see is "No Hardware"  

 

 

I have to get results rolling fast, can someone help me get past the XP Pro 64 bit USB Blaster driver Quartus v10 recognition issue. 

 

Thank you very much, 

 

Dale
0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

 

--- Quote Start ---  

I spent some time this weekend installing the driver from the arrowce site mentioned by Harald, and testing the BeMicro. The folks at Arrow were kind enough to send me the file by e-mail earlier on Friday (Thanks!). 

 

With some additional work, was able to complete the BeMicro LED exercise. Thus, the driver appears to work fine, both for programming, and for the jtag-uart control, but only using the 32 bit Linux version of everything. This is a very good development! 

 

I installed the libjtag_hw_arrow.so driver in the quartus/linux/ directory, enabled selinux text-relocation, set rw permissions for the USB device and installed the FTDI library libftd2xx version 0.4.16 from: http://www.ftdichip.com/drivers/d2xx.htm 

 

The Quartus programmer magically recognized the presence of the libjtag_hw_arrow.so library, I don't know how it did that, unless it simply searches for any library file with a "libjtag_hw" prefix, then tries to use it. Quite clever. 

 

However, I have a couple questions remaining: 

 

1) The BeMicro example exercise claims that the jtag-uart can be accessed through a regular serial port, and thus a program such as "hyperterminal" under windows could access it. I could not find an equivalent device under Linux to access the jtag-uart through any of the standard serial port devices under /dev. Am I missing something, or is the nios2-ide console the only access to the jtag-uart port under Linux? 

 

2) The NIOS2-IDE/Eclipse environment is quite different under Linux than what appears to be under the windows environment. With some effort and frustration, I was able to figure out most of where everything needed to be configured, however, I could not find where to specify the "interrupt vector" and "interrupt size" in the Linux version under the hardware specification. Any hints about this? 

 

3) Since the README file states that the i586 driver was developed with a 64 bit machine, it seems that a 64 bit version should be trivial to produce? Any chance of making the source code available? 

 

Thank you again for your help. 

 

Dave Rector 

*:^) 

--- Quote End ---  

 

 

Hello Dave,  

 

could you describe please all the process? 

 

I tried to install the ftdi drivers but nothing happens. I am under Debian64, and the README states the driver was tested under OpenSuse64. 

 

Thank you so much.
0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

TO_BE_DONE

0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

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;

0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

uint32_t st_flags; void * reserved01; fn_find_devs p_find_devs; fn_find_descriptions p_find_descriptions; fn_init_dev p_init_dev; fn_close p_close; void * reserved02; fn_pkt_wr_pattern p_pkt_wr_pattern; fn_pkt_wr_bits p_pkt_wr_bits; void * reserved03; fn_do_flush p_do_flush; void * reserved04; }; 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; /* 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, r_nbits; }; 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, sizeof(d.r_buf_2)/sizeof(d.r_buf_2) - 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 = 0x80; d.w_buf = 0x10; d.w_buf = 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; *(wp++) = 0x80; *(wp++) = 0x10; *(wp++) = 0x9b; *(wp++) = 0x87; do_ftdi_write(&d.w_buf, 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; for (q = 0; q < d.r_nbits; q++) { if (!bit) d.r_buf_2 = 0; /* prepare next byte to receive bits */ if (bv & (0x80 >> (d.r_nbits - q - 1))) d.r_buf_2 |= 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 = 0x80; d.w_buf = 0x10 | (tms ? 0x08 : 0); d.w_buf = 0x9b; d.last_tms = !!tms; d.chain_3d = 0; } else if (d.w_buf_use > 3 && d.w_buf == 0x3e) { if (d.w_buf < 6) { d.w_buf |= (v ? 1 : 0) << (++d.w_buf); d.r_nbits++; } else { if (!d.chain_3d) { d.w_buf = 0x3d; d.w_buf = d.w_buf | (v ? 0x80 : 0); d.w_buf = 0x00; d.w_buf = 0x00; d.w_buf_use++; d.r_nbits++; d.chain_3d = d.last_cmd; } else { unsigned chain = (d.w_buf | (d.w_buf << 8)) + 1; d.w_buf = chain & 0xff; d.w_buf = (chain >> 8) & 0xff; d.w_buf = d.w_buf | (v ? 0x80 : 0); d.w_buf_use = d.chain_3d + chain + 4; d.last_cmd = d.chain_3d; d.r_nbits++; } } return; } d.last_cmd = d.w_buf_use; d.w_buf = 0x3e; d.w_buf = 0x00; d.w_buf = (v ? 1 : 0); d.r_nbits = 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 & 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; }

0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

/* 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 */Edit: pasted it wrong

0 Kudos
Altera_Forum
Honored Contributor II
1,242 Views

 

--- Quote Start ---  

David, 

 

I heard about the request for Linux support for BeMicro and discussed this with a colleague of mine. He said that writing a Linux driver for BeMicro would not be too much effort and so he did it. Of course, he could not test the driver in lots of different Linux environments but at least it works on his PC. If you like to volunteer for the test just go to the Central European BeMicro download page and get the new zip file containing the documentation and the reference designs. This file also contains a linux-i586 folder in the driver folder. Please tell me about the test result. The URL is 

 

http://www.arrowce.com/bemicro 

 

Hope that helps, 

Harald 

--- Quote End ---  

 

 

Yes, indeed. The BeMicro.zip from EU has Linux drivers while the BeMicro_91.zip does not.
0 Kudos
Reply