gowin: add flash GW1N1 support
- eraseFlash need 65 x 32bits for GW1N1, 1 x 32bits for others - improve flashFlash with delay according to the model
This commit is contained in:
parent
aa752856c3
commit
50fa17b62f
|
|
@ -64,7 +64,7 @@ using namespace std;
|
||||||
#define EFLASH_ERASE 0x75
|
#define EFLASH_ERASE 0x75
|
||||||
|
|
||||||
Gowin::Gowin(Jtag *jtag, const string filename, bool flash_wr, bool sram_wr,
|
Gowin::Gowin(Jtag *jtag, const string filename, bool flash_wr, bool sram_wr,
|
||||||
bool verbose): Device(jtag, filename, verbose)
|
bool verbose): Device(jtag, filename, verbose), is_gw1n1(false)
|
||||||
{
|
{
|
||||||
_fs = NULL;
|
_fs = NULL;
|
||||||
if (_filename != "") {
|
if (_filename != "") {
|
||||||
|
|
@ -82,6 +82,10 @@ Gowin::Gowin(Jtag *jtag, const string filename, bool flash_wr, bool sram_wr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_jtag->setClkFreq(2500000, 0);
|
_jtag->setClkFreq(2500000, 0);
|
||||||
|
|
||||||
|
/* erase and program flash differ for GW1N1 */
|
||||||
|
if (idCode() == 0x0900281B)
|
||||||
|
is_gw1n1 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gowin::~Gowin()
|
Gowin::~Gowin()
|
||||||
|
|
@ -98,6 +102,7 @@ void Gowin::reset()
|
||||||
|
|
||||||
void Gowin::programFlash()
|
void Gowin::programFlash()
|
||||||
{
|
{
|
||||||
|
int status;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
|
|
@ -126,8 +131,20 @@ void Gowin::programFlash()
|
||||||
return;
|
return;
|
||||||
wr_rd(RELOAD, NULL, 0, NULL, 0);
|
wr_rd(RELOAD, NULL, 0, NULL, 0);
|
||||||
wr_rd(NOOP, NULL, 0, NULL, 0);
|
wr_rd(NOOP, NULL, 0, NULL, 0);
|
||||||
|
|
||||||
|
/* wait for reload */
|
||||||
|
usleep(150*1000);
|
||||||
|
|
||||||
|
/* check if file checksum == checksum in FPGA */
|
||||||
|
status = readUserCode();
|
||||||
|
if (_fs->checksum() != status) {
|
||||||
|
printError("SRAM Flash: FAIL");
|
||||||
|
printf("%04x %04x\n", _fs->checksum(), status);
|
||||||
|
} else
|
||||||
|
printSuccess("SRAM Flash: Success");
|
||||||
|
|
||||||
if (_verbose)
|
if (_verbose)
|
||||||
printInfo("%08x\n", readUserCode());
|
displayReadReg(readStatusReg());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gowin::program(unsigned int offset)
|
void Gowin::program(unsigned int offset)
|
||||||
|
|
@ -320,7 +337,6 @@ bool Gowin::flashFLASH(uint8_t *data, int length)
|
||||||
uint8_t tt[39];
|
uint8_t tt[39];
|
||||||
bzero(tt, 39);
|
bzero(tt, 39);
|
||||||
|
|
||||||
ProgressBar progress("Flash SRAM", byte_length, 50);
|
|
||||||
_jtag->go_test_logic_reset();
|
_jtag->go_test_logic_reset();
|
||||||
|
|
||||||
/* we have to send
|
/* we have to send
|
||||||
|
|
@ -329,7 +345,6 @@ bool Gowin::flashFLASH(uint8_t *data, int length)
|
||||||
* full bitstream
|
* full bitstream
|
||||||
*/
|
*/
|
||||||
int buffer_length = byte_length+(6*4);
|
int buffer_length = byte_length+(6*4);
|
||||||
unsigned char buffer[byte_length+(6*4)];
|
|
||||||
unsigned char bufvalues[]={
|
unsigned char bufvalues[]={
|
||||||
0x47, 0x57, 0x31, 0x4E,
|
0x47, 0x57, 0x31, 0x4E,
|
||||||
0xff, 0xff , 0xff, 0xff,
|
0xff, 0xff , 0xff, 0xff,
|
||||||
|
|
@ -337,16 +352,28 @@ bool Gowin::flashFLASH(uint8_t *data, int length)
|
||||||
0xff, 0xff , 0xff, 0xff,
|
0xff, 0xff , 0xff, 0xff,
|
||||||
0xff, 0xff , 0xff, 0xff,
|
0xff, 0xff , 0xff, 0xff,
|
||||||
0xff, 0xff , 0xff, 0xff};
|
0xff, 0xff , 0xff, 0xff};
|
||||||
memcpy(buffer, bufvalues, sizeof bufvalues);
|
|
||||||
memcpy(buffer+6*4, data, byte_length);
|
|
||||||
|
|
||||||
int nb_xpage = buffer_length/256;
|
int nb_xpage = buffer_length/256;
|
||||||
if (nb_xpage * 256 != buffer_length)
|
if (nb_xpage * 256 != buffer_length) {
|
||||||
nb_xpage++;
|
nb_xpage++;
|
||||||
|
buffer_length = nb_xpage * 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char buffer[buffer_length];
|
||||||
|
/* fill theorical size with 0xff */
|
||||||
|
memset(buffer, 0xff, buffer_length);
|
||||||
|
/* fill first page with code */
|
||||||
|
memcpy(buffer, bufvalues, 6*4);
|
||||||
|
/* bitstream just after opcode */
|
||||||
|
memcpy(buffer+6*4, data, byte_length);
|
||||||
|
|
||||||
|
|
||||||
|
ProgressBar progress("Flash SRAM", buffer_length, 50);
|
||||||
|
|
||||||
for (int i=0, xpage=0; xpage < nb_xpage; i+=(nb_iter*4), xpage++) {
|
for (int i=0, xpage=0; xpage < nb_xpage; i+=(nb_iter*4), xpage++) {
|
||||||
wr_rd(CONFIG_ENABLE, NULL, 0, NULL, 0);
|
wr_rd(CONFIG_ENABLE, NULL, 0, NULL, 0);
|
||||||
wr_rd(EF_PROGRAM, NULL, 0, NULL, 0);
|
wr_rd(EF_PROGRAM, NULL, 0, NULL, 0);
|
||||||
|
if (xpage != 0)
|
||||||
_jtag->read_write(tt, NULL, 312, 0);
|
_jtag->read_write(tt, NULL, 312, 0);
|
||||||
addr = xpage << 6;
|
addr = xpage << 6;
|
||||||
tmp[3] = 0xff&(addr >> 24);
|
tmp[3] = 0xff&(addr >> 24);
|
||||||
|
|
@ -367,8 +394,16 @@ bool Gowin::flashFLASH(uint8_t *data, int length)
|
||||||
for (int x=0; x < 4; x++)
|
for (int x=0; x < 4; x++)
|
||||||
tx[3-x] = t[x];
|
tx[3-x] = t[x];
|
||||||
_jtag->shiftDR(tx, NULL, 32);
|
_jtag->shiftDR(tx, NULL, 32);
|
||||||
|
|
||||||
|
if (!is_gw1n1)
|
||||||
_jtag->read_write(tt, NULL, 40, 0);
|
_jtag->read_write(tt, NULL, 40, 0);
|
||||||
}
|
}
|
||||||
|
if (is_gw1n1) {
|
||||||
|
//usleep(10*2400*2);
|
||||||
|
uint8_t tt2[6008/8];
|
||||||
|
memset(tt2, 0, 6008/8);
|
||||||
|
_jtag->read_write(tt2, tt2, 6008, 0);
|
||||||
|
}
|
||||||
progress.display(i);
|
progress.display(i);
|
||||||
}
|
}
|
||||||
/* 2.2.6.6 */
|
/* 2.2.6.6 */
|
||||||
|
|
@ -426,16 +461,28 @@ bool Gowin::flashSRAM(uint8_t *data, int length)
|
||||||
*/
|
*/
|
||||||
bool Gowin::eraseFLASH()
|
bool Gowin::eraseFLASH()
|
||||||
{
|
{
|
||||||
|
uint8_t tt[37500];
|
||||||
unsigned char tx[4] = {0, 0, 0, 0};
|
unsigned char tx[4] = {0, 0, 0, 0};
|
||||||
printInfo("erase Flash ", false);
|
printInfo("erase Flash ", false);
|
||||||
wr_rd(EFLASH_ERASE, NULL, 0, NULL, 0);
|
wr_rd(EFLASH_ERASE, NULL, 0, NULL, 0);
|
||||||
_jtag->set_state(Jtag::RUN_TEST_IDLE);
|
_jtag->set_state(Jtag::RUN_TEST_IDLE);
|
||||||
|
//_jtag->read_write(tt, tt, 37500*8, 0);
|
||||||
|
|
||||||
|
/* GW1N1 need 65 x 32bits
|
||||||
|
* others 1 x 32bits
|
||||||
|
*/
|
||||||
|
int nb_iter = (is_gw1n1)?65:1;
|
||||||
|
for (int i = 0; i < nb_iter; i++) {
|
||||||
_jtag->shiftDR(tx, NULL, 32);
|
_jtag->shiftDR(tx, NULL, 32);
|
||||||
/* TN653 specifies to wait for 120ms with
|
_jtag->toggleClk(6);
|
||||||
|
}
|
||||||
|
/* TN653 specifies to wait for 160ms with
|
||||||
* there are no bit in status register to specify
|
* there are no bit in status register to specify
|
||||||
* when this operation is done so we need to wait
|
* when this operation is done so we need to wait
|
||||||
*/
|
*/
|
||||||
usleep(120000);
|
//usleep(2*120000);
|
||||||
|
//uint8_t tt[37500];
|
||||||
|
_jtag->read_write(tt, tt, 37500*8, 0);
|
||||||
printSuccess("Done");
|
printSuccess("Done");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,5 +52,6 @@ class Gowin: public Device {
|
||||||
uint32_t readStatusReg();
|
uint32_t readStatusReg();
|
||||||
uint32_t readUserCode();
|
uint32_t readUserCode();
|
||||||
FsParser *_fs;
|
FsParser *_fs;
|
||||||
|
bool is_gw1n1;
|
||||||
};
|
};
|
||||||
#endif // GOWIN_HPP_
|
#endif // GOWIN_HPP_
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue