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
128
src/xilinx.cpp
128
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):
|
||||
Device(jtag, filename, file_type, verify, verbose),
|
||||
SPIInterface(filename, verbose, 256, verify),
|
||||
_device_package(device_package)
|
||||
_device_package(device_package), _irlen(6)
|
||||
{
|
||||
if (prg_type == Device::RD_FLASH) {
|
||||
_mode = Device::READ_MODE;
|
||||
|
|
@ -52,6 +52,7 @@ Xilinx::Xilinx(Jtag *jtag, const std::string &filename,
|
|||
|
||||
uint32_t idcode = _jtag->get_target_device_id();
|
||||
std::string family = fpga_list[idcode].family;
|
||||
_irlen = fpga_list[idcode].irlength;
|
||||
if (family.substr(0, 5) == "artix") {
|
||||
_fpga_family = ARTIX_FAMILY;
|
||||
} else if (family == "spartan7") {
|
||||
|
|
@ -157,6 +158,7 @@ bool Xilinx::zynqmp_init(const std::string &family)
|
|||
|
||||
_jtag->insert_first(0xdeadbeef, 6);
|
||||
_jtag->device_select(1);
|
||||
_irlen = 6;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -296,10 +298,14 @@ void Xilinx::program(unsigned int offset, bool unprotect_flash)
|
|||
return;
|
||||
}
|
||||
|
||||
if (_mode == Device::SPI_MODE)
|
||||
if (_mode == Device::SPI_MODE) {
|
||||
program_spi(bit, offset, unprotect_flash);
|
||||
else
|
||||
program_mem(bit);
|
||||
} else {
|
||||
if (_fpga_family == SPARTAN3_FAMILY)
|
||||
xc3s_flow_program(bit);
|
||||
else
|
||||
program_mem(bit);
|
||||
}
|
||||
|
||||
delete bit;
|
||||
}
|
||||
|
|
@ -321,7 +327,10 @@ bool Xilinx::load_bridge()
|
|||
try {
|
||||
BitParser bridge(bitname, true, _verbose);
|
||||
bridge.parse();
|
||||
program_mem(&bridge);
|
||||
if (_fpga_family == SPARTAN3_FAMILY)
|
||||
xc3s_flow_program(&bridge);
|
||||
else
|
||||
program_mem(&bridge);
|
||||
} catch (std::exception &e) {
|
||||
printError(e.what());
|
||||
throw std::runtime_error(e.what());
|
||||
|
|
@ -484,27 +493,116 @@ bool Xilinx::dumpFlash(uint32_t base_addr, uint32_t len)
|
|||
return SPIInterface::dump(base_addr, len);
|
||||
}
|
||||
|
||||
/* */
|
||||
/* internal flash (xc95) */
|
||||
/* based on ISE xx_1532.bsd files */
|
||||
/* */
|
||||
/* flow program for xc3s (legacy mode) */
|
||||
/* based on ISE spartan3/data/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()
|
||||
{
|
||||
uint8_t xfer_buf = 0x15;
|
||||
_jtag->shiftIR(XC95_ISC_ENABLE, 8);
|
||||
_jtag->shiftDR(&xfer_buf, NULL, 6);
|
||||
_jtag->toggleClk(1);
|
||||
uint8_t isc_enable = XC95_ISC_ENABLE;
|
||||
int drlen = 6, tcklen = 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()
|
||||
{
|
||||
_jtag->shiftIR(XC95_ISC_DISABLE, 8);
|
||||
_jtag->toggleClk((_jtag->getClkFreq() * 100) / 1000000);
|
||||
_jtag->shiftIR(BYPASS, 8);
|
||||
uint8_t isc_disable = XC95_ISC_DISABLE;
|
||||
int tcklen = ((_jtag->getClkFreq() * 100) / 1000000);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* */
|
||||
/* internal flash (xc95) */
|
||||
/* based on ISE xc9500yy/data/xx_1532.bsd files */
|
||||
/* */
|
||||
|
||||
bool Xilinx::flow_erase()
|
||||
{
|
||||
uint8_t xfer_buf[3] = {0x03, 0x00, 0x00};
|
||||
|
|
|
|||
|
|
@ -45,9 +45,20 @@ class Xilinx: public Device, SPIInterface {
|
|||
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
|
||||
*/
|
||||
|
|
@ -56,6 +67,11 @@ class Xilinx: public Device, SPIInterface {
|
|||
* \brief disable ISC mode
|
||||
*/
|
||||
void flow_disable();
|
||||
|
||||
/* -------------- */
|
||||
/* xc95 managment */
|
||||
/* -------------- */
|
||||
|
||||
/*!
|
||||
* \brief erase internal flash
|
||||
* \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_addr_size; /**< number of addr bits */
|
||||
char _cpld_base_name[7]; /**< cpld name (without package size) */
|
||||
int _irlen; /**< IR bit length */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue