add idcode readout
authorGreg Davill <greg.davill@gmail.com>
Sat, 18 Apr 2020 12:20:04 +0000 (21:50 +0930)
committerGreg Davill <greg.davill@gmail.com>
Sat, 18 Apr 2020 12:20:04 +0000 (21:50 +0930)
iceprog.c
lattice_cmds.h [new file with mode: 0644]
mpsse.c

index 0218f0d2ac566880be97240e73d0a2721ca5406d..9a1d11063582e261c014397c997333e17af1a8f8 100644 (file)
--- a/iceprog.c
+++ b/iceprog.c
@@ -42,6 +42,7 @@
 
 #include "mpsse.h"
 #include "jtag.h"
+#include "lattice_cmds.h"
 
 static bool verbose = false;
 
@@ -447,6 +448,43 @@ static void flash_disable_protection()
 
 }
 
+static void print_idcode(uint32_t idcode){
+       for(int i = 0; i < sizeof(ecp_devices)/sizeof(struct ecp_device_id); i++){
+               if(idcode == ecp_devices[i].device_id)
+               {
+                       printf("IDCODE: 0x%08x (%s)\n", idcode ,ecp_devices[i].device_name);
+                       return;
+               }
+       }
+       printf("IDCODE: 0x%08x does not match :(\n", idcode);
+}
+
+static void read_idcode(){
+
+       uint8_t data_in[4] = {0,0,0,0};
+       uint8_t data_out[4] = {0,0,0,0};
+
+       data_in[0] = READ_ID;
+       jtag_go_to_state(STATE_SHIFT_IR);
+       jtag_tap_shift(data_in, data_out, 8, true);
+
+       data_in[0] = 0;
+       jtag_go_to_state(STATE_SHIFT_DR);
+       jtag_tap_shift(data_in, data_out, 32, true);
+
+       uint32_t idcode = 0;
+
+
+
+       for(int i = 0; i< 4; i++)
+               idcode = data_out[i] << 24 | idcode >> 8;
+
+       fprintf(stderr, "IDCODE: %08x\n", idcode);
+
+       print_idcode(idcode);
+}
+
+
 // ---------------------------------------------------------
 // iceprog implementation
 // ---------------------------------------------------------
@@ -821,24 +859,9 @@ int main(int argc, char **argv)
 
        mpsse_jtag_init();
 
-       jtag_go_to_state(STATE_SHIFT_IR);
-
-       uint8_t data_in[4] = {0,0,0,0};
-       uint8_t data_out[4] = {0,0,0,0};
-
-       data_in[0] = 0xE0;
-       jtag_tap_shift(data_in, data_out, 8, true);
-       fprintf(stderr, " %02x\n", data_out[0]);
+       read_idcode();
 
-       jtag_go_to_state(STATE_SHIFT_DR);
-       jtag_tap_shift(data_in, data_out, 32, true);
 
-
-       fprintf(stderr, "Data: ");
-       for(int i = 0; i< 4; i++)
-               fprintf(stderr, " %02x", data_out[i]);
-       fprintf(stderr, "\n");
-       
        //flash_release_reset();
        usleep(100000);
 
