fprintf(stderr, " -o <offset in bytes> start address for read/write [default: 0]\n");
fprintf(stderr, " (append 'k' to the argument for size in kilobytes,\n");
fprintf(stderr, " or 'M' for size in megabytes)\n");
- fprintf(stderr, " -s slow SPI (50 kHz instead of 6 MHz)\n");
+ fprintf(stderr, " -k <divider> divider for SPI clock [default: 1]\n");
+ fprintf(stderr, " clock speed is 6MHz/divider");
+ fprintf(stderr, " -s slow SPI. (50 kHz instead of 6 MHz)\n");
+ fprintf(stderr, " Equivalent to -k 30\n");
fprintf(stderr, " -v verbose output\n");
fprintf(stderr, " -i [4,32,64] select erase block size [default: 64k]\n");
fprintf(stderr, "\n");
int erase_block_size = 64;
int erase_size = 0;
int rw_offset = 0;
+ int clkdiv = 1;
bool read_mode = false;
bool check_mode = false;
bool dont_erase = false;
bool prog_sram = false;
bool test_mode = false;
- bool slow_clock = false;
bool disable_protect = false;
bool disable_verify = false;
const char *filename = NULL;
/* Decode command line parameters */
int opt;
char *endptr;
- while ((opt = getopt_long(argc, argv, "d:i:I:rR:e:o:cbnStvspX", long_options, NULL)) != -1) {
+ while ((opt = getopt_long(argc, argv, "d:i:I:rR:e:o:k:scbnStvpX", long_options, NULL)) != -1) {
switch (opt) {
case 'd': /* device string */
devstr = optarg;
return EXIT_FAILURE;
}
break;
+ case 'k': /* set clock div */
+ clkdiv = strtol(optarg, &endptr, 0);
+ if (clkdiv < 1 || clkdiv > 65536) {
+ fprintf(stderr, "%s: clock divider must be in range 1-65536 `%s' is not a valid divider\n", my_name, optarg);
+ return EXIT_FAILURE;
+ }
+ break;
+ case 's': /* use slow SPI clock */
+ clkdiv = 30;
+ break;
case 'c': /* do not write just check */
check_mode = true;
break;
case 'v': /* provide verbose output */
verbose = true;
break;
- case 's': /* use slow SPI clock */
- slow_clock = true;
- break;
case 'p': /* disable flash protect before erase/write */
disable_protect = true;
break;
// ---------------------------------------------------------
fprintf(stderr, "init..\n");
- jtag_init(ifnum, devstr, slow_clock);
+ jtag_init(ifnum, devstr, clkdiv);
read_idcode();
read_status_register();
/**
* Performs any start-of-day tasks necessary to talk JTAG to our FPGA.
*/
-void jtag_init(int ifnum, const char *devstr, bool slow_clock)
+void jtag_init(int ifnum, const char *devstr, int clkdiv)
{
- mpsse_init(ifnum, devstr, slow_clock);
+ mpsse_init(ifnum, devstr, clkdiv);
jtag_set_current_state(STATE_TEST_LOGIC_RESET);
jtag_go_to_state(STATE_TEST_LOGIC_RESET);
}
//printf("jtag_shift_bytes(0x%08x,0x%08x,%u,%s);\n",input_data, output_data, data_bits, must_end ? "true" : "false");
uint32_t byte_count = data_bits / 8;
-
-
-
data[0] = MC_DATA_OUT | MC_DATA_IN | MC_DATA_LSB | MC_DATA_OCN;
data[1] = (byte_count - 1);
data[2] = (byte_count - 1) >> 8;
}
}
-void mpsse_init(int ifnum, const char *devstr, bool slow_clock)
+void mpsse_init(int ifnum, const char *devstr, int clkdiv)
{
enum ftdi_interface ftdi_ifnum = INTERFACE_A;
mpsse_send_byte(MC_TCK_X5);
- if (slow_clock) {
- // set 50 kHz clock
- mpsse_send_byte(MC_SET_CLK_DIV);
- mpsse_send_byte(29);
- mpsse_send_byte(0x00);
- } else {
- // set 6 MHz clock
- mpsse_send_byte(MC_SET_CLK_DIV);
- mpsse_send_byte(1);
- mpsse_send_byte(0x00);
- }
+ // set clock - actual clock is 6MHz/(clkdiv)
+ mpsse_send_byte(MC_SET_CLK_DIV);
+ mpsse_send_byte((clkdiv-1) & 0xff);
+ mpsse_send_byte((clkdiv-1) >> 8);
mpsse_send_byte(MC_SETB_LOW);
mpsse_send_byte(0x08); /* Value */
ftdi_disable_bitbang(&mpsse_ftdic);
ftdi_usb_close(&mpsse_ftdic);
ftdi_deinit(&mpsse_ftdic);
-}
\ No newline at end of file
+}