Small compatibility improvements, and added scsi2sd-monitor test program v4.02.02
authorMichael McMaster <michael@codesrc.com>
Mon, 20 Apr 2015 06:09:51 +0000 (16:09 +1000)
committerMichael McMaster <michael@codesrc.com>
Mon, 20 Apr 2015 06:09:51 +0000 (16:09 +1000)
32 files changed:
CHANGELOG
readme.txt
software/SCSI2SD/src/config.c
software/SCSI2SD/src/disk.c
software/SCSI2SD/src/mode.c
software/SCSI2SD/src/scsi.c
software/SCSI2SD/src/scsi.h
software/SCSI2SD/src/scsiPhy.c
software/SCSI2SD/src/scsiPhy.h
software/SCSI2SD/v3/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitter.h
software/SCSI2SD/v3/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfittergnu.inc
software/SCSI2SD/v3/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitteriar.inc
software/SCSI2SD/v3/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitterrv.inc
software/SCSI2SD/v3/SCSI2SD.cydsn/Generated_Source/PSoC5/cymetadata.c
software/SCSI2SD/v3/SCSI2SD.cydsn/SCSI2SD.cyfit
software/SCSI2SD/v3/SCSI2SD.cydsn/SCSI2SD.cyprj
software/SCSI2SD/v3/SCSI2SD.cydsn/TopDesign/TopDesign.cysch
software/SCSI2SD/v4/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitter.h
software/SCSI2SD/v4/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfittergnu.inc
software/SCSI2SD/v4/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitteriar.inc
software/SCSI2SD/v4/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitterrv.inc
software/SCSI2SD/v4/SCSI2SD.cydsn/Generated_Source/PSoC5/cymetadata.c
software/SCSI2SD/v4/SCSI2SD.cydsn/SCSI2SD.cyfit
software/SCSI2SD/v4/SCSI2SD.cydsn/SCSI2SD.cyprj
software/SCSI2SD/v4/SCSI2SD.cydsn/TopDesign/TopDesign.cysch
software/include/scsi2sd.h
software/scsi2sd-util/ConfigUtil.cc
software/scsi2sd-util/Makefile
software/scsi2sd-util/SCSI2SD_HID.cc
software/scsi2sd-util/SCSI2SD_HID.hh
software/scsi2sd-util/scsi2sd-monitor.cc [new file with mode: 0644]
software/scsi2sd-util/scsi2sd-util.cc

index cf022b57d4c7e3cceae274c55d975edf9c0d01b7..423d64eab00e8b32bcede602925e618f5bc59f7f 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,7 @@
-201501??               4.1.1
+20150420               4.2.2
+       - Improved compatibility with older SCSI1 hosts.
+
+20150123               4.1.1
        - Fix MODE SENSE bug when the allocation length is less than the
        page size.
        - Add WRITE BUFFER and WRITE AND VERIFY support.
        - Fix MODE SENSE bug when the allocation length is less than the
        page size.
        - Add WRITE BUFFER and WRITE AND VERIFY support.
index 1c22fde7046e8b8e5a0db56ad5bb7fbf77fdd5f2..11c43482214186be6936a979f4a7451e8ac5ebcf 100644 (file)
@@ -13,7 +13,6 @@ computer and a modern PC (who still has access to a working floppy drive ?)
 Features
 
     In-built active terminator.
 Features
 
     In-built active terminator.
-    Can optional supply terminator power back to the SCSI bus
     Emulates up to 4 SCSI devices
     Supports sector sizes from 64 bytes to 8192 bytes
     Firmware updatable over USB
     Emulates up to 4 SCSI devices
     Supports sector sizes from 64 bytes to 8192 bytes
     Firmware updatable over USB
@@ -95,6 +94,8 @@ Samplers
         SCSI cable reversed on S3200
         There are compatibility problems with the Akai MPC3000. It works (slowly) with the alternate Vailixi OS with multi-sector transfers disabled. 
     EMU Emulator E4X with EOS 3.00b and E6400 (classic) with Eos 4.01
         SCSI cable reversed on S3200
         There are compatibility problems with the Akai MPC3000. It works (slowly) with the alternate Vailixi OS with multi-sector transfers disabled. 
     EMU Emulator E4X with EOS 3.00b and E6400 (classic) with Eos 4.01
+    EMU E6400 w/ EOS2.80f
+    EMU Emax2
     Ensoniq ASR-X, ASR-10 (from v3.4, 2GB size limit)
         ASR-20 Requires TERMPWR jumper.
         ASR-X resets when writing to devices > 2Gb. 
     Ensoniq ASR-X, ASR-10 (from v3.4, 2GB size limit)
         ASR-20 Requires TERMPWR jumper.
         ASR-X resets when writing to devices > 2Gb. 
@@ -113,3 +114,5 @@ Other
        Reftek RT-72A Seismic datalogger.
                http://www.iris.iris.edu/passcal/Reftek/72A-R-005-00.1.pdf
                http://www.iris.iris.edu/passcal/Manual/rtfm.s3a.13.html
        Reftek RT-72A Seismic datalogger.
                http://www.iris.iris.edu/passcal/Reftek/72A-R-005-00.1.pdf
                http://www.iris.iris.edu/passcal/Manual/rtfm.s3a.13.html
+       Konami Simpson's Bowling arcade machine
+               http://forums.arcade-museum.com/showthread.php?p=3027446
index 6178b9fb43e9a72272a9a55c51227a4a70d596f4..732d4c477fb2ef8cb4a1b5841ac86e01cf8be5de 100755 (executable)
@@ -32,7 +32,7 @@
 \r
 #include <string.h>\r
 \r
 \r
 #include <string.h>\r
 \r
