all devices / spiInterface / main: added method / infra to detect flash chip with --detect -f
This commit is contained in:
parent
d0dd71a28a
commit
c468a69fc9
|
|
@ -46,6 +46,12 @@ class Altera: public Device, SPIInterface {
|
|||
/* spi interface */
|
||||
/*************************/
|
||||
|
||||
/*!
|
||||
* \brief display SPI flash ID and status register
|
||||
*/
|
||||
bool detect_flash() override {
|
||||
return SPIInterface::detect_flash();
|
||||
}
|
||||
/*!
|
||||
* \brief protect SPI flash blocks
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -123,6 +123,46 @@ void CologneChip::waitCfgDone()
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump flash contents to file. Works in both SPI and JTAG-SPI-bypass mode.
|
||||
*/
|
||||
bool CologneChip::detect_flash()
|
||||
{
|
||||
if (_spi) {
|
||||
/* enable output and hold reset */
|
||||
_spi->gpio_clear(_rstn_pin | _oen_pin);
|
||||
} else if (_ftdi_jtag) {
|
||||
/* enable output and disable reset */
|
||||
_ftdi_jtag->gpio_clear(_oen_pin);
|
||||
_ftdi_jtag->gpio_set(_rstn_pin);
|
||||
}
|
||||
|
||||
/* prepare SPI access */
|
||||
printInfo("Read Flash ", false);
|
||||
try {
|
||||
std::unique_ptr<SPIFlash> flash(_spi ?
|
||||
new SPIFlash(reinterpret_cast<SPIInterface *>(_spi), false, _verbose):
|
||||
new SPIFlash(this, false, _verbose));
|
||||
flash->read_id();
|
||||
flash->display_status_reg();
|
||||
} catch (std::exception &e) {
|
||||
printError("Fail");
|
||||
printError(std::string(e.what()));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_spi) {
|
||||
/* disable output and release reset */
|
||||
_spi->gpio_set(_rstn_pin | _oen_pin);
|
||||
} else if (_ftdi_jtag) {
|
||||
/* disable output */
|
||||
_ftdi_jtag->gpio_set(_oen_pin);
|
||||
}
|
||||
usleep(SLEEP_US);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump flash contents to file. Works in both SPI and JTAG-SPI-bypass mode.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ class CologneChip: public Device, SPIInterface {
|
|||
|
||||
bool cfgDone();
|
||||
void waitCfgDone();
|
||||
bool detect_flash() override;
|
||||
bool dumpFlash(uint32_t base_addr, uint32_t len) override;
|
||||
virtual bool protect_flash(uint32_t len) override {
|
||||
(void) len;
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ class Device {
|
|||
/**********************/
|
||||
/* flash access */
|
||||
/**********************/
|
||||
virtual bool detect_flash() {
|
||||
printError("detect flash not supported"); return false;}
|
||||
virtual bool dumpFlash(uint32_t base_addr, uint32_t len) {
|
||||
(void) base_addr; (void) len;
|
||||
printError("dump flash not supported"); return false;}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ class Gowin: public Device, SPIInterface {
|
|||
bool connectJtagToMCU() override;
|
||||
|
||||
/* spi interface */
|
||||
bool detect_flash() override {
|
||||
if (is_gw5a)
|
||||
return SPIInterface::detect_flash();
|
||||
printError("protect flash not supported"); return false;}
|
||||
bool protect_flash(uint32_t len) override {
|
||||
(void) len;
|
||||
printError("protect flash not supported"); return false;}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,12 @@ class Lattice: public Device, SPIInterface {
|
|||
return SPIInterface::dump(base_addr, len);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief display SPI flash ID and status register
|
||||
*/
|
||||
bool detect_flash() override {
|
||||
return SPIInterface::detect_flash();
|
||||
}
|
||||
/*!
|
||||
* \brief protect SPI flash blocks
|
||||
*/
|
||||
|
|
|
|||
20
src/main.cpp
20
src/main.cpp
|
|
@ -44,7 +44,7 @@ using namespace std;
|
|||
|
||||
struct arguments {
|
||||
int8_t verbose;
|
||||
bool reset, detect, verify, scan_usb;
|
||||
bool reset, detect, detect_flash, verify, scan_usb;
|
||||
unsigned int offset;
|
||||
string bit_file;
|
||||
string secondary_bit_file;
|
||||
|
|
@ -112,7 +112,10 @@ int main(int argc, char **argv)
|
|||
jtag_pins_conf_t pins_config = {0, 0, 0, 0};
|
||||
|
||||
/* command line args. */
|
||||
struct arguments args = {0, false, false, false, false, 0, "", "", "", "-", "", -1,
|
||||
struct arguments args = {0,
|
||||
//reset, detect, detect_flash, verify, scan_usb
|
||||
false, false, false, false, false,
|
||||
0, "", "", "", "-", "", -1,
|
||||
-1, 0, false, "-", false, false, false, false, Device::PRG_NONE, false,
|
||||
/* spi dfu file_type fpga_part bridge_path probe_firmware */
|
||||
false, false, "", "", "", "",
|
||||
|
|
@ -633,6 +636,11 @@ int main(int argc, char **argv)
|
|||
fpga->protect_flash(args.protect_flash);
|
||||
}
|
||||
|
||||
/* detect/display flash */
|
||||
if (args.detect_flash != 0) {
|
||||
fpga->detect_flash();
|
||||
}
|
||||
|
||||
if (args.prg_type == Device::RD_FLASH) {
|
||||
if (args.file_size == 0) {
|
||||
printError("Error: 0 size for dump");
|
||||
|
|
@ -1050,6 +1058,14 @@ int parse_opt(int argc, char **argv, struct arguments *args,
|
|||
cout << options.help() << endl;
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
// user ask detect with flash set
|
||||
// detect/display flash CHIP informations instead
|
||||
// of FPGA details
|
||||
if (args->detect && args->prg_type == Device::WR_FLASH) {
|
||||
args->detect = false;
|
||||
args->detect_flash = true;
|
||||
}
|
||||
} catch (const cxxopts::OptionException& e) {
|
||||
cerr << "Error parsing options: " << e.what() << endl;
|
||||
throw std::exception();
|
||||
|
|
|
|||
|
|
@ -23,6 +23,35 @@ SPIInterface::SPIInterface(const std::string &filename, int8_t verbose,
|
|||
{}
|
||||
|
||||
/* spiFlash generic acces */
|
||||
bool SPIInterface::detect_flash()
|
||||
{
|
||||
bool ret = true;
|
||||
printInfo("protect_flash: ", false);
|
||||
|
||||
/* move device to spi access */
|
||||
if (!prepare_flash_access()) {
|
||||
printError("Fail");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* spi flash access */
|
||||
try {
|
||||
// instanciate call (display flash ID is automatic)
|
||||
SPIFlash flash(this, false, _spif_verbose);
|
||||
// display status register
|
||||
flash.display_status_reg();
|
||||
|
||||
printSuccess("Done");
|
||||
} catch (std::exception &e) {
|
||||
printError("Fail");
|
||||
printError(e.what());
|
||||
ret = false;
|
||||
}
|
||||
|
||||
/* reload bitstream */
|
||||
return post_flash_access() && ret;
|
||||
}
|
||||
|
||||
bool SPIInterface::protect_flash(uint32_t len)
|
||||
{
|
||||
bool ret = true;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ class SPIInterface {
|
|||
bool skip_reset = false);
|
||||
virtual ~SPIInterface() {}
|
||||
|
||||
bool detect_flash();
|
||||
bool protect_flash(uint32_t len);
|
||||
bool unprotect_flash();
|
||||
bool bulk_erase_flash();
|
||||
|
|
|
|||
|
|
@ -1152,6 +1152,21 @@ bool Xilinx::dumpFlash(uint32_t base_addr, uint32_t len)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Xilinx::detect_flash()
|
||||
{
|
||||
if (_flash_chips & PRIMARY_FLASH) {
|
||||
select_flash_chip(PRIMARY_FLASH);
|
||||
if (!SPIInterface::detect_flash())
|
||||
return false;
|
||||
}
|
||||
if (_flash_chips & SECONDARY_FLASH) {
|
||||
select_flash_chip(SECONDARY_FLASH);
|
||||
if (!SPIInterface::detect_flash())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Xilinx::protect_flash(uint32_t len)
|
||||
{
|
||||
if (_flash_chips & PRIMARY_FLASH) {
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ class Xilinx: public Device, SPIInterface {
|
|||
*/
|
||||
uint32_t dumpRegister(const std::string reg_name);
|
||||
|
||||
/*!
|
||||
* \brief display SPI flash ID and status register
|
||||
*/
|
||||
bool detect_flash() override;
|
||||
/*!
|
||||
* \brief protect SPI flash blocks
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue