diff --git a/CHANGELOG b/CHANGELOG
index d0652af..41398d9 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,7 @@
drivers (openbsd, netbsd, and others) set a byte-to-byte timeout which
can be exceeded by SD card latency.
- Upgrade to PSoC Creator 3.1 and gcc 4.8.4.
+ - Integrated scsi2sd-debug functionality with scsi2sd-util.
20150108 4.0
- Fix handling requests for LUNs other than 0 from SCSI-2 hosts.
diff --git a/hardware/gerber/scsi2sd.xy b/hardware/gerber/scsi2sd.xy
deleted file mode 100644
index 444b04c..0000000
--- a/hardware/gerber/scsi2sd.xy
+++ /dev/null
@@ -1,55 +0,0 @@
-# PcbXY Version 1.0
-# Date: Tue 09 Dec 2014 09:51:33 GMT UTC
-# Author: Michael McMaster
-# Title: (unknown) - PCB X-Y
-# RefDes, Description, Value, X, Y, rotation, top/bottom
-# X,Y in mil. rotation in degrees.
-# --------------------------------------------
-Q1,"SOT23_MOSFET","unknown",3327.09,2042.42,90,top
-U4,"SO14","unknown",2243.00,2414.50,270,top
-C22,"cap_0402","100nF",2940.94,188.00,180,top
-U3,"SO14","unknown",2820.00,2412.00,270,top
-U5,"SO14","unknown",1742.00,2410.50,270,top
-R5,"SMD_SIMPLE-80-50","22?",2266.41,1116.78,0,top
-J5,"fci-10118192-0001LF","unknown",1952.25,128.13,0,top
-R4,"SMD_SIMPLE-80-50","22?",2226.00,1211.00,0,top
-C2,"SMD_SIMPLE-80-50","10uF",1845.00,1252.00,0,top
-C9,"cap_0402","100nF",1949.69,1352.00,0,top
-C8,"cap_0402","1uF",2369.68,1217.00,180,top
-C20,"cap_0402","1uF",2397.06,1296.82,90,top
-C21,"cap_0402","100nF",2770.31,2007.00,180,top
-C11,"cap_0402","100nF",1970.00,2306.68,270,top
-C3,"cap_0402","100nF",3045.00,2306.68,270,top
-C19,"cap_0402","100nF",2355.00,2141.68,270,top
-C23,"cap_0402","100nF",2345.63,1297.32,90,top
-C10,"cap_0402","100nF",2465.00,2306.68,270,top
-C17,"cap_0402","100nF",2030.00,2112.31,270,top
-C28,"cap_0402","100nF",2705.00,1347.32,90,top
-D2,"diode-DO-214AA-SMB","unknown",190.00,2882.35,90,top
-F1,"SMD_SIMPLE-120-60","1.5A Hold",146.00,3203.00,270,top
-D1,"diode-DO-214AA-SMB","unknown",925.00,2881.65,90,top
-F2,"SMD_SIMPLE-120-60","500mA Hold",1624.00,164.00,180,top
-D3,"diode-DO-214AA-SMB","unknown",1355.35,207.00,0,top
-R3,"SMD_SIMPLE-80-50","1600",3108.59,2124.22,180,top
-C26,"cap_0402","1uF",2815.00,1756.68,270,top
-C24,"cap_0402","100nF",2750.00,1757.31,270,top
-C27,"cap_0402","1uF",2815.00,1662.32,90,top
-U1,"TQFP100_14_reflow","unknown",2339.53,1723.95,0,top
-C13,"SMD_SIMPLE-80-50","10uF",2977.20,334.06,180,top
-U6,"DPAK","unknown",725.00,812.00,0,top
-C12,"SMD_SIMPLE-80-50","10uF",497.06,584.80,0,top
-U2,"DPAK","unknown",725.00,1987.00,0,top
-C5,"SMD_SIMPLE-80-50","10uF",548.23,1752.12,180,top
-J6,"wurth-microsd","unknown",2542.10,257.35,180,top
-R6,"SMD_SIMPLE-80-50","22?",3330.00,1907.00,0,top
-R7,"SMD_SIMPLE-80-50","56?",3325.00,2202.00,0,top
-C6,"SMD_SIMPLE-80-50","10uF",410.00,2312.00,0,top
-R9,"SMD_SIMPLE-80-50","154?",410.00,2217.00,0,top
-R8,"SMD_SIMPLE-80-50","120?",570.00,2217.00,0,top
-C16,"cap_0402","0.1uF",1335.00,2886.68,270,top
-C15,"cap_0402","0.1uF",2410.35,2886.03,270,top
-C14,"SMD_SIMPLE-120-60","47uF",785.00,1047.00,0,top
-C4,"SMD_SIMPLE-120-60","47uF",185.00,2622.00,0,top
-C7,"SMD_SIMPLE-120-60","47uF",845.00,1752.00,0,top
-C1,"SMD_SIMPLE-120-60","47uF",1225.00,2949.00,270,top
-LED1,"SMD_DIODE-80-50","unknown",3109.00,2015.00,0,top
diff --git a/software/SCSI2SD/src/mode.c b/software/SCSI2SD/src/mode.c
index 56f34d7..e748b1b 100755
--- a/software/SCSI2SD/src/mode.c
+++ b/software/SCSI2SD/src/mode.c
@@ -27,7 +27,18 @@ static const uint8 ReadWriteErrorRecoveryPage[] =
{
0x01, // Page code
0x0A, // Page length
-0x00, // No error recovery options for now
+
+// VMS 5.5-2 is very particular regarding the mode page values.
+// The required values for a SCSI2/NoTCQ device are:
+// AWRE=0 ARRE=0 TB=1 RC=0 EER=? PER=1 DTE=1 DCR=?
+// See ftp://www.digiater.nl/openvms/decus/vms94b/net94b/scsi_params_dkdriver.txt
+// X-Newsgroups: comp.os.vms
+// Subject: Re: VMS 6.1 vs. Seagate Disk Drives
+// Message-Id: <32g87h$8q@nntpd.lkg.dec.com>
+// From: weber@evms.enet.dec.com (Ralph O. Weber -- OpenVMS AXP)
+// Date: 12 Aug 1994 16:32:49 GMT
+0x26,
+
0x00, // Don't try recovery algorithm during reads
0x00, // Correction span 0
0x00, // Head offset count 0,
@@ -305,7 +316,7 @@ static void doModeSense(
case 0x0A:
pageIn(pc, idx, ControlModePage, sizeof(ControlModePage));
idx += sizeof(ControlModePage);
- break;
+ if (pageCode != 0x3f) break;
case 0x30:
pageIn(pc, idx, AppleVendorPage, sizeof(AppleVendorPage));
diff --git a/software/SCSI2SD/v3/SCSI2SD.cydsn/Generated_Source/PSoC5/USBFS_descr.c b/software/SCSI2SD/v3/SCSI2SD.cydsn/Generated_Source/PSoC5/USBFS_descr.c
index 3144a03..ccd6a78 100644
--- a/software/SCSI2SD/v3/SCSI2SD.cydsn/Generated_Source/PSoC5/USBFS_descr.c
+++ b/software/SCSI2SD/v3/SCSI2SD.cydsn/Generated_Source/PSoC5/USBFS_descr.c
@@ -94,7 +94,7 @@ const uint8 CYCODE USBFS_DEVICE0_CONFIGURATION0_DESCR[73u] = {
/* bEndpointAddress */ 0x01u,
/* bmAttributes */ 0x03u,
/* wMaxPacketSize */ 0x40u, 0x00u,
-/* bInterval */ 0x80u,
+/* bInterval */ 0x20u,
/*********************************************************************
* Endpoint Descriptor
*********************************************************************/
@@ -103,7 +103,7 @@ const uint8 CYCODE USBFS_DEVICE0_CONFIGURATION0_DESCR[73u] = {
/* bEndpointAddress */ 0x82u,
/* bmAttributes */ 0x03u,
/* wMaxPacketSize */ 0x40u, 0x00u,
-/* bInterval */ 0x40u,
+/* bInterval */ 0x20u,
/*********************************************************************
* Interface Descriptor
*********************************************************************/
@@ -135,7 +135,7 @@ const uint8 CYCODE USBFS_DEVICE0_CONFIGURATION0_DESCR[73u] = {
/* bEndpointAddress */ 0x03u,
/* bmAttributes */ 0x03u,
/* wMaxPacketSize */ 0x40u, 0x00u,
-/* bInterval */ 0x80u,
+/* bInterval */ 0x20u,
/*********************************************************************
* Endpoint Descriptor
*********************************************************************/
@@ -144,7 +144,7 @@ const uint8 CYCODE USBFS_DEVICE0_CONFIGURATION0_DESCR[73u] = {
/* bEndpointAddress */ 0x84u,
/* bmAttributes */ 0x03u,
/* wMaxPacketSize */ 0x40u, 0x00u,
-/* bInterval */ 0x40u
+/* bInterval */ 0x20u
};
/*********************************************************************
diff --git a/software/SCSI2SD/v3/SCSI2SD.cydsn/Generated_Source/PSoC5/cymetadata.c b/software/SCSI2SD/v3/SCSI2SD.cydsn/Generated_Source/PSoC5/cymetadata.c
index dfdc40a..acda16c 100644
--- a/software/SCSI2SD/v3/SCSI2SD.cydsn/Generated_Source/PSoC5/cymetadata.c
+++ b/software/SCSI2SD/v3/SCSI2SD.cydsn/Generated_Source/PSoC5/cymetadata.c
@@ -28,7 +28,7 @@ __attribute__ ((__section__(".cyloadablemeta"), used))
const uint8 cy_meta_loadable[] = {
0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
- 0x00u, 0x00u, 0x00u, 0x00u, 0x5Cu, 0xD1u, 0x05u, 0x04u,
+ 0x00u, 0x00u, 0x00u, 0x00u, 0x5Cu, 0xD1u, 0x10u, 0x04u,
0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
diff --git a/software/SCSI2SD/v3/SCSI2SD.cydsn/SCSI2SD.cyfit b/software/SCSI2SD/v3/SCSI2SD.cydsn/SCSI2SD.cyfit
index 3040c7e..cf48a6b 100644
Binary files a/software/SCSI2SD/v3/SCSI2SD.cydsn/SCSI2SD.cyfit and b/software/SCSI2SD/v3/SCSI2SD.cydsn/SCSI2SD.cyfit differ
diff --git a/software/SCSI2SD/v3/SCSI2SD.cydsn/TopDesign/TopDesign.cysch b/software/SCSI2SD/v3/SCSI2SD.cydsn/TopDesign/TopDesign.cysch
index 8bbd6de..6a33d2e 100755
Binary files a/software/SCSI2SD/v3/SCSI2SD.cydsn/TopDesign/TopDesign.cysch and b/software/SCSI2SD/v3/SCSI2SD.cydsn/TopDesign/TopDesign.cysch differ
diff --git a/software/SCSI2SD/v3/USB_Bootloader.cydsn/USB_Bootloader.cyfit b/software/SCSI2SD/v3/USB_Bootloader.cydsn/USB_Bootloader.cyfit
index 953ab81..c2bb61e 100644
Binary files a/software/SCSI2SD/v3/USB_Bootloader.cydsn/USB_Bootloader.cyfit and b/software/SCSI2SD/v3/USB_Bootloader.cydsn/USB_Bootloader.cyfit differ
diff --git a/software/SCSI2SD/v3/USB_Bootloader.cydsn/USB_Bootloader.cyprj.Micha_000 b/software/SCSI2SD/v3/USB_Bootloader.cydsn/USB_Bootloader.cyprj.Micha_000
index 688eb60..cbfc68c 100755
--- a/software/SCSI2SD/v3/USB_Bootloader.cydsn/USB_Bootloader.cyprj.Micha_000
+++ b/software/SCSI2SD/v3/USB_Bootloader.cydsn/USB_Bootloader.cyprj.Micha_000
@@ -1492,6 +1492,7 @@
+
@@ -1525,7 +1526,7 @@
-
+
@@ -2141,14 +2142,14 @@
C:\Program Files (x86)\Cypress\PSoC Creator\3.1\PSoC Creator\psoc\content\cyprimitives\CyPrimitives.cylib\ZeroTerminal\ZeroTerminal.v
C:\Program Files (x86)\Cypress\PSoC Creator\3.1\PSoC Creator\warp\lib\common\stdlogic\rtlpkg.vif
-
+
-
+
-
+
diff --git a/software/SCSI2SD/v4/SCSI2SD.cydsn/SCSI2SD.cyfit b/software/SCSI2SD/v4/SCSI2SD.cydsn/SCSI2SD.cyfit
index 1dbc822..67548f7 100644
Binary files a/software/SCSI2SD/v4/SCSI2SD.cydsn/SCSI2SD.cyfit and b/software/SCSI2SD/v4/SCSI2SD.cydsn/SCSI2SD.cyfit differ
diff --git a/software/SCSI2SD/v4/USB_Bootloader.cydsn/USB_Bootloader.cyfit b/software/SCSI2SD/v4/USB_Bootloader.cydsn/USB_Bootloader.cyfit
index 8d65665..73330ab 100644
Binary files a/software/SCSI2SD/v4/USB_Bootloader.cydsn/USB_Bootloader.cyfit and b/software/SCSI2SD/v4/USB_Bootloader.cydsn/USB_Bootloader.cyfit differ
diff --git a/software/build.sh b/software/build.sh
index d437f60..8834607 100755
--- a/software/build.sh
+++ b/software/build.sh
@@ -5,8 +5,7 @@ Linux)
# Builds all of the utilities (not firmware) under Linux.
# Requires mingw installed to cross-compile Windows targets.
- (cd scsi2sd-util && ./build.sh) &&
- (cd scsi2sd-debug && ./build.sh)
+ (cd scsi2sd-util && ./build.sh)
if [ $? -eq 0 ]; then
mkdir -p build/linux
@@ -14,25 +13,20 @@ Linux)
mkdir -p build/windows/32bit
cp scsi2sd-util/build/linux/scsi2sd-util build/linux
- cp scsi2sd-debug/build/linux/scsi2sd-debug build/linux
cp scsi2sd-util/build/windows/32bit/scsi2sd-util.exe build/windows/32bit
- cp scsi2sd-debug/build/windows/32bit/scsi2sd-debug.exe build/windows/32bit
cp scsi2sd-util/build/windows/64bit/scsi2sd-util.exe build/windows/64bit
- cp scsi2sd-debug/build/windows/64bit/scsi2sd-debug.exe build/windows/64bit
fi
;;
Darwin)
- make -C scsi2sd-util &&
- make -C scsi2sd-debug
+ make -C scsi2sd-util
if [ $? -eq 0 ]; then
mkdir -p build/mac
cp scsi2sd-util/build/mac/scsi2sd-util build/mac
- cp scsi2sd-debug/build/mac/scsi2sd-debug build/mac
fi
esac
diff --git a/software/scsi2sd-debug/.gitignore b/software/scsi2sd-debug/.gitignore
deleted file mode 100644
index 567609b..0000000
--- a/software/scsi2sd-debug/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-build/
diff --git a/software/scsi2sd-debug/Makefile b/software/scsi2sd-debug/Makefile
deleted file mode 100644
index 5690879..0000000
--- a/software/scsi2sd-debug/Makefile
+++ /dev/null
@@ -1,63 +0,0 @@
-
-CPPFLAGS = -I ../bootloaderhost/hidapi/hidapi -I ../bootloaderhost
-CFLAGS += -Wall -Wno-pointer-sign -O2
-CXXFLAGS += -Wall -O2
-VPATH += ../bootloaderhost
-
-TARGET ?= $(shell uname -s)
-ifeq ($(TARGET),Win32)
- VPATH += hidapi/windows
- LDFLAGS += -static -mconsole -mwindows -lsetupapi -lws2_32
- BUILD = build/windows/32bit
- CC=i686-w64-mingw32-gcc
- CXX=i686-w64-mingw32-g++
- EXE=.exe
-endif
-ifeq ($(TARGET),Win64)
- VPATH += hidapi/windows
- LDFLAGS += -static -mconsole -mwindows -lsetupapi -lws2_32
- BUILD = build/windows/64bit
- CC=x86_64-w64-mingw32-gcc
- CXX=x86_64-w64-mingw32-g++
- EXE=.exe
-endif
-ifeq ($(TARGET),Linux)
- VPATH += hidapi/linux
- LDFLAGS += -ludev
- BUILD = build/linux
-endif
-ifeq ($(TARGET),Darwin)
- # Should match OSX
- VPATH += ../bootloaderhost/hidapi-mac
- LDFLAGS += -framework IOKit -framework CoreFoundation
- CFLAGS += -mmacosx-version-min=10.7
- CXXFLAGS += -stdlib=libc++ -mmacosx-version-min=10.7 -std=c++0x
- CC=clang
- CXX=clang++
- BUILD=build/mac
-endif
-
-all: $(BUILD)/scsi2sd-debug$(EXE)
-
-HIDAPI = \
- $(BUILD)/hid.o \
-
-OBJ = \
- $(HIDAPI) \
- $(BUILD)/scsi2sd-debug.o \
- $(BUILD)/SCSI2SD_HID.o \
-
-$(BUILD)/%.o: %.c
- mkdir -p $(dir $@)
- $(CC) $(CPPFLAGS) $(CFLAGS) $^ -c -o $@
-
-$(BUILD)/%.o: %.cc
- mkdir -p $(dir $@)
- $(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -c -o $@
-
-$(BUILD)/scsi2sd-debug$(EXE): $(OBJ)
- mkdir -p $(dir $@)
- $(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
-
-clean:
- rm $(BUILD)/scsi2sd-debug$(EXE) $(OBJ)
diff --git a/software/scsi2sd-debug/build.sh b/software/scsi2sd-debug/build.sh
deleted file mode 100755
index 64b4eea..0000000
--- a/software/scsi2sd-debug/build.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-rm -rf build/
-make && \
- make TARGET=Win32 &&
- make TARGET=Win64
-
diff --git a/software/scsi2sd-debug/scsi2sd-debug.cc b/software/scsi2sd-debug/scsi2sd-debug.cc
deleted file mode 100644
index 542f162..0000000
--- a/software/scsi2sd-debug/scsi2sd-debug.cc
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright (C) 2014 Michael McMaster
-//
-// This file is part of SCSI2SD.
-//
-// SCSI2SD is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// SCSI2SD is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with SCSI2SD. If not, see .
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-// htonl/ntohl includes.
-#ifdef _WIN32
-#include
-#else
-#include
-#endif
-
-#include "hidapi.h"
-
-#define MIN(a,b) (a < b ? a : b)
-
-FILE* logfile = NULL;
-
-static void readConfig(hid_device* handle)
-{
- // First byte is the report ID (0)
- unsigned char buf[65];
- memset(buf, 0, sizeof(buf));
- int result = hid_read(handle, buf, sizeof(buf));
-
- if (result < 0)
- {
- fprintf(stderr, "USB HID Read Failure: %ls\n", hid_error(handle));
- }
- int i;
- for (i = 0; i < 32; ++i)
- {
- fprintf(logfile, "%02x ", buf[i]);
- }
- fprintf(logfile, "\n");
- fflush(logfile);
-}
-
-static void usage()
-{
- printf("Usage: scsi2sd-debug outputfile\n");
- printf("\n");
- printf("outputfile\tPath to the output log file.\n\n");
- printf("\n\n");
- exit(1);
-}
-
-
-int main(int argc, char* argv[])
-{
- printf("SCSI2SD Debug Utility.\n");
- printf("Copyright (C) 2014 Michael McMaster \n\n");
-
- if (argc != 2)
- {
- usage();
- exit(1);
- }
-
- logfile = fopen(argv[1], "w");
- if (!logfile)
- {
- fprintf(stderr, "Could not write to file %s.\n", argv[1]);
- exit(1);
- }
-
-
- uint16_t vendorId = 0x04B4; // Cypress
- uint16_t productId = 0x1337; // SCSI2SD
-
- printf(
- "USB device parameters\n\tVendor ID:\t0x%04X\n\tProduct ID:\t0x%04X\n",
- vendorId,
- productId);
-
- // Enumerate and print the HID devices on the system
- struct hid_device_info *dev = hid_enumerate(vendorId, productId);
-
- if (!dev)
- {
- fprintf(stderr, "ERROR: SCSI2SD USB device not found.\n");
- exit(1);
- }
-
- // We need the SECOND interface for debug data
- while (dev && dev->interface_number != 1)
- {
- dev = dev->next;
- }
- if (!dev)
- {
- fprintf(stderr, "ERROR: SCSI2SD Debug firmware not enabled.\n");
- exit(1);
- }
-
- printf("USB Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls",
- dev->vendor_id, dev->product_id, dev->path, dev->serial_number);
- printf("\n");
- printf(" Manufacturer: %ls\n", dev->manufacturer_string);
- printf(" Product: %ls\n", dev->product_string);
- printf("\n");
-
- hid_device* handle = hid_open_path(dev->path);
- if (!handle)
- {
- fprintf(
- stderr,
- "ERROR: Could not open device %s. Check permissions.\n", dev->path
- );
- exit(1);
- }
-
-
- while (1)
- {
- readConfig(handle);
- }
-
- return 0;
-}
-
diff --git a/software/scsi2sd-util/SCSI2SD_HID.cc b/software/scsi2sd-util/SCSI2SD_HID.cc
index e81821b..6944b83 100644
--- a/software/scsi2sd-util/SCSI2SD_HID.cc
+++ b/software/scsi2sd-util/SCSI2SD_HID.cc
@@ -90,7 +90,7 @@ HID::HID(hid_device_info* hidInfo) :
for (int i = 0; i < 4; ++i)
{
buf[0] = 0; // report id
- hid_read(dev, buf, HID_PACKET_SIZE);
+ hid_read_timeout(dev, buf, HID_PACKET_SIZE, HID_TIMEOUT_MS);
if (watchVal == -1) watchVal = buf[25];
configIntFound = configIntFound && (buf[25] == watchVal);
}
@@ -177,7 +177,7 @@ HID::enterBootloader()
};
int result = hid_write(myDebugHandle, hidBuf, sizeof(hidBuf));
- if (result < 0)
+ if (result <= 0)
{
const wchar_t* err = hid_error(myDebugHandle);
std::stringstream ss;
@@ -196,7 +196,7 @@ HID::readFlashRow(int array, int row, std::vector& out)
static_cast(array),
static_cast(row)
};
- sendHIDPacket(cmd, out);
+ sendHIDPacket(cmd, out, HIDPACKET_MAX_LEN / 62);
}
void
@@ -208,7 +208,7 @@ HID::writeFlashRow(int array, int row, const std::vector& in)
cmd.push_back(static_cast(array));
cmd.push_back(static_cast(row));
std::vector out;
- sendHIDPacket(cmd, out);
+ sendHIDPacket(cmd, out, 1);
if ((out.size() < 1) || (out[0] != CONFIG_STATUS_GOOD))
{
std::stringstream ss;
@@ -217,6 +217,30 @@ HID::writeFlashRow(int array, int row, const std::vector& in)
}
}
+bool
+HID::readSCSIDebugInfo(std::vector& buf)
+{
+ buf[0] = 0; // report id
+ hid_set_nonblocking(myDebugHandle, 1);
+ int result =
+ hid_read_timeout(
+ myDebugHandle,
+ &buf[0],
+ HID_PACKET_SIZE,
+ HID_TIMEOUT_MS);
+ hid_set_nonblocking(myDebugHandle, 0);
+
+ if (result <= 0)
+ {
+ const wchar_t* err = hid_error(myDebugHandle);
+ std::stringstream ss;
+ ss << "USB HID read failure: " << err;
+ throw std::runtime_error(ss.str());
+ }
+ return result > 0;
+}
+
+
void
HID::readHID(uint8_t* buffer, size_t len)
{
@@ -224,9 +248,9 @@ HID::readHID(uint8_t* buffer, size_t len)
buffer[0] = 0; // report id
int result = -1;
- for (int retry = 0; retry < 3 && result < 0; ++retry)
+ for (int retry = 0; retry < 3 && result <= 0; ++retry)
{
- result = hid_read(myConfigHandle, buffer, len);
+ result = hid_read_timeout(myConfigHandle, buffer, len, HID_TIMEOUT_MS);
}
if (result < 0)
@@ -243,9 +267,14 @@ HID::readDebugData()
{
uint8_t buf[HID_PACKET_SIZE];
buf[0] = 0; // report id
- int result = hid_read(myDebugHandle, buf, HID_PACKET_SIZE);
+ int result =
+ hid_read_timeout(
+ myDebugHandle,
+ buf,
+ HID_PACKET_SIZE,
+ HID_TIMEOUT_MS);
- if (result < 0)
+ if (result <= 0)
{
const wchar_t* err = hid_error(myDebugHandle);
std::stringstream ss;
@@ -292,7 +321,7 @@ HID::ping()
std::vector out;
try
{
- sendHIDPacket(cmd, out);
+ sendHIDPacket(cmd, out, 1);
}
catch (std::runtime_error& e)
{
@@ -302,26 +331,66 @@ HID::ping()
return (out.size() >= 1) && (out[0] == CONFIG_STATUS_GOOD);
}
+std::vector
+HID::getSD_CSD()
+{
+ std::vector cmd { CONFIG_SDINFO };
+ std::vector out;
+ try
+ {
+ sendHIDPacket(cmd, out, 1);
+ }
+ catch (std::runtime_error& e)
+ {
+ return std::vector(16);
+ }
+
+ out.resize(16);
+ return out;
+}
+
+std::vector
+HID::getSD_CID()
+{
+ std::vector cmd { CONFIG_SDINFO };
+ std::vector out;
+ try
+ {
+ sendHIDPacket(cmd, out, 1);
+ }
+ catch (std::runtime_error& e)
+ {
+ return std::vector(16);
+ }
+
+ std::vector result(16);
+ for (size_t i = 0; i < 16; ++i) result[i] = out[16 + i];
+ return result;
+}
+
void
-HID::sendHIDPacket(const std::vector& cmd, std::vector& out)
+HID::sendHIDPacket(
+ const std::vector& cmd,
+ std::vector& out,
+ size_t responseLength)
{
assert(cmd.size() <= HIDPACKET_MAX_LEN);
hidPacket_send(&cmd[0], cmd.size());
uint8_t hidBuf[HID_PACKET_SIZE];
const uint8_t* chunk = hidPacket_getHIDBytes(hidBuf);
+
while (chunk)
{
uint8_t reportBuf[HID_PACKET_SIZE + 1] = { 0x00 }; // Report ID
memcpy(&reportBuf[1], chunk, HID_PACKET_SIZE);
int result = -1;
- for (int retry = 0; retry < 10 && result < 0; ++retry)
+ for (int retry = 0; retry < 10 && result <= 0; ++retry)
{
result = hid_write(myConfigHandle, reportBuf, sizeof(reportBuf));
- if (result < 0) wxMilliSleep(8);
}
- if (result < 0)
+ if (result <= 0)
{
const wchar_t* err = hid_error(myConfigHandle);
std::stringstream ss;
@@ -335,16 +404,11 @@ HID::sendHIDPacket(const std::vector& cmd, std::vector& out)
size_t respLen;
resp = hidPacket_getPacket(&respLen);
- // We need to poll quick enough to not skip packets
- // This depends on the USB HID device poll rate parameter.
- // SCSI2SD uses a 32ms poll rate, so we check for new chunks at 4x
- // that rate.
- for (int retry = 0; retry < (HIDPACKET_MAX_LEN / 62) * 30 && !resp; ++retry)
+ for (int retry = 0; retry < responseLength * 2 && !resp; ++retry)
{
- readHID(hidBuf, sizeof(hidBuf));
+ readHID(hidBuf, sizeof(hidBuf)); // Will block
hidPacket_recv(hidBuf, HID_PACKET_SIZE);
resp = hidPacket_getPacket(&respLen);
- if (!resp) wxMilliSleep(8);
}
if (!resp)
diff --git a/software/scsi2sd-util/SCSI2SD_HID.hh b/software/scsi2sd-util/SCSI2SD_HID.hh
index 98d62ed..443b3df 100644
--- a/software/scsi2sd-util/SCSI2SD_HID.hh
+++ b/software/scsi2sd-util/SCSI2SD_HID.hh
@@ -43,6 +43,11 @@ public:
static const size_t HID_PACKET_SIZE = 64;
+ // HID intervals for 4.0.3 firmware: <= 128ms
+ // > 4.0.3 = 32ms.
+ static const size_t HID_TIMEOUT_MS = 256; // 2x HID Interval.
+
+
static HID* Open();
~HID();
@@ -50,19 +55,26 @@ public:
uint16_t getFirmwareVersion() const { return myFirmwareVersion; }
std::string getFirmwareVersionStr() const;
uint32_t getSDCapacity() const { return mySDCapacity; }
+ std::vector getSD_CSD();
+ std::vector getSD_CID();
void enterBootloader();
void readFlashRow(int array, int row, std::vector& out);
void writeFlashRow(int array, int row, const std::vector& in);
bool ping();
+
+ bool readSCSIDebugInfo(std::vector& buf);
+
private:
HID(hid_device_info* hidInfo);
void destroy();
void readDebugData();
void readHID(uint8_t* buffer, size_t len);
void sendHIDPacket(
- const std::vector& cmd, std::vector& out
+ const std::vector& cmd,
+ std::vector& out,
+ size_t responseLength
);
hid_device_info* myHidInfo;
diff --git a/software/scsi2sd-util/scsi2sd-util.cc b/software/scsi2sd-util/scsi2sd-util.cc
index c608e32..a5ec3ee 100644
--- a/software/scsi2sd-util/scsi2sd-util.cc
+++ b/software/scsi2sd-util/scsi2sd-util.cc
@@ -41,6 +41,7 @@
#include "Firmware.hh"
#include
+#include
#include
#include
#include
@@ -135,7 +136,8 @@ public:
AppFrame() :
wxFrame(NULL, wxID_ANY, "scsi2sd-util", wxPoint(50, 50), wxSize(600, 650)),
myInitialConfig(false),
- myTickCounter(0)
+ myTickCounter(0),
+ myLastPollTime(0)
{
wxMenu *menuFile = new wxMenu();
menuFile->Append(
@@ -155,17 +157,23 @@ public:
"Show &Log",
"Show debug log window");
+ wxMenu *menuDebug = new wxMenu();
+ mySCSILogChk = menuDebug->AppendCheckItem(
+ ID_SCSILog,
+ "Log SCSI data",
+ "Log SCSI commands");
+
wxMenu *menuHelp = new wxMenu();
menuHelp->Append(wxID_ABOUT);
wxMenuBar *menuBar = new wxMenuBar();
menuBar->Append( menuFile, "&File" );
+ menuBar->Append( menuDebug, "&Debug" );
menuBar->Append( menuWindow, "&Window" );
menuBar->Append( menuHelp, "&Help" );
SetMenuBar( menuBar );
CreateStatusBar();
- wxLogStatus(this, "Searching for SCSI2SD");
{
wxPanel* cfgPanel = new wxPanel(this);
@@ -208,16 +216,19 @@ public:
//Fit(); // Needed to reduce window size on Windows
FitInside(); // Needed on Linux to prevent status bar overlap
- myTimer = new wxTimer(this, ID_Timer);
- myTimer->Start(1000); //ms
-
myLogWindow = new wxLogWindow(this, wxT("scsi2sd-util debug log"), true);
+ myLogWindow->PassMessages(false); // Prevent messagebox popups
+
+ myTimer = new wxTimer(this, ID_Timer);
+ myTimer->Start(16); //ms, suitable for scsi debug logging
}
+
private:
wxLogWindow* myLogWindow;
std::vector myTargets;
wxButton* myLoadButton;
wxButton* mySaveButton;
+ wxMenuItem* mySCSILogChk;
wxTimer* myTimer;
shared_ptr myHID;
shared_ptr myBootloader;
@@ -225,6 +236,16 @@ private:
uint8_t myTickCounter;
+ time_t myLastPollTime;
+
+ void mmLogStatus(const std::string& msg)
+ {
+ // We set PassMessages to false on our log window to prevent popups, but
+ // this also prevents wxLogStatus from updating the status bar.
+ SetStatusText(msg);
+ wxLogMessage(this, "%s", msg.c_str());
+ }
+
void onConfigChanged(wxCommandEvent& event)
{
evaluate();
@@ -307,7 +328,8 @@ private:
ID_Notebook,
ID_BtnLoad,
ID_BtnSave,
- ID_LogWindow
+ ID_LogWindow,
+ ID_SCSILog
};
void OnID_ConfigDefaults(wxCommandEvent& event)
@@ -350,7 +372,7 @@ private:
this,
wxPD_AUTO_HIDE | wxPD_CAN_ABORT)
);
- wxLogStatus(this, "Searching for bootloader");
+ mmLogStatus("Searching for bootloader");
while (true)
{
try
@@ -358,7 +380,7 @@ private:
if (!myHID) myHID.reset(HID::Open());
if (myHID)
{
- wxLogStatus(this, "Resetting SCSI2SD into bootloader");
+ mmLogStatus("Resetting SCSI2SD into bootloader");
myHID->enterBootloader();
myHID.reset();
@@ -370,7 +392,7 @@ private:
myBootloader.reset(Bootloader::Open());
if (myBootloader)
{
- wxLogStatus(this, "Bootloader found");
+ mmLogStatus("Bootloader found");
break;
}
}
@@ -380,19 +402,19 @@ private:
// Verify the USB HID connection is valid
if (!myBootloader->ping())
{
- wxLogStatus(this, "Bootloader ping failed");
+ mmLogStatus("Bootloader ping failed");
myBootloader.reset();
}
else
{
- wxLogStatus(this, "Bootloader found");
+ mmLogStatus("Bootloader found");
break;
}
}
}
catch (std::exception& e)
{
- wxLogStatus(this, "%s", e.what());
+ mmLogStatus(e.what());
myHID.reset();
myBootloader.reset();
}
@@ -414,19 +436,19 @@ private:
{
if (myBootloader->isCorrectFirmware((*it)->getPath()))
{
- wxLogStatus(this,
- "Found firmware entry %s within archive %s",
- (*it)->getPath(),
- filename);
+ std::stringstream msg;
+ msg << "Found firmware entry " << (*it)->getPath() <<
+ " within archive " << filename;
+ mmLogStatus(msg.str());
tmpFile =
wxFileName::CreateTempFileName(
wxT("SCSI2SD_Firmware"), static_cast(NULL)
);
zipper::FileWriter out(tmpFile);
(*it)->decompress(out);
- wxLogStatus(this,
- "Firmware extracted to %s",
- tmpFile);
+ msg.clear();
+ msg << "Firmware extracted to " << tmpFile;
+ mmLogStatus(msg.str());
break;
}
}
@@ -446,7 +468,7 @@ private:
}
catch (std::exception& e)
{
- wxLogStatus(this, "%s", e.what());
+ mmLogStatus(e.what());
std::stringstream msg;
msg << "Could not open firmware file: " << e.what();
wxMessageBox(
@@ -469,7 +491,9 @@ private:
TheProgressWrapper.setProgressDialog(progress, totalFlashRows);
}
- wxLogStatus(this, "Upgrading firmware from file: %s", tmpFile);
+ std::stringstream msg;
+ msg << "Upgrading firmware from file: " << tmpFile;
+ mmLogStatus(msg.str());
try
{
@@ -480,7 +504,7 @@ private:
"Firmware update successful",
"Firmware OK",
wxOK);
- wxLogStatus(this, "Firmware update successful");
+ mmLogStatus("Firmware update successful");
myHID.reset();
@@ -489,7 +513,7 @@ private:
catch (std::exception& e)
{
TheProgressWrapper.clearProgressDialog();
- wxLogStatus(this, "%s", e.what());
+ mmLogStatus(e.what());
myHID.reset();
myBootloader.reset();
@@ -502,8 +526,42 @@ private:
}
}
+ void logSCSI()
+ {
+ if (!mySCSILogChk->IsChecked() ||
+ !myHID)
+ {
+ return;
+ }
+ try
+ {
+ std::vector info(HID::HID_PACKET_SIZE);
+ if (myHID->readSCSIDebugInfo(info))
+ {
+ std::stringstream msg;
+ msg << std::hex;
+ for (size_t i = 0; i < 32 && i < info.size(); ++i)
+ {
+ msg << std::setfill('0') << std::setw(2) <<
+ static_cast(info[i]) << ' ';
+ }
+ wxLogMessage(this, msg.str().c_str());
+ }
+ }
+ catch (std::exception& e)
+ {
+ wxLogWarning(this, e.what());
+ myHID.reset();
+ }
+ }
+
void OnID_Timer(wxTimerEvent& event)
{
+ logSCSI();
+ time_t now = time(NULL);
+ if (now == myLastPollTime) return;
+ myLastPollTime = now;
+
// Check if we are connected to the HID device.
// AND/or bootloader device.
try
@@ -523,7 +581,7 @@ private:
if (myBootloader)
{
- wxLogStatus(this, "%s", "SCSI2SD Bootloader Ready");
+ mmLogStatus("SCSI2SD Bootloader Ready");
}
}
@@ -551,24 +609,49 @@ private:
if (!supressLog)
{
// Oh dear, old firmware
- wxLogStatus(
- this,
- "Firmware update required. Version %s",
- myHID->getFirmwareVersionStr());
+ std::stringstream msg;
+ msg << "Firmware update required. Version " <<
+ myHID->getFirmwareVersionStr();
+ mmLogStatus(msg.str());
}
}
else
{
- wxLogStatus(
- this,
- "SCSI2SD Ready, firmware version %s",
- myHID->getFirmwareVersionStr());
+ std::stringstream msg;
+ msg << "SCSI2SD Ready, firmware version " <<
+ myHID->getFirmwareVersionStr();
+ mmLogStatus(msg.str());
+
+ std::vector csd(myHID->getSD_CSD());
+ std::vector cid(myHID->getSD_CID());
+ std::stringstream sdinfo;
+ sdinfo << "SD Capacity (512-byte sectors): " <<
+ myHID->getSDCapacity() << std::endl;
+
+ sdinfo << "SD CSD Register: ";
+ for (size_t i = 0; i < csd.size(); ++i)
+ {
+ sdinfo <<
+ std::hex << std::setfill('0') << std::setw(2) <<
+ static_cast(csd[i]);
+ }
+ sdinfo << std::endl;
+ sdinfo << "SD CID Register: ";
+ for (size_t i = 0; i < cid.size(); ++i)
+ {
+ sdinfo <<
+ std::hex << std::setfill('0') << std::setw(2) <<
+ static_cast(cid[i]);
+ }
+
+ wxLogMessage(this, "%s", sdinfo.str());
if (!myInitialConfig)
{
wxCommandEvent loadEvent(wxEVT_NULL, ID_BtnLoad);
GetEventHandler()->AddPendingEvent(loadEvent);
}
+
}
}
else
@@ -583,7 +666,8 @@ private:
}
catch (std::runtime_error& e)
{
- wxLogStatus(this, "%s", e.what());
+ std::cerr << e.what() << std::endl;
+ mmLogStatus(e.what());
}
evaluate();
@@ -594,7 +678,7 @@ private:
TimerLock lock(myTimer);
if (!myHID) return;
- wxLogStatus(this, "Loading configuration");
+ mmLogStatus("Loading configuration");
wxWindowPtr progress(
new wxGenericProgressDialog(
@@ -619,7 +703,7 @@ private:
std::stringstream ss;
ss << "Reading flash array " << SCSI_CONFIG_ARRAY <<
" row " << (flashRow + j);
- wxLogStatus(this, "%s", ss.str());
+ mmLogStatus(ss.str());
currentProgress += 1;
if (!progress->Update(
(100 * currentProgress) / totalProgress,
@@ -640,7 +724,7 @@ private:
}
catch (std::runtime_error& e)
{
- wxLogStatus(this, "%s", e.what());
+ mmLogStatus(e.what());
goto err;
}
@@ -653,7 +737,7 @@ private:
}
myInitialConfig = true;
- wxLogStatus(this, "%s", "Load Complete");
+ mmLogStatus("Load Complete");
while (progress->Update(100, "Load Complete"))
{
// Wait for the user to click "Close"
@@ -662,7 +746,7 @@ private:
goto out;
err:
- wxLogStatus(this, "%s", "Load failed");
+ mmLogStatus("Load failed");
while (progress->Update(100, "Load failed"))
{
// Wait for the user to click "Close"
@@ -671,7 +755,7 @@ private:
goto out;
abort:
- wxLogStatus(this, "Load Aborted");
+ mmLogStatus("Load Aborted");
out:
return;
@@ -682,7 +766,7 @@ private:
TimerLock lock(myTimer);
if (!myHID) return;
- wxLogStatus(this, "Saving configuration");
+ mmLogStatus("Saving configuration");
wxWindowPtr progress(
new wxGenericProgressDialog(
@@ -708,7 +792,7 @@ private:
std::stringstream ss;
ss << "Programming flash array " << SCSI_CONFIG_ARRAY <<
" row " << (flashRow + j);
- wxLogStatus(this, "%s", ss.str());
+ mmLogStatus(ss.str());
currentProgress += 1;
if (!progress->Update(
(100 * currentProgress) / totalProgress,
@@ -731,7 +815,7 @@ private:
}
catch (std::runtime_error& e)
{
- wxLogStatus(this, "%s", e.what());
+ mmLogStatus(e.what());
goto err;
}
}
@@ -741,7 +825,7 @@ private:
myHID->enterBootloader();
myHID.reset();
- wxLogStatus(this, "Save Complete");
+ mmLogStatus("Save Complete");
while (progress->Update(100, "Save Complete"))
{
// Wait for the user to click "Close"
@@ -750,7 +834,7 @@ private:
goto out;
err:
- wxLogStatus(this, "Save failed");
+ mmLogStatus("Save failed");
while (progress->Update(100, "Save failed"))
{
// Wait for the user to click "Close"
@@ -759,10 +843,10 @@ private:
goto out;
abort:
- wxLogStatus(this, "Save Aborted");
+ mmLogStatus("Save Aborted");
out:
- (void) true; // empty statement.
+ return;
}
void OnExit(wxCommandEvent& event)