From b77c5a22dfc74b3a0a166e8825a9d0c1ed885de4 Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Sun, 11 Jul 2021 11:32:10 +0200 Subject: [PATCH] spiFlash: add verify and dump method --- src/spiFlash.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ src/spiFlash.hpp | 22 ++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/src/spiFlash.cpp b/src/spiFlash.cpp index 3e85eb7..301cf1d 100644 --- a/src/spiFlash.cpp +++ b/src/spiFlash.cpp @@ -11,6 +11,7 @@ #include "ftdipp_mpsse.hpp" #include "progressBar.hpp" +#include "display.hpp" #include "spiFlash.hpp" #include "spiInterface.hpp" @@ -139,6 +140,47 @@ int SPIFlash::read(int base_addr, uint8_t *data, int len) return ret; } +bool SPIFlash::dump(const std::string &filename, const int &base_addr, + const int &len, int rd_burst) +{ + if (rd_burst == 0) + rd_burst = len; + + std::string data; + data.resize(rd_burst); + + printInfo("dump flash (May take time)"); + + printInfo("Open dump file ", false); + FILE *fd = fopen(filename.c_str(), "wb"); + if (!fd) { + printError("FAIL"); + return false; + } else { + printSuccess("DONE"); + } + + ProgressBar progress("Read flash ", len, 50, false); + for (int i = 0; i < len; i += rd_burst) { + if (rd_burst + i > len) + rd_burst = len - i; + if (0 != read(base_addr + i, (uint8_t*)&data[0], rd_burst)) { + progress.fail(); + printError("Failed to read flash"); + fclose(fd); + return false; + } + fwrite(data.c_str(), sizeof(uint8_t), rd_burst, fd); + progress.display(i); + } + + progress.done(); + + fclose(fd); + + return true; +} + int SPIFlash::erase_and_prog(int base_addr, uint8_t *data, int len) { if (_jedec_id == 0) @@ -174,6 +216,43 @@ int SPIFlash::erase_and_prog(int base_addr, uint8_t *data, int len) return 0; } +bool SPIFlash::verify(const int &base_addr, const uint8_t *data, + const int &len, int rd_burst) +{ + if (rd_burst == 0) + rd_burst = len; + + printInfo("Verifying write (May take time)"); + + std::string verify_data; + verify_data.resize(rd_burst); + + ProgressBar progress("Read flash ", len, 50, false); + for (int i = 0; i < len; i += rd_burst) { + if (rd_burst + i > len) + rd_burst = len - i; + if (0 != read(base_addr + i, (uint8_t*)&verify_data[0], rd_burst)) { + progress.fail(); + printError("Failed to read flash"); + return false; + } + + for (int ii = 0; ii < rd_burst; ii++) { + if ((uint8_t)verify_data[ii] != data[i+ii]) { + progress.fail(); + printError("Verification failed at " + + std::to_string(base_addr + i + ii)); + return false; + } + } + progress.display(i); + } + + progress.done(); + + return true; +} + void SPIFlash::reset() { uint8_t data[8]; diff --git a/src/spiFlash.hpp b/src/spiFlash.hpp index 11f4471..7bd80a0 100644 --- a/src/spiFlash.hpp +++ b/src/spiFlash.hpp @@ -33,8 +33,30 @@ class SPIFlash { int write_page(int addr, uint8_t *data, int len); /* read */ int read(int base_addr, uint8_t *data, int len); + /*! + * \brief read len Byte starting at base_addr and store + * into filename + * \param[in] filename: file name + * \param[in] base_addr: starting address in flash memory + * \param[in] len: length (in Byte) + * \param[in] rd_burst: size of packet to read + * \return false if read fails or filename can't be open, true otherwise + */ + bool dump(const std::string &filename, const int &base_addr, + const int &len, int rd_burst = 0); /* combo flash + erase */ int erase_and_prog(int base_addr, uint8_t *data, int len); + /*! + * \brief check if area base_addr to base_addr + len match + * data content + * \param[in] base_addr: base address to read + * \param[in] data: theorical area content + * \param[in] len: length (in Byte) to area and data + * \param[in] rd_burst: size of packet to read + * \return false if read fails or content didn't match, true otherwise + */ + bool verify(const int &base_addr, const uint8_t *data, + const int &len, int rd_burst = 0); /* display/info */ uint8_t read_status_reg(); virtual void read_id();