gowin: Implement user flash programming for GW1N9

This commit is contained in:
Jean THOMAS 2024-12-11 12:19:07 +01:00
parent ffa006d0ee
commit 46ff6cb2eb
2 changed files with 33 additions and 2 deletions

View File

@ -153,6 +153,22 @@ Gowin::Gowin(Jtag *jtag, const string filename, const string &file_type, std::st
}
}
if (user_flash.size() > 0) {
if (!is_gw1n9)
throw std::runtime_error("Unsupported FPGA model (only GW1N(R)-9(C) is supported at the moment)");
if (mcufw.size() > 0)
throw std::runtime_error("Microcontroller firmware and user flash can't be specified simultaneously");
_userflash = std::unique_ptr<ConfigBitstreamParser>(new RawParser(user_flash, false));
if (_userflash->parse() == EXIT_FAILURE) {
printError("FAIL");
throw std::runtime_error("can't parse file");
} else {
printSuccess("DONE");
}
}
if (is_gw5a && _mode == Device::FLASH_MODE) {
_jtag->setClkFreq(2500000);
_jtag->set_state(Jtag::TEST_LOGIC_RESET);
@ -293,6 +309,13 @@ void Gowin::programFlash()
return;
}
if (_userflash) {
const uint8_t *userflash_data = _userflash->getData();
int userflash_length = _userflash->getLength();
if (!writeFLASH(0x6D0, userflash_data, userflash_length, true))
return;
}
if (_verify)
printWarn("writing verification not supported");
@ -567,7 +590,7 @@ inline uint32_t bswap_32(uint32_t x)
}
/* TN653 p. 17-21 */
bool Gowin::writeFLASH(uint32_t page, const uint8_t *data, int length)
bool Gowin::writeFLASH(uint32_t page, const uint8_t *data, int length, bool invert_bits)
{
#if 1
@ -652,6 +675,13 @@ bool Gowin::writeFLASH(uint32_t page, const uint8_t *data, int length)
else
tx[x] = t[x];
}
if (invert_bits) {
for (int x = 0; x < 4; x++) {
tx[x] ^= 0xFF;
}
}
_jtag->shiftDR(tx, NULL, 32);
if (!is_gw1n1)

View File

@ -105,7 +105,7 @@ class Gowin: public Device, SPIInterface {
void programExtFlash(unsigned int offset, bool unprotect_flash);
void programSRAM();
bool writeSRAM(const uint8_t *data, int length);
bool writeFLASH(uint32_t page, const uint8_t *data, int length);
bool writeFLASH(uint32_t page, const uint8_t *data, int length, bool invert_bits = false);
void displayReadReg(const char *, uint32_t dev);
uint32_t readStatusReg();
uint32_t readUserCode();
@ -131,6 +131,7 @@ class Gowin: public Device, SPIInterface {
std::unique_ptr<ConfigBitstreamParser> _fs;
std::unique_ptr<ConfigBitstreamParser> _mcufw;
std::unique_ptr<ConfigBitstreamParser> _userflash;
uint32_t _idcode;
bool is_gw1n1;
bool is_gw1n4;