I'm sending the wireshark capture off list. Martin
On 04/27/2013 04:42 PM, Stefan Tauner wrote:
On Tue, 23 Apr 2013 10:16:27 -0600 Marc Jones marcj303@gmail.com wrote:
On Tue, Apr 23, 2013 at 9:21 AM, Joshua Zarr joshuazarr@gmail.com wrote:
Hi All,
I am using a dediprog SF100 to program the two flash chips (AT25DF321) on an intel Stargo CRB. Does flashrom support programming each chip individually?
I ran into the same thing. I think that the flashrom dediprog support needs a flag to switch the chipselect.
If anybody could supply us with traces of the USB traffic generated when another CS is used, we could probably add support for it. I dont know anything about the protocol or the vendor application but I guess it would be rather easy to find the interesting bits by creating and comparing dumps of two executions (e.g. the probing for a chip if that's supported) that differ only in the selected connection.
Thanks to the traces captured by Martin Roth, and confirmed by tests and analysis by Joshua Zarr, we can now use both target chips on the Dediprog SF100.
Signed-off-by: Stefan Tauner stefan.tauner@student.tuwien.ac.at --- dediprog.c | 51 +++++++++++++++++++++++++++++++++++++++------------ flashrom.8 | 12 ++++++++++++ 2 files changed, 51 insertions(+), 12 deletions(-)
diff --git a/dediprog.c b/dediprog.c index ae86810..2cf8949 100644 --- a/dediprog.c +++ b/dediprog.c @@ -560,19 +560,21 @@ static int dediprog_command_b(void) } #endif
-/* Command C is only sent after dediprog_check_devicestring, but not after every +/* Command Chip Select is only sent after dediprog_check_devicestring, but not after every * invocation of dediprog_check_devicestring. It is only sent after the first * dediprog_command_a(); dediprog_check_devicestring() sequence in each session. - * I'm tempted to call this one start_SPI_engine or finish_init. + * Bit #1 of the value changes the chip select: 0 is target 1, 1 is target 2 and parameter target can be 1 or 2 + * respectively. We don't know how to encode "3, Socket" and "0, reference card" yet. */ -static int dediprog_command_c(void) +static int dediprog_chip_select(int target) { int ret; - - ret = usb_control_msg(dediprog_handle, 0x42, 0x4, 0x0, 0x0, NULL, + uint16_t value = ((target - 1) & 1) << 1; + msg_pdbg("Selecting target chip %i\n", target); + ret = usb_control_msg(dediprog_handle, 0x42, 0x4, value, 0x0, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command C failed (%s)!\n", usb_strerror()); + msg_perr("Command Chip Select failed (%s)!\n", usb_strerror()); return 1; } return 0; @@ -722,7 +724,7 @@ static int parse_voltage(char *voltage) return millivolt; }
-static int dediprog_setup(void) +static int dediprog_setup(long target) { /* URB 6. Command A. */ if (dediprog_command_a()) { @@ -737,8 +739,8 @@ static int dediprog_setup(void) if (dediprog_check_devicestring()) { return 1; } - /* URB 10. Command C. */ - if (dediprog_command_c()) { + /* URB 10. Command Chip Select */ + if (dediprog_chip_select(target)) { return 1; } return 0; @@ -785,10 +787,11 @@ static int dediprog_shutdown(void *data) int dediprog_init(void) { struct usb_device *dev; - char *voltage, *device, *spispeed; + char *voltage, *device, *spispeed, *target_str; int spispeed_idx = 2; int millivolt = 3500; long usedevice = 0; + long target = 1; int i, ret;
msg_pspew("%s\n", __func__); @@ -841,6 +844,30 @@ int dediprog_init(void) } free(device);
+ target_str = extract_programmer_param("target"); + if (target_str) { + char *target_suffix; + errno = 0; + target = strtol(target_str, &target_suffix, 10); + if (errno != 0 || target_str == target_suffix) { + msg_perr("Error: Could not convert 'target'.\n"); + free(target_str); + return 1; + } + if (target < 1 || target > 2) { + msg_perr("Error: Value for 'target' is out of range.\n"); + free(target_str); + return 1; + } + if (strlen(target_suffix) > 0) { + msg_perr("Error: Garbage following 'target' value.\n"); + free(target_str); + return 1; + } + msg_pinfo("Using target %li.\n", target); + } + free(target_str); + /* Here comes the USB stuff. */ usb_init(); usb_find_busses(); @@ -877,13 +904,13 @@ int dediprog_init(void) dediprog_set_leds(PASS_ON|BUSY_ON|ERROR_ON);
/* Perform basic setup. */ - if (dediprog_setup()) { + if (dediprog_setup(target)) { dediprog_set_leds(PASS_OFF|BUSY_OFF|ERROR_ON); return 1; }
/* After setting voltage and speed, perform setup again. */ - if (dediprog_set_spi_voltage(0) || dediprog_set_spi_speed(spispeed_idx) || dediprog_setup()) { + if (dediprog_set_spi_voltage(0) || dediprog_set_spi_speed(spispeed_idx) || dediprog_setup(target)) { dediprog_set_leds(PASS_OFF|BUSY_OFF|ERROR_ON); return 1; } diff --git a/flashrom.8 b/flashrom.8 index e4e2b94..98f71d2 100644 --- a/flashrom.8 +++ b/flashrom.8 @@ -694,6 +694,18 @@ where can be .BR 375k ", " 750k ", " 1.5M ", " 2.18M ", " 3M ", " 8M ", " 12M " or " 24M (in Hz). The default is a frequency of 12 MHz. +.sp +An optional +.B target +parameter specifies which target chip should be used. Syntax is +.sp +.B " flashrom -p dediprog:target=value" +.sp +where +.B value +can be +.BR 1 " or " 2 +to select target chip 1 or 2 repectively. The default is target chip 1. .SS .BR "rayer_spi " programmer The default I/O base address used for the parallel port is 0x378 and you can use