gowin: merge CRC check into one method, check usercode/checksum as fallback when usercode register doesn't match computed file's checksum (issue #279)

This commit is contained in:
Gwenhael Goavec-Merou 2023-02-16 20:02:36 +01:00
parent 6f070d8e97
commit a481c1e699
2 changed files with 54 additions and 25 deletions

View File

@ -194,8 +194,6 @@ void Gowin::reset()
void Gowin::programFlash()
{
int status;
uint8_t *data = _fs->getData();
int length = _fs->getLength();
@ -240,16 +238,7 @@ void Gowin::programFlash()
usleep(2*150*1000);
/* check if file checksum == checksum in FPGA */
if (!skip_checksum) {
status = readUserCode();
int checksum = static_cast<FsParser *>(_fs)->checksum();
if (checksum != status) {
printError("CRC check : FAIL");
printf("%04x %04x\n", checksum, status);
} else {
printSuccess("CRC check: Success");
}
}
checkCRC();
if (_verbose)
displayReadReg(readStatusReg());
@ -258,7 +247,6 @@ void Gowin::programFlash()
void Gowin::program(unsigned int offset, bool unprotect_flash)
{
uint8_t *data;
uint32_t status;
int length;
if (_mode == NONE_MODE || !_fs)
@ -329,21 +317,57 @@ void Gowin::program(unsigned int offset, bool unprotect_flash)
if (!DisableCfg())
return;
/* check if file checksum == checksum in FPGA */
if (!skip_checksum) {
status = readUserCode();
uint32_t checksum = static_cast<FsParser *>(_fs)->checksum();
if (checksum != status) {
printError("SRAM Flash: FAIL");
printf("%04x %04x\n", checksum, status);
} else {
printSuccess("SRAM Flash: Success");
}
}
/* ocheck if file checksum == checksum in FPGA */
checkCRC();
if (_verbose)
displayReadReg(readStatusReg());
}
void Gowin::checkCRC()
{
if (!skip_checksum)
return;
bool is_match = true;
char mess[256];
uint32_t status = readUserCode();
uint16_t checksum = static_cast<FsParser *>(_fs)->checksum();
string hdr = "";
try {
hdr = _fs->getHeaderVal("checkSum");
} catch (std::exception &e) {
if (_verbose)
printError(e.what());
}
if (static_cast<uint16_t>(0xffff & status) != checksum) {
/* no match:
* user code register contains checksum or
* user_code when:
* set_option -user_code
* is used: try to compare with this value
*/
if (hdr.empty()) {
is_match = false;
snprintf(mess, 256, "Read: 0x%08x checksum: 0x%04x\n",
status, checksum);
} else {
uint32_t user_code = strtol(hdr.c_str(), NULL, 16);
if (status != user_code) {
is_match = false;
snprintf(mess, 256,
"Read 0x%08x (checksum: 0x%08x, user_code: 0x%08x)\n",
status, checksum, user_code);
}
}
}
if (is_match) {
printSuccess("CRC check: Success");
} else {
printError("CRC check : FAIL");
printError(mess);
}
}
bool Gowin::EnableCfg()
{
wr_rd(CONFIG_ENABLE, NULL, 0, NULL, 0);

View File

@ -55,10 +55,15 @@ class Gowin: public Device, SPIInterface {
void displayReadReg(uint32_t dev);
uint32_t readStatusReg();
uint32_t readUserCode();
/*!
* \brief compare usercode register with fs checksum and/or
* .fs usercode field
*/
void checkCRC();
ConfigBitstreamParser *_fs;
bool is_gw1n1;
bool is_gw2a;
bool skip_checksum;
bool skip_checksum; /**< bypass checksum verification (GW2A) */
bool _external_flash; /**< select between int or ext flash */
uint8_t _spi_sck; /**< clk signal offset in bscan SPI */
uint8_t _spi_cs; /**< cs signal offset in bscan SPI */