Skip to content

Commit

Permalink
all devices / spiInterface / main: added method / infra to detect fla…
Browse files Browse the repository at this point in the history
…sh chip with --detect -f
  • Loading branch information
trabucayre committed Jun 9, 2024
1 parent d0dd71a commit c468a69
Show file tree
Hide file tree
Showing 11 changed files with 126 additions and 2 deletions.
6 changes: 6 additions & 0 deletions src/altera.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
40 changes: 40 additions & 0 deletions src/colognechip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
1 change: 1 addition & 0 deletions src/colognechip.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions src/device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;}
Expand Down
4 changes: 4 additions & 0 deletions src/gowin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;}
Expand Down
6 changes: 6 additions & 0 deletions src/lattice.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
20 changes: 18 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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, "", "", "", "",
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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();
Expand Down
29 changes: 29 additions & 0 deletions src/spiInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/spiInterface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
15 changes: 15 additions & 0 deletions src/xilinx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 4 additions & 0 deletions src/xilinx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down

0 comments on commit c468a69

Please sign in to comment.