Skip to content

Commit

Permalink
jtagspi/pld: add support from lattice certus driver
Browse files Browse the repository at this point in the history
Provide	jtagspi	with specific procedures to be able to
use jtagspi for	programming spi-flash devices on lattice
certus and certus po devices.

Change-Id: I6a8ec16be78f86073a4ef5302f6241185b08e1c6
Signed-off-by: Daniel Anselmi <[email protected]>
Reviewed-on: https://review.openocd.org/c/openocd/+/7825
Tested-by: jenkins
Reviewed-by: Antonio Borneo <[email protected]>
  • Loading branch information
danselmi authored and borneoa committed Sep 23, 2023
1 parent 536f2a9 commit 3020270
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 0 deletions.
73 changes: 73 additions & 0 deletions src/pld/certus.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,76 @@ int lattice_certus_load(struct lattice_pld_device *lattice_device, struct lattic

return lattice_certus_exit_programming_mode(tap);
}

int lattice_certus_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_certus_enable_programming(tap);
if (retval != ERROR_OK)
return retval;

retval = lattice_certus_erase_device(pld_device_info);
if (retval != ERROR_OK) {
LOG_ERROR("erasing device failed");
return retval;
}

retval = lattice_certus_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_certus_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_certus_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;
}
3 changes: 3 additions & 0 deletions src/pld/certus.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,8 @@ int lattice_certus_read_status(struct jtag_tap *tap, uint64_t *status, uint64_t
int lattice_certus_read_usercode(struct jtag_tap *tap, uint32_t *usercode, uint32_t out);
int lattice_certus_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode);
int lattice_certus_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file);
int lattice_certus_connect_spi_to_jtag(struct lattice_pld_device *pld_device_info);
int lattice_certus_disconnect_spi_from_jtag(struct lattice_pld_device *pld_device_info);
int lattice_certus_get_facing_read_bits(struct lattice_pld_device *pld_device_info, unsigned int *facing_read_bits);

#endif /* OPENOCD_PLD_CERTUS_H */
6 changes: 6 additions & 0 deletions src/pld/lattice.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,8 @@ static int lattice_connect_spi_to_jtag(struct pld_device *pld_device)
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);
else if (pld_device_info->family == LATTICE_CERTUS)
return lattice_certus_connect_spi_to_jtag(pld_device_info);

return ERROR_FAIL;
}
Expand All @@ -376,6 +378,8 @@ static int lattice_disconnect_spi_from_jtag(struct pld_device *pld_device)
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);
else if (pld_device_info->family == LATTICE_CERTUS)
return lattice_certus_disconnect_spi_from_jtag(pld_device_info);

return ERROR_FAIL;
}
Expand All @@ -396,6 +400,8 @@ static int lattice_get_stuff_bits(struct pld_device *pld_device, unsigned int *f
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);
else if (pld_device_info->family == LATTICE_CERTUS)
return lattice_certus_get_facing_read_bits(pld_device_info, facing_read_bits);

return ERROR_FAIL;
}
Expand Down
8 changes: 8 additions & 0 deletions tcl/board/certuspro_evaluation.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,11 @@ transport select jtag
adapter speed 10000

source [find fpga/lattice_certuspro.cfg]

#openocd -f board/certuspro_evaluation.cfg -c "init" -c "pld load certuspro.pld shared_folder/certuspro_blinker_impl_1.bit"

set JTAGSPI_CHAIN_ID certuspro.pld
source [find cpld/jtagspi.cfg]

#jtagspi_init certuspro.pld "" -1
#jtagspi_program shared_folder/certuspro_blinker_impl1.bit 0

0 comments on commit 3020270

Please sign in to comment.