mirror of
https://github.com/fhgwright/SCSI2SD.git
synced 2024-06-02 06:41:36 +00:00
Added support for v4.2 boards
Renamed "pbook" firmware to "v4". Original "green" boards now under "v3". Add external LED support for v4 firmware. Added --reset to scsi2sd-config bootloaderhost can now reset the board.
This commit is contained in:
parent
186938a03f
commit
5e0f1e3360
|
@ -1,7 +1,12 @@
|
|||
201404xx 3.5
|
||||
20140713 3.5
|
||||
- Fixed several performance issues. Transfer rates up to 2.5MB/s are now
|
||||
possible.
|
||||
- Implemented the READ BUFFER scsi command for performance testing purposes.
|
||||
- Added support for the new "yellow" v4.2 revision boards.
|
||||
- Improved firmware uploading. bootloaderhost can now reset the board back
|
||||
to the bootloader.
|
||||
- Display firmware version in scsi2sd-config
|
||||
- Add "--reset" parameter to scsi2sd-config
|
||||
|
||||
20140418 3.4
|
||||
- Critical fix for writes when using non-standard block sizes.
|
||||
|
|
31
readme.txt
31
readme.txt
|
@ -62,19 +62,34 @@ Tested with a 16GB class 10 SD card, via the commands:
|
|||
|
||||
Compatibility
|
||||
|
||||
Tested with Linux (current), Apple Macintosh System 7.5.3 on LC-III, and LC-475 hardware.
|
||||
|
||||
Users have reported success on these systems:
|
||||
Desktop systems
|
||||
|
||||
Mac LC-III and LC-475
|
||||
Mac II running System 6.0.8
|
||||
Mac SE/30
|
||||
Apple IIgs using Apple II High Speed SCSI controller card (from v3.3)
|
||||
Symbolics Lisp Machine XL1200, using 1280 byte sectors (from v3.4)
|
||||
PDP-11/73 running RSX11M+ V4.6
|
||||
Amiga 500+ with GVP A530
|
||||
Atari TT030 System V
|
||||
|
||||
Samplers
|
||||
|
||||
Roland JS-30 Sampler
|
||||
Akai S1000, S3200, S3000XL, MPC 2000XL, DPS 12
|
||||
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
|
||||
Ensoniq ASR-X, ASR-10 (from v3.4, 2GB size limit)
|
||||
ASR-20 Requires TERMPWR jumper.
|
||||
Kurzweil K2000R
|
||||
See kurzweil.com for size limits which a dependant on the OS version. Older OS versions have a 1GB limit.
|
||||
SCSI cable reversed
|
||||
Casio FZ-20M
|
||||
Requires TERMPWR jumper. The manual shows the pin25 of the DB25 connector is "not connected".
|
||||
May require scsi2sd-config --apple flag
|
||||
|
||||
Other
|
||||
|
||||
HP 16601A logic analyzer
|
||||
Apple IIgs using Apple II High Speed SCSI controller card (from v3.3)
|
||||
Symbolics List Machine XL1200, using 1280 byte sectors (from v3.4)
|
||||
Fluke 9100 series
|
||||
PDP-11/73 running RSX11M+ V4.6
|
||||
Amiga 500+ with GVP A530
|
||||
Fluke 9100 series
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../SCSI2SD.cydsn/OddParityGen/
|
Binary file not shown.
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
../../SCSI2SD.cydsn/scsiTarget/
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
// CYDEV_EEPROM_ROW_SIZE == 16.
|
||||
static const char magic[CYDEV_EEPROM_ROW_SIZE] = "codesrc_00000002";
|
||||
static const uint16_t FIRMWARE_VERSION = 0x0350;
|
||||
|
||||
// Config shadow RAM (copy of EEPROM)
|
||||
static Config shadow =
|
||||
|
@ -48,6 +49,7 @@ enum USB_ENDPOINTS
|
|||
{
|
||||
USB_EP_OUT = 1,
|
||||
USB_EP_IN = 2,
|
||||
USB_EP_COMMAND = 3,
|
||||
USB_EP_DEBUG = 4
|
||||
};
|
||||
enum USB_STATE
|
||||
|
@ -172,6 +174,7 @@ void configPoll()
|
|||
if (reset)
|
||||
{
|
||||
USBFS_EnableOutEP(USB_EP_OUT);
|
||||
USBFS_EnableOutEP(USB_EP_COMMAND);
|
||||
usbInEpState = usbDebugEpState = USB_IDLE;
|
||||
}
|
||||
|
||||
|
@ -238,14 +241,31 @@ void configPoll()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef MM_DEBUG
|
||||
void debugPoll()
|
||||
{
|
||||
if (!usbReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(USBFS_GetEPState(USB_EP_COMMAND) == USBFS_OUT_BUFFER_FULL)
|
||||
{
|
||||
// The host sent us some data!
|
||||
int byteCount = USBFS_GetEPCount(USB_EP_COMMAND);
|
||||
USBFS_ReadOutEP(USB_EP_COMMAND, (uint8 *)&debugBuffer, byteCount);
|
||||
|
||||
if (byteCount >= 1 &&
|
||||
debugBuffer[0] == 0x01)
|
||||
{
|
||||
// Reboot command.
|
||||
Bootloadable_1_Load();
|
||||
}
|
||||
|
||||
// Allow the host to send us another command.
|
||||
// (assuming we didn't reboot outselves)
|
||||
USBFS_EnableOutEP(USB_EP_COMMAND);
|
||||
}
|
||||
|
||||
switch (usbDebugEpState)
|
||||
{
|
||||
case USB_IDLE:
|
||||
|
@ -265,6 +285,14 @@ void debugPoll()
|
|||
debugBuffer[24] = scsiDev.cmdCount;
|
||||
debugBuffer[25] = scsiDev.watchdogTick;
|
||||
|
||||
debugBuffer[58] = sdDev.capacity >> 24;
|
||||
debugBuffer[59] = sdDev.capacity >> 16;
|
||||
debugBuffer[60] = sdDev.capacity >> 8;
|
||||
debugBuffer[61] = sdDev.capacity;
|
||||
|
||||
debugBuffer[62] = FIRMWARE_VERSION >> 8;
|
||||
debugBuffer[63] = FIRMWARE_VERSION;
|
||||
|
||||
USBFS_LoadInEP(USB_EP_DEBUG, (uint8 *)&debugBuffer, sizeof(debugBuffer));
|
||||
usbDebugEpState = USB_DATA_SENT;
|
||||
break;
|
||||
|
@ -287,18 +315,11 @@ CY_ISR(debugTimerISR)
|
|||
debugPoll();
|
||||
CyExitCriticalSection(savedIntrStatus);
|
||||
}
|
||||
#endif
|
||||
|
||||
void debugInit()
|
||||
{
|
||||
#ifdef MM_DEBUG
|
||||
Debug_Timer_Interrupt_StartEx(debugTimerISR);
|
||||
Debug_Timer_Start();
|
||||
#else
|
||||
Debug_Timer_Interrupt_Stop();
|
||||
Debug_Timer_Stop();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// Public method for storing MODE SELECT results.
|
||||
|
|
|
@ -180,7 +180,6 @@ static void doWrite(uint32 lba, uint32 blocks)
|
|||
// multi-block write is minimal.
|
||||
transfer.multiBlock = 1;
|
||||
|
||||
if (blocks > 1) scsiDev.needReconnect = 1;
|
||||
sdWriteMultiSectorPrep();
|
||||
}
|
||||
}
|
||||
|
@ -216,7 +215,6 @@ static void doRead(uint32 lba, uint32 blocks)
|
|||
else
|
||||
{
|
||||
transfer.multiBlock = 1;
|
||||
scsiDev.needReconnect = 1;
|
||||
sdReadMultiSectorPrep();
|
||||
}
|
||||
}
|
||||
|
@ -612,7 +610,10 @@ void scsiDiskInit()
|
|||
}
|
||||
#endif
|
||||
|
||||
if (SD_CD_Read() == 1)
|
||||
// The Card-detect switches of micro-sd sockets are not standard. Don't make
|
||||
// use of SD_CD so we can use sockets from other manufacturers.
|
||||
// Detect presence of the card by testing whether it responds to commands.
|
||||
// if (SD_CD_Read() == 1)
|
||||
{
|
||||
int retry;
|
||||
blockDev.state = blockDev.state | DISK_PRESENT;
|
||||
|
|
77
software/SCSI2SD/src/led.c
Executable file
77
software/SCSI2SD/src/led.c
Executable file
|
@ -0,0 +1,77 @@
|
|||
// Copyright (C) 2014 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/>.
|
||||
|
||||
#include "led.h"
|
||||
|
||||
// External LED support only exists on the 3.5" v4 board.
|
||||
// The powerbook v4 board ties the pin to ground.
|
||||
// The v3 boards do not have any such pin.
|
||||
#ifdef EXTLED_CTL
|
||||
#define HAVE_EXTLED 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EXTLED
|
||||
static int enable_EXTLED = 0;
|
||||
#endif
|
||||
|
||||
void ledInit()
|
||||
{
|
||||
#ifdef HAVE_EXTLED
|
||||
EXTLED_SetDriveMode(EXTLED_DM_DIG_HIZ | EXTLED_DM_RES_UP);
|
||||
int val = EXTLED_Read();
|
||||
if (val)
|
||||
{
|
||||
// Pin is not tied to ground, so it's safe to use.
|
||||
enable_EXTLED = 1;
|
||||
EXTLED_SetDriveMode(LED1_DM_STRONG);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pin is tied to ground. Using it would damage hardware
|
||||
// This is the case for the powerbook boards.
|
||||
enable_EXTLED = 0;
|
||||
EXTLED_SetDriveMode(EXTLED_DM_DIG_HIZ);
|
||||
|
||||
}
|
||||
#endif
|
||||
ledOff();
|
||||
}
|
||||
|
||||
void ledOn()
|
||||
{
|
||||
LED1_Write(0);
|
||||
|
||||
#ifdef HAVE_EXTLED
|
||||
if (enable_EXTLED)
|
||||
{
|
||||
EXTLED_Write(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ledOff()
|
||||
{
|
||||
LED1_Write(1);
|
||||
|
||||
#ifdef HAVE_EXTLED
|
||||
if (enable_EXTLED)
|
||||
{
|
||||
EXTLED_Write(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -19,7 +19,8 @@
|
|||
|
||||
#include "device.h"
|
||||
|
||||
#define ledOn() LED1_Write(0)
|
||||
#define ledOff() LED1_Write(1)
|
||||
void ledInit(void);
|
||||
void ledOn(void);
|
||||
void ledOff(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,7 +26,7 @@ const char* Notice = "Copyright (C) 2014 Michael McMaster <michael@codesrc.com>"
|
|||
|
||||
int main()
|
||||
{
|
||||
ledOff();
|
||||
ledInit();
|
||||
|
||||
// Enable global interrupts.
|
||||
// Needed for RST and ATN interrupt handlers.
|
||||
|
@ -41,17 +41,10 @@ int main()
|
|||
scsiInit();
|
||||
scsiDiskInit();
|
||||
|
||||
if (!(blockDev.state & DISK_INITIALISED))
|
||||
{
|
||||
while (1) { ledOn();CyDelay(200); ledOff();CyDelay(200); }
|
||||
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
#ifdef MM_DEBUG
|
||||
scsiDev.watchdogTick++;
|
||||
#endif
|
||||
|
||||
scsiPoll();
|
||||
scsiDiskPoll();
|
||||
configPoll();
|
||||
|
|
|
@ -111,93 +111,12 @@ static void enter_Status(uint8 status)
|
|||
scsiDev.status = status;
|
||||
scsiDev.phase = STATUS;
|
||||
|
||||
|
||||
#ifdef MM_DEBUG
|
||||
scsiDev.lastStatus = scsiDev.status;
|
||||
scsiDev.lastSense = scsiDev.sense.code;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void doReselectTest()
|
||||
{
|
||||
scsiDev.needReconnect = 0;
|
||||
scsiEnterPhase(MESSAGE_IN);
|
||||
scsiWriteByte(0x02); // save data pointer
|
||||
|
||||
// TODO check if this message was rejected.
|
||||
|
||||
scsiWriteByte(0x04); // disconnect msg.
|
||||
enter_BusFree();
|
||||
|
||||
CyDelay(100);
|
||||
|
||||
while (1)
|
||||
{
|
||||
int sel = SCSI_ReadPin(SCSI_In_SEL);
|
||||
int bsy = SCSI_ReadPin(SCSI_In_BSY);
|
||||
if (!sel && !bsy)
|
||||
{
|
||||
// TODO wait bus settle delay
|
||||
CyDelayUs(1); // TODO bus free delay 800ns
|
||||
|
||||
// Arbitrate.
|
||||
ledOn();
|
||||
SCSI_Out_Bits_Write(scsiDev.scsiIdMask);
|
||||
SCSI_Out_Ctl_Write(1); // Write bits manually.
|
||||
SCSI_SetPin(SCSI_Out_BSY);
|
||||
|
||||
CyDelayUs(3); // arbitrate delay. 2.4us.
|
||||
|
||||
uint8_t dbx = scsiReadDBxPins();
|
||||
sel = SCSI_ReadPin(SCSI_In_SEL);
|
||||
if (sel || ((dbx ^ scsiDev.scsiIdMask) > scsiDev.scsiIdMask))
|
||||
{
|
||||
// Lost arbitration.
|
||||
SCSI_Out_Ctl_Write(0);
|
||||
SCSI_ClearPin(SCSI_Out_BSY);
|
||||
ledOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Won arbitration
|
||||
SCSI_SetPin(SCSI_Out_SEL);
|
||||
CyDelayUs(1); // Bus clear + Bus settle.
|
||||
|
||||
// Reselection phase
|
||||
scsiEnterPhase(__scsiphase_io); // TODO get rid of delay
|
||||
SCSI_Out_Bits_Write(scsiDev.scsiIdMask | (1 << scsiDev.initiatorId));
|
||||
CyDelayCycles(4); // 2 deskew delays
|
||||
SCSI_ClearPin(SCSI_Out_BSY);
|
||||
CyDelayUs(1); // Bus Settle Delay
|
||||
|
||||
bsy = SCSI_ReadPin(SCSI_In_BSY);
|
||||
while (!bsy) { bsy = SCSI_ReadPin(SCSI_In_BSY); } // Wait for initiator.
|
||||
SCSI_SetPin(SCSI_Out_BSY);
|
||||
|
||||
// Prepare for the initial IDENTIFY message.
|
||||
scsiEnterPhase(MESSAGE_IN);
|
||||
|
||||
SCSI_Out_Ctl_Write(0);
|
||||
SCSI_ClearPin(SCSI_Out_SEL);
|
||||
|
||||
// Send identify command
|
||||
scsiWriteByte(0x80);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Continue with status.
|
||||
|
||||
}
|
||||
|
||||
static void process_Status()
|
||||
{
|
||||
if (scsiDev.status == GOOD && scsiDev.needReconnect && scsiDev.allowDisconnect)
|
||||
{
|
||||
// doReselectTest();
|
||||
}
|
||||
scsiEnterPhase(STATUS);
|
||||
|
||||
uint8 message;
|
||||
|
@ -222,10 +141,8 @@ static void process_Status()
|
|||
}
|
||||
scsiWriteByte(scsiDev.status);
|
||||
|
||||
#ifdef MM_DEBUG
|
||||
scsiDev.lastStatus = scsiDev.status;
|
||||
scsiDev.lastSense = scsiDev.sense.code;
|
||||
#endif
|
||||
|
||||
// Command Complete occurs AFTER a valid status has been
|
||||
// sent. then we go bus-free.
|
||||
|
@ -325,17 +242,13 @@ static void process_Command()
|
|||
lun = scsiDev.cdb[1] >> 5;
|
||||
control = scsiDev.cdb[scsiDev.cdbLen - 1];
|
||||
|
||||
#ifdef MM_DEBUG
|
||||
scsiDev.cmdCount++;
|
||||
#endif
|
||||
|
||||
if (scsiDev.resetFlag)
|
||||
{
|
||||
#ifdef MM_DEBUG
|
||||
// Don't log bogus commands
|
||||
scsiDev.cmdCount--;
|
||||
memset(scsiDev.cdb, 0xff, sizeof(scsiDev.cdb));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
else if (scsiDev.parityError)
|
||||
|
@ -501,9 +414,7 @@ static void doReserveRelease()
|
|||
|
||||
static void scsiReset()
|
||||
{
|
||||
#ifdef MM_DEBUG
|
||||
scsiDev.rstCount++;
|
||||
#endif
|
||||
ledOff();
|
||||
|
||||
scsiPhyReset();
|
||||
|
@ -513,7 +424,6 @@ static void scsiReset()
|
|||
scsiDev.phase = BUS_FREE;
|
||||
scsiDev.atnFlag = 0;
|
||||
scsiDev.resetFlag = 0;
|
||||
scsiDev.needReconnect = 0;
|
||||
|
||||
if (scsiDev.unitAttention != POWER_ON_RESET)
|
||||
{
|
||||
|
@ -548,8 +458,6 @@ static void enter_SelectionPhase()
|
|||
scsiDev.dataLen = 0;
|
||||
scsiDev.status = GOOD;
|
||||
scsiDev.phase = SELECTION;
|
||||
scsiDev.needReconnect = 0;
|
||||
scsiDev.allowDisconnect = 0;
|
||||
|
||||
transfer.blocks = 0;
|
||||
transfer.currentBlock = 0;
|
||||
|
@ -593,9 +501,7 @@ static void process_SelectionPhase()
|
|||
SCSI_SetPin(SCSI_Out_BSY);
|
||||
ledOn();
|
||||
|
||||
#ifdef MM_DEBUG
|
||||
scsiDev.selCount++;
|
||||
#endif
|
||||
|
||||
// Wait until the end of the selection phase.
|
||||
while (!scsiDev.resetFlag)
|
||||
|
@ -643,9 +549,7 @@ static void process_MessageOut()
|
|||
scsiDev.atnFlag = 0;
|
||||
scsiDev.parityError = 0;
|
||||
scsiDev.msgOut = scsiReadByte();
|
||||
#ifdef MM_DEBUG
|
||||
scsiDev.msgCount++;
|
||||
#endif
|
||||
|
||||
if (scsiDev.parityError)
|
||||
{
|
||||
|
@ -731,7 +635,7 @@ static void process_MessageOut()
|
|||
//enter_Status(CHECK_CONDITION);
|
||||
messageReject();
|
||||
}
|
||||
scsiDev.allowDisconnect = scsiDev.msgOut & 0x40;
|
||||
//scsiDev.allowDisconnect = scsiDev.msgOut & 0x40;
|
||||
}
|
||||
else if (scsiDev.msgOut >= 0x20 && scsiDev.msgOut <= 0x2F)
|
||||
{
|
||||
|
|
|
@ -17,12 +17,6 @@
|
|||
#ifndef SCSI_H
|
||||
#define SCSI_H
|
||||
|
||||
// Set this to true to log SCSI commands and status information via
|
||||
// USB HID packets. The can be captured and viewed in wireshark.
|
||||
// For windows users, capture using USBPcap http://desowin.org/usbpcap/
|
||||
//#define MM_DEBUG 1
|
||||
#undef MM_DEBUG
|
||||
|
||||
#include "geometry.h"
|
||||
#include "sense.h"
|
||||
|
||||
|
@ -110,7 +104,6 @@ typedef struct
|
|||
|
||||
void (*postDataOutHook)(void);
|
||||
|
||||
#ifdef MM_DEBUG
|
||||
uint8 cmdCount;
|
||||
uint8 selCount;
|
||||
uint8 rstCount;
|
||||
|
@ -118,10 +111,6 @@ typedef struct
|
|||
uint8 watchdogTick;
|
||||
uint8 lastStatus;
|
||||
uint8 lastSense;
|
||||
#endif
|
||||
|
||||
uint8 allowDisconnect;
|
||||
uint8 needReconnect;
|
||||
} ScsiDevice;
|
||||
|
||||
extern ScsiDevice scsiDev;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user