jtagspi/pld: add support from lattice ecp5 driver
Provide jtagspi with specific procedures to be able to use jtagspi for programming spi-flash devices on lattice ecp5 devices. Change-Id: I4a4a60f21d7e8685a5b8320b9c6ebdc2693bbd21 Signed-off-by: Daniel Anselmi <danselmi@gmx.ch> Reviewed-on: https://review.openocd.org/c/openocd/+/7824 Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Tested-by: jenkins
This commit is contained in:
parent
2b99846ab6
commit
536f2a9f2a
|
@ -205,3 +205,74 @@ int lattice_ecp5_load(struct lattice_pld_device *lattice_device, struct lattice_
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -14,5 +14,8 @@ int lattice_ecp5_read_status(struct jtag_tap *tap, uint32_t *status, uint32_t ou
|
|||
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 */
|
||||
|
|
|
@ -355,6 +355,8 @@ static int lattice_connect_spi_to_jtag(struct pld_device *pld_device)
|
|||
|
||||
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;
|
||||
}
|
||||
|
@ -372,6 +374,8 @@ static int lattice_disconnect_spi_from_jtag(struct pld_device *pld_device)
|
|||
|
||||
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;
|
||||
}
|
||||
|
@ -390,6 +394,8 @@ static int lattice_get_stuff_bits(struct pld_device *pld_device, unsigned int *f
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#define ISC_ERASE 0x0E
|
||||
#define ISC_DISABLE 0x26
|
||||
#define PROGRAM_SPI 0x3A
|
||||
#define LSC_READ_STATUS 0x3C
|
||||
#define LSC_INIT_ADDRESS 0x46
|
||||
#define LSC_BITSTREAM_BURST 0x7A
|
||||
|
|
|
@ -15,5 +15,11 @@ adapter speed 6000
|
|||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue