diff --git a/src/board.hpp b/src/board.hpp index 6a1e4d4..33de882 100644 --- a/src/board.hpp +++ b/src/board.hpp @@ -126,7 +126,10 @@ static std::map board_list = { JTAG_BOARD("colorlight-i5", "", "cmsisdap", 0, 0, CABLE_DEFAULT), JTAG_BOARD("colorlight-i9", "", "cmsisdap", 0, 0, CABLE_DEFAULT), JTAG_BOARD("colorlight-i9+", "xc7a50tfgg484", "", 0, 0, CABLE_DEFAULT), - JTAG_BOARD("crosslinknx_evn", "", "ft2232", 0, 0, CABLE_DEFAULT), + JTAG_BOARD("crosslinknx_evn", "", "ft2232", 0, 0, CABLE_DEFAULT), + JTAG_BOARD("certusnx_versa_evn", "", "ft2232", 0, 0, CABLE_DEFAULT), + JTAG_BOARD("certuspronx_evn", "", "ft2232", 0, 0, CABLE_DEFAULT), + JTAG_BOARD("certuspronx_versa_evn", "", "ft2232", 0, 0, CABLE_DEFAULT), JTAG_BOARD("cyc1000", "10cl025256", "ft2232", 0, 0, CABLE_DEFAULT), JTAG_BOARD("c10lp-refkit", "10cl055484", "ft2232", 0, 0, CABLE_DEFAULT), JTAG_BOARD("de0", "", "usb-blaster",0, 0, CABLE_DEFAULT), diff --git a/src/lattice.cpp b/src/lattice.cpp index c4a5570..8b23a1a 100644 --- a/src/lattice.cpp +++ b/src/lattice.cpp @@ -28,7 +28,7 @@ using namespace std; #define ISC_ENABLE 0xC6 /* ISC_ENABLE - Offline Mode */ # define ISC_ENABLE_FLASH_MODE (1 << 3) # define ISC_ENABLE_SRAM_MODE (0 << 3) -#define ISC_ENABLE_TRANSPARANT 0x74 /* This command is used to put the device in transparent mode */ +#define ISC_ENABLE_TRANSPARENT 0x74 /* ISC_ENABLE_X This command is used to put the device in transparent mode */ #define ISC_DISABLE 0x26 /* ISC_DISABLE */ #define READ_DEVICE_ID_CODE 0xE0 /* IDCODE_PUB */ #define FLASH_ERASE 0x0E /* ISC_ERASE */ @@ -91,7 +91,7 @@ using namespace std; #define READ_FEABITS 0xFB /* LSC_READ_FEABITS */ /* See feaParser.hpp for FEAbit definitions */ #define PROG_DONE 0x5E /* ISC_PROGRAM_DONE - This command is used to program the done bit */ -#define REFRESH 0x79 /* LSC_REFRESH */ +#define REFRESH 0x79 /* LSC_REFRESH - Equivalent to toggle PROGRAMN pin */ #define READ_STATUS_REGISTER 0x3C /* LSC_READ_STATUS */ # define REG_STATUS_DONE (1 << 8) /* Flash or SRAM Done Flag (ISC_EN=0 -> 1 Successful Flash to SRAM transfer, ISC_EN=1 -> 1 Programmed) */ # define REG_STATUS_ISC_EN (1 << 9) /* Enable Configuration Interface (1=Enable, 0=Disable) */ @@ -103,6 +103,7 @@ using namespace std; # define REG_STATUS_AUTH_DONE (1 << 18) /* Authentication done */ # define REG_STATUS_PRI_BOOT_FAIL (1 << 21) /* Primary boot failure (1= Fail) even though secondary boot successful */ # define REG_STATUS_CNF_CHK_MASK (0x0f << 23) /* Configuration Status Check */ +#define REG_STATUS_PRV_CNF_CHK_MASK (0x0fUL << 33) /* NEXUS_FAMILY: Configuration Status Check of previous bitstrem */ # define REG_STATUS_MACHXO3D_CNF_CHK_MASK (0x0f << 22) /* Configuration Status Check */ # define REG_STATUS_EXEC_ERR (1 << 26) /*** NOT specified for MachXO3D ***/ # define REG_STATUS_DEV_VERIFIED (1 << 27) /* I=0 Device verified correct, I=1 Device failed to verify */ @@ -133,6 +134,7 @@ using namespace std; #define PROG_ECDSA_PUBKEY3 0x63 /* This command is used to program the fourth 128 bits of the ECDSA Public Key. */ #define READ_ECDSA_PUBKEY3 0x64 /* This command is used to read the fourth 128 bits of the ECDSA Public Key. */ #define ISC_NOOP 0xff /* This command is no operation command (NOOP) or null operation. */ +#define LSC_DEVICE_CONTROL 0x7D /* Multiple commands. Bit 3: configuration reset */ #define PUBKEY_LENGTH_BYTES 64 /* length of the public key (MachXO3D) in bytes */ @@ -204,6 +206,8 @@ Lattice::Lattice(Jtag *jtag, const string filename, const string &file_type, _fpga_family = NEXUS_FAMILY; } else if (family == "CertusNX") { _fpga_family = NEXUS_FAMILY; + } else if (family == "CertusProNX") { + _fpga_family = NEXUS_FAMILY; } else { printError("Unknown device family"); throw std::exception(); @@ -253,9 +257,9 @@ void displayFeabits(uint16_t _featbits) (((_featbits>>2)&0x01)?"Enabled" : "Disabled")); } -bool Lattice::checkStatus(uint32_t val, uint32_t mask) +bool Lattice::checkStatus(uint64_t val, uint64_t mask) { - uint32_t reg = readStatusReg(); + uint64_t reg = readStatusReg(); return ((reg & mask) == val) ? true : false; } @@ -303,7 +307,40 @@ bool Lattice::program_mem() memset(tx_buf, 0xff, 26); wr_rd(0x1C, tx_buf, 26, NULL, 0); - wr_rd(0xFf, NULL, 0, NULL, 0); + /* LSC_REFRESH 0x79 -- "Equivalent to toggle PROGRAMN pin" + * We REFRESH only if the fpga is in a status of error due to + * the previous bitstream. For example, this happens if + * no bitstream is present on the SPI FLASH + */ + /*flag to understand if we refreshed or not*/ + bool was_refreshed; + if (_fpga_family == NEXUS_FAMILY) { + if (!checkStatus(0, REG_STATUS_PRV_CNF_CHK_MASK)) { + printInfo("Error in previous bitstream execution. REFRESH: ", false); + wr_rd(REFRESH, NULL, 0, NULL, 0); + _jtag->set_state(Jtag::RUN_TEST_IDLE); + _jtag->toggleClk(1000); + /* In Lattice FPGA-TN-02099 document in a note it's reported that there + is a delay time after LSC_REFRESH where "Duration could be in + seconds". Without whis waiting time, busy flag can't be cleared.*/ + sleep(5); + was_refreshed = true; + if (!checkStatus(0, REG_STATUS_PRV_CNF_CHK_MASK)) { + printError("FAIL"); + displayReadReg(readStatusReg()); + return false; + } else { + printSuccess("DONE"); + } + } else { + was_refreshed = false; + if (_verbose){ + printInfo("No error in previous bitstream execution.", true); + } + } + } else { + was_refreshed = false; + } /* ISC Enable 0xC6 */ printInfo("Enable configuration: ", false); @@ -315,6 +352,29 @@ bool Lattice::program_mem() printSuccess("DONE"); } + if (was_refreshed) { + /* LSC_DEVICE_CONTROL 0x7D -- configuration reset */ + printInfo("Configuration Logic Reset: ", false); + uint8_t tx_tmp[1] = {0x08}; + wr_rd(LSC_DEVICE_CONTROL, tx_tmp, 1, NULL, 0); + _jtag->set_state(Jtag::RUN_TEST_IDLE); + _jtag->toggleClk(1000); + if(!pollBusyFlag()) { + printError("FAIL"); + return false; + } + + tx_tmp[0] = 0x00; + wr_rd(LSC_DEVICE_CONTROL, tx_tmp, 1, NULL, 0); + _jtag->set_state(Jtag::RUN_TEST_IDLE); + _jtag->toggleClk(1000); + if(!pollBusyFlag()) { + printError("FAIL"); + return false; + } + printSuccess("DONE"); + } + /* ISC ERASE */ printInfo("SRAM erase: ", false); if (flashErase(FLASH_ERASE_SRAM) == false) { @@ -356,6 +416,9 @@ bool Lattice::program_mem() _jtag->shiftDR(tmp, NULL, size*8, next_state); } + _jtag->set_state(Jtag::RUN_TEST_IDLE); + _jtag->toggleClk(1000); + uint32_t status_mask; if (_fpga_family == MACHXO3D_FAMILY) status_mask = REG_STATUS_MACHXO3D_CNF_CHK_MASK; @@ -888,20 +951,35 @@ bool Lattice::checkID() return true; } +/* returns the number of bits of the Device Status Register + * accordingly to _fpga_family + */ +int Lattice::get_statusreg_size(){ + if (_fpga_family == NEXUS_FAMILY) { + return 64; + } else{ + return 32; + } +} + /* feabits is MSB first * maybe this register too * or not */ -uint32_t Lattice::readStatusReg() +uint64_t Lattice::readStatusReg() { - uint32_t reg; - uint8_t rx[4], tx[4]; + uint64_t reg; + uint8_t rx[8], tx[8]; + + int reg_len = get_statusreg_size() / 8; + /* valgrind warn */ - memset(tx, 0, 4); - wr_rd(READ_STATUS_REGISTER, tx, 4, rx, 4); + memset(tx, 0, 8); + memset(rx, 0, 8); + wr_rd(READ_STATUS_REGISTER, tx, reg_len, rx, reg_len); _jtag->set_state(Jtag::RUN_TEST_IDLE); _jtag->toggleClk(1000); - reg = rx[3] << 24 | rx[2] << 16 | rx[1] << 8 | rx[0]; + reg = (uint64_t) rx[7] << 56 | (uint64_t) rx[6] << 48 | (uint64_t) rx[5] << 40 | (uint64_t) rx[4] << 32 | rx[3] << 24 | rx[2] << 16 | rx[1] << 8 | rx[0]; return reg; } @@ -940,7 +1018,7 @@ bool Lattice::wr_rd(uint8_t cmd, return true; } -void Lattice::displayReadReg(uint32_t dev) +void Lattice::displayReadReg(uint64_t dev) { uint8_t err; printf("displayReadReg\n"); @@ -1021,7 +1099,6 @@ void Lattice::displayReadReg(uint32_t dev) if ((dev >> 31) & 0x01) printf("\tFT Mode\n"); } -#if 0 if (_fpga_family == NEXUS_FAMILY) { if ((dev >> 33) & 0x01) printf("\tDry Run Done\n"); err = (dev >> 34)&0x0f; @@ -1089,7 +1166,7 @@ void Lattice::displayReadReg(uint32_t dev) } if ((dev >> 50) & 0x01) printf("\tAuthentication Done\n"); if ((dev >> 51) & 0x01) printf("\tDry Run Authentication Done\n"); -#endif + } } bool Lattice::pollBusyFlag(bool verbose) @@ -1307,7 +1384,7 @@ uint16_t Lattice::getUFMStartPageFromJEDEC(JedParser *_jed, int id) addres. TODO: In any case, JEDEC files don't carry part information. Verify against IDCODE read previously? */ - + if(raw_page_offset > 9211) { return raw_page_offset - 9211 - 1; // 7000 } else if(raw_page_offset > 5758) { diff --git a/src/lattice.hpp b/src/lattice.hpp index cf694ed..1a74861 100644 --- a/src/lattice.hpp +++ b/src/lattice.hpp @@ -73,6 +73,8 @@ class Lattice: public Device, SPIInterface { lattice_family_t _fpga_family; + int get_statusreg_size(); + bool program_intFlash(ConfigBitstreamParser *_cbp); bool program_extFlash(unsigned int offset, bool unprotect_flash); bool wr_rd(uint8_t cmd, uint8_t *tx, int tx_len, @@ -100,9 +102,9 @@ class Lattice: public Device, SPIInterface { bool flashErase(uint32_t mask); bool flashProg(uint32_t start_addr, const std::string &name, std::vector data); - bool checkStatus(uint32_t val, uint32_t mask); - void displayReadReg(uint32_t dev); - uint32_t readStatusReg(); + bool checkStatus(uint64_t val, uint64_t mask); + void displayReadReg(uint64_t dev); + uint64_t readStatusReg(); uint64_t readFeaturesRow(); bool writeFeaturesRow(uint64_t features, bool verify); uint16_t readFeabits(); diff --git a/src/part.hpp b/src/part.hpp index 0c45448..34e20c7 100644 --- a/src/part.hpp +++ b/src/part.hpp @@ -212,6 +212,9 @@ static std::map fpga_list = { {0x310F0043, {"lattice", "CertusNX", "LFD2NX-17", 8}}, {0x310F1043, {"lattice", "CertusNX", "LFD2NX-40", 8}}, + /* Lattice CertusPro-NX */ + {0x010F4043, {"lattice", "CertusProNX", "LFCPNX-100", 8}}, + /**************************************************************************/ /* Gowin */ /**************************************************************************/