Merge pull request #390 from bg-gsl/lattice_fix_program
Lattice programming fix and boards added
This commit is contained in:
commit
5a3ab610a5
|
|
@ -126,7 +126,10 @@ static std::map <std::string, target_board_t> 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),
|
||||
|
|
|
|||
107
src/lattice.cpp
107
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) {
|
||||
|
|
|
|||
|
|
@ -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<std::string> 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();
|
||||
|
|
|
|||
|
|
@ -212,6 +212,9 @@ static std::map <uint32_t, fpga_model> fpga_list = {
|
|||
{0x310F0043, {"lattice", "CertusNX", "LFD2NX-17", 8}},
|
||||
{0x310F1043, {"lattice", "CertusNX", "LFD2NX-40", 8}},
|
||||
|
||||
/* Lattice CertusPro-NX */
|
||||
{0x010F4043, {"lattice", "CertusProNX", "LFCPNX-100", 8}},
|
||||
|
||||
/**************************************************************************/
|
||||
/* Gowin */
|
||||
/**************************************************************************/
|
||||
|
|
|
|||
Loading…
Reference in New Issue