diff --git a/lattice_cmds.h b/lattice_cmds.h
new file mode 100644 (file)
index 0000000..5e42d6c
--- /dev/null
@@ -0,0 +1,65 @@
+
+#include <stdint.h>
+
+/* Not sure if all of these are applicable to the JTAG interface */
+enum lattice_cmd
+{
+       ISC_NOOP = 0xFF, /* 0 bits - Non-operation */
+       READ_ID = 0xE0, /* 24 bits - Read out the 32-bit IDCODE of the device */
+       USERCODE = 0xC0, /* 24 bits - Read 32-bit usercode */
+       LSC_READ_STATUS = 0x3C, /* 24 bits - Read out internal status */
+       LSC_CHECK_BUSY = 0xF0, /* 24 bits - Read 1 bit busy flag to check the command execution status */
+       LSC_REFRESH = 0x79, /* 24 bits - Equivalent to toggle PROGRAMN pin */
+       ISC_ENABLE = 0xC6, /* 24 bits - Enable the Offline configuration mode */
+       ISC_ENABLE_X = 0x74, /* 24 bits - Enable the Transparent configuration mode */
+       ISC_DISABLE = 0x26, /* 24 bits - Disable the configuration operation */
+       ISC_PROGRAM_USERCODE = 0xC2, /* 24 bits - Write the 32-bit new USERCODE data to USERCODE register */
+       ISC_ERASE = 0x0E, /* 24 bits - Bulk erase the memory array base on the access mode and array selection */
+       ISC_PROGRAM_DONE = 0x5E, /* 24 bits - Program the DONE bit if the device is in Configuration state. */
+       ISC_PROGRAM_SECURITY = 0xCE, /* 24 bits - Program the Security bit if the device is in Configuration state */
+       LSC_INIT_ADDRESS = 0x46, /* 24 bits - Initialize the Address Shift Register */
+       LSC_WRITE_ADDRESS = 0xB4, /* 24 bits - Write the 16 bit Address Register to move the address quickly */
+       LSC_BITSTREAM_BURST = 0x7A, /* 24 bits - Program the device the whole bitstream sent in as the command operand */
+       LSC_PROG_INCR_RTI = 0x82, /* 24 bits - Write configuration data to the configuration memory frame at current address and post increment the address, Byte 2~0 of the opcode indicate number of the frames included in the operand field */
+       LSC_PROG_INCR_ENC = 0xB6, /* 24 bits - Encrypt the configuration data then write */
+       LSC_PROG_INCR_CMP = 0xB8, /* 24 bits - Decompress the configuration data, then write */
+       LSC_PROG_INCR_CNE = 0xBA, /* 24 bits - Decompress and Encrypt the configuration data, then write */
+       LSC_VERIFY_INCR_RTI = 0x6A, /* 24 bits - Read back the configuration memory frame selected by the address register and post increment the address */
+       LSC_PROG_CTRL0 = 0x22, /* 24 bits - Modify the Control Register 0 */
+       LSC_READ_CTRL0 = 0x20, /* 24 bits - Read the Control Register 0 */
+       LSC_RESET_CRC = 0x3B, /* 24 bits - Reset 16-bit frame CRC register to 0x0000 */
+       LSC_READ_CRC = 0x60, /* 24 bits - Read 16-bit frame CRC register content */
+       LSC_PROG_SED_CRC = 0xA2, /* 24 bits - Program the calculated 32-bit CRC based on configuration bit values only into overall CRC register */
+       LSC_READ_SED_CRC = 0xA4, /* 24 bits - Read the 32-bit SED CRC */
+       LSC_PROG_PASSWORD = 0xF1, /* 24 bits - Program 64-bit password into the non-volatile memory (Efuse) */
+       LSC_READ_PASSWORD = 0xF2, /* 24 bits - Read out the 64-bit password before activated for verification */
+       LSC_SHIFT_PASSWORD = 0xBC, /* 24 bits - Shift in the password to unlock for re-configuration (necessary when password protection feature is active). */
+       LSC_PROG_CIPHER_KEY = 0xF3, /* 24 bits - Program the 128-bit cipher key into Efuse */
+       LSC_READ_CIPHER_KEY = 0xF4, /* 24 bits - Read out the 128-bit cipher key before activated for verification */
+       LSC_PROG_FEATURE = 0xE4, /* 24 bits - Program User Feature, such as Customer ID, I2C Slave Address, Unique ID Header */
+       LSC_READ_FEATURE = 0xE7, /* 24 bits - Read User Feature, such as Customer ID, I2C Slave Address, Unique ID Header */
+       LSC_PROG_FEABITS = 0xF8, /* 24 bits - Program User Feature Bits, such as CFG port and pin persistence, PWD_EN, PWD_ALL, DEC_ONLY, Feature Row Lock etc. */
+       LSC_READ_FEABITS = 0xFB, /* 24 bits - Read User Feature Bits, such as CFH port and pin persistence, PWD_EN, PWD_ALL, DEC_ONLY, Feature Row Lock etc. */
+       LSC_PROG_OTP = 0xF9, /* 24 bits - Program OTP bits, to set Memory Sectors One Time Programmable */
+       LSC_READ_OTP = 0xFA, /* 24 bits - Read OTP bits setting */
+};
+
+
+struct ecp_device_id {
+       const char* device_name;
+       uint32_t    device_id;
+};
+
+const struct ecp_device_id ecp_devices[] =
+{
+       {"LFE5U-12"   , 0x21111043 },
+       {"LFE5U-25"   , 0x41111043 },
+       {"LFE5U-45"   , 0x41112043 },
+       {"LFE5U-85"   , 0x41113043 },
+       {"LFE5UM-25"  , 0x01111043 },
+       {"LFE5UM-45"  , 0x01112043 },
+       {"LFE5UM-85"  , 0x01113043 },
+       {"LFE5UM5G-25", 0x81111043 },
+       {"LFE5UM5G-45", 0x81112043 },
+       {"LFE5UM5G-85", 0x81113043 }
+};
diff --git a/mpsse.c b/mpsse.c
index 5090d7447654287fe1dc58d5d06acb4c0685e40a..736c8070b29f5a806bcc3f4f9c0ece89969410a9 100644 (file)
--- a/mpsse.c
+++ b/mpsse.c
@@ -54,49 +54,6 @@ bool mpsse_ftdic_open = false;
 bool mpsse_ftdic_latency_set = false;
 unsigned char mpsse_ftdi_latency;
 
