xilinx,lattice,device: add verify write into flash
This commit is contained in:
parent
b150bbdd23
commit
c471d25bb5
|
|
@ -211,6 +211,7 @@ openFPGALoader -- a program to flash FPGA
|
|||
--spi SPI mode (only for FTDI in serial mode)
|
||||
-v, --verbose Produce verbose output
|
||||
-h, --help Give this help list
|
||||
--verify Verify write operation (SPI Flash only)
|
||||
-V, --Version Print program version
|
||||
|
||||
Mandatory or optional arguments to long options are also mandatory or optional
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
Altera::Altera(Jtag *jtag, const std::string &filename,
|
||||
const std::string &file_type, int8_t verbose):
|
||||
Device(jtag, filename, file_type, verbose), _svf(_jtag, _verbose)
|
||||
Device(jtag, filename, file_type, false, verbose), _svf(_jtag, _verbose)
|
||||
{
|
||||
if (!_file_extension.empty()) {
|
||||
if (_file_extension == "svf" || _file_extension == "rbf")
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
Anlogic::Anlogic(Jtag *jtag, const std::string &filename,
|
||||
const std::string &file_type,
|
||||
Device::prog_type_t prg_type, int8_t verbose):
|
||||
Device(jtag, filename, file_type, verbose), _svf(_jtag, _verbose)
|
||||
Device(jtag, filename, file_type, false, verbose), _svf(_jtag, _verbose)
|
||||
{
|
||||
if (!_file_extension.empty()) {
|
||||
if (_file_extension == "svf")
|
||||
|
|
|
|||
|
|
@ -6,10 +6,11 @@
|
|||
using namespace std;
|
||||
|
||||
Device::Device(Jtag *jtag, string filename, const string &file_type,
|
||||
int8_t verbose):
|
||||
bool verify, int8_t verbose):
|
||||
_filename(filename),
|
||||
_file_extension(filename.substr(filename.find_last_of(".") +1)),
|
||||
_mode(NONE_MODE), _verbose(verbose > 0), _quiet(verbose < 0)
|
||||
_mode(NONE_MODE), _verify(verify), _verbose(verbose > 0),
|
||||
_quiet(verbose < 0)
|
||||
{
|
||||
if (!file_type.empty())
|
||||
_file_extension = file_type;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class Device {
|
|||
} prog_type_t;
|
||||
|
||||
Device(Jtag *jtag, std::string filename, const std::string &file_type,
|
||||
int8_t verbose = false);
|
||||
bool verify, int8_t verbose = false);
|
||||
virtual ~Device();
|
||||
virtual void program(unsigned int offset = 0) = 0;
|
||||
virtual int idCode() = 0;
|
||||
|
|
@ -37,6 +37,7 @@ class Device {
|
|||
std::string _filename;
|
||||
std::string _file_extension;
|
||||
enum prog_mode _mode;
|
||||
bool _verify; /**< verify flash write */
|
||||
bool _verbose;
|
||||
bool _quiet;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ Efinix::Efinix(FtdiSpi* spi, const std::string &filename,
|
|||
const std::string &file_type,
|
||||
uint16_t rst_pin, uint16_t done_pin,
|
||||
int8_t verbose):
|
||||
Device(NULL, filename, file_type, verbose), _rst_pin(rst_pin),
|
||||
Device(NULL, filename, file_type, false, verbose), _rst_pin(rst_pin),
|
||||
_done_pin(done_pin)
|
||||
{
|
||||
_spi = spi;
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ using namespace std;
|
|||
|
||||
Gowin::Gowin(Jtag *jtag, const string filename, const string &file_type,
|
||||
Device::prog_type_t prg_type,
|
||||
int8_t verbose): Device(jtag, filename, file_type, verbose),
|
||||
int8_t verbose): Device(jtag, filename, file_type, false, verbose),
|
||||
is_gw1n1(false)
|
||||
{
|
||||
_fs = NULL;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ Ice40::Ice40(FtdiSpi* spi, const std::string &filename,
|
|||
const std::string &file_type,
|
||||
uint16_t rst_pin, uint16_t done_pin,
|
||||
int8_t verbose):
|
||||
Device(NULL, filename, file_type, verbose), _rst_pin(rst_pin),
|
||||
Device(NULL, filename, file_type, false, verbose), _rst_pin(rst_pin),
|
||||
_done_pin(done_pin)
|
||||
{
|
||||
_spi = spi;
|
||||
|
|
|
|||
|
|
@ -69,8 +69,9 @@ using namespace std;
|
|||
# define REG_STATUS_EXEC_ERR (1 << 26)
|
||||
|
||||
Lattice::Lattice(Jtag *jtag, const string filename, const string &file_type,
|
||||
Device::prog_type_t prg_type, int8_t verbose):
|
||||
Device(jtag, filename, file_type, verbose), _fpga_family(UNKNOWN_FAMILY)
|
||||
Device::prog_type_t prg_type, bool verify, int8_t verbose):
|
||||
Device(jtag, filename, file_type, verify, verbose),
|
||||
_fpga_family(UNKNOWN_FAMILY)
|
||||
{
|
||||
if (!_file_extension.empty()) {
|
||||
if (_file_extension == "jed" || _file_extension == "mcs") {
|
||||
|
|
@ -358,8 +359,10 @@ bool Lattice::program_intFlash()
|
|||
return false;
|
||||
}
|
||||
/* verify write */
|
||||
if (_verify) {
|
||||
if (Verify(cfg_data) == false)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* missing usercode update */
|
||||
|
||||
|
|
@ -454,6 +457,31 @@ bool Lattice::program_extFlash(unsigned int offset)
|
|||
flash.read_status_reg();
|
||||
flash.erase_and_prog(offset, data, length);
|
||||
|
||||
if (_verify) {
|
||||
printInfo("Verifying write");
|
||||
string verify_data;
|
||||
verify_data.resize(length);
|
||||
printInfo("Read flash ", false);
|
||||
if (0 != flash.read(offset, (uint8_t*)&verify_data[0], length)) {
|
||||
printError("FAIL");
|
||||
return false;
|
||||
} else {
|
||||
printSuccess("DONE");
|
||||
}
|
||||
|
||||
ProgressBar progress("Check", length, 50, _quiet);
|
||||
for (int i = 0; i < length; i++) {
|
||||
if ((uint8_t)verify_data[i] != data[i]) {
|
||||
progress.fail();
|
||||
printError("Verification failed at " +
|
||||
std::to_string(offset + i));
|
||||
return false;
|
||||
}
|
||||
progress.display(i);
|
||||
}
|
||||
progress.done();
|
||||
}
|
||||
|
||||
delete _bit;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
class Lattice: public Device, SPIInterface {
|
||||
public:
|
||||
Lattice(Jtag *jtag, std::string filename, const std::string &file_type,
|
||||
Device::prog_type_t prg_type,
|
||||
Device::prog_type_t prg_type, bool verify,
|
||||
int8_t verbose);
|
||||
int idCode() override;
|
||||
int userCode();
|
||||
|
|
|
|||
14
src/main.cpp
14
src/main.cpp
|
|
@ -46,7 +46,7 @@ using namespace std;
|
|||
|
||||
struct arguments {
|
||||
int8_t verbose;
|
||||
bool reset, detect;
|
||||
bool reset, detect, verify;
|
||||
unsigned int offset;
|
||||
string bit_file;
|
||||
string device;
|
||||
|
|
@ -80,9 +80,9 @@ 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, 0, "", "", "-", "", -1, 6000000, "-",
|
||||
false, false, false, false, Device::WR_SRAM, false, false, false, "",
|
||||
"", "", -1};
|
||||
struct arguments args = {0, false, false, false, 0, "", "", "-", "", -1,
|
||||
6000000, "-", false, false, false, false, Device::WR_SRAM, false,
|
||||
false, false, "", "", "", -1};
|
||||
/* parse arguments */
|
||||
try {
|
||||
if (parse_opt(argc, argv, &args, &pins_config))
|
||||
|
|
@ -355,7 +355,7 @@ int main(int argc, char **argv)
|
|||
try {
|
||||
if (fab == "xilinx") {
|
||||
fpga = new Xilinx(jtag, args.bit_file, args.file_type,
|
||||
args.prg_type, args.fpga_part, args.verbose);
|
||||
args.prg_type, args.fpga_part, args.verify, args.verbose);
|
||||
} else if (fab == "altera") {
|
||||
fpga = new Altera(jtag, args.bit_file, args.file_type,
|
||||
args.verbose);
|
||||
|
|
@ -367,7 +367,7 @@ int main(int argc, char **argv)
|
|||
args.prg_type, args.verbose);
|
||||
} else if (fab == "lattice") {
|
||||
fpga = new Lattice(jtag, args.bit_file, args.file_type,
|
||||
args.prg_type, args.verbose);
|
||||
args.prg_type, args.verify, args.verbose);
|
||||
} else {
|
||||
printError("Error: manufacturer " + fab + " not supported");
|
||||
delete(jtag);
|
||||
|
|
@ -485,6 +485,8 @@ int parse_opt(int argc, char **argv, struct arguments *args, jtag_pins_conf_t *p
|
|||
cxxopts::value<bool>(args->spi))
|
||||
("v,verbose", "Produce verbose output", cxxopts::value<bool>(verbose))
|
||||
("h,help", "Give this help list")
|
||||
("verify", "Verify write operation (SPI Flash only)",
|
||||
cxxopts::value<bool>(args->verify))
|
||||
("V,Version", "Print program version");
|
||||
|
||||
options.parse_positional({"bitstream"});
|
||||
|
|
|
|||
|
|
@ -17,8 +17,9 @@
|
|||
Xilinx::Xilinx(Jtag *jtag, const std::string &filename,
|
||||
const std::string &file_type,
|
||||
Device::prog_type_t prg_type,
|
||||
std::string device_package, int8_t verbose):
|
||||
Device(jtag, filename, file_type, verbose),_device_package(device_package)
|
||||
std::string device_package, bool verify, int8_t verbose):
|
||||
Device(jtag, filename, file_type, verify, verbose),
|
||||
_device_package(device_package)
|
||||
{
|
||||
if (!_file_extension.empty()) {
|
||||
if (_file_extension == "mcs") {
|
||||
|
|
@ -146,11 +147,44 @@ void Xilinx::program_spi(ConfigBitstreamParser * bit, unsigned int offset)
|
|||
throw std::runtime_error(e.what());
|
||||
}
|
||||
|
||||
uint8_t *data = bit->getData();
|
||||
int length = bit->getLength() / 8;
|
||||
|
||||
SPIFlash spiFlash(this, (_verbose ? 1 : (_quiet ? -1 : 0)));
|
||||
spiFlash.reset();
|
||||
spiFlash.read_id();
|
||||
spiFlash.read_status_reg();
|
||||
spiFlash.erase_and_prog(offset, bit->getData(), bit->getLength()/8);
|
||||
spiFlash.erase_and_prog(offset, data, length);
|
||||
|
||||
/* verify write if required */
|
||||
if (_verify) {
|
||||
std::string verify_data;
|
||||
verify_data.resize(256);
|
||||
|
||||
ProgressBar progress("Verifying write", length, 50, _quiet);
|
||||
int rd_length = 256;
|
||||
for (int i = 0; i < length; i+=rd_length) {
|
||||
if (rd_length + i > length)
|
||||
rd_length = length - i;
|
||||
if (0 != spiFlash.read(offset + i, (uint8_t*)&verify_data[0],
|
||||
rd_length)) {
|
||||
progress.fail();
|
||||
printError("Failed to read flash");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < rd_length; ii++) {
|
||||
if ((uint8_t)verify_data[ii] != data[i + ii]) {
|
||||
progress.fail();
|
||||
printError("Verification failed at " +
|
||||
std::to_string(offset + i + ii));
|
||||
return;
|
||||
}
|
||||
}
|
||||
progress.display(i);
|
||||
}
|
||||
progress.done();
|
||||
}
|
||||
}
|
||||
|
||||
void Xilinx::program_mem(ConfigBitstreamParser *bitfile)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ class Xilinx: public Device, SPIInterface {
|
|||
Xilinx(Jtag *jtag, const std::string &filename,
|
||||
const std::string &file_type,
|
||||
Device::prog_type_t prg_type,
|
||||
std::string device_package, int8_t verbose);
|
||||
std::string device_package,
|
||||
bool verify, int8_t verbose);
|
||||
~Xilinx();
|
||||
|
||||
void program(unsigned int offset = 0) override;
|
||||
|
|
|
|||
Loading…
Reference in New Issue