-static const uint16_t FIRMWARE_VERSION = 0x0411;\r
+static const uint16_t FIRMWARE_VERSION = 0x0422;\r
 \r
 enum USB_ENDPOINTS\r
 {\r
 \r
 enum USB_ENDPOINTS\r
 {\r
@@ -53,8 +53,30 @@ static int usbInEpState;
 static int usbDebugEpState;\r
 static int usbReady;\r
 \r
 static int usbDebugEpState;\r
 static int usbReady;\r
 \r
+uint8_t DEFAULT_CONFIG[256]\r
+       __attribute__ ((section(".DEFAULT_CONFIG"))) =\r
+{\r
+       CONFIG_TARGET_ENABLED,\r
+       CONFIG_FIXED,\r
+       0,\r
+       0,\r
+       0, 0, 0, 0,\r
+       0xff, 0xff, 0x3f, 0x00, // 4194303, 2GB - 1 sector\r
+       0x00, 0x02, //512\r
+       63, 0,\r
+       255, 0,\r
+       ' ', 'c', 'o', 'd', 'e', 's', 'r', 'c',\r
+       ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'S', 'C', 'S', 'I', '2', 'S', 'D',\r
+       ' ', '4', '.', '2',\r
+       '1','2','3','4','5','6','7','8','1','2','3','4','5','6','7','8'\r
+};\r
+// otherwise linker removes unused section.\r
+volatile uint8_t trickLinker;\r
+\r
 void configInit()\r
 {\r
 void configInit()\r
 {\r
+       trickLinker = DEFAULT_CONFIG[0];\r
+\r
        // The USB block will be powered by an internal 3.3V regulator.\r
        // The PSoC must be operating between 4.6V and 5V for the regulator\r
        // to work.\r
        // The USB block will be powered by an internal 3.3V regulator.\r
        // The PSoC must be operating between 4.6V and 5V for the regulator\r
        // to work.\r
@@ -132,6 +154,20 @@ sdInfoCommand()
 \r
        hidPacket_send(response, sizeof(response));\r
 }\r
 \r
        hidPacket_send(response, sizeof(response));\r
 }\r
+\r
+\r
+static void\r
+scsiTestCommand()\r
+{\r
+       int resultCode = scsiSelfTest();\r
+       uint8_t response[] =\r
+       {\r
+               resultCode == 0 ? CONFIG_STATUS_GOOD : CONFIG_STATUS_ERR,\r
+               resultCode\r
+       };\r
+       hidPacket_send(response, sizeof(response));\r
+}\r
+\r
 static void\r
 processCommand(const uint8_t* cmd, size_t cmdSize)\r
 {\r
 static void\r
 processCommand(const uint8_t* cmd, size_t cmdSize)\r
 {\r
@@ -157,6 +193,10 @@ processCommand(const uint8_t* cmd, size_t cmdSize)
                sdInfoCommand();\r
                break;\r
 \r
                sdInfoCommand();\r
                break;\r
 \r
+       case CONFIG_SCSITEST:\r
+               scsiTestCommand();\r
+               break;\r
+\r
        case CONFIG_NONE: // invalid\r
        default:\r
                break;\r
        case CONFIG_NONE: // invalid\r
        default:\r
                break;\r
index af1c50a944062f78bf88f501708d711fe065a4cc..5b6a70d0d930dd8ef34cb6d67d02c4a9a4018b6d 100755 (executable)
@@ -728,7 +728,7 @@ void scsiDiskPoll()
                {\r
                        if (scsiDev.parityError &&\r
                                (scsiDev.target->cfg->flags & CONFIG_ENABLE_PARITY) &&\r
                {\r
                        if (scsiDev.parityError &&\r
                                (scsiDev.target->cfg->flags & CONFIG_ENABLE_PARITY) &&\r
-                               !scsiDev.compatMode)\r
+                               (scsiDev.compatMode >= COMPAT_SCSI2))\r
                        {\r
                                scsiDev.target->sense.code = ABORTED_COMMAND;\r
                                scsiDev.target->sense.asc = SCSI_PARITY_ERROR;\r
                        {\r
                                scsiDev.target->sense.code = ABORTED_COMMAND;\r
                                scsiDev.target->sense.asc = SCSI_PARITY_ERROR;\r
index c66608acbbe951d0a5282e088e2320c0b5141c7d..4ed790f4738e0fd4f849ef200b5fb3a2df67591a 100755 (executable)
@@ -145,231 +145,224 @@ static void pageIn(int pc, int dataIdx, const uint8* pageData, int pageLen)
 static void doModeSense(\r
        int sixByteCmd, int dbd, int pc, int pageCode, int allocLength)\r
 {\r
 static void doModeSense(\r
        int sixByteCmd, int dbd, int pc, int pageCode, int allocLength)\r
 {\r
-       if (pc == 0x03) // Saved Values not supported.\r
+       ////////////// Mode Parameter Header\r
+       ////////////////////////////////////\r
+\r
+       // Skip the Mode Data Length, we set that last.\r
+       int idx = 1;\r
+       if (!sixByteCmd) ++idx;\r
+\r
+       uint8_t mediumType = 0;\r
+       uint8_t deviceSpecificParam = 0;\r
+       uint8_t density = 0;\r
+       switch (scsiDev.target->cfg->deviceType == CONFIG_OPTICAL)\r
        {\r
        {\r
-               scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = SAVING_PARAMETERS_NOT_SUPPORTED;\r
-               scsiDev.phase = STATUS;\r
+       case CONFIG_FIXED:\r
+       case CONFIG_REMOVEABLE:\r
+               mediumType = 0; // We should support various floppy types here!\r
+               // Contains cache bits (0) and a Write-Protect bit.\r
+               deviceSpecificParam =\r
+                       (blockDev.state & DISK_WP) ? 0x80 : 0;\r
+               density = 0; // reserved for direct access\r
+               break;\r
+\r
+       case CONFIG_FLOPPY_14MB:\r
+               mediumType = 0x1E; // 90mm/3.5"\r
+               deviceSpecificParam =\r
+                       (blockDev.state & DISK_WP) ? 0x80 : 0;\r
+               density = 0; // reserved for direct access\r
+               break;\r
+\r
+       case CONFIG_OPTICAL:\r
+               mediumType = 0x02; // 120mm CDROM, data only.\r
+               deviceSpecificParam = 0;\r
+               density = 0x01; // User data only, 2048bytes per sector.\r
+               break;\r
+\r
+       };\r
+\r
+       scsiDev.data[idx++] = mediumType;\r
+       scsiDev.data[idx++] = deviceSpecificParam;\r
+\r
+       if (sixByteCmd)\r
+       {\r
+               if (dbd)\r
+               {\r
+                       scsiDev.data[idx++] = 0; // No block descriptor\r
+               }\r
+               else\r
+               {\r
+                       // One block descriptor of length 8 bytes.\r
+                       scsiDev.data[idx++] = 8;\r
+               }\r
        }\r
        else\r
        {\r
        }\r
        else\r
        {\r
-               ////////////// Mode Parameter Header\r
-               ////////////////////////////////////\r
-\r
-               // Skip the Mode Data Length, we set that last.\r
-               int idx = 1;\r
-               if (!sixByteCmd) ++idx;\r
-\r
-               uint8_t mediumType = 0;\r
-               uint8_t deviceSpecificParam = 0;\r
-               uint8_t density = 0;\r
-               switch (scsiDev.target->cfg->deviceType == CONFIG_OPTICAL)\r
-               {\r
-               case CONFIG_FIXED:\r
-               case CONFIG_REMOVEABLE:\r
-                       mediumType = 0; // We should support various floppy types here!\r
-                       // Contains cache bits (0) and a Write-Protect bit.\r
-                       deviceSpecificParam =\r
-                               (blockDev.state & DISK_WP) ? 0x80 : 0;\r
-                       density = 0; // reserved for direct access\r
-                       break;\r
-\r
-               case CONFIG_FLOPPY_14MB:\r
-                       mediumType = 0x1E; // 90mm/3.5"\r
-                       deviceSpecificParam =\r
-                               (blockDev.state & DISK_WP) ? 0x80 : 0;\r
-                       density = 0; // reserved for direct access\r
-                       break;\r
-\r
-               case CONFIG_OPTICAL:\r
-                       mediumType = 0x02; // 120mm CDROM, data only.\r
-                       deviceSpecificParam = 0;\r
-                       density = 0x01; // User data only, 2048bytes per sector.\r
-                       break;\r
-\r
-               };\r
-\r
-               scsiDev.data[idx++] = mediumType;\r
-               scsiDev.data[idx++] = deviceSpecificParam;\r
-\r
-               if (sixByteCmd)\r
+               scsiDev.data[idx++] = 0; // Reserved\r
+               scsiDev.data[idx++] = 0; // Reserved\r
+               if (dbd)\r
                {\r
                {\r
-                       if (dbd)\r
-                       {\r
-                               scsiDev.data[idx++] = 0; // No block descriptor\r
-                       }\r
-                       else\r
-                       {\r
-                               // One block descriptor of length 8 bytes.\r
-                               scsiDev.data[idx++] = 8;\r
-                       }\r
+                       scsiDev.data[idx++] = 0; // No block descriptor\r
+                       scsiDev.data[idx++] = 0; // No block descriptor\r
                }\r
                else\r
                {\r
                }\r
                else\r
                {\r
-                       scsiDev.data[idx++] = 0; // Reserved\r
-                       scsiDev.data[idx++] = 0; // Reserved\r
-                       if (dbd)\r
-                       {\r
-                               scsiDev.data[idx++] = 0; // No block descriptor\r
-                               scsiDev.data[idx++] = 0; // No block descriptor\r
-                       }\r
-                       else\r
-                       {\r
-                               // One block descriptor of length 8 bytes.\r
-                               scsiDev.data[idx++] = 0;\r
-                               scsiDev.data[idx++] = 8;\r
-                       }\r
+                       // One block descriptor of length 8 bytes.\r
+                       scsiDev.data[idx++] = 0;\r
+                       scsiDev.data[idx++] = 8;\r
                }\r
                }\r
+       }\r
 \r
 \r
-               ////////////// Block Descriptor\r
-               ////////////////////////////////////\r
-               if (!dbd)\r
-               {\r
-                       scsiDev.data[idx++] = density;\r
-                       // Number of blocks\r
-                       // Zero == all remaining blocks shall have the medium\r
-                       // characteristics specified.\r
-                       scsiDev.data[idx++] = 0;\r
-                       scsiDev.data[idx++] = 0;\r
-                       scsiDev.data[idx++] = 0;\r
+       ////////////// Block Descriptor\r
+       ////////////////////////////////////\r
+       if (!dbd)\r
+       {\r
+               scsiDev.data[idx++] = density;\r
+               // Number of blocks\r
+               // Zero == all remaining blocks shall have the medium\r
+               // characteristics specified.\r
+               scsiDev.data[idx++] = 0;\r
+               scsiDev.data[idx++] = 0;\r
+               scsiDev.data[idx++] = 0;\r
+\r
+               scsiDev.data[idx++] = 0; // reserved\r
+\r
+               // Block length\r
+               uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;\r
+               scsiDev.data[idx++] = bytesPerSector >> 16;\r
+               scsiDev.data[idx++] = bytesPerSector >> 8;\r
+               scsiDev.data[idx++] = bytesPerSector & 0xFF;\r
+       }\r
 \r
 \r
-                       scsiDev.data[idx++] = 0; // reserved\r
+       int pageFound = 0;\r
 \r
 \r
-                       // Block length\r
-                       uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;\r
-                       scsiDev.data[idx++] = bytesPerSector >> 16;\r
-                       scsiDev.data[idx++] = bytesPerSector >> 8;\r
-                       scsiDev.data[idx++] = bytesPerSector & 0xFF;\r
-               }\r
+       if (pageCode == 0x01 || pageCode == 0x3F)\r
+       {\r
+               pageFound = 1;\r
+               pageIn(pc, idx, ReadWriteErrorRecoveryPage, sizeof(ReadWriteErrorRecoveryPage));\r
+               idx += sizeof(ReadWriteErrorRecoveryPage);\r
+       }\r
 \r
 \r
-               int pageFound = 0;\r
+       if (pageCode == 0x02 || pageCode == 0x3F)\r
+       {\r
+               pageFound = 1;\r
+               pageIn(pc, idx, DisconnectReconnectPage, sizeof(DisconnectReconnectPage));\r
+               idx += sizeof(DisconnectReconnectPage);\r
+       }\r
 \r
 \r
-               if (pageCode == 0x01 || pageCode == 0x3F)\r
+       if (pageCode == 0x03 || pageCode == 0x3F)\r
+       {\r
+               pageFound = 1;\r
+               pageIn(pc, idx, FormatDevicePage, sizeof(FormatDevicePage));\r
+               if (pc != 0x01)\r
                {\r
                {\r
-                       pageFound = 1;\r
-                       pageIn(pc, idx, ReadWriteErrorRecoveryPage, sizeof(ReadWriteErrorRecoveryPage));\r
-                       idx += sizeof(ReadWriteErrorRecoveryPage);\r
+                       // Fill out the configured bytes-per-sector\r
+                       uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;\r
+                       scsiDev.data[idx+12] = bytesPerSector >> 8;\r
+                       scsiDev.data[idx+13] = bytesPerSector & 0xFF;\r
                }\r
                }\r
-\r
-               if (pageCode == 0x02 || pageCode == 0x3F)\r
+               else\r
                {\r
                {\r
-                       pageFound = 1;\r
-                       pageIn(pc, idx, DisconnectReconnectPage, sizeof(DisconnectReconnectPage));\r
-                       idx += sizeof(DisconnectReconnectPage);\r
+                       // Set a mask for the changeable values.\r
+                       scsiDev.data[idx+12] = 0xFF;\r
+                       scsiDev.data[idx+13] = 0xFF;\r
                }\r
 \r
                }\r
 \r
-               if (pageCode == 0x03 || pageCode == 0x3F)\r
-               {\r
-                       pageFound = 1;\r
-                       pageIn(pc, idx, FormatDevicePage, sizeof(FormatDevicePage));\r
-                       if (pc != 0x01)\r
-                       {\r
-                               // Fill out the configured bytes-per-sector\r
-                               uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;\r
-                               scsiDev.data[idx+12] = bytesPerSector >> 8;\r
-                               scsiDev.data[idx+13] = bytesPerSector & 0xFF;\r
-                       }\r
-                       else\r
-                       {\r
-                               // Set a mask for the changeable values.\r
-                               scsiDev.data[idx+12] = 0xFF;\r
-                               scsiDev.data[idx+13] = 0xFF;\r
-                       }\r
+               idx += sizeof(FormatDevicePage);\r
+       }\r
 \r
 \r
-                       idx += sizeof(FormatDevicePage);\r
-               }\r
+       if (pageCode == 0x04 || pageCode == 0x3F)\r
+       {\r
+               pageFound = 1;\r
+               pageIn(pc, idx, RigidDiskDriveGeometry, sizeof(RigidDiskDriveGeometry));\r
 \r
 \r
-               if (pageCode == 0x04 || pageCode == 0x3F)\r
+               if (pc != 0x01)\r
                {\r
                {\r
-                       pageFound = 1;\r
-                       pageIn(pc, idx, RigidDiskDriveGeometry, sizeof(RigidDiskDriveGeometry));\r
-\r
-                       if (pc != 0x01)\r
-                       {\r
-                               // Need to fill out the number of cylinders.\r
-                               uint32 cyl;\r
-                               uint8 head;\r
-                               uint32 sector;\r
-                               LBA2CHS(\r
-                                       getScsiCapacity(\r
-                                               scsiDev.target->cfg->sdSectorStart,\r
-                                               scsiDev.target->liveCfg.bytesPerSector,\r
-                                               scsiDev.target->cfg->scsiSectors),\r
-                                       &cyl,\r
-                                       &head,\r
-                                       &sector);\r
-\r
-                               scsiDev.data[idx+2] = cyl >> 16;\r
-                               scsiDev.data[idx+3] = cyl >> 8;\r
-                               scsiDev.data[idx+4] = cyl;\r
-\r
-                               memcpy(&scsiDev.data[idx+6], &scsiDev.data[idx+2], 3);\r
-                               memcpy(&scsiDev.data[idx+9], &scsiDev.data[idx+2], 3);\r
-                       }\r
-\r
-                       idx += sizeof(RigidDiskDriveGeometry);\r
+                       // Need to fill out the number of cylinders.\r
+                       uint32 cyl;\r
+                       uint8 head;\r
+                       uint32 sector;\r
+                       LBA2CHS(\r
+                               getScsiCapacity(\r
+                                       scsiDev.target->cfg->sdSectorStart,\r
+                                       scsiDev.target->liveCfg.bytesPerSector,\r
+                                       scsiDev.target->cfg->scsiSectors),\r
+                               &cyl,\r
+                               &head,\r
+                               &sector);\r
+\r
+                       scsiDev.data[idx+2] = cyl >> 16;\r
+                       scsiDev.data[idx+3] = cyl >> 8;\r
+                       scsiDev.data[idx+4] = cyl;\r
+\r
+                       memcpy(&scsiDev.data[idx+6], &scsiDev.data[idx+2], 3);\r
+                       memcpy(&scsiDev.data[idx+9], &scsiDev.data[idx+2], 3);\r
                }\r
 \r
                }\r
 \r
-               // DON'T output the following pages for SCSI1 hosts. They get upset when\r
-               // we have more data to send than the allocation length provided.\r
-               // (ie. Try not to output any more pages below this comment)\r
+               idx += sizeof(RigidDiskDriveGeometry);\r
+       }\r
 \r
 \r
+       // DON'T output the following pages for SCSI1 hosts. They get upset when\r
+       // we have more data to send than the allocation length provided.\r
+       // (ie. Try not to output any more pages below this comment)\r
 \r
 \r
-               if (!scsiDev.compatMode && (pageCode == 0x08 || pageCode == 0x3F))\r
-               {\r
-                       pageFound = 1;\r
-                       pageIn(pc, idx, CachingPage, sizeof(CachingPage));\r
-                       idx += sizeof(CachingPage);\r
-               }\r
 \r
 \r
-               if (!scsiDev.compatMode && (pageCode == 0x0A || pageCode == 0x3F))\r
-               {\r
-                       pageFound = 1;\r
-                       pageIn(pc, idx, ControlModePage, sizeof(ControlModePage));\r
-                       idx += sizeof(ControlModePage);\r
-               }\r
+       if ((scsiDev.compatMode >= COMPAT_SCSI2) &&\r
+               (pageCode == 0x08 || pageCode == 0x3F))\r
+       {\r
+               pageFound = 1;\r
+               pageIn(pc, idx, CachingPage, sizeof(CachingPage));\r
+               idx += sizeof(CachingPage);\r
+       }\r
 \r
 \r
-               if ((\r
-                               (scsiDev.target->cfg->quirks == CONFIG_QUIRKS_APPLE) ||\r
-                               (idx + sizeof(AppleVendorPage) <= allocLength)\r
-                       ) &&\r
-                       (pageCode == 0x30 || pageCode == 0x3F))\r
-               {\r
-                       pageFound = 1;\r
-                       pageIn(pc, idx, AppleVendorPage, sizeof(AppleVendorPage));\r
-                       idx += sizeof(AppleVendorPage);\r
-               }\r
+       if ((scsiDev.compatMode >= COMPAT_SCSI2)\r
+               && (pageCode == 0x0A || pageCode == 0x3F))\r
+       {\r
+               pageFound = 1;\r
+               pageIn(pc, idx, ControlModePage, sizeof(ControlModePage));\r
+               idx += sizeof(ControlModePage);\r
+       }\r
+\r
+       if ((\r
+                       (scsiDev.target->cfg->quirks == CONFIG_QUIRKS_APPLE) ||\r
+                       (idx + sizeof(AppleVendorPage) <= allocLength)\r
+               ) &&\r
+               (pageCode == 0x30 || pageCode == 0x3F))\r
+       {\r
+               pageFound = 1;\r
+               pageIn(pc, idx, AppleVendorPage, sizeof(AppleVendorPage));\r
+               idx += sizeof(AppleVendorPage);\r
+       }\r
 \r
 \r
-               if (!pageFound)\r
+       if (!pageFound)\r
+       {\r
+               // Unknown Page Code\r
+               pageFound = 0;\r
+               scsiDev.status = CHECK_CONDITION;\r
+               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
+               scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
+               scsiDev.phase = STATUS;\r
+       }\r
+       else\r
+       {\r
+               // Go back and fill out the mode data length\r
+               if (sixByteCmd)\r
                {\r
                {\r
-                       // Unknown Page Code\r
-                       pageFound = 0;\r
-                       scsiDev.status = CHECK_CONDITION;\r
-                       scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-                       scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
-                       scsiDev.phase = STATUS;\r
+                       // Cannot currently exceed limits. yay\r
+                       scsiDev.data[0] = idx - 1;\r
                }\r
                else\r
                {\r
                }\r
                else\r
                {\r
-                       // Go back and fill out the mode data length\r
-                       if (sixByteCmd)\r
-                       {\r
-                               // Cannot currently exceed limits. yay\r
-                               scsiDev.data[0] = idx - 1;\r
-                       }\r
-                       else\r
-                       {\r
-                               scsiDev.data[0] = ((idx - 2) >> 8);\r
-                               scsiDev.data[1] = (idx - 2);\r
-                       }\r
-\r
-                       scsiDev.dataLen = idx > allocLength ? allocLength : idx;\r
-                       scsiDev.phase = DATA_IN;\r
+                       scsiDev.data[0] = ((idx - 2) >> 8);\r
+                       scsiDev.data[1] = (idx - 2);\r
                }\r
                }\r
+\r
+               scsiDev.dataLen = idx > allocLength ? allocLength : idx;\r
+               scsiDev.phase = DATA_IN;\r
        }\r
 }\r
 \r
        }\r
 }\r
 \r
+\r
 // Callback after the DATA OUT phase is complete.\r
 static void doModeSelect(void)\r
 {\r
 // Callback after the DATA OUT phase is complete.\r
 static void doModeSelect(void)\r
 {\r
index 15622d5969234640c27bbf515aecc9a79b6d0e52..0e5a78d9797c55ab4966e3314401d322edac7cca 100755 (executable)
@@ -53,7 +53,7 @@ static void enter_BusFree()
 {\r
        // This delay probably isn't needed for most SCSI hosts, but it won't\r
        // hurt either. It's possible some of the samplers needed this delay.\r
 {\r
        // This delay probably isn't needed for most SCSI hosts, but it won't\r
        // hurt either. It's possible some of the samplers needed this delay.\r
-       if (scsiDev.compatMode)\r
+       if (scsiDev.compatMode < COMPAT_SCSI2)\r
        {\r
                CyDelayUs(2);\r
        }\r
        {\r
                CyDelayUs(2);\r
        }\r
@@ -214,7 +214,7 @@ static void process_DataOut()
 \r
                if (scsiDev.parityError &&\r
                        (scsiDev.target->cfg->flags & CONFIG_ENABLE_PARITY) &&\r
 \r
                if (scsiDev.parityError &&\r
                        (scsiDev.target->cfg->flags & CONFIG_ENABLE_PARITY) &&\r
-                       !scsiDev.compatMode)\r
+                       (scsiDev.compatMode >= COMPAT_SCSI2))\r
                {\r
                        scsiDev.target->sense.code = ABORTED_COMMAND;\r
                        scsiDev.target->sense.asc = SCSI_PARITY_ERROR;\r
                {\r
                        scsiDev.target->sense.code = ABORTED_COMMAND;\r
                        scsiDev.target->sense.asc = SCSI_PARITY_ERROR;\r
@@ -274,7 +274,7 @@ static void process_Command()
        }\r
        else if (scsiDev.parityError &&\r
                (scsiDev.target->cfg->flags & CONFIG_ENABLE_PARITY) &&\r
        }\r
        else if (scsiDev.parityError &&\r
                (scsiDev.target->cfg->flags & CONFIG_ENABLE_PARITY) &&\r
-               !scsiDev.compatMode)\r
+               (scsiDev.compatMode >= COMPAT_SCSI2))\r
        {\r
                scsiDev.target->sense.code = ABORTED_COMMAND;\r
                scsiDev.target->sense.asc = SCSI_PARITY_ERROR;\r
        {\r
                scsiDev.target->sense.code = ABORTED_COMMAND;\r
                scsiDev.target->sense.asc = SCSI_PARITY_ERROR;\r
@@ -459,6 +459,7 @@ static void scsiReset()
        scsiDev.atnFlag = 0;\r
        scsiDev.resetFlag = 0;\r
        scsiDev.lun = -1;\r
        scsiDev.atnFlag = 0;\r
        scsiDev.resetFlag = 0;\r
        scsiDev.lun = -1;\r
+       scsiDev.compatMode = COMPAT_UNKNOWN;\r
 \r
        if (scsiDev.target)\r
        {\r
 \r
        if (scsiDev.target)\r
        {\r
@@ -500,7 +501,6 @@ static void enter_SelectionPhase()
        scsiDev.phase = SELECTION;\r
        scsiDev.lun = -1;\r
        scsiDev.discPriv = 0;\r
        scsiDev.phase = SELECTION;\r
        scsiDev.lun = -1;\r
        scsiDev.discPriv = 0;\r
-       scsiDev.compatMode = 0;\r
 \r
        scsiDev.initiatorId = -1;\r
        scsiDev.target = NULL;\r
 \r
        scsiDev.initiatorId = -1;\r
        scsiDev.target = NULL;\r
@@ -513,6 +513,12 @@ static void enter_SelectionPhase()
 \r
 static void process_SelectionPhase()\r
 {\r
 \r
 static void process_SelectionPhase()\r
 {\r
+       if (scsiDev.compatMode < COMPAT_SCSI2)\r
+       {\r
+               // Required for some older SCSI1 devices using a 5380 chip.\r
+               CyDelayUs(100);\r
+       }\r
+\r
        int sel = SCSI_ReadFilt(SCSI_Filt_SEL);\r
        int bsy = SCSI_ReadFilt(SCSI_Filt_BSY);\r
 \r
        int sel = SCSI_ReadFilt(SCSI_Filt_SEL);\r
        int bsy = SCSI_ReadFilt(SCSI_Filt_BSY);\r
 \r
@@ -552,7 +558,11 @@ static void process_SelectionPhase()
                if (!scsiDev.atnFlag)\r
                {\r
                        target->unitAttention = 0;\r
                if (!scsiDev.atnFlag)\r
                {\r
                        target->unitAttention = 0;\r
-                       scsiDev.compatMode = 1;\r
+                       scsiDev.compatMode = COMPAT_SCSI1;\r
+               }\r
+               else if (scsiDev.compatMode == COMPAT_UNKNOWN)\r
+               {\r
+                       scsiDev.compatMode = COMPAT_SCSI2;\r
                }\r
 \r
                // We've been selected!\r
                }\r
 \r
                // We've been selected!\r
@@ -611,7 +621,7 @@ static void process_MessageOut()
 \r
        if (scsiDev.parityError &&\r
                (scsiDev.target->cfg->flags & CONFIG_ENABLE_PARITY) &&\r
 \r
        if (scsiDev.parityError &&\r
                (scsiDev.target->cfg->flags & CONFIG_ENABLE_PARITY) &&\r
-               !scsiDev.compatMode)\r
+               (scsiDev.compatMode >= COMPAT_SCSI2))\r
        {\r
                // Skip the remaining message bytes, and then start the MESSAGE_OUT\r
                // phase again from the start. The initiator will re-send the\r
        {\r
                // Skip the remaining message bytes, and then start the MESSAGE_OUT\r
                // phase again from the start. The initiator will re-send the\r
@@ -872,6 +882,7 @@ void scsiInit()
        scsiDev.resetFlag = 1;\r
        scsiDev.phase = BUS_FREE;\r
        scsiDev.target = NULL;\r
        scsiDev.resetFlag = 1;\r
        scsiDev.phase = BUS_FREE;\r
        scsiDev.target = NULL;\r
+       scsiDev.compatMode = COMPAT_UNKNOWN;\r
 \r
        int i;\r
        for (i = 0; i < MAX_SCSI_TARGETS; ++i)\r
 \r
        int i;\r
        for (i = 0; i < MAX_SCSI_TARGETS; ++i)\r
index 2a48af38d5aeb24de12c0d168703e5680e73fa50..adb61c80e4bd6ce911ba8573f519a85d12cc6885 100755 (executable)
@@ -57,6 +57,13 @@ typedef enum
        MSG_LINKED_COMMAND_COMPLETE_WITH_FLAG = 0x0B
 } SCSI_MESSAGE;
 
        MSG_LINKED_COMMAND_COMPLETE_WITH_FLAG = 0x0B
 } SCSI_MESSAGE;
 
+typedef enum
+{
+       COMPAT_UNKNOWN,
+       COMPAT_SCSI1,
+       COMPAT_SCSI2
+} SCSI_COMPAT_MODE;
+
 // Maximum value for bytes-per-sector.
 #define MAX_SECTOR_SIZE 8192
 #define MIN_SECTOR_SIZE 64
 // Maximum value for bytes-per-sector.
 #define MAX_SECTOR_SIZE 8192
 #define MIN_SECTOR_SIZE 64
@@ -112,7 +119,7 @@ typedef struct
        uint8 cdbLen; // 6, 10, or 12 byte message.
        int8 lun; // Target lun, set by IDENTIFY message.
        uint8 discPriv; // Disconnect priviledge.
        uint8 cdbLen; // 6, 10, or 12 byte message.
        int8 lun; // Target lun, set by IDENTIFY message.
        uint8 discPriv; // Disconnect priviledge.
-       uint8_t compatMode; // true for SCSI1 and SASI hosts.
+       uint8_t compatMode; // SCSI_COMPAT_MODE
 
        // Only let the reserved initiator talk to us.
        // A 3rd party may be sending the RESERVE/RELEASE commands
 
        // Only let the reserved initiator talk to us.
        // A 3rd party may be sending the RESERVE/RELEASE commands
index 5952b8553b011970d98efb9f228f222ef2b8c198..900192ba790df61ab07a295b7a335ed15b756a73 100755 (executable)
@@ -447,4 +447,87 @@ void scsiPhyInit()
 \r
        SCSI_RST_ISR_StartEx(scsiResetISR);\r
 }\r
 \r
        SCSI_RST_ISR_StartEx(scsiResetISR);\r
 }\r
+\r
+// 1 = DBx error\r
+// 2 = Parity error\r
+// 4 = MSG error\r
+// 8 = CD error\r
+// 16 = IO error\r
+// 32 = other error\r
+int scsiSelfTest()\r
+{\r
+       int result = 0;\r
+\r
+       // TEST DBx and DBp\r
+       int i;\r
+       SCSI_Out_Ctl_Write(1); // Write bits manually.\r
+       SCSI_CTL_PHASE_Write(__scsiphase_io); // Needed for parity generation\r
+       for (i = 0; i < 256; ++i)\r
+       {\r
+               SCSI_Out_Bits_Write(i);\r
+               scsiDeskewDelay();\r
+               if (scsiReadDBxPins() != (i & 0xff))\r
+               {\r
+                       result |= 1;\r
+               }\r
+               if (Lookup_OddParity[i & 0xff] != SCSI_ReadPin(SCSI_In_DBP))\r
+               {\r
+                       result |= 2;\r
+               }\r
+       }\r
+       SCSI_Out_Ctl_Write(0); // Write bits normally.\r
+\r
+       // TEST MSG, CD, IO\r
+       for (i = 0; i < 8; ++i)\r
+       {\r
+               SCSI_CTL_PHASE_Write(i);\r
+               scsiDeskewDelay();\r
+\r
+               if (SCSI_ReadPin(SCSI_In_MSG) != !!(i & __scsiphase_msg))\r
+               {\r
+                       result |= 4;\r
+               }\r
+               if (SCSI_ReadPin(SCSI_In_CD) != !!(i & __scsiphase_cd))\r
+               {\r
+                       result |= 8;\r
+               }\r
+               if (SCSI_ReadPin(SCSI_In_IO) != !!(i & __scsiphase_io))\r
+               {\r
+                       result |= 16;\r
+               }\r
+       }\r
+       SCSI_CTL_PHASE_Write(0);\r
+\r
+       uint32_t signalsOut[] = { SCSI_Out_ATN, SCSI_Out_BSY, SCSI_Out_RST, SCSI_Out_SEL };\r
+       uint32_t signalsIn[] = { SCSI_Filt_ATN, SCSI_Filt_BSY, SCSI_Filt_RST, SCSI_Filt_SEL };\r
+\r
+       for (i = 0; i < 4; ++i)\r
+       {\r
+               SCSI_SetPin(signalsOut[i]);\r
+               scsiDeskewDelay();\r
+\r
+               int j;\r
+               for (j = 0; j < 4; ++j)\r
+               {\r
+                       if (i == j)\r
+                       {\r
+                               if (! SCSI_ReadFilt(signalsIn[j]))\r
+                               {\r
+                                       result |= 32;\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               if (SCSI_ReadFilt(signalsIn[j]))\r
+                               {\r
+                                       result |= 32;\r
+                               }\r
+                       }\r
+               }\r
+               SCSI_ClearPin(signalsOut[i]);\r
+       }\r
+       return result;\r
+}\r
+\r
+\r
 #pragma GCC pop_options\r
 #pragma GCC pop_options\r
index b4c0f79f86b6b0cf166532e320584fb54d1f846c..006107be73ec8fede69e1096096f4f1b9a60674b 100755 (executable)
@@ -88,4 +88,6 @@ uint8_t scsiReadDBxPins(void);
 
 void scsiEnterPhase(int phase);
 
 
 void scsiEnterPhase(int phase);
 
+int scsiSelfTest(void);
+
 #endif
 #endif
index 0db6988e736bd75741b28a9e027ec19dbea47ec7..6df123ee25a0d321bcd872f884f743b0b9dfc1d8 100644 (file)
 #define USBFS_arb_int__INTC_CLR_PD_REG CYREG_NVIC_CLRPEND0\r
 #define USBFS_arb_int__INTC_MASK 0x400000u\r
 #define USBFS_arb_int__INTC_NUMBER 22u\r
 #define USBFS_arb_int__INTC_CLR_PD_REG CYREG_NVIC_CLRPEND0\r
 #define USBFS_arb_int__INTC_MASK 0x400000u\r
 #define USBFS_arb_int__INTC_NUMBER 22u\r
-#define USBFS_arb_int__INTC_PRIOR_NUM 7u\r
+#define USBFS_arb_int__INTC_PRIOR_NUM 6u\r
 #define USBFS_arb_int__INTC_PRIOR_REG CYREG_NVIC_PRI_22\r
 #define USBFS_arb_int__INTC_SET_EN_REG CYREG_NVIC_SETENA0\r
 #define USBFS_arb_int__INTC_SET_PD_REG CYREG_NVIC_SETPEND0\r
 #define USBFS_arb_int__INTC_PRIOR_REG CYREG_NVIC_PRI_22\r
 #define USBFS_arb_int__INTC_SET_EN_REG CYREG_NVIC_SETENA0\r
 #define USBFS_arb_int__INTC_SET_PD_REG CYREG_NVIC_SETPEND0\r
index 6c74b5f1ca6049bb899428e96a26fbe5a0e85b01..a7a6401781845c70a657e54def62e74ef93ed812 100644 (file)
 .set USBFS_arb_int__INTC_CLR_PD_REG, CYREG_NVIC_CLRPEND0\r
 .set USBFS_arb_int__INTC_MASK, 0x400000\r
 .set USBFS_arb_int__INTC_NUMBER, 22\r
 .set USBFS_arb_int__INTC_CLR_PD_REG, CYREG_NVIC_CLRPEND0\r
 .set USBFS_arb_int__INTC_MASK, 0x400000\r
 .set USBFS_arb_int__INTC_NUMBER, 22\r
-.set USBFS_arb_int__INTC_PRIOR_NUM, 7\r
+.set USBFS_arb_int__INTC_PRIOR_NUM, 6\r
 .set USBFS_arb_int__INTC_PRIOR_REG, CYREG_NVIC_PRI_22\r
 .set USBFS_arb_int__INTC_SET_EN_REG, CYREG_NVIC_SETENA0\r
 .set USBFS_arb_int__INTC_SET_PD_REG, CYREG_NVIC_SETPEND0\r
 .set USBFS_arb_int__INTC_PRIOR_REG, CYREG_NVIC_PRI_22\r
 .set USBFS_arb_int__INTC_SET_EN_REG, CYREG_NVIC_SETENA0\r
 .set USBFS_arb_int__INTC_SET_PD_REG, CYREG_NVIC_SETPEND0\r
index ec34581615a30f1dabe51d4fd4988215bec4e02c..dc757612c38b98f053d01ad53add5e061a13979b 100644 (file)
@@ -103,7 +103,7 @@ USBFS_arb_int__INTC_CLR_EN_REG EQU CYREG_NVIC_CLRENA0
 USBFS_arb_int__INTC_CLR_PD_REG EQU CYREG_NVIC_CLRPEND0\r
 USBFS_arb_int__INTC_MASK EQU 0x400000\r
 USBFS_arb_int__INTC_NUMBER EQU 22\r
 USBFS_arb_int__INTC_CLR_PD_REG EQU CYREG_NVIC_CLRPEND0\r
 USBFS_arb_int__INTC_MASK EQU 0x400000\r
 USBFS_arb_int__INTC_NUMBER EQU 22\r
-USBFS_arb_int__INTC_PRIOR_NUM EQU 7\r
+USBFS_arb_int__INTC_PRIOR_NUM EQU 6\r
 USBFS_arb_int__INTC_PRIOR_REG EQU CYREG_NVIC_PRI_22\r
 USBFS_arb_int__INTC_SET_EN_REG EQU CYREG_NVIC_SETENA0\r
 USBFS_arb_int__INTC_SET_PD_REG EQU CYREG_NVIC_SETPEND0\r
 USBFS_arb_int__INTC_PRIOR_REG EQU CYREG_NVIC_PRI_22\r
 USBFS_arb_int__INTC_SET_EN_REG EQU CYREG_NVIC_SETENA0\r
 USBFS_arb_int__INTC_SET_PD_REG EQU CYREG_NVIC_SETPEND0\r
index be5a1f5419fc80de186fdc2813be2da050d13386..aba1877fdd0de6bbab696b180c97fd89d84e25ec 100644 (file)
@@ -103,7 +103,7 @@ USBFS_arb_int__INTC_CLR_EN_REG EQU CYREG_NVIC_CLRENA0
 USBFS_arb_int__INTC_CLR_PD_REG EQU CYREG_NVIC_CLRPEND0\r
 USBFS_arb_int__INTC_MASK EQU 0x400000\r
 USBFS_arb_int__INTC_NUMBER EQU 22\r
 USBFS_arb_int__INTC_CLR_PD_REG EQU CYREG_NVIC_CLRPEND0\r
 USBFS_arb_int__INTC_MASK EQU 0x400000\r
 USBFS_arb_int__INTC_NUMBER EQU 22\r
-USBFS_arb_int__INTC_PRIOR_NUM EQU 7\r
+USBFS_arb_int__INTC_PRIOR_NUM EQU 6\r
 USBFS_arb_int__INTC_PRIOR_REG EQU CYREG_NVIC_PRI_22\r
 USBFS_arb_int__INTC_SET_EN_REG EQU CYREG_NVIC_SETENA0\r
 USBFS_arb_int__INTC_SET_PD_REG EQU CYREG_NVIC_SETPEND0\r
 USBFS_arb_int__INTC_PRIOR_REG EQU CYREG_NVIC_PRI_22\r
 USBFS_arb_int__INTC_SET_EN_REG EQU CYREG_NVIC_SETENA0\r
 USBFS_arb_int__INTC_SET_PD_REG EQU CYREG_NVIC_SETPEND0\r
index c07d02183aa13063ce8c4fc63b40cd0f85dabc43..efccf012d39da78658fbe708e0b971d8e0fee94e 100644 (file)
@@ -28,7 +28,7 @@ __attribute__ ((__section__(".cyloadablemeta"), used))
 const uint8 cy_meta_loadable[] = {\r
     0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,\r
     0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,\r
 const uint8 cy_meta_loadable[] = {\r
     0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,\r
     0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,\r
-    0x00u, 0x00u, 0x00u, 0x00u, 0x5Cu, 0xD1u, 0x20u, 0x04u,\r
+    0x00u, 0x00u, 0x00u, 0x00u, 0x5Cu, 0xD1u, 0x22u, 0x04u,\r
     0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,\r
     0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,\r
     0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,\r
     0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,\r
     0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,\r
     0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,\r
index afd79826236e1737d755aa6f2c186daa64813489..bcf9ae3a1aa2b828cf77786718583b78efe7799a 100644 (file)
Binary files a/software/SCSI2SD/v3/SCSI2SD.cydsn/SCSI2SD.cyfit and b/software/SCSI2SD/v3/SCSI2SD.cydsn/SCSI2SD.cyfit differ
index 2f7d469276b2c19d6be6945e73629b3d303edb16..e30584eb0016b0dda3531911233044c2da06653a 100755 (executable)
 <name_val_pair name="c9323d49-d323-40b8-9b59-cc008d68a989@Release@CortexM3@Linker@General@Enable printf Float" v="True" />\r
 <name_val_pair name="c9323d49-d323-40b8-9b59-cc008d68a989@Release@CortexM3@Linker@Optimization@Optimization Level" v="Size" />\r
 <name_val_pair name="c9323d49-d323-40b8-9b59-cc008d68a989@Release@CortexM3@Linker@Optimization@Remove Unused Functions" v="True" />\r
 <name_val_pair name="c9323d49-d323-40b8-9b59-cc008d68a989@Release@CortexM3@Linker@General@Enable printf Float" v="True" />\r
 <name_val_pair name="c9323d49-d323-40b8-9b59-cc008d68a989@Release@CortexM3@Linker@Optimization@Optimization Level" v="Size" />\r
 <name_val_pair name="c9323d49-d323-40b8-9b59-cc008d68a989@Release@CortexM3@Linker@Optimization@Remove Unused Functions" v="True" />\r
-<name_val_pair name="c9323d49-d323-40b8-9b59-cc008d68a989@Release@CortexM3@Linker@Command Line@Command Line" v="" />\r
+<name_val_pair name="c9323d49-d323-40b8-9b59-cc008d68a989@Release@CortexM3@Linker@Command Line@Command Line" v="-Wl,--section-start=.DEFAULT_CONFIG=0x0001BC00" />\r
 </name>\r
 </platform>\r
 <platform>\r
 </name>\r
 </platform>\r
 <platform>\r
index e5f05a0a0c9c7052a0eec14602add899d53acdb6..285360e4abeae639c89f245d1c7ba7f4d1b5e516 100755 (executable)
Binary files a/software/SCSI2SD/v3/SCSI2SD.cydsn/TopDesign/TopDesign.cysch and b/software/SCSI2SD/v3/SCSI2SD.cydsn/TopDesign/TopDesign.cysch differ
index ae0e2a06c21edaa7f6b22af1fbf0bec880492ce7..159ba3d1f7e4d0b6d942c334edd94bb00d47d9bf 100644 (file)
 #define USBFS_arb_int__INTC_CLR_PD_REG CYREG_NVIC_CLRPEND0
 #define USBFS_arb_int__INTC_MASK 0x400000u
 #define USBFS_arb_int__INTC_NUMBER 22u
 #define USBFS_arb_int__INTC_CLR_PD_REG CYREG_NVIC_CLRPEND0
 #define USBFS_arb_int__INTC_MASK 0x400000u
 #define USBFS_arb_int__INTC_NUMBER 22u
-#define USBFS_arb_int__INTC_PRIOR_NUM 7u
+#define USBFS_arb_int__INTC_PRIOR_NUM 6u
 #define USBFS_arb_int__INTC_PRIOR_REG CYREG_NVIC_PRI_22
 #define USBFS_arb_int__INTC_SET_EN_REG CYREG_NVIC_SETENA0
 #define USBFS_arb_int__INTC_SET_PD_REG CYREG_NVIC_SETPEND0
 #define USBFS_arb_int__INTC_PRIOR_REG CYREG_NVIC_PRI_22
 #define USBFS_arb_int__INTC_SET_EN_REG CYREG_NVIC_SETENA0
 #define USBFS_arb_int__INTC_SET_PD_REG CYREG_NVIC_SETPEND0
 #define SD_RX_DMA__DRQ_CTL CYREG_IDMUX_DRQ_CTL0
 #define SD_RX_DMA__DRQ_NUMBER 2u
 #define SD_RX_DMA__NUMBEROF_TDS 0u
 #define SD_RX_DMA__DRQ_CTL CYREG_IDMUX_DRQ_CTL0
 #define SD_RX_DMA__DRQ_NUMBER 2u
 #define SD_RX_DMA__NUMBEROF_TDS 0u
-#define SD_RX_DMA__PRIORITY 2u
+#define SD_RX_DMA__PRIORITY 0u
 #define SD_RX_DMA__TERMIN_EN 0u
 #define SD_RX_DMA__TERMIN_SEL 0u
 #define SD_RX_DMA__TERMOUT0_EN 1u
 #define SD_RX_DMA__TERMIN_EN 0u
 #define SD_RX_DMA__TERMIN_SEL 0u
 #define SD_RX_DMA__TERMOUT0_EN 1u
 #define SD_TX_DMA__DRQ_CTL CYREG_IDMUX_DRQ_CTL0
 #define SD_TX_DMA__DRQ_NUMBER 3u
 #define SD_TX_DMA__NUMBEROF_TDS 0u
 #define SD_TX_DMA__DRQ_CTL CYREG_IDMUX_DRQ_CTL0
 #define SD_TX_DMA__DRQ_NUMBER 3u
 #define SD_TX_DMA__NUMBEROF_TDS 0u
-#define SD_TX_DMA__PRIORITY 2u
+#define SD_TX_DMA__PRIORITY 1u
 #define SD_TX_DMA__TERMIN_EN 0u
 #define SD_TX_DMA__TERMIN_SEL 0u
 #define SD_TX_DMA__TERMOUT0_EN 1u
 #define SD_TX_DMA__TERMIN_EN 0u
 #define SD_TX_DMA__TERMIN_SEL 0u
 #define SD_TX_DMA__TERMOUT0_EN 1u
index be56b1516d6745a311dbf8936c6f5829c8964ff3..0b4af89b5951576224ecc0bdd33c8fe2053a3dc7 100644 (file)
 .set USBFS_arb_int__INTC_CLR_PD_REG, CYREG_NVIC_CLRPEND0
 .set USBFS_arb_int__INTC_MASK, 0x400000
 .set USBFS_arb_int__INTC_NUMBER, 22
 .set USBFS_arb_int__INTC_CLR_PD_REG, CYREG_NVIC_CLRPEND0
 .set USBFS_arb_int__INTC_MASK, 0x400000
 .set USBFS_arb_int__INTC_NUMBER, 22
-.set USBFS_arb_int__INTC_PRIOR_NUM, 7
+.set USBFS_arb_int__INTC_PRIOR_NUM, 6
 .set USBFS_arb_int__INTC_PRIOR_REG, CYREG_NVIC_PRI_22
 .set USBFS_arb_int__INTC_SET_EN_REG, CYREG_NVIC_SETENA0
 .set USBFS_arb_int__INTC_SET_PD_REG, CYREG_NVIC_SETPEND0
 .set USBFS_arb_int__INTC_PRIOR_REG, CYREG_NVIC_PRI_22
 .set USBFS_arb_int__INTC_SET_EN_REG, CYREG_NVIC_SETENA0
 .set USBFS_arb_int__INTC_SET_PD_REG, CYREG_NVIC_SETPEND0
 .set SD_RX_DMA__DRQ_CTL, CYREG_IDMUX_DRQ_CTL0
 .set SD_RX_DMA__DRQ_NUMBER, 2
 .set SD_RX_DMA__NUMBEROF_TDS, 0
 .set SD_RX_DMA__DRQ_CTL, CYREG_IDMUX_DRQ_CTL0
 .set SD_RX_DMA__DRQ_NUMBER, 2
 .set SD_RX_DMA__NUMBEROF_TDS, 0
-.set SD_RX_DMA__PRIORITY, 2
+.set SD_RX_DMA__PRIORITY, 0
 .set SD_RX_DMA__TERMIN_EN, 0
 .set SD_RX_DMA__TERMIN_SEL, 0
 .set SD_RX_DMA__TERMOUT0_EN, 1
 .set SD_RX_DMA__TERMIN_EN, 0
 .set SD_RX_DMA__TERMIN_SEL, 0
 .set SD_RX_DMA__TERMOUT0_EN, 1
 .set SD_TX_DMA__DRQ_CTL, CYREG_IDMUX_DRQ_CTL0
 .set SD_TX_DMA__DRQ_NUMBER, 3
 .set SD_TX_DMA__NUMBEROF_TDS, 0
 .set SD_TX_DMA__DRQ_CTL, CYREG_IDMUX_DRQ_CTL0
 .set SD_TX_DMA__DRQ_NUMBER, 3
 .set SD_TX_DMA__NUMBEROF_TDS, 0
-.set SD_TX_DMA__PRIORITY, 2
+.set SD_TX_DMA__PRIORITY, 1
 .set SD_TX_DMA__TERMIN_EN, 0
 .set SD_TX_DMA__TERMIN_SEL, 0
 .set SD_TX_DMA__TERMOUT0_EN, 1
 .set SD_TX_DMA__TERMIN_EN, 0
 .set SD_TX_DMA__TERMIN_SEL, 0
 .set SD_TX_DMA__TERMOUT0_EN, 1
index a59ad0e638fb8c58d05c86fde6410b5a36e7fa9e..b6c06fb416796ed5a9481fe86aadebe7302fa621 100644 (file)
@@ -104,7 +104,7 @@ USBFS_arb_int__INTC_CLR_EN_REG EQU CYREG_NVIC_CLRENA0
 USBFS_arb_int__INTC_CLR_PD_REG EQU CYREG_NVIC_CLRPEND0
 USBFS_arb_int__INTC_MASK EQU 0x400000
 USBFS_arb_int__INTC_NUMBER EQU 22
 USBFS_arb_int__INTC_CLR_PD_REG EQU CYREG_NVIC_CLRPEND0
 USBFS_arb_int__INTC_MASK EQU 0x400000
 USBFS_arb_int__INTC_NUMBER EQU 22
-USBFS_arb_int__INTC_PRIOR_NUM EQU 7
+USBFS_arb_int__INTC_PRIOR_NUM EQU 6
 USBFS_arb_int__INTC_PRIOR_REG EQU CYREG_NVIC_PRI_22
 USBFS_arb_int__INTC_SET_EN_REG EQU CYREG_NVIC_SETENA0
 USBFS_arb_int__INTC_SET_PD_REG EQU CYREG_NVIC_SETPEND0
 USBFS_arb_int__INTC_PRIOR_REG EQU CYREG_NVIC_PRI_22
 USBFS_arb_int__INTC_SET_EN_REG EQU CYREG_NVIC_SETENA0
 USBFS_arb_int__INTC_SET_PD_REG EQU CYREG_NVIC_SETPEND0
@@ -2322,7 +2322,7 @@ SCSI_Out_DBx__DB7__SLW EQU CYREG_PRT2_SLW
 SD_RX_DMA__DRQ_CTL EQU CYREG_IDMUX_DRQ_CTL0
 SD_RX_DMA__DRQ_NUMBER EQU 2
 SD_RX_DMA__NUMBEROF_TDS EQU 0
 SD_RX_DMA__DRQ_CTL EQU CYREG_IDMUX_DRQ_CTL0
 SD_RX_DMA__DRQ_NUMBER EQU 2
 SD_RX_DMA__NUMBEROF_TDS EQU 0
-SD_RX_DMA__PRIORITY EQU 2
+SD_RX_DMA__PRIORITY EQU 0
 SD_RX_DMA__TERMIN_EN EQU 0
 SD_RX_DMA__TERMIN_SEL EQU 0
 SD_RX_DMA__TERMOUT0_EN EQU 1
 SD_RX_DMA__TERMIN_EN EQU 0
 SD_RX_DMA__TERMIN_SEL EQU 0
 SD_RX_DMA__TERMOUT0_EN EQU 1
@@ -2344,7 +2344,7 @@ SD_RX_DMA_COMPLETE__INTC_SET_PD_REG EQU CYREG_NVIC_SETPEND0
 SD_TX_DMA__DRQ_CTL EQU CYREG_IDMUX_DRQ_CTL0
 SD_TX_DMA__DRQ_NUMBER EQU 3
 SD_TX_DMA__NUMBEROF_TDS EQU 0
 SD_TX_DMA__DRQ_CTL EQU CYREG_IDMUX_DRQ_CTL0
 SD_TX_DMA__DRQ_NUMBER EQU 3
 SD_TX_DMA__NUMBEROF_TDS EQU 0
-SD_TX_DMA__PRIORITY EQU 2
+SD_TX_DMA__PRIORITY EQU 1
 SD_TX_DMA__TERMIN_EN EQU 0
 SD_TX_DMA__TERMIN_SEL EQU 0
 SD_TX_DMA__TERMOUT0_EN EQU 1
 SD_TX_DMA__TERMIN_EN EQU 0
 SD_TX_DMA__TERMIN_SEL EQU 0
 SD_TX_DMA__TERMOUT0_EN EQU 1
index f2b9e4cc717e341e128762ca794b3ad7075f4193..4cc15c6e29cba7ad7cb2cc77b8dbc021ee41190e 100644 (file)
@@ -104,7 +104,7 @@ USBFS_arb_int__INTC_CLR_EN_REG EQU CYREG_NVIC_CLRENA0
 USBFS_arb_int__INTC_CLR_PD_REG EQU CYREG_NVIC_CLRPEND0
 USBFS_arb_int__INTC_MASK EQU 0x400000
 USBFS_arb_int__INTC_NUMBER EQU 22
 USBFS_arb_int__INTC_CLR_PD_REG EQU CYREG_NVIC_CLRPEND0
 USBFS_arb_int__INTC_MASK EQU 0x400000
 USBFS_arb_int__INTC_NUMBER EQU 22
-USBFS_arb_int__INTC_PRIOR_NUM EQU 7
+USBFS_arb_int__INTC_PRIOR_NUM EQU 6
 USBFS_arb_int__INTC_PRIOR_REG EQU CYREG_NVIC_PRI_22
 USBFS_arb_int__INTC_SET_EN_REG EQU CYREG_NVIC_SETENA0
 USBFS_arb_int__INTC_SET_PD_REG EQU CYREG_NVIC_SETPEND0
 USBFS_arb_int__INTC_PRIOR_REG EQU CYREG_NVIC_PRI_22
 USBFS_arb_int__INTC_SET_EN_REG EQU CYREG_NVIC_SETENA0
 USBFS_arb_int__INTC_SET_PD_REG EQU CYREG_NVIC_SETPEND0
@@ -2322,7 +2322,7 @@ SCSI_Out_DBx__DB7__SLW EQU CYREG_PRT2_SLW
 SD_RX_DMA__DRQ_CTL EQU CYREG_IDMUX_DRQ_CTL0
 SD_RX_DMA__DRQ_NUMBER EQU 2
 SD_RX_DMA__NUMBEROF_TDS EQU 0
 SD_RX_DMA__DRQ_CTL EQU CYREG_IDMUX_DRQ_CTL0
 SD_RX_DMA__DRQ_NUMBER EQU 2
 SD_RX_DMA__NUMBEROF_TDS EQU 0
-SD_RX_DMA__PRIORITY EQU 2
+SD_RX_DMA__PRIORITY EQU 0
 SD_RX_DMA__TERMIN_EN EQU 0
 SD_RX_DMA__TERMIN_SEL EQU 0
 SD_RX_DMA__TERMOUT0_EN EQU 1
 SD_RX_DMA__TERMIN_EN EQU 0
 SD_RX_DMA__TERMIN_SEL EQU 0
 SD_RX_DMA__TERMOUT0_EN EQU 1
@@ -2344,7 +2344,7 @@ SD_RX_DMA_COMPLETE__INTC_SET_PD_REG EQU CYREG_NVIC_SETPEND0
 SD_TX_DMA__DRQ_CTL EQU CYREG_IDMUX_DRQ_CTL0
 SD_TX_DMA__DRQ_NUMBER EQU 3
 SD_TX_DMA__NUMBEROF_TDS EQU 0
 SD_TX_DMA__DRQ_CTL EQU CYREG_IDMUX_DRQ_CTL0
 SD_TX_DMA__DRQ_NUMBER EQU 3
 SD_TX_DMA__NUMBEROF_TDS EQU 0
-SD_TX_DMA__PRIORITY EQU 2
+SD_TX_DMA__PRIORITY EQU 1
 SD_TX_DMA__TERMIN_EN EQU 0
 SD_TX_DMA__TERMIN_SEL EQU 0
 SD_TX_DMA__TERMOUT0_EN EQU 1
 SD_TX_DMA__TERMIN_EN EQU 0
 SD_TX_DMA__TERMIN_SEL EQU 0
 SD_TX_DMA__TERMOUT0_EN EQU 1
index dfaca9dbd6ea6be52b101aa3ab8dfbecd735f74d..ee269a7a8f85a5c515444851393c1c5ac0ab76d0 100644 (file)
@@ -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,
 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, 0x10u, 0x04u,
+    0x00u, 0x00u, 0x00u, 0x00u, 0x5Cu, 0xD1u, 0x22u, 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,
     0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
     0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
     0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
index 7cb75d6f146f8d2f097fcefd88623521e35f01d8..239ad50c6bea88d7a70ebf0b0becdf0db1a6a51d 100644 (file)
Binary files a/software/SCSI2SD/v4/SCSI2SD.cydsn/SCSI2SD.cyfit and b/software/SCSI2SD/v4/SCSI2SD.cydsn/SCSI2SD.cyfit differ
index 0f6ea55877f20ad2dd50ea463d2afc3ef9653828..465dedebd18f2100e95ec8c793d029c7f2b19c4c 100755 (executable)
 <name_val_pair name="c9323d49-d323-40b8-9b59-cc008d68a989@Release@CortexM3@Linker@General@Enable printf Float" v="True" />
 <name_val_pair name="c9323d49-d323-40b8-9b59-cc008d68a989@Release@CortexM3@Linker@Optimization@Optimization Level" v="Size" />
 <name_val_pair name="c9323d49-d323-40b8-9b59-cc008d68a989@Release@CortexM3@Linker@Optimization@Remove Unused Functions" v="True" />
 <name_val_pair name="c9323d49-d323-40b8-9b59-cc008d68a989@Release@CortexM3@Linker@General@Enable printf Float" v="True" />
 <name_val_pair name="c9323d49-d323-40b8-9b59-cc008d68a989@Release@CortexM3@Linker@Optimization@Optimization Level" v="Size" />
 <name_val_pair name="c9323d49-d323-40b8-9b59-cc008d68a989@Release@CortexM3@Linker@Optimization@Remove Unused Functions" v="True" />
-<name_val_pair name="c9323d49-d323-40b8-9b59-cc008d68a989@Release@CortexM3@Linker@Command Line@Command Line" v="" />
+<name_val_pair name="c9323d49-d323-40b8-9b59-cc008d68a989@Release@CortexM3@Linker@Command Line@Command Line" v="-Wl,--section-start=.DEFAULT_CONFIG=0x0001BC00" />
 </name>
 </platform>
 <platform>
 </name>
 </platform>
 <platform>
index 99cb769501466d5cb2b54cbcb910995adf8e2ba9..71ca821975e55475d833c3860e79a297b84003e0 100755 (executable)
Binary files a/software/SCSI2SD/v4/SCSI2SD.cydsn/TopDesign/TopDesign.cysch and b/software/SCSI2SD/v4/SCSI2SD.cydsn/TopDesign/TopDesign.cysch differ
index cec7485c7da3957f493e9ee7cf76544843780ce8..3e8cf47f8e05d7b92e0206927040954b964b8786 100755 (executable)
@@ -181,7 +181,14 @@ typedef enum
        // Response:
        // uint8_t[16] CSD
        // uint8_t[16] CID
        // Response:
        // uint8_t[16] CSD
        // uint8_t[16] CID
-       CONFIG_SDINFO
+       CONFIG_SDINFO,
+
+       // Command content:
+       // uint8_t CONFIG_SCSITEST
+       // Response:
+       // CONFIG_STATUS
+       // uint8_t result code (0 = passed)
+       CONFIG_SCSITEST
 } CONFIG_COMMAND;
 
 typedef enum
 } CONFIG_COMMAND;
 
 typedef enum
index e717cf8d5db80393c0c220e1827701371d56e290..446a91b7c4c070207c7089eae844c68e27e0955b 100644 (file)
@@ -24,7 +24,6 @@
 
 using namespace SCSI2SD;
 
 
 using namespace SCSI2SD;
 
-ADD QUIRKS MODES
 namespace
 {
        // Endian conversion routines.
 namespace
 {
        // Endian conversion routines.
@@ -105,7 +104,7 @@ ConfigUtil::Default(size_t targetIdx)
        config.headsPerCylinder = 255;
        memcpy(config.vendor, " codesrc", 8);
        memcpy(config.prodId, "         SCSI2SD", 16);
        config.headsPerCylinder = 255;
        memcpy(config.vendor, " codesrc", 8);
        memcpy(config.prodId, "         SCSI2SD", 16);
-       memcpy(config.revision, " 4.0", 4);
+       memcpy(config.revision, " 4.2", 4);
        memcpy(config.serial, "1234567812345678", 16);
 
        // Reserved fields, already set to 0
        memcpy(config.serial, "1234567812345678", 16);
 
        // Reserved fields, already set to 0
@@ -146,6 +145,7 @@ ConfigUtil::toBytes(const TargetConfig& _config)
        return std::vector<uint8_t>(begin, begin + sizeof(config));
 }
 
        return std::vector<uint8_t>(begin, begin + sizeof(config));
 }
 
+/*
 wxXmlNode*
 ConfigUtil::toXML(const TargetConfig& config)
 {
 wxXmlNode*
 ConfigUtil::toXML(const TargetConfig& config)
 {
@@ -203,3 +203,4 @@ ConfigUtil::deserialise(const std::string& in)
 {
 
 }
 {
 
 }
+*/
index d1ae7453cc9f8f2b7125ddae2ada16e7826476ab..22794df063282f4eab8abf9a4917140d8de270b6 100755 (executable)
@@ -51,7 +51,7 @@ endif
 
 export CC CXX
 
 
 export CC CXX
 
-all:  $(BUILD)/scsi2sd-util$(EXE)
+all:  $(BUILD)/scsi2sd-util$(EXE) $(BUILD)/scsi2sd-monitor$(EXE)
 
 CYAPI = \
        $(BUILD)/cybtldr_api2.o \
 
 CYAPI = \
        $(BUILD)/cybtldr_api2.o \
@@ -66,7 +66,6 @@ HIDAPI = \
 
 OBJ = \
        $(CYAPI) $(HIDAPI) \
 
 OBJ = \
        $(CYAPI) $(HIDAPI) \
-       $(BUILD)/scsi2sd-util.o \
        $(BUILD)/ConfigUtil.o \
        $(BUILD)/Firmware.o \
        $(BUILD)/TargetPanel.o \
        $(BUILD)/ConfigUtil.o \
        $(BUILD)/Firmware.o \
        $(BUILD)/TargetPanel.o \
@@ -74,8 +73,14 @@ OBJ = \
        $(BUILD)/SCSI2SD_HID.o \
        $(BUILD)/hidpacket.o \
 
        $(BUILD)/SCSI2SD_HID.o \
        $(BUILD)/hidpacket.o \
 
+EXEOBJ = \
+       $(BUILD)/scsi2sd-util.o \
+       $(BUILD)/scsi2sd-monitor.o \
+
+
 
 $(OBJ): $(BUILD)/zlib/buildstamp
 
 $(OBJ): $(BUILD)/zlib/buildstamp
+$(EXEOBJ): $(BUILD)/zlib/buildstamp
 $(BUILD)/zlib/buildstamp:
        mkdir -p $(dir $@)
        ( \
 $(BUILD)/zlib/buildstamp:
        mkdir -p $(dir $@)
        ( \
@@ -87,6 +92,7 @@ $(BUILD)/zlib/buildstamp:
        touch $@
 
 $(OBJ): $(BUILD)/wx.buildstamp
        touch $@
 
 $(OBJ): $(BUILD)/wx.buildstamp
+$(EXEOBJ): $(BUILD)/wx.buildstamp
 $(BUILD)/wx.buildstamp: $(BUILD)/zlib/buildstamp
        mkdir -p $(dir $@)
        ( \
 $(BUILD)/wx.buildstamp: $(BUILD)/zlib/buildstamp
        mkdir -p $(dir $@)
        ( \
@@ -97,6 +103,7 @@ $(BUILD)/wx.buildstamp: $(BUILD)/zlib/buildstamp
        touch $@
 
 $(OBJ): $(BUILD)/libzipper/buildstamp
        touch $@
 
 $(OBJ): $(BUILD)/libzipper/buildstamp
+$(EXEOBJ): $(BUILD)/libzipper/buildstamp
 $(BUILD)/libzipper/buildstamp: $(BUILD)/zlib/buildstamp
        mkdir -p $(dir $@)
        ( \
 $(BUILD)/libzipper/buildstamp: $(BUILD)/zlib/buildstamp
        mkdir -p $(dir $@)
        ( \
@@ -114,7 +121,11 @@ $(BUILD)/%.o: %.cc
        mkdir -p $(dir $@)
        $(CXX) $(CPPFLAGS) $(CXXFLAGS) `$(BUILD)/wx-config --cxxflags` $< -c -o $@
 
        mkdir -p $(dir $@)
        $(CXX) $(CPPFLAGS) $(CXXFLAGS) `$(BUILD)/wx-config --cxxflags` $< -c -o $@
 
-$(BUILD)/scsi2sd-util$(EXE): $(OBJ)
+$(BUILD)/scsi2sd-util$(EXE): $(OBJ) $(BUILD)/scsi2sd-util.o
+       mkdir -p $(dir $@)
+       $(CXX) $(CXXFLAGS) $^ $(LDFLAGS) `$(BUILD)/wx-config --libs` -o $@
+
+$(BUILD)/scsi2sd-monitor$(EXE): $(OBJ) $(BUILD)/scsi2sd-monitor.o
        mkdir -p $(dir $@)
        $(CXX) $(CXXFLAGS) $^ $(LDFLAGS) `$(BUILD)/wx-config --libs` -o $@
 
        mkdir -p $(dir $@)
        $(CXX) $(CXXFLAGS) $^ $(LDFLAGS) `$(BUILD)/wx-config --libs` -o $@
 
index b2aa4d0cef4c0f094f36bb625d6ea0b5b42e9a41..df83b67af463160648c5085429e2174084643f22 100644 (file)
@@ -338,7 +338,7 @@ HID::getSD_CSD()
        std::vector<uint8_t> out;
        try
        {
        std::vector<uint8_t> out;
        try
        {
-               sendHIDPacket(cmd, out, 1);
+               sendHIDPacket(cmd, out, 16);
        }
        catch (std::runtime_error& e)
        {
        }
        catch (std::runtime_error& e)
        {
@@ -356,7 +356,7 @@ HID::getSD_CID()
        std::vector<uint8_t> out;
        try
        {
        std::vector<uint8_t> out;
        try
        {
-               sendHIDPacket(cmd, out, 1);
+               sendHIDPacket(cmd, out, 16);
        }
        catch (std::runtime_error& e)
        {
        }
        catch (std::runtime_error& e)
        {
@@ -368,6 +368,23 @@ HID::getSD_CID()
        return result;
 }
 
        return result;
 }
 
+bool
+HID::scsiSelfTest()
+{
+       std::vector<uint8_t> cmd { CONFIG_SCSITEST };
+       std::vector<uint8_t> out;
+       try
+       {
+               sendHIDPacket(cmd, out, 2);
+       }
+       catch (std::runtime_error& e)
+       {
+               return false;
+       }
+       return (out.size() >= 1) && (out[0] == CONFIG_STATUS_GOOD);
+}
+
+
 void
 HID::sendHIDPacket(
        const std::vector<uint8_t>& cmd,
 void
 HID::sendHIDPacket(
        const std::vector<uint8_t>& cmd,
index 443b3df73bdc0115ea4b8042ea805742f917c7e2..2cf17471ae685c3a1b535de19decdcbee6a8822f 100644 (file)
@@ -58,6 +58,8 @@ public:
        std::vector<uint8_t> getSD_CSD();
        std::vector<uint8_t> getSD_CID();
 
        std::vector<uint8_t> getSD_CSD();
        std::vector<uint8_t> getSD_CID();
 
+       bool scsiSelfTest();
+
        void enterBootloader();
 
        void readFlashRow(int array, int row, std::vector<uint8_t>& out);
        void enterBootloader();
 
        void readFlashRow(int array, int row, std::vector<uint8_t>& out);
diff --git a/software/scsi2sd-util/scsi2sd-monitor.cc b/software/scsi2sd-util/scsi2sd-monitor.cc
new file mode 100644 (file)
index 0000000..872001a
--- /dev/null
@@ -0,0 +1,288 @@
+//     Copyright (C) 2015 Michael McMaster <michael@codesrc.com>
+//
+//     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 <http://www.gnu.org/licenses/>.
+
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include <wx/wxprec.h>
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+#include <wx/filedlg.h>
+#include <wx/filefn.h>
+#include <wx/filename.h>
+#include <wx/log.h>
+#include <wx/notebook.h>
+#include <wx/progdlg.h>
+#include <wx/utils.h>
+#include <wx/windowptr.h>
+#include <wx/thread.h>
+
+#include <zipper.hh>
+
+#include "ConfigUtil.hh"
+#include "TargetPanel.hh"
+#include "SCSI2SD_Bootloader.hh"
+#include "SCSI2SD_HID.hh"
+#include "Firmware.hh"
+
+#include <algorithm>
+#include <iomanip>
+#include <vector>
+#include <set>
+#include <sstream>
+
+#if __cplusplus >= 201103L
+#include <cstdint>
+#include <memory>
+using std::shared_ptr;
+#else
+#include <stdint.h>
+#include <tr1/memory>
+using std::tr1::shared_ptr;
+#endif
+
+#define MIN_FIRMWARE_VERSION 0x0400
+
+using namespace SCSI2SD;
+
+namespace
+{
+
+static uint8_t sdCrc7(uint8_t* chr, uint8_t cnt, uint8_t crc)
+{
+       uint8_t a;
+       for(a = 0; a < cnt; a++)
+       {
+               uint8_t data = chr[a];
+               uint8_t i;
+               for(i = 0; i < 8; i++)
+               {
+                       crc <<= 1;
+                       if ((data & 0x80) ^ (crc & 0x80))
+                       {
+                               crc ^= 0x09;
+                       }
+                       data <<= 1;
+               }
+       }
+       return crc & 0x7F;
+}
+
+class TimerLock
+{
+public:
+       TimerLock(wxTimer* timer) :
+               myTimer(timer),
+               myInterval(myTimer->GetInterval())
+       {
+               myTimer->Stop();
+       };
+
+       virtual ~TimerLock()
+       {
+               if (myTimer && myInterval > 0)
+               {
+                       myTimer->Start(myInterval);
+               }
+       }
+private:
+       wxTimer* myTimer;
+       int myInterval;
+};
+
+class AppFrame : public wxFrame
+{
+public:
+       AppFrame() :
+               wxFrame(NULL, wxID_ANY, "scsi2sd-monitor", wxPoint(50, 50), wxSize(250, 150))
+       {
+               wxFlexGridSizer *fgs = new wxFlexGridSizer(3, 2, 9, 25);
+
+               fgs->Add(new wxStaticText(this, wxID_ANY, wxT("SCSI2SD Device:")));
+               myBoardText = new wxStaticText(this, wxID_ANY, wxT(""));
+               fgs->Add(myBoardText);
+               fgs->Add(new wxStaticText(this, wxID_ANY, wxT("SD Test:")));
+               mySDText = new wxStaticText(this, wxID_ANY, wxT(""));
+               fgs->Add(mySDText);
+               fgs->Add(new wxStaticText(this, wxID_ANY, wxT("SCSI Test:")));
+               mySCSIText = new wxStaticText(this, wxID_ANY, wxT(""));
+               fgs->Add(mySCSIText);
+
+               wxBoxSizer* hbox = new wxBoxSizer(wxHORIZONTAL);
+               hbox->Add(fgs, 1, wxALL | wxEXPAND, 15);
+               this->SetSizer(hbox);
+               Centre();
+
+               //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);
+       }
+
+private:
+       wxTimer* myTimer;
+       shared_ptr<HID> myHID;
+       shared_ptr<Bootloader> myBootloader;
+
+       wxStaticText* myBoardText;
+       wxStaticText* mySDText;
+       wxStaticText* mySCSIText;
+
+       enum
+       {
+               ID_ConfigDefaults = wxID_HIGHEST + 1,
+               ID_Timer
+       };
+
+       void evaluate()
+       {
+               if (myHID)
+               {
+                       std::stringstream msg;
+                       msg << "Ready, " <<
+                               myHID->getFirmwareVersionStr();
+                       myBoardText->SetLabelText(msg.str());
+
+
+                       std::vector<uint8_t> csd(myHID->getSD_CSD());
+                       std::vector<uint8_t> cid(myHID->getSD_CID());
+
+                       bool sdGood = false;
+                       for (size_t i = 0; i < 16; ++i)
+                       {
+                               if (csd[i] != 0)
+                               {
+                                       sdGood = true;
+                                       //break;
+                               }
+                       }
+
+                       sdGood = sdGood &&
+                               (sdCrc7(&csd[0], 15, 0) == (csd[15] >> 1)) &&
+                               (sdCrc7(&cid[0], 15, 0) == (cid[15] >> 1));
+
+                       if (sdGood)
+                       {
+                               mySDText->SetLabelText("OK");
+                       }
+                       else
+                       {
+                               mySDText->SetLabelText("FAIL");
+                       }
+
+                       if (myHID->scsiSelfTest())
+                       {
+                               mySCSIText->SetLabelText("OK");
+                       }
+                       else
+                       {
+                               mySCSIText->SetLabelText("FAIL");
+                       }
+               }
+               else
+               {
+                       if (myBootloader)
+                       {
+                               myBoardText->SetLabelText("Bootloader");
+                       }
+                       else
+                       {
+                               myBoardText->SetLabelText("Missing");
+                       }
+                       mySDText->SetLabelText("-");
+                       mySCSIText->SetLabelText("-");
+               }
+       }
+
+       void OnID_Timer(wxTimerEvent& event)
+       {
+               // Check if we are connected to the HID device.
+               // AND/or bootloader device.
+               try
+               {
+                       if (myBootloader)
+                       {
+                               // Verify the USB HID connection is valid
+                               if (!myBootloader->ping())
+                               {
+                                       myBootloader.reset();
+                               }
+                       }
+
+                       if (!myBootloader)
+                       {
+                               myBootloader.reset(Bootloader::Open());
+                       }
+
+                       if (myHID && !myHID->ping())
+                       {
+                               // Verify the USB HID connection is valid
+std::cerr << "RESET!" << std::endl;
+                               myHID.reset();
+                       }
+
+                       if (!myHID)
+                       {
+                               myHID.reset(HID::Open());
+
+                       }
+               }
+               catch (std::runtime_error& e)
+               {
+                       std::cerr << e.what() << std::endl;
+               }
+
+               evaluate();
+       }
+
+       // Note: Don't confuse this with the wxApp::OnExit virtual method
+       void OnExitEvt(wxCommandEvent& event)
+       {
+               Close(true);
+       }
+
+       wxDECLARE_EVENT_TABLE();
+};
+
+wxBEGIN_EVENT_TABLE(AppFrame, wxFrame)
+       EVT_MENU(wxID_EXIT, AppFrame::OnExitEvt)
+
+       EVT_TIMER(AppFrame::ID_Timer, AppFrame::OnID_Timer)
+
+wxEND_EVENT_TABLE()
+
+
+
+class App : public wxApp
+{
+public:
+       virtual bool OnInit()
+       {
+               AppFrame* frame = new AppFrame();
+               frame->Show(true);
+               SetTopWindow(frame);
+               return true;
+       }
+};
+} // namespace
+
+// Main Method
+wxIMPLEMENT_APP(App);
+
+
index cc26e8ba05fc78dbb624cc07c07608895d8e04d3..6e3e782abf8152bd3d16c6a72bfdc573eec50fc3 100644 (file)
@@ -108,6 +108,26 @@ void ProgressUpdate(unsigned char arrayId, unsigned short rowNum)
 namespace
 {
 
 namespace
 {
 
+static uint8_t sdCrc7(uint8_t* chr, uint8_t cnt, uint8_t crc)
+{
+       uint8_t a;
+       for(a = 0; a < cnt; a++)
+       {
+               uint8_t data = chr[a];
+               uint8_t i;
+               for(i = 0; i < 8; i++)
+               {
+                       crc <<= 1;
+                       if ((data & 0x80) ^ (crc & 0x80))
+                       {
+                               crc ^= 0x09;
+                       }
+                       data <<= 1;
+               }
+       }
+       return crc & 0x7F;
+}
+
 class TimerLock
 {
 public:
 class TimerLock
 {
 public:
@@ -163,6 +183,11 @@ public:
                        "Log SCSI data",
                        "Log SCSI commands");
 
                        "Log SCSI data",
                        "Log SCSI commands");
 
+               mySelfTestChk = menuDebug->AppendCheckItem(
+                       ID_SelfTest,
+                       "SCSI Standalone Self-Test",
+                       "SCSI Standalone Self-Test");
+
                wxMenu *menuHelp = new wxMenu();
                menuHelp->Append(wxID_ABOUT);
 
                wxMenu *menuHelp = new wxMenu();
                menuHelp->Append(wxID_ABOUT);
 
@@ -229,6 +254,7 @@ private:
        wxButton* myLoadButton;
        wxButton* mySaveButton;
        wxMenuItem* mySCSILogChk;
        wxButton* myLoadButton;
        wxButton* mySaveButton;
        wxMenuItem* mySCSILogChk;
+       wxMenuItem* mySelfTestChk;
        wxTimer* myTimer;
        shared_ptr<HID> myHID;
        shared_ptr<Bootloader> myBootloader;
        wxTimer* myTimer;
        shared_ptr<HID> myHID;
        shared_ptr<Bootloader> myBootloader;
@@ -329,7 +355,8 @@ private:
                ID_BtnLoad,
                ID_BtnSave,
                ID_LogWindow,
                ID_BtnLoad,
                ID_BtnSave,
                ID_LogWindow,
-               ID_SCSILog
+               ID_SCSILog,
+               ID_SelfTest
        };
 
        void OnID_ConfigDefaults(wxCommandEvent& event)
        };
 
        void OnID_ConfigDefaults(wxCommandEvent& event)
@@ -629,6 +656,10 @@ private:
                                                        myHID->getSDCapacity() << std::endl;
 
                                                sdinfo << "SD CSD Register: ";
                                                        myHID->getSDCapacity() << std::endl;
 
                                                sdinfo << "SD CSD Register: ";
+                                               if (sdCrc7(&csd[0], 15, 0) != (csd[15] >> 1))
+                                               {
+                                                       sdinfo << "BADCRC ";
+                                               }
                                                for (size_t i = 0; i < csd.size(); ++i)
                                                {
                                                        sdinfo <<
                                                for (size_t i = 0; i < csd.size(); ++i)
                                                {
                                                        sdinfo <<
@@ -637,6 +668,10 @@ private:
                                                }
                                                sdinfo << std::endl;
                                                sdinfo << "SD CID Register: ";
                                                }
                                                sdinfo << std::endl;
                                                sdinfo << "SD CID Register: ";
+                                               if (sdCrc7(&cid[0], 15, 0) != (cid[15] >> 1))
+                                               {
+                                                       sdinfo << "BADCRC ";
+                                               }
                                                for (size_t i = 0; i < cid.size(); ++i)
                                                {
                                                        sdinfo <<
                                                for (size_t i = 0; i < cid.size(); ++i)
                                                {
                                                        sdinfo <<
@@ -646,6 +681,14 @@ private:
 
                                                wxLogMessage(this, "%s", sdinfo.str());
 
 
                                                wxLogMessage(this, "%s", sdinfo.str());
 
+                                               if (mySelfTestChk->IsChecked())
+                                               {
+                                                       std::stringstream scsiInfo;
+                                                       scsiInfo << "SCSI Self-Test: " <<
+                                                               (myHID->scsiSelfTest() ? "Passed" : "FAIL");
+                                                       wxLogMessage(this, "%s", scsiInfo.str());
+                                               }
+
                                                if (!myInitialConfig)
                                                {
                                                        wxCommandEvent loadEvent(wxEVT_NULL, ID_BtnLoad);
                                                if (!myInitialConfig)
                                                {
                                                        wxCommandEvent loadEvent(wxEVT_NULL, ID_BtnLoad);