Merge pull request #218 from ejdan/efinix-jtag

efinix: support loading a bitstream to SRAM using only JTAG pins (no GPIO)
This commit is contained in:
Gwenhael Goavec-Merou 2022-05-02 07:05:37 +02:00 committed by GitHub
commit 2bbf372a1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 14 additions and 10 deletions

View File

@ -42,6 +42,8 @@ Efinix::Efinix(Jtag* jtag, const std::string &filename,
_spi(NULL), _rst_pin(0), _done_pin(0), _cs_pin(0), _spi(NULL), _rst_pin(0), _done_pin(0), _cs_pin(0),
_oe_pin(0) _oe_pin(0)
{ {
_ftdi_jtag = reinterpret_cast<FtdiJtagMPSSE *>(jtag);
/* WA: before using JTAG, device must restart with cs low /* WA: before using JTAG, device must restart with cs low
* but cs and rst for xyloni are connected to interfaceA (ie SPI) * but cs and rst for xyloni are connected to interfaceA (ie SPI)
* TODO: some boards have cs, reset and done in both interface * TODO: some boards have cs, reset and done in both interface
@ -56,7 +58,8 @@ Efinix::Efinix(Jtag* jtag, const std::string &filename,
} else if (board_name == "titanium_ti60_f225_jtag") { } else if (board_name == "titanium_ti60_f225_jtag") {
spi_board_name = "titanium_ti60_f225"; spi_board_name = "titanium_ti60_f225";
} else { } else {
throw std::runtime_error("Error: unknown board name"); printInfo("Using efinix JTAG interface (no GPIO)");
return;
} }
/* 2: retrieve spi board */ /* 2: retrieve spi board */
@ -73,7 +76,6 @@ Efinix::Efinix(Jtag* jtag, const std::string &filename,
/* 5: open SPI interface */ /* 5: open SPI interface */
_spi = new FtdiSpi(spi_cable->config, spi_board->spi_pins_config, _spi = new FtdiSpi(spi_cable->config, spi_board->spi_pins_config,
jtag->getClkFreq(), verbose > 0); jtag->getClkFreq(), verbose > 0);
_ftdi_jtag = reinterpret_cast<FtdiJtagMPSSE *>(jtag);
/* 6: configure pins direction and default state */ /* 6: configure pins direction and default state */
_spi->gpio_set_output(_oe_pin | _rst_pin | _cs_pin); _spi->gpio_set_output(_oe_pin | _rst_pin | _cs_pin);
@ -111,7 +113,7 @@ void Efinix::program(unsigned int offset, bool unprotect_flash)
if (_file_extension == "hex") { if (_file_extension == "hex") {
bit = new EfinixHexParser(_filename); bit = new EfinixHexParser(_filename);
} else { } else {
if (offset == 0) { if (offset == 0 && _spi) {
printError("Error: can't write raw data at the beginning of the flash"); printError("Error: can't write raw data at the beginning of the flash");
throw std::exception(); throw std::exception();
} }
@ -225,13 +227,15 @@ void Efinix::programJTAG(uint8_t *data, int length)
int xfer_len = 512, tx_end; int xfer_len = 512, tx_end;
uint8_t tx[512]; uint8_t tx[512];
/* trion has to be reseted with cs low */ if(_spi) {
_spi->gpio_clear(_oe_pin | _cs_pin | _rst_pin); /* trion has to be reseted with cs low */
usleep(30000); _spi->gpio_clear(_oe_pin | _cs_pin | _rst_pin);
_spi->gpio_set(_rst_pin); // assert RST usleep(30000);
usleep(50000); _spi->gpio_set(_rst_pin); // assert RST
_spi->gpio_set(_oe_pin | _rst_pin); // release OE usleep(50000);
usleep(50000); _spi->gpio_set(_oe_pin | _rst_pin); // release OE
usleep(50000);
}
/* force run_test_idle state */ /* force run_test_idle state */
_jtag->set_state(Jtag::RUN_TEST_IDLE); _jtag->set_state(Jtag::RUN_TEST_IDLE);