

                               chiprog manual
                               --------------



                                Introduction
                                ------------

 There are some pretty neat MCU/FPGA/flash components at low prices at Digikey
but most of the time Linux is not well supported for these or needs workarounds
or the provided tools are too bloatware for commandline. On the other hand a lot
of foundries have their own specific kits/tools for programming their different
chips at certain prices and I see no point collecting them for experimenting or
versalite projects. I prefer a uniform makefile-based dev.environment instead.
(Easy-to-start devkits have relevance but I've put up with them a while ago.)

 This program 'chiprog' is a chip programmer software using FTDI's cheap FT230XS
USB-to-UART/GPIO chip. I made it to be an universal programmer which is made
of cheap components (essentially the 2USD FT230XS only) and can be built easily.
It has FIFO inside which can work in synchronous fashion which means it can
send timed clocks and data while receiving timed response from the target chip. 
(USB protocol can only send data in datachunks/packages/frames by design, which
means milliseconds are spent between sending parts of data. FIFO circumvents 
this limitation and it seems it does the job fine, maybe only some very timing
sensitive chips won't like the occasionally suspended datastream.)
 I could achieve reading/writing three chip-types already: the Winbond serial 
SPI flash (and the same type of standard SPI PROM chips from other companies),
Silicon Labs Busy Bee and Universal Bee (maybe other Bees) and Lattice's iCE40 
FPGA chips (tried with iCE40LP384). At least these are the chips I tested so far
with chiprog and they proved working. I don't have many different chips at hand
just the ones I worked with, so I can't be 100% sure all Bee MCUs and SPI 
flashes or iCE40s are programmable with this tool. Theoretically the are...
 As a reference, the exact chip models I programmed with chiprog successfully:
  Winbond 25x40VSSIG , SiLabs EFM8UB20F32G-A-QFP48 (via C2 or USB-bootloader) ,
  SiLabs EFM8BB31F16G-A-QFP32 (via UART, not C2) , Lattice ICE40LP384-SG32

 Usage of this simple program can be found out if you simply run it on command
line without any extra parameters. I compiled and used it in Linux but as this
application uses only C standard libraries and libusb-1.0 as dependency, it 
might be fairly easy to compile/port it on other platforms. Despite using FTDI 
chip, libftdi library is not required, I do every initialization (even setting 
EEPROM config for CBUS pins) in the code internally only relying on libusb for 
communication. (If you're not root, chiprog can't detach automatically loaded
kernel drivers (/dev/ttyUSB0 / /dev/hidrawX), in that case delete its udev rule.
 Chiprog doesn't read .hex files, only raw binary files are read/written. If you
have a .hex only, there are tools to convert it to raw binary, like hex2bin or
hexbin tool of ASEM-51 assembler. (Which seems a good 8051 macro-assembler btw.)
AS31 simple assembler can output raw binary directly though it doesn't seem to
have conditional assembly and macros. Maybe asxxxx/as8051 or SDCC version of it
is the best mixture. (Usage: sdas8051 -o xx.rel xx.asm ; sdld -i xx.rel ;
                             sdobjcopy -Iihex -Obinary xx.ihx xx.bin )
 It's always a good idea to verify whether a chip-programming was successful. 
Chiprog doesn't have a built-in mechanism for it but you can read the contents
of the chip after successful programming, and compare the original file to the
new file acquired from the chip with 'diff' tool. In case there's mismatch you
may try again, probably only some temporary problems caused the write-errors due
to too long cable or noisy environment or timing irregularities of USB port. The
unsuccessful intermediate communication is often tolerated by chiprog: I tried
not to abort on every error but that doesn't solve serious issues of course.
 Only full device erase (except in bootloader-based flashing) and full/partial
device read/write is possible with always-zero starting position, so individual
pages of flash are not read/written by chiprog.
 Size of content to read from chips must be given explicitly but size of content
to write into the chip can be automatically taken from filesize by giving 0 as
that commandline argument. Debug option is handful as it makes chiprog a little
bit more verbose no what happens in the background. You can see and run some
examples (test targets like testflash, testub2, testice, etc.) in Makefile.
 Only one chiprog device may be used at a time as chiprog doesn't enumerate if
there are more of them connected, it uses the one found first on USB ports.



                            Schematic diagram
                            -----------------

Simple schematic (well, kindof) for chiprog (view with monospace fontset):
(The PCB is simple too, ground should reside around edges, Vio can be connected
 to Reset# and 3.3V outputs under the chip. Capacitors and series resistors
 on the USB wires are not even necessary with my direct cable-less connection.
 100nF buffer capacitors on power lines may be there to be on the safe side.
 As seen in the schematic, series 100 Ohm resistors on CBUS/DBUS output pins are
 recommended to avoid overcurrent that might be caused occasionally by clashes 
 between the FTDI and target device outputs. (Better be safe than sorry.)
 Sorry for the upside-down GND/3V3 but PCB bottom layer is better reflected so.)

           .--------------------.
           |                    |                  Programmer-port:
       .------------------*----------------------. ----------------
       |   |              |     |                | (pin-header receptacles)
       |   |  .--|>|-/\/\-*  .---------------.   |
       |   |  |  LED  470 |  |  |    100 Ohm |   O GND
       *-||*  `-----. Ohm |  |  |  .--/\/\-. |     
       |100|        |     |  |  |  |       | `--<O DATA_IN  (DBUS1 / RxD @ UART)
 USB   | nF| .---|  |  x  |  |  |  |  |--. |      
 ---   |   | |  -----------------------o | `---->O CLOCK    (DBUS2 / RTS#)
       |   | |  |8  7  6  5  4  3  2  1| |  100    
 GND O-*   | |  |D+ C2 D3 G D1 Vio D2 D0 `-/\/\->O DATA_OUT (DBUS0 / TxD @ UART)
       |   | |  |                      |          
  D+ O-------'  | FTDI FT230XS-U 16SSOP| .-/\/\--O GPIO3 (CDONE) (CBUS3/SLEEP#)
       |   |    |                      | |  100   
  D- O-------.  |D- 3V R Vcc G C1 C0 C3| | .---->O CHIPSELECT (CBUS0 / TXDEN)
       |   | |  |9 10 11 12 13 14 15 16| | |      
 +5V O---. | |  ------------------------ | | .---O GPIO1 (CRESET) (CBUS1/RXLED#)
       | | | `---|  |  |  |  |  |  |  |--' | |    
       | | |        |  |  |  |  `\ |       | |   O 3.3V regulator-output
       | | `--------*--*--|--|-. | `--/\/\-' |   |      (FTDI has one built in)
       | |                |  | | |    100    |   |
    GND| `--*-------------'  | | `------/\/\-'   |
       |    =100nF           | |         100     |
       `----*----------------' `-----------------'

DBUS (DATA-in/out and CLOCK) pins can be controlled/read by FIFO in the FTDI,
so they are used for time-sensitive tasks. The default baudrate of FTDI enables
around 2.5Mbit/s by default on DBUS. I didn't disturb that setting (commented
out in the source) as it's a good candidate for most devices, not too fast and
not too slow. Flow-control in FTDI DBUS bitbang-mode is turned off so they act
in a quasi-GPIO mode, no start/stop-bits injected, chiprog gets full control of
what is sent out or received. CBUS pins are set to GPIO mode instead of their
predefined (SLEEP#/RXLED#/etc.) modes and can be used for any function that
doesn't require fast/sensitive timing, likewise I selected CHIPSELECT function
for CBUS0...




                           SPI flash programming
                           ---------------------

 The flash programming ability comes handy for example when you brick a PC by
flashing an unmatched BIOS version to it or if the BIOS flashing procedure fails
in the middle. I myself bricked my ASUS EeePC 701 while experimenting with BIOS
versions, but by desoldering and wiring the 8-pin 25x40 flash chip appropriately
to chiprog's FT230XS output-headers, I could reprogram the correct BIOS and save
my little netbook... Also I think, while iCE40 NVCM can't be programmed yet by
chiprog, a serial flash can be used in conjunction with the FPGA and that can
be programmed by chiprog. This is the usual setup for iCE40 FPGA anyway as it
has only once-programmable OTP NVCM onboard which is not suitable for prototype
experiments. (Programming protocol can be found in datasheet of SPI flash.)
SPI Flash programming on chiprog is fairly fast, cca 4kbytes per secound IIRC.
Note: before writing the flash, a chip-erase command clears the whole flash.

Connecting the SPI flash chips with standard pinout to chiprog:
(Obviously DI to DATA_OUT, DO to DATA_IN, CLK to CLOCK, CS# to CHIPSELECT,
 GND to GND, Vcc and HOLD# and WP# to 3.3V supply.)

                .----------------------------------.
                |                                  |
       GND O----|-------. .---------------------.  |
                |       | |       SPI flash     |  |
    DATAIN O<------.    | |    o-------------.  |  |
                |  |  .--------|1 CS#   Vcc 8|--*  |
     CLOCK O>---'  |  | | |    |             |  |  |
                   `-----------|2 DO  HOLD# 7|--*--|--.
   DATAOUT O>-.       | | |    |             |     |  | 
              |       | | `----|3 WP#   CLK 6|-----'  |
           O  |       | |      |             |        |
              |       | `------|4 GND    DI 5|-.      |
CHIPSELECT O>-|-------'        `-------------' |      |
              |                                |      |
           O  `--------------------------------'      |
                                                      |
    3V3OUT O------------------------------------------'

command example: chiprog r sflash flashcontent.bin 65536 debug
		 chiprog w sflash flashcontent.out 465



                         Silicon Labs MCU programming
                         ----------------------------

 Busy/Universal Bee microcontrollers got my attention by their impressive set of
capabilities and yet best prices. (Much more economic than the famous ATmega's.)
The problem with these chips is their odd programming interface called C2. It is
kind of complex compared to SPI as it has Data input and output mixed into
one single wire. This means the programmer's output should be able to switch
very fast and frequently between input/output modes. FT230XS can't do it fast
on its DBUS pins, but I found out a solution: by adding a 220 Ohm resistor 
between DATA input and output pins and connecting the SiLabs MCU's C2D (data) 
pin to the data-input of chiprog, there's no need to switch input/output modes
(enable/disable driver) and the line can still be bidirectional. When the MCU
turns its driver off (most of the time), chiprog can use the data-line through
the series 220 Ohm which is small enough that it doesn't ruin signal edges much,
but when MCU wants to drive the data-line, the 220 Ohm prevents bus contention,
and no matter what is output on chiprog's data-output, the MCU can drive the
input of chiprog high or low. Chiprog's output pulls the dataline a bit in this
case but 0 or 1 cases are still clean enough. (MCU can drive around 15mA fine.)
Programming SiLabs MCU is very slow due to the needed InBusy/OutReady polling
mechanisms of C2 over USB: around 100 bytes per second on my EeePC900 netbook! 
 In a way chiprog with FT230XS can be thought of as a bootstrap which works 
immediately without any special coding/bootloader, sometimes (in case of SiLabs)
slowish for mass code-compile-burn cycles. But it can be a life-saver at times 
though, when you don't have other options to program a Silicon Labs MCU, e.g.
you have an Universal Bee but it lacks bootloader like mine (made before 2016?).
Note: Before writing (even partially) the whole flash gets erased in the MCU.

 C2 protocol is explained in application note AN127 available at SiLabs site.
However the new one is bogus as pointed out at SiLabs Forum, old AN127 seems OK.
 I found some information at Silicon Labs Community forum that other projects
exist too for Linux which target their chips and C2 protocol. What's more the
Linux kernel has C2 built-in since 2008. Some people could flash SiLabs chips
with Raspberry-PI using ec2drv or ec2drv-new or C2-Flash project codes.)

Connecting Silicon Labs MCU for C2-type of interfacing:
(It's a pity that my EFM8UB2 didn't have a USB bootloader. Else all this stuff 
 would have been unnecessary as it could have been programmed via USB tools.
 The 1kOhm pullup resistor at C2CK is advised by SiLabs but EFM8UB2 could be
 programmed well without it. Your mileage may vary. )

                                |------ - -
       GND O--------------------|GND
                                |
    DATAIN O<--------*----------|C2D
                     |          |
     CLOCK O>--------|---*-/\/\-|C2CK/RSTb (series resistor is not necessary
                     |   | (220)| but may prevent contention at RSTb low pulse
   DATAOUT O>--/\/\--'   |      | which the MCU generates when it powers up.) 
               220 Ohm   \      |  
           O             /      |  Silicon Labs EFM8 Universal Bee
                         \ (1k) |  ----------------- or Busy Bee / etc.
           O             /      |
                         |      |
           O             |  .---|Vdd (connect Vio too to 3.3V if it's present)
                         |  |   |
    3V3OUT O-------------*--'   |--------- - -

command example: chiprog w efm8 bootloader.bin 0 debug


Programming EFM8 with UART-bootloader:
--------------------------------------
 I couldn't program my EFM8BB31F16G-QFP32 Busy Bee MCU through C2 for some
reason. Asked for help at SiLabs community forum but no idea why it doesn't work
with EFM8BB3 while it worked fine with EFM8UB2 even without the 1kOhm pullup.
Maybe BB3 has different C2 physical layer (circuitry) and it doesn't like my
resistor-workaround between DATAIN and DATAOUT depicted above, dunno. I'll try.
 Never mind, if you have an UART bootloader in your EFM8BB3 (or other EFM8s as
stated in the datasheets) preloaded by SiLabs before shipping, chiprog can use 
the FTDI to behave as normal RS232-like UART instead of bitbanging and it can 
program EFM8 chips through their UART Tx and Rx lines. The bootloader receives 
some commands and data-payload in specified frames (described in AN945) and 
replies with a statusbyte. Readback of flash is not supported by the bootloader.
 The baudrate is set to 115200 for this mode, most compatible with EFM8 chips.
Note: Partial programming leaves the bootloader intact, no full chip-erase. (You
can see some more info about efm8load/etc. but it didn't work for me.)

So I think you guessed that a different connection is needed for UART flashing:

                           ,-------- - -
      GND O----------------|GND
                           |                   EFM8BB3/etc.
   DATAIN O<---------------|UART Tx (P0.4?)    ------------
                           |
    CLOCK O>---------------|C2CK/RSTb (used to reset device before flashing)
                           |                 (chiprog does it automatically)
  DATAOUT O>---------------|UART-Rx (P0.5?)
                           |
    CBUS3 O>---------------|C2D/P3.7/etc (bootloader-selector pin, see AN945)
                           |(needed for programmed chip to enter bootloader by
          O  ,--*-------,  | holding this pin down during C2CK/RSTb low-pulse.)
             |  |       |  |                    (chiprog does it automatically)
          O  | ===(1uF) *--|Vdd
             |  |       |  |
   3V3OUT O--' ---GND   `--|Vio (if there is separate Vio)
                           `-------- - -

command example: chiprog w efm8uart blinker.bin 0


Programming EFM8 with UART-bootloader - DBUS-only version:
----------------------------------------------------------
When my CBUS pins whent wrong on my FTDI for some reason, for a while I could
only program the BB3 via DBUS. I substituted the missing CBUS3 by connecting 
DBUS3 to C2D/P3.7, to automatize the bootloader selection at programming start.
(You can do it manually too if you don't want to rewire DBUS3 to replace CBUS3,
 this can be done by a switch that connects to ground. If this is done through
a series 1kOhm resistor, the pin P3.7 can be used as GPIO after programming.)
For this I made a new entry called 'efm8uartdbus', but it works with 'efm8uart'
too, though this solution is cleaner and doesn't disturb the CBUS which is good
if it became faulty. So an example would look like this for this method:

  chiprog w efm8uartdbus blabla.bin 0 debug


Programming EFM8UB equipped with USB and USB-bootloader:
--------------------------------------------------------
 If you're lucky and you have the promised USB bootloader in your EFM8UB chip,
or you can burn it with the FTDI via C2, then you can program the EFM8UB faster
directly through its USB pins. Though there still can be some quirks,for example
in my EFM8UB2 the bootloader didn't work. I've read at SiLabs forum that (some?)
earlier (model A?) chips couldn't start the bootloader at reset no matter if the
$A5 signature is present near the end of flash. So I had to make a 'ljmp 0x7E20'
(this address depends on chip-type) at reset-vector address $0000, concatenate
it with the bootloader .hex file at right location (padded so it aligns $7A00),
then upload this 'bootstrap' bootloader into the EFM8UB2 with C2 protocol first.
Magically then 'lsusb' command of Linux finally listed it as 'Cygnal' device.
 If you were unlucky and your bootloader couldn't start (even when flash $0000
is unprogrammed or you hold pin 3.7/etc down at startup), then you should always
append a short routine before your program to check if the RSTb signal on C2CK
pin was made: 

bootm:	mov A, 0xEF        ;bootmanager: check RSTSRC reset-source
	cjne A, #1, begin  ;if POWER-ON or other reset start app
	ljmp 0x7E20 ;?     ;address of bootloader USB-programming direct entry
begin:  ;your application code starts here

You can put a push-button between C2CK/RSTb and GND and pushing it will enter 
programming mode. If you leave it alone the application starts at power-up.

 I guess this workaround if unnecessary in newer fixed chips as they can enter
bootloader at startup and go into programming-mode (address $7E20 in 32k UB2)
when a given pin is held low for a period. These pins are defined for every
chips in AN945 bootloader appnote. (3.7, 3.0, etc.)
 The appnote also describes a tool 'efm8load' and AN945SW.zip holds the source
for this program beside the bootloader hex files and sources. After some tweak-
work I could start efm8load.py but unfortunately there's only an .exe (win32)
version of the other tool 'hex2boot' and no source so we can't generate the
required .efm8 bootrecord file in Linux. Maybe using Wine, but who wants to
install that big package just for this? I created a bootrecord by hand but it
didn't work (I got a ? assuming an error) while chiprog worked. That's about it.
Note: Partial programming leaves the bootloader intact, no full chip-erase.

The connections needed for direct USB-bootloader programming (no FTDI needed):
(This is a bus-powered setup. If you have 3.3V supply connections differ. The
 bypass capacitor at Vdd is important to have stable 3.3V.)
                  
                   ,-------------------
               ,---|Vbus (senses USB)
               |   | 
      ,---*----*---|Vregin (if bus-povered)
      |   |        | 
      | (===) ,----|Vdd (3.3V output from internal regulator)
 USB  |   |   |    |
      |   |  ===   |      EFM8UB2/etc MCU
+5V O-'   |   |1uF |      ---------------
          |   |    |
 D- O--------------|D- (USB data minus)
          |   |    |
 D+ O--------------|D+ (USB data plus)
          |   |    |
GND O-*---*---*----|GND
      |            |
      |    ----    |
      `----o  o----|RSTb (C2D) for faulty bootloader-logic, or pin3.7/3.0/etc 
      Push-button  `-------------------

command example: chiprog w efm8usb example.bin 0



                  Lattice iCE40 configuration/programming
                  ---------------------------------------

 The Lattice iCE40 FPGA chips need a bit more connections to chiprog, the full
set of pins may be utilized. It's important (unfortunately) to have 2.5V Vpp
supply even when one-time programmable (OTP) NVCM (non-volatile config-memory)
is not modified. It seems though a simple diode from the 3.3V supply to Vpp is
adequate to provide the 2.5 (max. 2.64V!) for this task. Maybe NVCM programming
requires a stable 2.5V by a proper regulator, I couldn't test it yet as I don't
have enough information how NVCM programming is done for the iCE40. 
Beside the 3.3V VccIO the core should be supplied with 1.2V. A cheap regulator
like Micrel MIC5365-1.2YC5-TR worked quite OK for me. (Needs output capacitor 
and at startup it still gave bigger than 1.2V, 2 diodes in series between GND
and Vcc supply-rail might protect the FPGA core in case LDO behaves abnormal.)
 Writing the volatile CRAM (config-SRAM) of the FPGA is of course just for 
prototyping and development, in the end system it should keep its wiring, and 
that can be solved by SPI flash (mentioned above) or NVCM, or it can be 
programmed by an MCU through SPI in a similar way chiprog does it from a PC. 
(The protocol is explained fairly well in Lattice's PDF about programming and
configuring iCE40 FPGA, but They're less verbose on NVCM and how to read iCE40.)
 Interestingly it doesn't seem to matter that minimal clock-frequency is 1MHz
in iCE40 datasheet. The FTDI chip has this clock frequency (baudrate) by default
but it pauses in the clock due to the nature of the USB port (around 1ms waits 
between datachunks) but it seems fine. Who knows, this may worsen in the future,
but I suppose the clock-high/low times are the correct details and there is no
maximal value given in the datasheet.
Note: Send the whole bitstream to iCE40! Partial flashing has no point on FPGAs.

Connection of the iCE40 FPGA to chiprog's pin-headers:
(No need for external pullup-resistors on CRESET and CDONE because FTDI has them
 built inside. No need for resistor towards GND on SPI_SS, chiprog's CHIPSELECT
 pin can drive it low when needed during CRESET transition.)

                              .-------------
                              |
       GND O------------------|GND (may be more connected GND pins on the chip)
                              |
    DATAIN O<-----------------|SPI_SO (only needed for NVCM programming / read)
                              |        (but needs to be connected)
     CLOCK O>-----------------|SPI_SCK
                              |
   DATAOUT O>-----------------|SPI_SI
                              |
 CDONE(GP3)O<-----------------|CDONE (high-active, FPGA asserts when prog.ready)
                              |
CHIPSELECT O>-----------------|SPI_SS_B (low:slave)
                              |
CRESET(GP1)O>-----------------|CRESET# (low-active)
                              |
    3V3OUT O--*----*-------*--|Vcc_SPI (supply rail for SPI clock and data pins)
              |    |       |  |
              |    |       `--|VccIO2 (supply for CRESET and CDONE in IO bank 2)
              |    | 1N4148   |       (other VccIOs to be connected if needed)
              |    `--|>|-----|Vpp (2.5V NVCM/programming supply-input)
              |  ___          |
              `-|LDO|------*--|Vcc (1.2V FPGA-core power supply input)
               	`---'1.2V  |  |
                  |       === `------------------
                 ---   1uF |
                 GND      ---
                          GND 

code example: chiprog w ice40 counter.bin 0

 I need to mention a tool called 'iceprog' which is a part of IceStorm project.
I already implemented LP384 support in IceStorm with guidance of Clifford Wolf.
This project is kinda Holy Grail for linux-based FPGA development for people
like me who want to take control over every bits and pieces in fast commandline.


                         Lattice iCE40 DBUS-only
                         -----------------------

 When my CBUS lines in the FT230XS went wrong, they couldn't switch to output 
mode. For this I solved the iCE40 programming by using only DBUS lines, until 
a new FT230XS arrived. (I added the 100 Ohm resistors to the new one's outputs 
to hopefully prevent failures like this in the future.)
 The connections look like this: (SS is always at 0V by 1kOhm resistor, SDO of 
the FPGA is not used so not connected, CDONE is connected in place of it. CRESET
is driven now by DBUS3 line of the FT230XS, which was unconnected originally.) 

                              .-------------
                              |
       GND O---------*--------|GND (may be more connected GND pins on the chip)
                     |        |
    DATAIN O<------------.    |SPI_SO not connected  
                     |   |    |                                    
     CLOCK O>-----------------|SPI_SCK
                     |   |    |
   DATAOUT O>-----------------|SPI_SI
                     |   |    |
           O         |   `----|CDONE (high-active, FPGA asserts when prog.ready)
                     |1kOhm   |
           O      GND`--/\/\--|SPI_SS_B (low:slave)
                              |
  DBUS3!!! O>-----------------|CRESET# (low-active)
                              |
    3V3OUT O--*----*-------*--|Vcc_SPI (supply rail for SPI clock and data pins)
              |    |       |  |
              |    |       `--|VccIO2 (supply for CRESET and CDONE in IO bank 2)
              |    | 1N4148   |       (other VccIOs to be connected if needed)
              |    `--|>|-----|Vpp (2.5V NVCM/programming supply-input)
              |  ___          |
              `-|LDO|------*--|Vcc (1.2V FPGA-core power supply input)
               	`---'1.2V  |  |
                  |       === `------------------
                 ---   1uF |
                 GND      ---
                          GND 

code example: chiprog w ice40dbus whatever.bin 0 debug




                              Closing words
                              -------------

 Future plans? I don't have yet. I created this tool to save money by not buying
all manufacturers' programming kits/cables for a bigger sum of money. If others
benefit from it too that's an icing on the cake. It turned out that FTDI chips
are not the best for SiLabs C2 programming due to the slowness of the USB port
for different interactive/polling and sensitive timing (microsecond-oriented) 
tasks. That's why Cypress EZ USB (FX/FX2/FXLP) chips and USB-equipped micro-
controllers are much better as an universal programmer. If they have enough me-
mory to hold the bitstream/binary file entirely (like 16kB RAM in CY7C68013),
then it doesn't matter how jittering the USB bus transfer was, the MCU core can
program the target chip in any timing it wants, if it has the programmer code.
 So actually I have plans for the future, but not for the FTDI chip but a bit
more expensive (~3USD) Cypress chips or microcontrollers like Universal Bee or
Atmel SAM4S (or PICkit2) to be used as programmer for Silicon Labs chips. If I
get a new chip-type that can be programmed fast enough with FTDI, I'll implement
it with this chiprog FT230XS, if not, I'll make it with the more advanced chips.
 I asked Lattice for NVCM programming details but they wanted me to sign a NDA
(non-disclosure agreement) which is not compatible with my opensource aims. So
we need to reverse-engineer the NVCM protocol but it seems iCEcube2 generates
some files with '.nvcm' extension beside the bitstream file, which contains the
commands for NVCM programming and seems not too hard for reverse-engineering.
 I hope I'll have luck and will be able to program the iCE40 FPGAs permanently
in the end, armed with the info...

Anyway, good luck, I hope you'll have success with chiprog on your setup as much
as I had. Of course I don't take responsibility for any negative effects/damage
which you may cause to your equipments/parts while using this tool... But I'll
try to lend a hand for a solution if I'm asked for help. On the other hand if
you can give me feedback about working chip-types/etc, it will be welcome.

 The source code is nothing near beautiful but I don't have the time to polish
all bits and pieces of it. If anyone wants to bring it further, feel free to
modify the code to your needs. License is WTF, so do what the fuck you want with
this code, literally. Yet I'd be glad if you mention my name as the original 
author... If you're an average user and don't want to modify this code I advise
to use the precompiled binary in this folder as GCC and other compilers change
from time to time and may not compile my code exactly as my version (gcc-5.4.0).



       2017 Hermit Software (Mihaly Horvath)   http://hermit.sidrip.com
