const uint32_t mask3 = STATUS_DONE_BIT | STATUS_FAIL_FLAG;
return lattice_verify_status_register_u32(lattice_device, out, expected2, mask3, false);
}
+
+int lattice_ecp5_connect_spi_to_jtag(struct lattice_pld_device *pld_device_info)
+{
+ if (!pld_device_info)
+ return ERROR_FAIL;
+
+ struct jtag_tap *tap = pld_device_info->tap;
+ if (!tap)
+ return ERROR_FAIL;
+
+ if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) == PROGRAM_SPI)
+ return ERROR_OK;
+
+ // erase configuration
+ int retval = lattice_preload(pld_device_info);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = lattice_ecp5_enable_sram_programming(tap);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = lattice_ecp5_erase_sram(tap);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = lattice_ecp5_exit_programming_mode(tap);
+ if (retval != ERROR_OK)
+ return retval;
+
+ // connect jtag to spi pins
+ retval = lattice_set_instr(tap, PROGRAM_SPI, TAP_IDLE);
+ if (retval != ERROR_OK)
+ return retval;
+
+ struct scan_field field;
+ uint8_t buffer[2] = {0xfe, 0x68};
+ field.num_bits = 16;
+ field.out_value = buffer;
+ field.in_value = NULL;
+ jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
+
+ return jtag_execute_queue();
+}
+
+int lattice_ecp5_disconnect_spi_from_jtag(struct lattice_pld_device *pld_device_info)
+{
+ if (!pld_device_info)
+ return ERROR_FAIL;
+
+ struct jtag_tap *tap = pld_device_info->tap;
+ if (!tap)
+ return ERROR_FAIL;
+
+ /* Connecting it again takes way too long to do it multiple times for writing
+ a bitstream (ca. 0.4s each access).
+ We just leave it connected since SCS will not be active when not in shift_dr state.
+ So there is no need to change instruction, just make sure we are not in shift dr state. */
+ jtag_add_runtest(2, TAP_IDLE);
+ return jtag_execute_queue();
+}
+
+int lattice_ecp5_get_facing_read_bits(struct lattice_pld_device *pld_device_info, unsigned int *facing_read_bits)
+{
+ if (!pld_device_info)
+ return ERROR_FAIL;
+
+ *facing_read_bits = 0;
+
+ return ERROR_OK;
+}
int lattice_ecp5_read_usercode(struct jtag_tap *tap, uint32_t *usercode, uint32_t out);
int lattice_ecp5_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode);
int lattice_ecp5_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file);
+int lattice_ecp5_connect_spi_to_jtag(struct lattice_pld_device *pld_device_info);
+int lattice_ecp5_disconnect_spi_from_jtag(struct lattice_pld_device *pld_device_info);
+int lattice_ecp5_get_facing_read_bits(struct lattice_pld_device *pld_device_info, unsigned int *facing_read_bits);
#endif /* OPENOCD_PLD_ECP5_H */
if (pld_device_info->family == LATTICE_ECP2 || pld_device_info->family == LATTICE_ECP3)
return lattice_ecp2_3_connect_spi_to_jtag(pld_device_info);
+ else if (pld_device_info->family == LATTICE_ECP5)
+ return lattice_ecp5_connect_spi_to_jtag(pld_device_info);
return ERROR_FAIL;
}
if (pld_device_info->family == LATTICE_ECP2 || pld_device_info->family == LATTICE_ECP3)
return lattice_ecp2_3_disconnect_spi_from_jtag(pld_device_info);
+ else if (pld_device_info->family == LATTICE_ECP5)
+ return lattice_ecp5_disconnect_spi_from_jtag(pld_device_info);
return ERROR_FAIL;
}
if (pld_device_info->family == LATTICE_ECP2 || pld_device_info->family == LATTICE_ECP3)
return lattice_ecp2_3_get_facing_read_bits(pld_device_info, facing_read_bits);
+ else if (pld_device_info->family == LATTICE_ECP5)
+ return lattice_ecp5_get_facing_read_bits(pld_device_info, facing_read_bits);
return ERROR_FAIL;
}
source [find fpga/lattice_ecp5.cfg]
-#openocd -f board/ecp5_evaluation.cfg -c "init" -c "pld load 0 shared_folder/ecp5_blinker_impl1.bit"
+#openocd -f board/ecp5_evaluation.cfg -c "init" -c "pld load ecp5.pld shared_folder/ecp5_blinker_impl1.bit"
#ipdbg -start -tap ecp5.tap -hub 0x32 -port 5555 -tool 0
+
+set JTAGSPI_CHAIN_ID ecp5.pld
+source [find cpld/jtagspi.cfg]
+
+#jtagspi_init ecp5.pld "" -1
+#jtagspi_program shared_folder/ecp5_blinker_impl1_slow.bit 0