-/* Not sure if all of these are applicable to the JTAG interface */
-enum lattice_cmd
-{
-       ISC_NOOP = 0xFF, /* 0 bits - Non-operation */
-       READ_ID = 0xE0, /* 24 bits - Read out the 32-bit IDCODE of the device */
-       USERCODE = 0xC0, /* 24 bits - Read 32-bit usercode */
-       LSC_READ_STATUS = 0x3C, /* 24 bits - Read out internal status */
-       LSC_CHECK_BUSY = 0xF0, /* 24 bits - Read 1 bit busy flag to check the command execution status */
-       LSC_REFRESH = 0x79, /* 24 bits - Equivalent to toggle PROGRAMN pin */
-       ISC_ENABLE = 0xC6, /* 24 bits - Enable the Offline configuration mode */
-       ISC_ENABLE_X = 0x74, /* 24 bits - Enable the Transparent configuration mode */
-       ISC_DISABLE = 0x26, /* 24 bits - Disable the configuration operation */
-       ISC_PROGRAM_USERCODE = 0xC2, /* 24 bits - Write the 32-bit new USERCODE data to USERCODE register */
-       ISC_ERASE = 0x0E, /* 24 bits - Bulk erase the memory array base on the access mode and array selection */
-       ISC_PROGRAM_DONE = 0x5E, /* 24 bits - Program the DONE bit if the device is in Configuration state. */
-       ISC_PROGRAM_SECURITY = 0xCE, /* 24 bits - Program the Security bit if the device is in Configuration state */
-       LSC_INIT_ADDRESS = 0x46, /* 24 bits - Initialize the Address Shift Register */
-       LSC_WRITE_ADDRESS = 0xB4, /* 24 bits - Write the 16 bit Address Register to move the address quickly */
-       LSC_BITSTREAM_BURST = 0x7A, /* 24 bits - Program the device the whole bitstream sent in as the command operand */
-       LSC_PROG_INCR_RTI = 0x82, /* 24 bits - Write configuration data to the configuration memory frame at current address and post increment the address, Byte 2~0 of the opcode indicate number of the frames included in the operand field */
-       LSC_PROG_INCR_ENC = 0xB6, /* 24 bits - Encrypt the configuration data then write */
-       LSC_PROG_INCR_CMP = 0xB8, /* 24 bits - Decompress the configuration data, then write */
-       LSC_PROG_INCR_CNE = 0xBA, /* 24 bits - Decompress and Encrypt the configuration data, then write */
-       LSC_VERIFY_INCR_RTI = 0x6A, /* 24 bits - Read back the configuration memory frame selected by the address register and post increment the address */
-       LSC_PROG_CTRL0 = 0x22, /* 24 bits - Modify the Control Register 0 */
-       LSC_READ_CTRL0 = 0x20, /* 24 bits - Read the Control Register 0 */
-       LSC_RESET_CRC = 0x3B, /* 24 bits - Reset 16-bit frame CRC register to 0x0000 */
-       LSC_READ_CRC = 0x60, /* 24 bits - Read 16-bit frame CRC register content */
-       LSC_PROG_SED_CRC = 0xA2, /* 24 bits - Program the calculated 32-bit CRC based on configuration bit values only into overall CRC register */
-       LSC_READ_SED_CRC = 0xA4, /* 24 bits - Read the 32-bit SED CRC */
-       LSC_PROG_PASSWORD = 0xF1, /* 24 bits - Program 64-bit password into the non-volatile memory (Efuse) */
-       LSC_READ_PASSWORD = 0xF2, /* 24 bits - Read out the 64-bit password before activated for verification */
-       LSC_SHIFT_PASSWORD = 0xBC, /* 24 bits - Shift in the password to unlock for re-configuration (necessary when password protection feature is active). */
-       LSC_PROG_CIPHER_KEY = 0xF3, /* 24 bits - Program the 128-bit cipher key into Efuse */
-       LSC_READ_CIPHER_KEY = 0xF4, /* 24 bits - Read out the 128-bit cipher key before activated for verification */
-       LSC_PROG_FEATURE = 0xE4, /* 24 bits - Program User Feature, such as Customer ID, I2C Slave Address, Unique ID Header */
-       LSC_READ_FEATURE = 0xE7, /* 24 bits - Read User Feature, such as Customer ID, I2C Slave Address, Unique ID Header */
-       LSC_PROG_FEABITS = 0xF8, /* 24 bits - Program User Feature Bits, such as CFG port and pin persistence, PWD_EN, PWD_ALL, DEC_ONLY, Feature Row Lock etc. */
-       LSC_READ_FEABITS = 0xFB, /* 24 bits - Read User Feature Bits, such as CFH port and pin persistence, PWD_EN, PWD_ALL, DEC_ONLY, Feature Row Lock etc. */
-       LSC_PROG_OTP = 0xF9, /* 24 bits - Program OTP bits, to set Memory Sectors One Time Programmable */
-       LSC_READ_OTP = 0xFA, /* 24 bits - Read OTP bits setting */
-};
-
 
 // ---------------------------------------------------------
 // MPSSE / FTDI function implementations