SPI Programming Sequence for iCE40HX8K-EVB

Started by cdan, April 03, 2026, 01:04:38 PM

Previous topic - Next topic

cdan

I am using an external programmer (pico-serprog) to program the iCE40HX8K via SPI. Programming only works if C_RESET is pulled LOW before powering on the board. If C_RESET is pulled LOW after power is already applied, SPI communication fails.

Can you confirm: When C_RESET is pulled LOW while the board is already powered on, do the SDI, SDO, and SCK pins on the FPGA chip enter high-impedance (Hi-Z) state? Is there a specific reset/power-on sequence required for the iCE40 to enter SPI programming mode?

LubOlimex

Yes, this is expected way to reliably be able to program via SPI. This is mentioned in our guides, for example when using OLIMEXINO-32U4 to re-program the board via Arduino IDE:

https://github.com/OLIMEX/iCE40HX1K-EVB/tree/master/programmer/olimexino-32u4%20firmware

Notice this part in the README.md:

"BUT+RST to start USB to Serial Hold BUT down until last restart, i.e. for a rather long time. Think of BUT as a shift-button to RST, but that must be held down a long time after RST has been released.

This is useful when developing FPGA-projects that use serial communication with the computer that you used to program it with. You don't have to buy an extra USB to serial converter or use an extra USB cable or port."
Technical support and documentation manager at Olimex

olin

#2
Hi cdan,

can you clarify what you try to do? Is it:
a) program the Flash IC on iCE40HX8K via SPI?
or
b) execute the FPGA bitstream on iCE40HX8K via SPI?

These are 2 different things.
If you do option b) you need to swap MOSI and MISO lines on your MCU.
Also, to execute bitstream you need to keep the SPI_CS low BEFORE you raise
the C_RESET pin High (during FPGA reset), or else the FPGA will try to use Flash IC to read the bitstream from.

Swapping MISO and MOSI lines is easy on some MCUs (like ESP32) because it is software defined. On others MCUs that is not so simple, and Olimex designers though about it, and added a hardware option on their EVB board to swap MISO / MOSI lines. See note 2 on the schematic, it says:
"2. When iCE40HX8K Direct SRAM programming is used, unmount R9 and populate R19!"
That seems like a good option, but it is quite hard for a hobbyist with intermediate soldering skills to solder 0201 resistor in a tiny space. The 2 resistors (R9/R19) should have been designed as 0805 (or at least 0603) for that option to be useful.

cdan

Hello,
sorry for the late response.

LubOlimex, thank you for the confirmation.

olin,
Quotecan you clarify what you try to do?
a) program the Flash IC on iCE40HX8K via SPI?
Yes, I have a Raspberry Pi Pico on which I run a modified version of the https://github.com/stacksmashing/pico-serprog

My modification implements the S_CMD_S_PIN_STATE command plus it pulls CRESET down before acquiring the bus and pulls it back high after releasing the bus.

I am using flashrom to read/write the Flash IC
flashrom -V -p serprog:dev=/dev/tty.usbmodem1301:4800 ...
The issue I have is that the communication between the iCE40HX8K board and my Pico is working as expected (I can read/write) if I first remove the power from iCE40HX8K, pull CRESET down then apply the power to iCE40HX8K.

If CRESET is pulled down while the iCE40HX8K board is powered on, the SPI communication stops working. Probing the SPI bus with a logic analyzer, during this setup, shows garbage being read from the Flash IC.

My iCE40HX8K is Rev. B

Regards,
Dan

LubOlimex

Maybe there is some parasitic powering via the SPI lines.
Technical support and documentation manager at Olimex