Hi!
The following patch adds support to configure Lattice iCE40 FPGAs
(formerly Silicon Blue parts). The support is to add support for the SPI
flash memories attached to the FPGA.
iCE40 FPGAs read its configuration from an SPI memory.
This patch should support the HW-USBN-2B Lattice cable, but I used a
generic FTDI FT2232 cable.
It works very well for the iCE40 Blink Evaluation Kit. This kit have an
M25P10-A SPI flash.
Note that Lattice provides a tool for free, but I had problems with the
command line version of the tool. Not to mention that the GUI version
takes 1 minute, 6 seconds to configure the memory and flashrom 6 seconds ;-)
About the patch:
- The patch is for ft2232_spi.c file, it adds a new cable type to the
ft2232_spi driver.
- The type is named ice40
- Lattice's cable used GPIOL0 as CS (named SS), for this reason the
patch uses this pin.
- During the flash configuration the FPGA must in reset state. GPIOL3
controls the RESET line (active low), this is the same line used by
Lattice cable.
- Before even trying to detect a memory you must wake-up it. This is
because the FPGA puts the memory to sleep. I know it sound a little bit
crazy to send a command to a memory that you don't even know is there,
but you can't detect it (read ID commands are ignored when the memory is
in deep power down mode).
- At exit the patch puts the memory to sleep and disconnects the cable.
This releases the reset and hence the FPGA boots from the memory.
Ideally you should check if the FPGA successfully loaded the memory
content. But for this you need to read the CDONE line, lamentably this
line can't be accessed in the Blink kit.
Is this patch acceptable?
Regards, SET
--
Ing. Salvador Eduardo Tropea http://utic.inti.gob.ar/
INTI - Micro y Nanoelectrónica (CMNB) http://www.inti.gob.ar/
Unidad Técnica Sistemas Inteligentes Av. General Paz 5445
Tel: (+54 11) 4724 6300 ext. 6919 San Martín - B1650KNA
FAX: (+54 11) 4754 5194 Buenos Aires * Argentina
Index: ft2232_spi.c
===================================================================
--- ft2232_spi.c (revisión: 1955)
+++ ft2232_spi.c (copia de trabajo)
@@ -102,6 +102,11 @@
static uint8_t cs_bits = 0x08;
static uint8_t pindir = 0x0b;
static struct ftdi_context ftdic_context;
+/* SPI configuration memory for iCE40 FPGAs */
+static char ice40_mode = 0;
+/* iCE40 memory commands */
+#define RELEASE_FROM_POWER_DOWN 0xAB
+#define DEEP_POWER_DOWN 0xB9
static const char *get_ft2232_devicename(int ft2232_vid, int ft2232_type)
{
@@ -168,6 +173,28 @@
.write_aai = default_spi_write_aai,
};
+/* Put the data bits in the shutdown state. */
+static int ice40_deinit(void *ftdic)
+{
+ unsigned char buf[4];
+
+ /* Put the memory to sleep, saves power */
+ msg_pdbg("Memory power down\n");
+ buf[0] = DEEP_POWER_DOWN;
+ if (ft2232_spi_send_command(NULL,1,0,buf,NULL))
+ return -1;
+
+ /* Disconnect the cable to avoid contention */
+ msg_pdbg("Set data bits, cable disable\n");
+ buf[0] = SET_BITS_LOW;
+ buf[1] = 0;
+ buf[2] = 0; /* All inputs => HiZ */
+ if (send_buf((struct ftdi_context *)ftdic, buf, 3))
+ return -1;
+
+ return 0;
+}
+
/* Returns 0 upon success, a negative number upon errors. */
int ft2232_spi_init(void)
{
@@ -273,6 +300,22 @@
} else if (!strcasecmp(arg, "google-servo-v2-legacy")) {
ft2232_vid = GOOGLE_VID;
ft2232_type = GOOGLE_SERVO_V2_PID0;
+ } else if (!strcasecmp(arg, "ice40")) {
+ /* HW-USBN-2B or generic FTDI cable */
+ ft2232_type = FTDI_FT2232H_PID;
+ channel_count = 2;
+ /* The IOL3 pin is used as system reset (needed to disable the FPGA)
+ * IOL0 pin is used instead of CS, called SS
+ * value: 0x10 #RST=low, SS=high, DI=low, DO=low, SK=low
+ * dir: 0x93 #RST=output, SS=output, DI=input, DO=output, SK=output */
+ cs_bits = 0x10;
+ pindir = 0x93;
+ ice40_mode = 1;
+ if (register_shutdown(ice40_deinit,ftdic)) {
+ msg_perr("Error: Unable to register shutdown sequence.\n");
+ return -9;
+ }
+
} else {
msg_perr("Error: Invalid device type specified.\n");
free(arg);
@@ -420,6 +463,14 @@
register_spi_master(&spi_master_ft2232);
+ /* iCE40 mode: memory wake-up */
+ if (ice40_mode) {
+ msg_pdbg("Memory wake-up\n");
+ buf[0] = RELEASE_FROM_POWER_DOWN;
+ if (ft2232_spi_send_command(NULL,1,0,buf,NULL))
+ msg_perr("Unable to send wake-up command.\n");
+ }
+
return 0;
ftdi_err:
_______________________________________________
flashrom mailing list
flashrom@flashrom.org
https://www.flashrom.org/mailman/listinfo/flashrom