-2016100X ?
+20170329 6.1.0
- Enable synchronous transfers on SCSI1 hosts
- Support 4MB/s sync transfers for Amiga A590 (WD33C93)
- - Faster SD performance, but cannot use USB + SD at the same time.
+ - Merge v4.7 release changes, excluding custom mode/inquiry pages
+ - various bug fixes
20161006 6.0.13
- Fixed SCSI timing issue
src/firmware/tape.c \
src/firmware/time.c \
src/firmware/trace.c \
+ src/firmware/vendor.c \
${USBCOMPOSITE_SRC}
build/firmware.elf: $(SRC) rtl/fpga_bitmap.o $(STM32OBJS)
typedef enum
{
S2S_CFG_QUIRKS_NONE,
- S2S_CFG_QUIRKS_APPLE
+ S2S_CFG_QUIRKS_APPLE,
+ S2S_CFG_QUIRKS_OMTI
} S2S_CFG_QUIRKS;
+typedef enum
+{
+ S2S_CFG_SPEED_NoLimit,
+ S2S_CFG_SPEED_ASYNC_15,
+ S2S_CFG_SPEED_ASYNC_33,
+ S2S_CFG_SPEED_ASYNC_50,
+ S2S_CFG_SPEED_SYNC_5,
+ S2S_CFG_SPEED_SYNC_10
+} S2S_CFG_SPEED;
+
typedef struct __attribute__((packed))
{
// bits 7 -> 3 = S2S_CFG_TARGET_FLAGS
uint8_t selectionDelay; // milliseconds. 255 = auto
uint8_t flags6; // S2S_CFG_FLAGS6
- uint8_t reserved[120]; // Pad out to 128 bytes
+ uint8_t scsiSpeed;
+
+ uint8_t reserved[119]; // Pad out to 128 bytes
} S2S_BoardCfg;
typedef enum
\r
#include <string.h>\r
\r
-static const uint16_t FIRMWARE_VERSION = 0x060E;\r
+static const uint16_t FIRMWARE_VERSION = 0x0610;\r
\r
// 1 flash row\r
static const uint8_t DEFAULT_CONFIG[128] =\r
response[26] = blockDev.state;\r
response[27] = scsiDev.lastSenseASC >> 8;\r
response[28] = scsiDev.lastSenseASC;\r
- response[29] = *SCSI_STS_DBX;\r
+ response[29] = *SCSI_STS_DBX & 0xff; // What we've read\r
response[30] = LastTrace;\r
- response[31] = 0; // Unused\r
+ response[31] = *SCSI_STS_DBX >> 8; // What we're writing\r
hidPacket_send(response, sizeof(response));\r
}\r
\r
uint32_t sectors =\r
rem < maxSectors ? rem : maxSectors;\r
scsiRead(&scsiDev.data[0], sectors * SD_SECTOR_SIZE, &parityError);\r
+\r
if (!parityError)\r
{\r
sdTmpWrite(&scsiDev.data[0], i + sdLBA, sectors);\r
}\r
i += sectors;\r
+\r
#if 0\r
// Wait for the next DMA interrupt. It's beneficial to halt the\r
// processor to give the DMA controller more memory bandwidth to\r
//#include "debug.h"\r
#include "tape.h"\r
#include "mo.h"\r
+#include "vendor.h"\r
\r
#include <string.h>\r
\r
}\r
#endif\r
\r
+\r
scsiEnterBusFree();\r
\r
// Wait for the initiator to cease driving signals\r
uint8_t message;\r
\r
uint8_t control = scsiDev.cdb[scsiDev.cdbLen - 1];\r
+\r
+ if (scsiDev.target->cfg->quirks == S2S_CFG_QUIRKS_OMTI)\r
+ {\r
+ // OMTI non-standard LINK control\r
+ if (control & 0x01)\r
+ {\r
+ scsiDev.phase = COMMAND;\r
+ return;\r
+ }\r
+ }\r
+\r
if ((scsiDev.status == GOOD) && (control & 0x01))\r
{\r
// Linked command.\r
{\r
message = MSG_COMMAND_COMPLETE;\r
}\r
+\r
+ if (scsiDev.target->cfg->quirks == S2S_CFG_QUIRKS_OMTI)\r
+ {\r
+ scsiDev.status |= (scsiDev.target->targetId & 0x03) << 5;\r
+ }\r
+\r
scsiWriteByte(scsiDev.status);\r
\r
scsiDev.lastStatus = scsiDev.status;\r
{\r
scsiReadBuffer();\r
}\r
- else if (!scsiModeCommand())\r
+ else if (!scsiModeCommand() && !scsiVendorCommand())\r
{\r
scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
scsiDev.target->sense.asc = INVALID_COMMAND_OPERATION_CODE;\r
int transferPeriod = extmsg[1];\r
int offset = extmsg[2];\r
\r
- if ((transferPeriod < scsiDev.minSyncPeriod) ||\r
+ if ((\r
+ (transferPeriod > 0) &&\r
+ (transferPeriod < scsiDev.minSyncPeriod)) ||\r
(scsiDev.minSyncPeriod == 0))\r
{\r
scsiDev.minSyncPeriod = transferPeriod;\r
// Amiga A590 (WD33C93 chip) only does 3.5MB/s sync\r
// After 80 we start to run out of bits in the fpga timing\r
// register.\r
- (transferPeriod == 0))\r
+ (transferPeriod == 0) ||\r
+ ((scsiDev.boardCfg.scsiSpeed != S2S_CFG_SPEED_NoLimit) &&\r
+ (scsiDev.boardCfg.scsiSpeed <= S2S_CFG_SPEED_ASYNC_50)))\r
{\r
scsiDev.target->syncOffset = 0;\r
scsiDev.target->syncPeriod = 0;\r
{\r
scsiDev.target->syncPeriod = 12; // 50ns, 20MB/s\r
}\r
- else */if (transferPeriod <= 25)\r
+ else */if (transferPeriod <= 25 &&\r
+ ((scsiDev.boardCfg.scsiSpeed == S2S_CFG_SPEED_NoLimit) ||\r
+ (scsiDev.boardCfg.scsiSpeed >= S2S_CFG_SPEED_SYNC_10)))\r
{\r
scsiDev.target->syncPeriod = 25; // 100ns, 10MB/s\r
- } else {\r
+\r
+ } else if (transferPeriod < 50 &&\r
+ ((scsiDev.boardCfg.scsiSpeed == S2S_CFG_SPEED_NoLimit) ||\r
+ (scsiDev.boardCfg.scsiSpeed >= S2S_CFG_SPEED_SYNC_10)))\r
+ {\r
+ scsiDev.target->syncPeriod = transferPeriod;\r
+ } else if (transferPeriod >= 50)\r
+ {\r
scsiDev.target->syncPeriod = transferPeriod;\r
+ } else {\r
+ scsiDev.target->syncPeriod = 50;\r
}\r
}\r
\r
\r
#include <string.h>\r
\r
-// Time until we consider ourselves selected\r
-// 400ns at 108MHz\r
-#define SCSI_DEFAULT_SELECTION 43\r
-#define SCSI_FAST_SELECTION 5\r
+static uint8_t asyncTimings[][4] =\r
+{\r
+/* Speed, Assert, Deskew, Hold, Glitch */\r
+{/*1.5MB/s*/ 28, 18, 13, 13},\r
+{/*3.3MB/s*/ 13, 6, 6, 13},\r
+{/*5MB/s*/ 9, 6, 6, 6} // 80ns\r
+};\r
\r
-// async.\r
-// Assumes a 108MHz fpga clock.\r
-// 2:0 Deskew count, 55ns\r
-// 6:4 Hold count, 53ns\r
-// 3:0 Assertion count, 80ns\r
-#define SCSI_DEFAULT_DESKEW 0x6\r
-#define SCSI_DEFAULT_TIMING ((0x6 << 4) | 0x9)\r
+#define SCSI_ASYNC_15 0\r
+#define SCSI_ASYNC_33 1\r
+#define SCSI_ASYNC_50 2\r
\r
-// 3.125MB/s (80 period) to < 10MB/s sync\r
-// Assumes a 108MHz fpga clock. (9 ns)\r
-// (((period * 4) / 2) * 0.8) / 9\r
-// Done using 3 fixed point math.\r
-// 2:0 Deskew count, 55ns normal, or 25ns if faster than 5.5MB/s\r
-// 6:4 Hold count, 53ns normal, or 33ns if faster than 5.5MB/s\r
-// 3:0 Assertion count, variable\r
-#define SCSI_SYNC_DESKEW(period) (period < 45 ? SCSI_FAST10_DESKEW : SCSI_DEFAULT_DESKEW)\r
-#define SCSI_SYNC_TIMING(period) (((period < 45 ? 0x4 : 0x6) << 4) | ((((((int)period) * 177) + 750)/1000) & 0xF))\r
+// 5MB/s synchronous timing\r
+#define SCSI_FAST5_DESKEW 6 // 55ns\r
+#define SCSI_FAST5_HOLD 6 // 53ns\r
\r
-// 10MB/s\r
+// 10MB/s synchronous timing\r
// 2:0 Deskew count, 25ns\r
// 6:4 Hold count, 33ns\r
// 3:0 Assertion count, 30ns\r
// We want deskew + hold + assert + 3 to add up to 11 clocks\r
// the fpga code has 1 clock of overhead when transitioning from deskew to\r
// assert to hold\r
-#define SCSI_FAST10_DESKEW 2\r
-#define SCSI_FAST10_TIMING ((0x3 << 4) | 0x3)\r
\r
-// 20MB/s\r
-// 2:0 Deskew count, 12ns\r
-// 6:4 Hold count, 17ns\r
-// 3:0 Assertion count, 15ns\r
-#define SCSI_FAST20_DESKEW 1\r
-#define SCSI_FAST20_TIMING ((0x2 << 4) | 0x2)\r
+#define SCSI_FAST10_DESKEW 2 // 25ns\r
+#define SCSI_FAST10_HOLD 3 // 33ns\r
+#define SCSI_FAST10_ASSERT 3 // 30ns\r
+\r
+#define syncDeskew(period) ((period) < 45 ? \\r
+ SCSI_FAST10_DESKEW : SCSI_FAST5_DESKEW)\r
+\r
+#define syncHold(period) ((period) < 45 ? \\r
+ ((period) == 25 ? SCSI_FAST10_HOLD : 4) /* 25ns/33ns */\\r
+ : SCSI_FAST5_HOLD)\r
+\r
+\r
+// 3.125MB/s (80 period) to < 10MB/s sync\r
+// Assumes a 108MHz fpga clock. (9 ns)\r
+// (((period * 4) / 2) * 0.8) / 9\r
+// Done using 3 fixed point math.\r
+// 3:0 Assertion count, variable\r
+#define syncAssertion(period) ((((((int)period) * 177) + 750)/1000) & 0xF)\r
+\r
+// Time until we consider ourselves selected\r
+// 400ns at 108MHz\r
+#define SCSI_DEFAULT_SELECTION 43\r
+#define SCSI_FAST_SELECTION 5\r
\r
// Private DMA variables.\r
static int dmaInProgress = 0;\r
*SCSI_CTRL_PHASE = 0;\r
}\r
\r
+static void\r
+scsiSetTiming(\r
+ uint8_t assertClocks,\r
+ uint8_t deskew,\r
+ uint8_t hold,\r
+ uint8_t glitch)\r
+{\r
+ *SCSI_CTRL_DESKEW = ((hold & 7) << 5) | (deskew & 0x1F);\r
+ *SCSI_CTRL_TIMING = (assertClocks & 0x3F);\r
+ *SCSI_CTRL_TIMING3 = (glitch & 0xF);\r
+}\r
+\r
+static void\r
+scsiSetDefaultTiming()\r
+{\r
+ const uint8_t* asyncTiming = asyncTimings[3];\r
+ scsiSetTiming(\r
+ asyncTiming[0],\r
+ asyncTiming[1],\r
+ asyncTiming[2],\r
+ asyncTiming[3]);\r
+}\r
+\r
void scsiEnterPhase(int phase)\r
{\r
// ANSI INCITS 362-2002 SPI-3 10.7.1:\r
if ((newPhase == DATA_IN || newPhase == DATA_OUT) &&\r
scsiDev.target->syncOffset)\r
{\r
- if (scsiDev.target->syncPeriod == 12)\r
+ \r
+ if (scsiDev.target->syncPeriod <= 25)\r
{\r
- // SCSI2 FAST-20 Timing. 20MB/s.\r
- *SCSI_CTRL_DESKEW = SCSI_FAST20_DESKEW;\r
- *SCSI_CTRL_TIMING = SCSI_FAST20_TIMING;\r
- }\r
- else if (scsiDev.target->syncPeriod == 25)\r
- {\r
- // SCSI2 FAST Timing. 10MB/s.\r
- *SCSI_CTRL_DESKEW = SCSI_FAST10_DESKEW;\r
- *SCSI_CTRL_TIMING = SCSI_FAST10_TIMING;\r
+ scsiSetTiming(SCSI_FAST10_ASSERT, SCSI_FAST10_DESKEW, SCSI_FAST10_HOLD, 1);\r
}\r
else\r
{\r
- *SCSI_CTRL_DESKEW = SCSI_SYNC_DESKEW(scsiDev.target->syncPeriod);\r
- *SCSI_CTRL_TIMING = SCSI_SYNC_TIMING(scsiDev.target->syncPeriod);\r
+ scsiSetTiming(\r
+ syncAssertion(scsiDev.target->syncPeriod),\r
+ syncDeskew(scsiDev.target->syncPeriod),\r
+ syncHold(scsiDev.target->syncPeriod),\r
+ scsiDev.target->syncPeriod < 45 ? 1 : 5);\r
}\r
\r
// See note 26 in SCSI 2 standard: SCSI 1 implementations may assume\r
} else {\r
*SCSI_CTRL_SYNC_OFFSET = scsiDev.target->syncOffset;\r
}\r
- } else {\r
+ }\r
+ else\r
+ {\r
+\r
*SCSI_CTRL_SYNC_OFFSET = 0;\r
+ const uint8_t* asyncTiming;\r
+\r
+ if (scsiDev.boardCfg.scsiSpeed == S2S_CFG_SPEED_NoLimit ||\r
+ scsiDev.boardCfg.scsiSpeed >= S2S_CFG_SPEED_ASYNC_50) {\r
+\r
+ asyncTiming = asyncTimings[SCSI_ASYNC_50];\r
+ } else if (scsiDev.boardCfg.scsiSpeed >= S2S_CFG_SPEED_ASYNC_33) {\r
\r
- // 5MB/s Timing\r
- *SCSI_CTRL_DESKEW = SCSI_DEFAULT_DESKEW;\r
- *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;\r
+ asyncTiming = asyncTimings[SCSI_ASYNC_33];\r
+ \r
+ } else {\r
+ asyncTiming = asyncTimings[SCSI_ASYNC_15];\r
+ }\r
+ scsiSetTiming(\r
+ asyncTiming[0],\r
+ asyncTiming[1],\r
+ asyncTiming[2],\r
+ asyncTiming[3]);\r
}\r
\r
*SCSI_CTRL_PHASE = newPhase;\r
*SCSI_CTRL_DBX = 0;\r
\r
*SCSI_CTRL_SYNC_OFFSET = 0;\r
- *SCSI_CTRL_DESKEW = SCSI_DEFAULT_DESKEW;\r
- *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;\r
+ scsiSetDefaultTiming();\r
\r
// DMA Benchmark code\r
// Currently 11MB/s.\r
*SCSI_CTRL_DBX = 0;\r
\r
*SCSI_CTRL_SYNC_OFFSET = 0;\r
- *SCSI_CTRL_DESKEW = SCSI_DEFAULT_DESKEW;\r
- *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;\r
+ scsiSetDefaultTiming();\r
\r
*SCSI_CTRL_SEL_TIMING = SCSI_DEFAULT_SELECTION;\r
\r
{\r
*SCSI_CTRL_DBX = i;\r
busSettleDelay();\r
- if (*SCSI_STS_DBX != (i & 0xff))\r
+ // STS_DBX is 16 bit!\r
+ if ((*SCSI_STS_DBX & 0xff) != (i & 0xff))\r
{\r
result |= 1;\r
}\r
#define SCSI_DATA_CNT_SET ((volatile uint8_t*)0x6000000C)
#define SCSI_CTRL_DBX ((volatile uint8_t*)0x6000000E)
#define SCSI_CTRL_SYNC_OFFSET ((volatile uint8_t*)0x60000010)
-#define SCSI_CTRL_DESKEW ((volatile uint8_t*)0x60000012)
-#define SCSI_CTRL_TIMING ((volatile uint8_t*)0x60000014)
+#define SCSI_CTRL_DESKEW ((volatile uint8_t*)0x60000012)// Timing
+#define SCSI_CTRL_TIMING ((volatile uint8_t*)0x60000014)//Timing2
+#define SCSI_CTRL_TIMING3 ((volatile uint8_t*)0x6000001A)//Timing3
#define SCSI_CTRL_FLAGS ((volatile uint8_t*)0x60000016)
#define SCSI_CTRL_FLAGS_DISABLE_GLITCH 0x1
#define SCSI_CTRL_FLAGS_ENABLE_PARITY 0x2
#define SCSI_STS_FIFO_COMPLETE ((volatile uint8_t*)0x60000024)
#define SCSI_STS_SELECTED ((volatile uint8_t*)0x60000026)
#define SCSI_STS_SCSI ((volatile uint8_t*)0x60000028)
-#define SCSI_STS_DBX ((volatile uint8_t*)0x6000002A)
+
+// top 8 bits = data we're writing.
+// bottom 8 bits = data we're reading
+#define SCSI_STS_DBX ((volatile uint16_t*)0x6000002A)
+
#define SCSI_STS_PARITY_ERR ((volatile uint8_t*)0x6000002C)
#define SCSI_FIFO_DATA ((volatile uint16_t*)0x60000040)
uint32_t s2s_diffTime_ms(uint32_t start, uint32_t end);
uint32_t s2s_elapsedTime_ms(uint32_t since);
-#define s2s_cpu_freq 120000000LL
+#define s2s_cpu_freq 108000000LL
#define s2s_delay_ms(delay) s2s_delay_clocks((delay) * (s2s_cpu_freq / 1000))
#define s2s_delay_us(delay) s2s_delay_clocks((delay) * (s2s_cpu_freq / 1000000))
void s2s_delay_clocks(uint32_t delay);
myParent(parent),
myDelayValidator(new wxIntegerValidator<uint8_t>)
{
- wxFlexGridSizer *fgs = new wxFlexGridSizer(11, 2, 9, 25);
+ wxFlexGridSizer *fgs = new wxFlexGridSizer(13, 2, 9, 25);
fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
myTermCtrl =
myTermCtrl->SetToolTip(_("Enable active terminator. Both ends of the SCSI chain must be terminated."));
fgs->Add(myTermCtrl);
+ fgs->Add(new wxStaticText(this, wxID_ANY, _("SCSI Speed Limit")));
+ wxString speeds[] = {
+ wxT("No limit"),
+ wxT("Async, 1.5MB/s"),
+ wxT("Async, 3.3MB/s"),
+ wxT("Async, 5 MB/s"),
+ wxT("Sync, 5 MB/s")};
+
+ myScsiSpeedCtrl =
+ new wxChoice(
+ this,
+ ID_scsiSpeedCtrl,
+ wxDefaultPosition,
+ wxDefaultSize,
+ sizeof(speeds) / sizeof(wxString),
+ speeds
+ );
+ myScsiSpeedCtrl->SetToolTip(_("Limit SCSI interface speed"));
+ fgs->Add(myScsiSpeedCtrl);
+
fgs->Add(new wxStaticText(this, wxID_ANY, _("Startup Delay (seconds)")));
myStartDelayCtrl =
new wxTextCtrl(
myScsi2Ctrl->SetToolTip(_("Enable high-performance mode. May cause problems with SASI/SCSI1 hosts."));
fgs->Add(myScsi2Ctrl);
- fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
- myGlitchCtrl =
- new wxCheckBox(
- this,
- ID_glitchCtrl,
- _("Disable glitch filter"));
- myGlitchCtrl->SetToolTip(_("Improve performance at the cost of noise immunity. Only use with short cables."));
- fgs->Add(myGlitchCtrl);
-
- fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
- myCacheCtrl =
- new wxCheckBox(
- this,
- ID_cacheCtrl,
- _("Enable disk cache (experimental)"));
- myCacheCtrl->SetToolTip(_("SD IO commands aren't completed when SCSI commands complete"));
- fgs->Add(myCacheCtrl);
-
- fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
- myDisconnectCtrl =
- new wxCheckBox(
- this,
- ID_disconnectCtrl,
- _("Enable SCSI Disconnect"));
- myDisconnectCtrl->SetToolTip(_("Release the SCSI bus while waiting for SD card writes to complete. Must also be enabled in host OS."));
- fgs->Add(myDisconnectCtrl);
-
fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
mySelLatchCtrl =
new wxCheckBox(
(myParityCtrl->IsChecked() ? S2S_CFG_ENABLE_PARITY : 0) |
(myUnitAttCtrl->IsChecked() ? S2S_CFG_ENABLE_UNIT_ATTENTION : 0) |
(myScsi2Ctrl->IsChecked() ? S2S_CFG_ENABLE_SCSI2 : 0) |
- (myGlitchCtrl->IsChecked() ? S2S_CFG_DISABLE_GLITCH : 0) |
- (myCacheCtrl->IsChecked() ? S2S_CFG_ENABLE_CACHE: 0) |
- (myDisconnectCtrl->IsChecked() ? S2S_CFG_ENABLE_DISCONNECT: 0) |
(mySelLatchCtrl->IsChecked() ? S2S_CFG_ENABLE_SEL_LATCH : 0) |
(myMapLunsCtrl->IsChecked() ? S2S_CFG_MAP_LUNS_TO_IDS : 0);
config.startupDelay = CtrlGetValue<unsigned int>(myStartDelayCtrl).first;
config.selectionDelay = CtrlGetValue<unsigned int>(mySelDelayCtrl).first;
+ config.scsiSpeed = myScsiSpeedCtrl->GetSelection();
return config;
}
myParityCtrl->SetValue(config.flags & S2S_CFG_ENABLE_PARITY);
myUnitAttCtrl->SetValue(config.flags & S2S_CFG_ENABLE_UNIT_ATTENTION);
myScsi2Ctrl->SetValue(config.flags & S2S_CFG_ENABLE_SCSI2);
- myGlitchCtrl->SetValue(config.flags & S2S_CFG_DISABLE_GLITCH);
myTermCtrl->SetValue(config.flags6 & S2S_CFG_ENABLE_TERMINATOR);
- myCacheCtrl->SetValue(config.flags & S2S_CFG_ENABLE_CACHE);
- myDisconnectCtrl->SetValue(config.flags & S2S_CFG_ENABLE_DISCONNECT);
mySelLatchCtrl->SetValue(config.flags & S2S_CFG_ENABLE_SEL_LATCH);
myMapLunsCtrl->SetValue(config.flags & S2S_CFG_MAP_LUNS_TO_IDS);
conv << static_cast<unsigned int>(config.selectionDelay);
mySelDelayCtrl->ChangeValue(conv.str());
}
+ myScsiSpeedCtrl->SetSelection(config.scsiSpeed);
}
ID_parityCtrl = wxID_HIGHEST + 1,
ID_unitAttCtrl,
ID_scsi2Ctrl,
- ID_glitchCtrl,
ID_termCtrl,
- ID_cacheCtrl,
- ID_disconnectCtrl,
ID_selLatchCtrl,
ID_mapLunsCtrl,
ID_startDelayCtrl,
- ID_selDelayCtrl
+ ID_selDelayCtrl,
+ ID_scsiSpeedCtrl
};
wxWindow* myParent;
wxCheckBox* myParityCtrl;
wxCheckBox* myUnitAttCtrl;
wxCheckBox* myScsi2Ctrl;
- wxCheckBox* myGlitchCtrl;
wxCheckBox* myTermCtrl;
- wxCheckBox* myCacheCtrl;
- wxCheckBox* myDisconnectCtrl;
wxCheckBox* mySelLatchCtrl;
wxCheckBox* myMapLunsCtrl;
wxIntegerValidator<uint8_t>* myDelayValidator;
wxTextCtrl* myStartDelayCtrl;
wxTextCtrl* mySelDelayCtrl;
+
+ wxChoice* myScsiSpeedCtrl;
};
} // namespace SCSI2SD
" <!-- ********************************************************\n" <<
" Space separated list. Available options:\n" <<
" apple\t\tReturns Apple-specific mode pages\n" <<
+ " omti\t\tOMTI host non-standard link control\n" <<
" ********************************************************* -->\n" <<
- " <quirks>" <<
- (config.quirks & S2S_CFG_QUIRKS_APPLE ? "apple" : "") <<
+ " <quirks>";
+ if (config.quirks == S2S_CFG_QUIRKS_APPLE)
+ {
+ s << "apple";
+ }
+ else if (config.quirks == S2S_CFG_QUIRKS_OMTI)
+ {
+ s << "omti";
+ }
+
+ s <<
"</quirks>\n" <<
"\n\n" <<
(config.flags & S2S_CFG_ENABLE_SCSI2 ? "true" : "false") <<
"</enableScsi2>\n" <<
- " <enableCache>" <<
- (config.flags & S2S_CFG_ENABLE_CACHE ? "true" : "false") <<
- "</enableCache>\n" <<
-
- " <!-- ********************************************************\n" <<
- " Setting to 'true' will result in increased performance at the\n" <<
- " cost of lower noise immunity.\n" <<
- " Only set to true when using short cables with only 1 or two\n" <<
- " devices. This should remain off when using external SCSI1 DB25\n" <<
- " cables.\n" <<
- " ********************************************************* -->\n" <<
- " <disableGlitchFilter>" <<
- (config.flags & S2S_CFG_DISABLE_GLITCH ? "true" : "false") <<
- "</disableGlitchFilter>\n" <<
-
-
- " <enableDisconnect>" <<
- (config.flags & S2S_CFG_ENABLE_DISCONNECT ? "true" : "false") <<
- "</enableDisconnect>\n" <<
-
" <!-- ********************************************************\n" <<
" Respond to very short duration selection attempts. This supports\n" <<
" non-standard hardware, but is generally safe to enable.\n" <<
" <mapLunsToIds>" <<
(config.flags & S2S_CFG_MAP_LUNS_TO_IDS ? "true" : "false") <<
"</mapLunsToIds>\n" <<
+
+
+ " <!-- ********************************************************\n" <<
+ " Delay (in milliseconds) before responding to a SCSI selection.\n" <<
+ " 255 (auto) sets it to 0 for SCSI2 hosts and 1ms otherwise.\n" <<
+ " Some samplers need this set to 1 manually.\n" <<
+ " ********************************************************* -->\n" <<
+ " <selectionDelay>" << static_cast<int>(config.selectionDelay) << "</selectionDelay>\n" <<
+
+ " <!-- ********************************************************\n" <<
+ " Startup delay (in seconds) before responding to the SCSI bus \n" <<
+ " after power on. Default = 0.\n" <<
+ " ********************************************************* -->\n" <<
+ " <startupDelay>" << static_cast<int>(config.startupDelay) << "</startupDelay>\n" <<
+
+ " <!-- ********************************************************\n" <<
+ " Speed limit the SCSI interface. This is the -max- speed the \n" <<
+ " device will run at. The actual spee depends on the capability\n" <<
+ " of the host controller.\n" <<
+ " 0 No limit\n" <<
+ " 1 Async 1.5MB/s\n" <<
+ " 2 Async 3.3MB/s\n" <<
+ " 3 Async 5MB/s\n" <<
+ " 4 Sync 5MB/s\n" <<
+ " 5 Sync 10MB/s\n" <<
+ " ********************************************************* -->\n" <<
+ " <scsiSpeed>" << static_cast<int>(config.scsiSpeed) << "</scsiSpeed>\n" <<
+
"</S2S_BoardCfg>\n";
return s.str();
{
result.quirks |= S2S_CFG_QUIRKS_APPLE;
}
+ else if (quirk == "omti")
+ {
+ result.quirks |= S2S_CFG_QUIRKS_OMTI;
+ }
}
}
else if (child->GetName() == "deviceType")
wxXmlNode *child = node->GetChildren();
while (child)
{
-// FIXME WHERE IS SELECTION DELAY ? STARTUP DELAY ? FFS.
- if (child->GetName() == "unitAttention")
+ if (child->GetName() == "selectionDelay")
+ {
+ result.selectionDelay = parseInt(child, 255);
+ }
+ else if (child->GetName() == "startupDelay")
+ {
+ result.startupDelay = parseInt(child, 255);
+ }
+ else if (child->GetName() == "unitAttention")
{
std::string s(child->GetNodeContent().mb_str());
if (s == "true")
result.flags = result.flags & ~S2S_CFG_ENABLE_SCSI2;
}
}
- else if (child->GetName() == "disableGlitchFilter")
- {
- std::string s(child->GetNodeContent().mb_str());
- if (s == "true")
- {
- result.flags |= S2S_CFG_DISABLE_GLITCH;
- }
- else
- {
- result.flags = result.flags & ~S2S_CFG_DISABLE_GLITCH;
- }
- }
else if (child->GetName() == "enableTerminator")
{
std::string s(child->GetNodeContent().mb_str());
result.flags6 = result.flags & ~S2S_CFG_ENABLE_TERMINATOR;
}
}
- else if (child->GetName() == "enableCache")
- {
- std::string s(child->GetNodeContent().mb_str());
- if (s == "true")
- {
- result.flags |= S2S_CFG_ENABLE_CACHE;
- }
- else
- {
- result.flags = result.flags & ~S2S_CFG_ENABLE_CACHE;
- }
- }
- else if (child->GetName() == "enableDisconnect")
- {
- std::string s(child->GetNodeContent().mb_str());
- if (s == "true")
- {
- result.flags |= S2S_CFG_ENABLE_DISCONNECT;
- }
- else
- {
- result.flags = result.flags & ~S2S_CFG_ENABLE_DISCONNECT;
- }
- }
else if (child->GetName() == "selLatch")
{
std::string s(child->GetNodeContent().mb_str());
result.flags = result.flags & ~S2S_CFG_MAP_LUNS_TO_IDS;
}
}
+ else if (child->GetName() == "scsiSpeed")
+ {
+ result.scsiSpeed = parseInt(child, S2S_CFG_SPEED_SYNC_10);
+ }
child = child->GetNext();
}
return result;
-DHAVE_LIBUSB_1_0 \
-CFLAGS += -Wall -Wno-pointer-sign -O2 -g
-CXXFLAGS += -Wall -O2 -g -std=c++0x
+CFLAGS += -Wall -Wno-pointer-sign -O2 -g -fPIC
+CXXFLAGS += -Wall -O2 -g -std=c++0x -fPIC
LDFLAGS += -L$(BUILD)/libzipper/.libs -lzipper \
$(LDFLAGS_ZLIB) \
# wxWidgets 3.0.2 uses broken Webkit headers under OSX Yosemeti
# liblzma not available on OSX 10.7
-WX_CONFIG=--disable-webkit --disable-webviewwebkit \
+# --disable-mediactrl for missing Quicktime.h on Mac OSX Sierra
+WX_CONFIG=--disable-webkit --disable-webviewwebkit --disable-mediactrl \
--without-libtiff --without-libjbig --without-liblzma --without-opengl \
--enable-monolithic --enable-stl --disable-shared
all: $(BUILD)/scsi2sd-util6.dmg
$(BUILD)/scsi2sd-util6.dmg: $(BUILD)/scsi2sd-util6 $(BUILD)/dfu-util/buildstamp
+ rm -rf $(dir $@)/dmg $@
mkdir -p $(dir $@)/dmg
cp $(BUILD)/scsi2sd-util6 $(BUILD)/dfu-util/src/dfu-util $(dir $@)/dmg
chmod a+rx $(dir $@)/dmg/*
switch (myDeviceTypeCtrl->GetSelection())
{
case S2S_CFG_OPTICAL:
- // TODO mySectorSizeCtrl->ChangeValue("2048");
- // TODO mySectorSizeCtrl->Enable(false);
+ mySectorSizeCtrl->ChangeValue("2048");
+ mySectorSizeCtrl->Enable(true); // Enable override
break;
case S2S_CFG_FLOPPY_14MB:
mySectorSizeCtrl->ChangeValue("512");
ID_ConfigDefaults,
_("Load &Defaults"),
_("Load default configuration options."));
+
+ menuFile->AppendSeparator();
+ myLoadButton = menuFile->Append(
+ ID_BtnLoad,
+ _("Load from device"),
+ _("Load configuration from hardware device"));
+ mySaveButton = menuFile->Append(
+ ID_BtnSave,
+ _("Save to device"),
+ _("Save configuration to hardware device"));
+
+ menuFile->AppendSeparator();
menuFile->Append(
ID_Firmware,
_("&Upgrade Firmware..."),
tabs->Fit();
fgs->Add(tabs);
-
- wxPanel* btnPanel = new wxPanel(cfgPanel);
- wxFlexGridSizer *btnFgs = new wxFlexGridSizer(1, 2, 5, 5);
- btnPanel->SetSizer(btnFgs);
- myLoadButton =
- new wxButton(btnPanel, ID_BtnLoad, _("Load from device"));
- btnFgs->Add(myLoadButton);
- mySaveButton =
- new wxButton(btnPanel, ID_BtnSave, _("Save to device"));
- btnFgs->Add(mySaveButton);
- fgs->Add(btnPanel);
-
- btnPanel->Fit();
cfgPanel->Fit();
}
wxLogWindow* myLogWindow;
BoardPanel* myBoardPanel;
std::vector<TargetPanel*> myTargets;
- wxButton* myLoadButton;
- wxButton* mySaveButton;
wxMenuItem* mySCSILogChk;
wxMenuItem* mySelfTestChk;
+ wxMenuItem* myLoadButton;
+ wxMenuItem* mySaveButton;
wxTimer* myTimer;
shared_ptr<HID> myHID;
bool myInitialConfig;
{
wxMessageBox(
"SCSI2SD (scsi2sd-util6)\n"
- "Copyright (C) 2014-2016 Michael McMaster <michael@codesrc.com>\n"
+ "Copyright (C) 2014-2017 Michael McMaster <michael@codesrc.com>\n"
"\n"
"This program is free software: you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
EVT_COMMAND(wxID_ANY, ConfigChangedEvent, AppFrame::onConfigChanged)
- EVT_BUTTON(ID_BtnSave, AppFrame::doSave)
- EVT_BUTTON(ID_BtnLoad, AppFrame::doLoad)
+ EVT_MENU(ID_BtnSave, AppFrame::doSave)
+ EVT_MENU(ID_BtnLoad, AppFrame::doLoad)
EVT_CLOSE(AppFrame::OnCloseEvt)
#include "wx/osx/private.h"
#if wxOSX_USE_COCOA_OR_CARBON
- #include <QuickTime/QuickTime.h>
+// #include <QuickTime/QuickTime.h>
#endif
// ----------------------------------------------------------------------------
#endif
#ifndef __WXOSX_IPHONE__
-#include <QuickTime/QuickTime.h>
+//#include <QuickTime/QuickTime.h>
#endif
CGColorSpaceRef wxMacGetGenericRGBColorSpace();