Comments
Patch
===================================================================
@@ -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: