xilinx: adapts flow_disable/flow_enable for xc3s, adding custom method to load bitstream for xc3s
This commit is contained in:
parent
386f89ea3a
commit
9243a21fe2
120
src/xilinx.cpp
120
src/xilinx.cpp
|
|
@ -31,7 +31,7 @@ Xilinx::Xilinx(Jtag *jtag, const std::string &filename,
|
||||||
const std::string &device_package, bool verify, int8_t verbose):
|
const std::string &device_package, bool verify, int8_t verbose):
|
||||||
Device(jtag, filename, file_type, verify, verbose),
|
Device(jtag, filename, file_type, verify, verbose),
|
||||||
SPIInterface(filename, verbose, 256, verify),
|
SPIInterface(filename, verbose, 256, verify),
|
||||||
_device_package(device_package)
|
_device_package(device_package), _irlen(6)
|
||||||
{
|
{
|
||||||
if (prg_type == Device::RD_FLASH) {
|
if (prg_type == Device::RD_FLASH) {
|
||||||
_mode = Device::READ_MODE;
|
_mode = Device::READ_MODE;
|
||||||
|
|
@ -52,6 +52,7 @@ Xilinx::Xilinx(Jtag *jtag, const std::string &filename,
|
||||||
|
|
||||||
uint32_t idcode = _jtag->get_target_device_id();
|
uint32_t idcode = _jtag->get_target_device_id();
|
||||||
std::string family = fpga_list[idcode].family;
|
std::string family = fpga_list[idcode].family;
|
||||||
|
_irlen = fpga_list[idcode].irlength;
|
||||||
if (family.substr(0, 5) == "artix") {
|
if (family.substr(0, 5) == "artix") {
|
||||||
_fpga_family = ARTIX_FAMILY;
|
_fpga_family = ARTIX_FAMILY;
|
||||||
} else if (family == "spartan7") {
|
} else if (family == "spartan7") {
|
||||||
|
|
@ -157,6 +158,7 @@ bool Xilinx::zynqmp_init(const std::string &family)
|
||||||
|
|
||||||
_jtag->insert_first(0xdeadbeef, 6);
|
_jtag->insert_first(0xdeadbeef, 6);
|
||||||
_jtag->device_select(1);
|
_jtag->device_select(1);
|
||||||
|
_irlen = 6;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -296,10 +298,14 @@ void Xilinx::program(unsigned int offset, bool unprotect_flash)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_mode == Device::SPI_MODE)
|
if (_mode == Device::SPI_MODE) {
|
||||||
program_spi(bit, offset, unprotect_flash);
|
program_spi(bit, offset, unprotect_flash);
|
||||||
|
} else {
|
||||||
|
if (_fpga_family == SPARTAN3_FAMILY)
|
||||||
|
xc3s_flow_program(bit);
|
||||||
else
|
else
|
||||||
program_mem(bit);
|
program_mem(bit);
|
||||||
|
}
|
||||||
|
|
||||||
delete bit;
|
delete bit;
|
||||||
}
|
}
|
||||||
|
|
@ -321,6 +327,9 @@ bool Xilinx::load_bridge()
|
||||||
try {
|
try {
|
||||||
BitParser bridge(bitname, true, _verbose);
|
BitParser bridge(bitname, true, _verbose);
|
||||||
bridge.parse();
|
bridge.parse();
|
||||||
|
if (_fpga_family == SPARTAN3_FAMILY)
|
||||||
|
xc3s_flow_program(&bridge);
|
||||||
|
else
|
||||||
program_mem(&bridge);
|
program_mem(&bridge);
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
printError(e.what());
|
printError(e.what());
|
||||||
|
|
@ -484,27 +493,116 @@ bool Xilinx::dumpFlash(uint32_t base_addr, uint32_t len)
|
||||||
return SPIInterface::dump(base_addr, len);
|
return SPIInterface::dump(base_addr, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* flow program for xc3s (legacy mode) */
|
||||||
|
/* based on ISE spartan3/data/xx_1532.bsd files */
|
||||||
/* */
|
/* */
|
||||||
/* internal flash (xc95) */
|
|
||||||
/* based on ISE xx_1532.bsd files */
|
bool Xilinx::xc3s_flow_program(ConfigBitstreamParser *bit)
|
||||||
/* */
|
{
|
||||||
|
int byte_length = bit->getLength() / 8;
|
||||||
|
int burst_len = byte_length / 100;
|
||||||
|
uint8_t *data = bit->getData();
|
||||||
|
int tx_len = burst_len * 8, tx_end = Jtag::SHIFT_DR;
|
||||||
|
ProgressBar progress("Flash SRAM", byte_length, 50, _quiet);
|
||||||
|
|
||||||
|
flow_enable();
|
||||||
|
|
||||||
|
if (_jtag->shiftIR(JPROGRAM, _irlen) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* wait until memory cleared (DS099 v3.1 fig.30 p.52) */
|
||||||
|
uint8_t tx_buf = BYPASS, rx_buf;
|
||||||
|
do {
|
||||||
|
if (_jtag->shiftIR(&tx_buf, &rx_buf, _irlen) < 0)
|
||||||
|
return false;
|
||||||
|
} while (!(rx_buf & 0x10)); // wait until INIT
|
||||||
|
|
||||||
|
if (_jtag->shiftIR(JSHUTDOWN, _irlen) < 0)
|
||||||
|
return false;
|
||||||
|
_jtag->toggleClk(16);
|
||||||
|
if (_jtag->shiftIR(CFG_IN, _irlen) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i = 0;byte_length > 0; byte_length-=burst_len, data+=burst_len) {
|
||||||
|
if (burst_len > byte_length) {
|
||||||
|
tx_len = byte_length * 8;
|
||||||
|
tx_end = Jtag::RUN_TEST_IDLE;
|
||||||
|
}
|
||||||
|
if (_jtag->shiftDR(data, NULL, tx_len, tx_end) < 0) {
|
||||||
|
progress.fail();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_jtag->flush();
|
||||||
|
progress.display(i);
|
||||||
|
i+= burst_len;
|
||||||
|
}
|
||||||
|
progress.done();
|
||||||
|
_jtag->toggleClk(1);
|
||||||
|
if (_jtag->shiftIR(JSTART, _irlen) < 0)
|
||||||
|
return false;
|
||||||
|
_jtag->toggleClk(32);
|
||||||
|
if (_jtag->shiftIR(BYPASS, _irlen) < 0)
|
||||||
|
return false;
|
||||||
|
data[0] = 0x00;
|
||||||
|
if (_jtag->shiftDR(data, NULL, 1) < 0)
|
||||||
|
return false;
|
||||||
|
_jtag->toggleClk(1);
|
||||||
|
|
||||||
|
flow_disable();
|
||||||
|
do {
|
||||||
|
if (_jtag->shiftIR(&tx_buf, &rx_buf, _irlen) < 0)
|
||||||
|
return false;
|
||||||
|
} while (!(rx_buf & 0x20)); // wait until DONE
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Xilinx::flow_enable()
|
void Xilinx::flow_enable()
|
||||||
{
|
{
|
||||||
uint8_t xfer_buf = 0x15;
|
uint8_t xfer_buf = 0x15;
|
||||||
_jtag->shiftIR(XC95_ISC_ENABLE, 8);
|
uint8_t isc_enable = XC95_ISC_ENABLE;
|
||||||
_jtag->shiftDR(&xfer_buf, NULL, 6);
|
int drlen = 6, tcklen = 1;
|
||||||
_jtag->toggleClk(1);
|
if (_fpga_family == SPARTAN3_FAMILY) {
|
||||||
|
xfer_buf = 0x00;
|
||||||
|
isc_enable = ISC_ENABLE;
|
||||||
|
drlen = 5;
|
||||||
|
tcklen = 16;
|
||||||
|
}
|
||||||
|
if (_jtag->shiftIR(isc_enable, _irlen) < 0)
|
||||||
|
return;
|
||||||
|
if (_jtag->shiftDR(&xfer_buf, NULL, drlen) < 0)
|
||||||
|
return;
|
||||||
|
_jtag->toggleClk(tcklen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Xilinx::flow_disable()
|
void Xilinx::flow_disable()
|
||||||
{
|
{
|
||||||
_jtag->shiftIR(XC95_ISC_DISABLE, 8);
|
uint8_t isc_disable = XC95_ISC_DISABLE;
|
||||||
_jtag->toggleClk((_jtag->getClkFreq() * 100) / 1000000);
|
int tcklen = ((_jtag->getClkFreq() * 100) / 1000000);
|
||||||
_jtag->shiftIR(BYPASS, 8);
|
|
||||||
|
if (_fpga_family == SPARTAN3_FAMILY) {
|
||||||
|
isc_disable = ISC_DISABLE;
|
||||||
|
tcklen = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_jtag->shiftIR(isc_disable, _irlen) < 0)
|
||||||
|
return;
|
||||||
|
_jtag->toggleClk(tcklen);
|
||||||
|
if (_jtag->shiftIR(BYPASS, _irlen) < 0)
|
||||||
|
return;
|
||||||
|
if (_fpga_family == SPARTAN3_FAMILY) {
|
||||||
|
uint8_t xfer_buf = 0;
|
||||||
|
if (_jtag->shiftDR(&xfer_buf, NULL, 1) < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
_jtag->toggleClk(1);
|
_jtag->toggleClk(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* internal flash (xc95) */
|
||||||
|
/* based on ISE xc9500yy/data/xx_1532.bsd files */
|
||||||
|
/* */
|
||||||
|
|
||||||
bool Xilinx::flow_erase()
|
bool Xilinx::flow_erase()
|
||||||
{
|
{
|
||||||
uint8_t xfer_buf[3] = {0x03, 0x00, 0x00};
|
uint8_t xfer_buf[3] = {0x03, 0x00, 0x00};
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,20 @@ class Xilinx: public Device, SPIInterface {
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
|
||||||
/* -------------- */
|
/* -------------- */
|
||||||
/* xc95 managment */
|
/* xc3s managment */
|
||||||
/* -------------- */
|
/* -------------- */
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief load SRAM (enable ISC, load
|
||||||
|
* and disable ISC
|
||||||
|
* \return false if something wrong
|
||||||
|
*/
|
||||||
|
bool xc3s_flow_program(ConfigBitstreamParser *bit);
|
||||||
|
|
||||||
|
/* ------------------- */
|
||||||
|
/* xc95/xc3s managment */
|
||||||
|
/* ------------------- */
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief enable ISC mode
|
* \brief enable ISC mode
|
||||||
*/
|
*/
|
||||||
|
|
@ -56,6 +67,11 @@ class Xilinx: public Device, SPIInterface {
|
||||||
* \brief disable ISC mode
|
* \brief disable ISC mode
|
||||||
*/
|
*/
|
||||||
void flow_disable();
|
void flow_disable();
|
||||||
|
|
||||||
|
/* -------------- */
|
||||||
|
/* xc95 managment */
|
||||||
|
/* -------------- */
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief erase internal flash
|
* \brief erase internal flash
|
||||||
* \return false if something wrong
|
* \return false if something wrong
|
||||||
|
|
@ -166,6 +182,7 @@ class Xilinx: public Device, SPIInterface {
|
||||||
uint16_t _cpld_nb_col; /**< number of cols in a row */
|
uint16_t _cpld_nb_col; /**< number of cols in a row */
|
||||||
uint16_t _cpld_addr_size; /**< number of addr bits */
|
uint16_t _cpld_addr_size; /**< number of addr bits */
|
||||||
char _cpld_base_name[7]; /**< cpld name (without package size) */
|
char _cpld_base_name[7]; /**< cpld name (without package size) */
|
||||||
|
int _irlen; /**< IR bit length */
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue