ice40: add support for verify and dump
This commit is contained in:
parent
fb8f50cb52
commit
98a2e836fa
|
|
@ -26,6 +26,7 @@
|
|||
#include "display.hpp"
|
||||
#include "ftdispi.hpp"
|
||||
#include "device.hpp"
|
||||
#include "progressBar.hpp"
|
||||
#include "rawParser.hpp"
|
||||
#include "spiFlash.hpp"
|
||||
|
||||
|
|
@ -78,6 +79,9 @@ void Ice40::program(unsigned int offset)
|
|||
return;
|
||||
}
|
||||
|
||||
uint8_t *data = bit.getData();
|
||||
int length = bit.getLength() / 8;
|
||||
|
||||
_spi->gpio_clear(_rst_pin);
|
||||
|
||||
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), _quiet);
|
||||
|
|
@ -86,10 +90,32 @@ void Ice40::program(unsigned int offset)
|
|||
|
||||
printf("%02x\n", flash.read_status_reg());
|
||||
flash.read_id();
|
||||
flash.erase_and_prog(offset, bit.getData(), bit.getLength() / 8);
|
||||
flash.erase_and_prog(offset, data, length);
|
||||
|
||||
if (_verify)
|
||||
printWarn("writing verification not supported");
|
||||
if (_verify) {
|
||||
printInfo("Verifying write");
|
||||
std::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;
|
||||
} 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;
|
||||
}
|
||||
progress.display(i);
|
||||
}
|
||||
progress.done();
|
||||
}
|
||||
|
||||
_spi->gpio_set(_rst_pin);
|
||||
usleep(12000);
|
||||
|
|
@ -104,3 +130,56 @@ void Ice40::program(unsigned int offset)
|
|||
else
|
||||
printSuccess("DONE");
|
||||
}
|
||||
|
||||
bool Ice40::dumpFlash(const std::string &filename,
|
||||
uint32_t base_addr, uint32_t len)
|
||||
{
|
||||
uint32_t timeout = 1000;
|
||||
_spi->gpio_clear(_rst_pin);
|
||||
|
||||
std::string data;
|
||||
data.resize(len);
|
||||
|
||||
/* prepare SPI access */
|
||||
printInfo("Read Flash ", false);
|
||||
try {
|
||||
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), _verbose);
|
||||
flash.reset();
|
||||
flash.power_up();
|
||||
flash.read_id();
|
||||
flash.read_status_reg();
|
||||
flash.read(base_addr, (uint8_t*)&data[0], len);
|
||||
} catch (std::exception &e) {
|
||||
printError("Fail");
|
||||
printError(std::string(e.what()));
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE *fd = fopen(filename.c_str(), "wb");
|
||||
if (!fd) {
|
||||
printError("Fail");
|
||||
return false;
|
||||
}
|
||||
|
||||
fwrite(data.c_str(), sizeof(uint8_t), len, fd);
|
||||
fclose(fd);
|
||||
|
||||
printSuccess("Done");
|
||||
|
||||
/* prepare SPI access */
|
||||
|
||||
_spi->gpio_set(_rst_pin);
|
||||
usleep(12000);
|
||||
|
||||
printInfo("Wait for CDONE ", false);
|
||||
do {
|
||||
timeout--;
|
||||
usleep(12000);
|
||||
} while (((_spi->gpio_get(true) & _done_pin) == 0) && timeout > 0);
|
||||
if (timeout == 0)
|
||||
printError("FAIL");
|
||||
else
|
||||
printSuccess("DONE");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ class Ice40: public Device {
|
|||
~Ice40();
|
||||
|
||||
void program(unsigned int offset = 0) override;
|
||||
bool dumpFlash(const std::string &filename,
|
||||
uint32_t base_addr, uint32_t len);
|
||||
/* not supported in SPI Active mode */
|
||||
int idCode() override {return 0;}
|
||||
void reset() override;
|
||||
|
|
|
|||
10
src/main.cpp
10
src/main.cpp
|
|
@ -194,7 +194,15 @@ int main(int argc, char **argv)
|
|||
} else if (board->manufacturer == "lattice") {
|
||||
Ice40 target(spi, args.bit_file, args.file_type,
|
||||
board->reset_pin, board->done_pin, args.verify, args.verbose);
|
||||
target.program(args.offset);
|
||||
if (args.prg_type == Device::RD_FLASH) {
|
||||
if (args.file_size == 0) {
|
||||
printError("Error: 0 size for dump");
|
||||
} else {
|
||||
target.dumpFlash(args.bit_file, args.offset, args.file_size);
|
||||
}
|
||||
} else {
|
||||
target.program(args.offset);
|
||||
}
|
||||
} else {
|
||||
RawParser *bit = NULL;
|
||||
if (board->reset_pin) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue