
Hi,
sorry for the delay... I finally cleaned up my xilinx spartan3 code, and here is a proposal for an optional block write (originally called fast write).
The observation is that using callbacks for every single data/clock line change takes very long, doing this in a monolithic function is much faster; additionally, you could take advantage of some hardware (e.g. SPI, although I did not get this to work yet) to do the actual load.
Best regards, Wolfgang
PS: sorry I can not provide a better patch at the moment, git-diff without any arguments prints out an empty diff for any file present in the tree, and I do not know what I did to cause this.
diff --git a/common/spartan3.c b/common/spartan3.c old mode 100644 new mode 100755 index f7c4f8c..a386006 --- a/common/spartan3.c +++ b/common/spartan3.c @@ -40,7 +40,7 @@ #endif
#undef CFG_FPGA_CHECK_BUSY -#undef CFG_FPGA_PROG_FEEDBACK +// #undef CFG_FPGA_PROG_FEEDBACK
/* Note: The assumption is that we cannot possibly run fast enough to * overrun the device (the Slave Parallel mode can free run at 50MHz). @@ -505,35 +505,39 @@ static int Spartan3_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) } } while ((*fn->init) (cookie));
- /* Load the data */ - while (bytecount < bsize) { - - /* Xilinx detects an error if INIT goes low (active) - while DONE is low (inactive) */ - if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) { - puts ("** CRC error during FPGA load.\n"); - return (FPGA_FAIL); - } - val = data [bytecount ++]; - i = 8; - do { - /* Deassert the clock */ - (*fn->clk) (FALSE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - /* Write data */ - (*fn->wr) ((val & 0x80), TRUE, cookie); - CONFIG_FPGA_DELAY (); - /* Assert the clock */ - (*fn->clk) (TRUE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - val <<= 1; - i --; - } while (i > 0); + if(*fn->fwr) + (*fn->fwr) (data, bsize, TRUE, cookie); + else { + /* Load the data */ + while (bytecount < bsize) { + + /* Xilinx detects an error if INIT goes low (active) + while DONE is low (inactive) */ + if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) { + puts ("** CRC error during FPGA load.\n"); + return (FPGA_FAIL); + } + val = data [bytecount ++]; + i = 8; + do { + /* Deassert the clock */ + (*fn->clk) (FALSE, TRUE, cookie); + CONFIG_FPGA_DELAY (); + /* Write data */ + (*fn->wr) ((val & 0x80), TRUE, cookie); + CONFIG_FPGA_DELAY (); + /* Assert the clock */ + (*fn->clk) (TRUE, TRUE, cookie); + CONFIG_FPGA_DELAY (); + val <<= 1; + i --; + } while (i > 0);
#ifdef CFG_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); /* let them know we are alive */ + if (bytecount % (bsize / 40) == 0) + putc ('.'); /* let them know we are alive */ #endif + } }
CONFIG_FPGA_DELAY (); @@ -638,6 +642,11 @@ static int Spartan3_ss_reloc (Xilinx_desc * desc, ulong reloc_offset) addr = (ulong) (fn->wr) + reloc_offset; fn_r->wr = (Xilinx_wr_fn) addr;
+ if(*fn->fwr) { + addr = (ulong) (fn->fwr) + reloc_offset; + fn_r->fwr = (Xilinx_fastwr_fn) addr; + } + fn_r->relocated = TRUE;
} else { diff --git a/include/spartan3.h b/include/spartan3.h old mode 100644 new mode 100755 index 65a3f5a..11735e7 --- a/include/spartan3.h +++ b/include/spartan3.h @@ -58,6 +58,8 @@ typedef struct { Xilinx_init_fn init; Xilinx_done_fn done; Xilinx_wr_fn wr; +// for block write (fast_write): + Xilinx_fastwr_fn fwr; int relocated; } Xilinx_Spartan3_Slave_Serial_fns;