recast verbose to int8_t to have more level of verbosity (-1 quiet, 0 normal, 1 verbose), add --quiet option, display progress bar when verbosity level >= 0

This commit is contained in:
Gwenhael Goavec-Merou 2021-01-30 07:57:49 +01:00
parent 1992360667
commit ad21a3bb36
22 changed files with 114 additions and 68 deletions

View File

@ -149,6 +149,7 @@ openFPGALoader -- a program to flash FPGA
Gowin and ECP5 devices)
-o, --offset arg start offset in EEPROM
--pins arg pin config (only for ft232R) TDI:TDO:TCK:TMS
--quiet Produce quiet output (no progress bar)
-r, --reset reset FPGA after operations
--spi SPI mode (only for FTDI in serial mode)
-v, --verbose Produce verbose output

View File

@ -16,7 +16,7 @@
// DATA_DIR is defined at compile time.
#define BIT_FOR_FLASH (DATA_DIR "/openFPGALoader/test_sfl.svf")
Altera::Altera(Jtag *jtag, const std::string &filename, bool verbose):
Altera::Altera(Jtag *jtag, const std::string &filename, int8_t verbose):
Device(jtag, filename, verbose), _svf(_jtag, _verbose)
{
if (_filename != "") {
@ -60,7 +60,7 @@ void Altera::programMem()
_jtag->set_state(Jtag::RUN_TEST_IDLE);
_jtag->toggleClk(12000);
/* write */
ProgressBar progress("Flash SRAM", byte_length, 50);
ProgressBar progress("Flash SRAM", byte_length, 50, _quiet);
/* 2.2.6.5 */
_jtag->set_state(Jtag::SHIFT_DR);

View File

@ -9,7 +9,7 @@
class Altera: public Device {
public:
Altera(Jtag *jtag, const std::string &filename, bool verbose);
Altera(Jtag *jtag, const std::string &filename, int8_t verbose);
~Altera();
void programMem();

View File

@ -34,7 +34,7 @@
#define IRLENGTH 8
Anlogic::Anlogic(Jtag *jtag, const std::string &filename,
bool flash_wr, bool sram_wr, bool verbose):
bool flash_wr, bool sram_wr, int8_t verbose):
Device(jtag, filename, verbose), _svf(_jtag, _verbose)
{
(void)flash_wr;
@ -140,7 +140,7 @@ void Anlogic::program(unsigned int offset)
_jtag->toggleClk(15);
_jtag->set_state(Jtag::SHIFT_DR);
ProgressBar progress("Loading", len, 50);
ProgressBar progress("Loading", len, 50, _quiet);
int pos = 0;
uint8_t *ptr = data;
while (len > 0) {

View File

@ -29,7 +29,7 @@
class Anlogic: public Device, SPIInterface {
public:
Anlogic(Jtag *jtag, const std::string &filename,
bool flash_wr, bool sram_wr, bool verbose);
bool flash_wr, bool sram_wr, int8_t verbose);
~Anlogic();
void program(unsigned int offset = 0) override;

View File

@ -5,13 +5,13 @@
using namespace std;
Device::Device(Jtag *jtag, string filename, bool verbose):
Device::Device(Jtag *jtag, string filename, int8_t verbose):
_filename(filename),
_file_extension(filename.substr(filename.find_last_of(".") +1)),
_mode(NONE_MODE), _verbose(verbose)
_mode(NONE_MODE), _verbose(verbose > 0), _quiet(verbose < 0)
{
_jtag = jtag;
if (_verbose)
if (verbose > 0)
cout << "File type : " << _file_extension << endl;
}

View File

@ -18,7 +18,7 @@ class Device {
FLASH_MODE = 1,
MEM_MODE = 2
};
Device(Jtag *jtag, std::string filename, bool verbose = false);
Device(Jtag *jtag, std::string filename, int8_t verbose = false);
virtual ~Device();
virtual void program(unsigned int offset = 0) = 0;
virtual int idCode() = 0;
@ -29,6 +29,7 @@ class Device {
std::string _file_extension;
enum prog_mode _mode;
bool _verbose;
bool _quiet;
};
#endif

View File

@ -32,7 +32,7 @@
Efinix::Efinix(FtdiSpi* spi, const std::string &filename,
uint16_t rst_pin, uint16_t done_pin,
bool verbose):
int8_t verbose):
Device(NULL, filename, verbose), _rst_pin(rst_pin),
_done_pin(done_pin)
{

View File

@ -27,7 +27,7 @@ class Efinix: public Device {
public:
Efinix(FtdiSpi *spi, const std::string &filename,
uint16_t rst_pin, uint16_t done_pin,
bool verbose);
int8_t verbose);
~Efinix();
void program(unsigned int offset = 0) override;

View File

@ -70,7 +70,7 @@ using namespace std;
#define EFLASH_ERASE 0x75
Gowin::Gowin(Jtag *jtag, const string filename, bool flash_wr, bool sram_wr,
bool verbose): Device(jtag, filename, verbose), is_gw1n1(false)
int8_t verbose): Device(jtag, filename, verbose), is_gw1n1(false)
{
_fs = NULL;
if (_filename != "") {
@ -376,7 +376,7 @@ bool Gowin::flashFLASH(uint8_t *data, int length)
memcpy(buffer+6*4, data, byte_length);
ProgressBar progress("write Flash", buffer_length, 50);
ProgressBar progress("write Flash", buffer_length, 50, _quiet);
for (int i=0, xpage=0; xpage < nb_xpage; i+=(nb_iter*4), xpage++) {
wr_rd(CONFIG_ENABLE, NULL, 0, NULL, 0);
@ -427,7 +427,7 @@ bool Gowin::flashSRAM(uint8_t *data, int length)
int tx_len, tx_end;
int byte_length = length / 8;
ProgressBar progress("Flash SRAM", byte_length, 50);
ProgressBar progress("Flash SRAM", byte_length, 50, _quiet);
/* 2.2.6.4 */
wr_rd(XFER_WRITE, NULL, 0, NULL, 0);

View File

@ -31,7 +31,7 @@
class Gowin: public Device {
public:
Gowin(Jtag *jtag, std::string filename, bool flash_wr, bool sram_wr,
bool verbose);
int8_t verbose);
~Gowin();
int idCode() override;
void reset() override;

View File

@ -31,7 +31,7 @@
Ice40::Ice40(FtdiSpi* spi, const std::string &filename,
uint16_t rst_pin, uint16_t done_pin,
bool verbose):
int8_t verbose):
Device(NULL, filename, verbose), _rst_pin(rst_pin),
_done_pin(done_pin)
{
@ -79,7 +79,7 @@ void Ice40::program(unsigned int offset)
_spi->gpio_clear(_rst_pin);
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), _verbose);
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), _quiet);
flash.reset();
flash.power_up();

View File

@ -27,7 +27,7 @@ class Ice40: public Device {
public:
Ice40(FtdiSpi *spi, const std::string &filename,
uint16_t rst_pin, uint16_t done_pin,
bool verbose);
int8_t verbose);
~Ice40();
void program(unsigned int offset = 0) override;

View File

@ -68,7 +68,7 @@ using namespace std;
# define REG_STATUS_EXEC_ERR (1 << 26)
Lattice::Lattice(Jtag *jtag, const string filename,
bool flash_wr, bool sram_wr, bool verbose):
bool flash_wr, bool sram_wr, int8_t verbose):
Device(jtag, filename, verbose), _fpga_family(UNKNOWN_FAMILY)
{
(void)sram_wr;
@ -225,7 +225,7 @@ bool Lattice::program_mem()
uint8_t tmp[1024];
int size = 1024;
ProgressBar progress("Loading", length, 50);
ProgressBar progress("Loading", length, 50, _quiet);
for (int i = 0; i < length; i += size) {
progress.display(i);
@ -864,7 +864,7 @@ bool Lattice::flashErase(uint8_t mask)
bool Lattice::flashProg(uint32_t start_addr, const string &name, vector<string> data)
{
(void)start_addr;
ProgressBar progress("Writing " + name, data.size(), 50);
ProgressBar progress("Writing " + name, data.size(), 50, _quiet);
for (uint32_t line = 0; line < data.size(); line++) {
wr_rd(PROG_CFG_FLASH, (uint8_t *)data[line].c_str(),
16, NULL, 0);
@ -893,7 +893,7 @@ bool Lattice::Verify(std::vector<std::string> data, bool unlock)
memset(tx_buf, 0, 16);
bool failure = false;
ProgressBar progress("Verifying", data.size(), 50);
ProgressBar progress("Verifying", data.size(), 50, _quiet);
for (size_t line = 0; line< data.size(); line++) {
_jtag->set_state(Jtag::RUN_TEST_IDLE);
_jtag->toggleClk(2);
@ -914,9 +914,12 @@ bool Lattice::Verify(std::vector<std::string> data, bool unlock)
if (unlock)
DisableISC();
progress.done();
if (failure)
progress.fail();
else
progress.done();
return true;
return !failure;
}
uint64_t Lattice::readFeaturesRow()

View File

@ -32,7 +32,7 @@
class Lattice: public Device, SPIInterface {
public:
Lattice(Jtag *jtag, std::string filename, bool flash_wr, bool sram_wr,
bool verbose);
int8_t verbose);
int idCode() override;
int userCode();
void reset() override {}

View File

@ -44,7 +44,8 @@
using namespace std;
struct arguments {
bool verbose, reset, detect;
int8_t verbose;
bool reset, detect;
unsigned int offset;
string bit_file;
string device;
@ -74,7 +75,7 @@ int main(int argc, char **argv)
jtag_pins_conf_t pins_config = {0, 0, 0, 0};
/* command line args. */
struct arguments args = {false, false, false, 0, "", "", "-", "", -1, 6000000, "-",
struct arguments args = {0, false, false, 0, "", "", "-", "", -1, 6000000, "-",
false, false, false, false, false, true, false, false};
/* parse arguments */
try {
@ -119,7 +120,7 @@ int main(int argc, char **argv)
}
if (args.cable[0] == '-') { /* if no board and no cable */
if (args.verbose)
if (args.verbose > 0)
cout << "No cable or board specified: using direct ft2232 interface" << endl;
args.cable = "ft2232";
}
@ -154,7 +155,7 @@ int main(int argc, char **argv)
spi_pins_conf_t pins_config = board->spi_pins_config;
try {
spi = new FtdiSpi(cable.config, pins_config, args.freq, args.verbose);
spi = new FtdiSpi(cable.config, pins_config, args.freq, args.verbose > 0);
} catch (std::exception &e) {
printError("Error: Failed to claim cable");
return EXIT_FAILURE;
@ -226,7 +227,7 @@ int main(int argc, char **argv)
vector<int> listDev;
int found = jtag->detectChain(listDev, 5);
if (args.verbose)
if (args.verbose > 0)
cout << "found " << std::to_string(found) << " devices" << endl;
if (found > 1) {
printError("Error: currently only one device is supported");
@ -244,7 +245,7 @@ int main(int argc, char **argv)
cerr << "Error: device " << hex << idcode << " not supported" << endl;
delete(jtag);
return EXIT_FAILURE;
} else if (args.verbose || args.detect) {
} else if (args.verbose > 0 || args.detect) {
printf("idcode 0x%x\nmanufacturer %s\nmodel %s\nfamily %s\n",
idcode,
fpga_list[idcode].manufacturer.c_str(),
@ -338,6 +339,7 @@ int parse_opt(int argc, char **argv, struct arguments *args, jtag_pins_conf_t *p
string freqo;
vector<string> pins;
bool verbose, quiet;
try {
cxxopts::Options options(argv[0], "openFPGALoader -- a program to flash FPGA",
"<gwenhael.goavec-merou@trabucayre.com>");
@ -375,11 +377,13 @@ int parse_opt(int argc, char **argv, struct arguments *args, jtag_pins_conf_t *p
cxxopts::value<unsigned int>(args->offset))
("pins", "pin config (only for ft232R) TDI:TDO:TCK:TMS",
cxxopts::value<vector<string>>(pins))
("quiet", "Produce quiet output (no progress bar)",
cxxopts::value<bool>(quiet))
("r,reset", "reset FPGA after operations",
cxxopts::value<bool>(args->reset))
("spi", "SPI mode (only for FTDI in serial mode)",
cxxopts::value<bool>(args->spi))
("v,verbose", "Produce verbose output", cxxopts::value<bool>(args->verbose))
("v,verbose", "Produce verbose output", cxxopts::value<bool>(verbose))
("h,help", "Give this help list")
("V,Version", "Print program version");
@ -391,6 +395,15 @@ int parse_opt(int argc, char **argv, struct arguments *args, jtag_pins_conf_t *p
return 1;
}
if (verbose && quiet) {
printError("Error: can't select quiet and verbose mode in same time");
throw std::exception();
}
if (verbose)
args->verbose = 1;
if (quiet)
args->verbose = -1;
if (result.count("Version")) {
cout << "openFPGALoader " << VERSION << endl;
return 1;

View File

@ -20,13 +20,22 @@
#include "progressBar.hpp"
#include "display.hpp"
ProgressBar::ProgressBar(std::string mess, int maxValue, int progressLen):
_mess(mess), _maxValue(maxValue), _progressLen(progressLen)
ProgressBar::ProgressBar(std::string mess, int maxValue, int progressLen,
bool quiet): _mess(mess), _maxValue(maxValue),
_progressLen(progressLen), _quiet(quiet), _first(true)
{
last_time = clock();
}
void ProgressBar::display(int value, char force)
{
if (_quiet) {
if (_first) {
printInfo(_mess + ": ", false);
_first = false;
}
return;
}
clock_t this_time = clock();
if (!force && ((((float)(this_time - last_time))/CLOCKS_PER_SEC) < 0.2))
{
@ -36,24 +45,28 @@ void ProgressBar::display(int value, char force)
float percent = ((float)value * 100.0f)/(float)_maxValue;
float nbEq = (percent * (float) _progressLen)/100.0f;
//fprintf(stderr, "\r%s: [", _mess.c_str());
printInfo("\r" + _mess + ": [", false);
for (int z=0; z < nbEq; z++) {
fputc('=', stderr);
}
fprintf(stderr, "%*s", (int)(_progressLen-nbEq), "");
//fprintf(stderr, "] %3.2f%%", percent);
printInfo("] " + std::to_string(percent) + "%", false);
}
void ProgressBar::done()
{
display(_maxValue, true);
//fprintf(stderr, "\nDone\n");
printSuccess("\nDone");
if (_quiet) {
printSuccess("Done");
} else {
display(_maxValue, true);
printSuccess("\nDone");
}
}
void ProgressBar::fail()
{
display(_maxValue, true);
//fprintf(stderr, "\nDone\n");
printError("\nFail");
if (_quiet) {
printError("\nFail");
} else {
display(_maxValue, true);
printError("\nFail");
}
}

View File

@ -22,7 +22,8 @@
class ProgressBar {
public:
ProgressBar(std::string mess, int maxValue, int progressLen);
ProgressBar(std::string mess, int maxValue, int progressLen,
bool quiet = false);
void display(int value, char force = 0);
void done();
void fail();
@ -31,6 +32,8 @@ class ProgressBar {
int _maxValue;
int _progressLen;
clock_t last_time; //records the time of last progress bar update
bool _quiet;
bool _first;
};
#endif

View File

@ -60,7 +60,7 @@
#define FLASH_WRVECR 0x61
#define FLASH_RDVECR 0x65
SPIFlash::SPIFlash(SPIInterface *spi, bool verbose):_spi(spi), _verbose(verbose)
SPIFlash::SPIFlash(SPIInterface *spi, int8_t verbose):_spi(spi), _verbose(verbose)
{
}
@ -85,20 +85,32 @@ int SPIFlash::sector_erase(int addr)
int SPIFlash::sectors_erase(int base_addr, int size)
{
int ret = 0;
int start_addr = base_addr;
int end_addr = (base_addr + size + 0xffff) & ~0xffff;
ProgressBar progress("Erasing", end_addr, 50);
ProgressBar progress("Erasing", end_addr, 50, _verbose < 0);
for (int addr = start_addr; addr < end_addr; addr += 0x10000) {
if (write_enable() == -1)
return -1;
if (sector_erase(addr) == -1)
return -1;
if (_spi->spi_wait(FLASH_RDSR, FLASH_RDSR_WIP, 0x00, 100000, false) == -1)
return -1;
if (write_enable() == -1) {
ret = -1;
break;
}
if (sector_erase(addr) == -1) {
ret = -1;
break;
}
if (_spi->spi_wait(FLASH_RDSR, FLASH_RDSR_WIP, 0x00, 100000, false) == -1) {
ret = -1;
break;
}
progress.display(addr);
}
progress.done();
return 0;
if (ret == 0)
progress.done();
else
progress.fail();
return ret;
}
int SPIFlash::write_page(int addr, uint8_t *data, int len)
@ -143,7 +155,7 @@ int SPIFlash::erase_and_prog(int base_addr, uint8_t *data, int len)
if (disable_protection() != 0)
return -1;
}
ProgressBar progress("Writing", len, 50);
ProgressBar progress("Writing", len, 50, _verbose < 0);
if (sectors_erase(base_addr, len) == -1)
return -1;
@ -177,11 +189,11 @@ void SPIFlash::read_id()
for (int i=0; i < 4; i++) {
d = d << 8;
d |= (0x00ff & (int)rx[i]);
if (_verbose)
if (_verbose > 0)
printf("%x ", rx[i]);
}
if (_verbose)
if (_verbose > 0)
printf("read %x\n", d);
/* read extented */
@ -201,7 +213,7 @@ void SPIFlash::read_id()
printf("EDID + CFD length : %02x\n", rx[3]);
printf("EDID : %02x%02x\n", rx[5], rx[4]);
printf("CFD : ");
if (_verbose) {
if (_verbose > 0) {
for (int i = 6; i < len; i++)
printf("%02x ", rx[i]);
printf("\n");
@ -215,7 +227,7 @@ uint8_t SPIFlash::read_status_reg()
{
uint8_t rx;
_spi->spi_put(FLASH_RDSR, NULL, &rx, 1);
if (_verbose) {
if (_verbose > 0) {
printf("RDSR : %02x\n", rx);
printf("WIP : %d\n", rx&0x01);
printf("WEL : %d\n", (rx>>1)&0x01);
@ -230,7 +242,7 @@ uint16_t SPIFlash::readNonVolatileCfgReg()
{
uint8_t rx[2];
_spi->spi_put(FLASH_RDNVCR, NULL, rx, 2);
if (_verbose)
if (_verbose > 0)
printf("Non Volatile %x %x\n", rx[0], rx[1]);
return (rx[1] << 8) | rx[0];
}
@ -239,7 +251,7 @@ uint16_t SPIFlash::readVolatileCfgReg()
{
uint8_t rx[2];
_spi->spi_put(FLASH_RDVCR, NULL, rx, 2);
if (_verbose)
if (_verbose > 0)
printf("Volatile %x %x\n", rx[0], rx[1]);
return (rx[1] << 8) | rx[0];
}
@ -273,7 +285,7 @@ int SPIFlash::write_disable()
int ret = _spi->spi_wait(FLASH_RDSR, FLASH_RDSR_WEL, 0x00, 1000);
if (ret == -1)
printf("write disable: Error\n");
else if (_verbose)
else if (_verbose > 0)
printf("write disable: Success\n");
return ret;
}

View File

@ -22,7 +22,7 @@
class SPIFlash {
public:
SPIFlash(SPIInterface *spi, bool verbose);
SPIFlash(SPIInterface *spi, int8_t verbose);
/* power */
void power_up();
void power_down();
@ -48,7 +48,7 @@ class SPIFlash {
uint16_t readVolatileCfgReg();
private:
SPIInterface *_spi;
bool _verbose;
int8_t _verbose;
};
#endif

View File

@ -14,7 +14,7 @@
#include "progressBar.hpp"
Xilinx::Xilinx(Jtag *jtag, const std::string &filename,
bool flash_wr, bool sram_wr, bool verbose):
bool flash_wr, bool sram_wr, int8_t verbose):
Device(jtag, filename, verbose)
{
if (_filename != ""){
@ -122,7 +122,7 @@ void Xilinx::program_spi(unsigned int offset)
printSuccess("DONE");
}
SPIFlash spiFlash(this, _verbose);
SPIFlash spiFlash(this, (_verbose ? 1 : (_quiet ? -1 : 0)));
spiFlash.reset();
spiFlash.read_id();
spiFlash.read_status_reg();
@ -194,7 +194,7 @@ void Xilinx::program_mem(BitParser &bitfile)
int tx_len, tx_end;
int burst_len = byte_length / 100;
ProgressBar progress("Flash SRAM", byte_length, 50);
ProgressBar progress("Flash SRAM", byte_length, 50, _quiet);
for (int i=0; i < byte_length; i+=burst_len) {
if (i + burst_len > byte_length) {

View File

@ -11,7 +11,7 @@
class Xilinx: public Device, SPIInterface {
public:
Xilinx(Jtag *jtag, const std::string &filename,
bool flash_wr, bool sram_wr, bool verbose);
bool flash_wr, bool sram_wr, int8_t verbose);
~Xilinx();
void program(unsigned int offset = 0) override;