Sunday, December 20, 2020

iCE40 FPGA Programming with WSL and Open Source Tools

Here are some notes on programming the Lattice Semiconductor iCE40 FPGA chip.

This is supplementary information to the awesome learn-fpga walk-through by @BrunoLevy01 that I worked on a couple of weekends ago, specifically the IceStick Tutorial, but for Windows and WSL instead of Linux.


The default Windows drivers are FTDIBUS. Unfortunately this driver will typically NOT work to program the iCE40. If later changed with Zadig, they can be returned to the Windows default by right-clicking on the item in Device Manager and selecting "Update Driver". Choosing "Search Automatically for Driver" should assign the default FTDIBUS drivers. (either that, or just wait for Windows to arbitrarily change it back when you least expected it)

It may be best to start with plugging the device directly into the computer, rather than using a hub. Sometimes there are "issues". 

To program the iCE40 with iceprog assign the libusbK drivers with Zadig:  

Oddly, I found that I needed to assign the libusbK drivers to BOTH Interface 0 and Interface 1 in order to be able to successfully program the iCE40. Further, not only did the drivers need to be installed on both interfaces, but after doing so - I had to unplug (wait a few seconds) and plug in the device for successful programming when the drivers were first changed.

The drivers will almost certainly revert back to the FTDI default at Windows update time, and perhaps arbitrary other times as well.

It seems that the WinUSB drivers also work for successful programming.

Note that nether the libusbK nor the WinUSB drivers will show up as a COM port in Windows, so no TTY connection with something like putty.

Assigning the USB Serial drivers, and the Lattice shows up as a COM port. But here, iceprog will not see the iCE40 to program it.

Program only on the first interface:  iceprog.exe -I A femtosoc.bin

Attempting to program on the second interface gets stuck here at the erase step:

$ /mnt/c/Users/gojimmypi/.icestudio/apio/packages/toolchain-ice40/bin/iceprog.exe -I A femtosoc.bin
init..
cdone: high
reset..
cdone: low
init..
cdone: high
reset..
cdone: high
Extended Device String Length is 0xFF, this is likely a read error. Ignorig...
flash ID: 0xFF 0xFF 0xFF 0xFF
file size: 32220
erase 64kB sector at 0x000000..


This is what it looks like when iceprog cannot find the USB device:
0 $ /mnt/c/Users/gojimmypi/.icestudio/apio/packages/toolchain-ice40/bin/iceprog.exe -I A femtosoc.bin
init..
Can't find iCE FTDI USB device (vendor_id 0x0403, device_id 0x6010 or 0x6014).
ABORT.

If Zadig was used to assign the USBSER driver, the above step may not work. Assign it to something else (recommended libusbK) and then try again.

WinUSB devices show up here in Device Manager: 


Changing Interface 1 appears to also change Interface 0. However the reverse is not true. Thus it is best to assign drivers to Interface 1 first.


Reminder: When assigning new drivers, it is usually best to unplug and re-plug the iCE40 stick after drivers are changed with Zadig, otherwise iceprog may fail.

Note that for a "real" Ubuntu - in this case on a VM on a Windows host, the iCEStick shows up as 3 devices, no fussing with Zadig or anything else:


Here, the make terminal just works:


I was unable to persuade WSL, with any sort of Zadig drivers, to recognize the iCEStick in terminal mode. If it was a plain TTY terminal, it might have worked, but since I am using WSL1 and the target is /dev/ttyUSB1 - I don't this this would ever work on WSL1. Perhaps with WSL2 native USB support?


Find gojimmypi at gojimmypi.github.io

I'm currently working on my new blog home at  gojimmypi.github.io After implementing a variety of features such as dark mode , syntax hi...