|  | @@ -28,45 +28,53 @@
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #include <string.h>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -// Time until we consider ourselves selected
 | 
	
		
			
				|  |  | -// 400ns at 108MHz
 | 
	
		
			
				|  |  | -#define SCSI_DEFAULT_SELECTION 43
 | 
	
		
			
				|  |  | -#define SCSI_FAST_SELECTION 5
 | 
	
		
			
				|  |  | +static uint8_t asyncTimings[][4] =
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +/* Speed,    Assert,    Deskew,    Hold,    Glitch */
 | 
	
		
			
				|  |  | +{/*1.5MB/s*/ 28,        18,        13,      13},
 | 
	
		
			
				|  |  | +{/*3.3MB/s*/ 13,        6,         6,       13},
 | 
	
		
			
				|  |  | +{/*5MB/s*/   9,         6,         6,       6} // 80ns
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -// async.
 | 
	
		
			
				|  |  | -// Assumes a 108MHz fpga clock.
 | 
	
		
			
				|  |  | -// 2:0 Deskew count, 55ns
 | 
	
		
			
				|  |  | -// 6:4 Hold count, 53ns
 | 
	
		
			
				|  |  | -// 3:0 Assertion count, 80ns
 | 
	
		
			
				|  |  | -#define SCSI_DEFAULT_DESKEW 0x6
 | 
	
		
			
				|  |  | -#define SCSI_DEFAULT_TIMING ((0x6 << 4) | 0x9)
 | 
	
		
			
				|  |  | +#define SCSI_ASYNC_15 0
 | 
	
		
			
				|  |  | +#define SCSI_ASYNC_33 1
 | 
	
		
			
				|  |  | +#define SCSI_ASYNC_50 2
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -// 3.125MB/s (80 period) to < 10MB/s sync
 | 
	
		
			
				|  |  | -// Assumes a 108MHz fpga clock. (9 ns)
 | 
	
		
			
				|  |  | -// (((period * 4) / 2) * 0.8) / 9
 | 
	
		
			
				|  |  | -// Done using 3 fixed point math.
 | 
	
		
			
				|  |  | -// 2:0 Deskew count, 55ns normal, or 25ns if faster than 5.5MB/s
 | 
	
		
			
				|  |  | -// 6:4 Hold count, 53ns normal, or 33ns if faster than 5.5MB/s
 | 
	
		
			
				|  |  | -// 3:0 Assertion count, variable
 | 
	
		
			
				|  |  | -#define SCSI_SYNC_DESKEW(period) (period < 45 ? SCSI_FAST10_DESKEW : SCSI_DEFAULT_DESKEW)
 | 
	
		
			
				|  |  | -#define SCSI_SYNC_TIMING(period) (((period < 45 ? 0x4 : 0x6) << 4) | ((((((int)period) * 177) + 750)/1000) & 0xF))
 | 
	
		
			
				|  |  | +// 5MB/s synchronous timing
 | 
	
		
			
				|  |  | +#define SCSI_FAST5_DESKEW 6 // 55ns
 | 
	
		
			
				|  |  | +#define SCSI_FAST5_HOLD 6 // 53ns
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -// 10MB/s
 | 
	
		
			
				|  |  | +// 10MB/s synchronous timing
 | 
	
		
			
				|  |  |  // 2:0 Deskew count, 25ns
 | 
	
		
			
				|  |  |  // 6:4 Hold count, 33ns
 | 
	
		
			
				|  |  |  // 3:0 Assertion count, 30ns
 | 
	
		
			
				|  |  |  // We want deskew + hold + assert + 3 to add up to 11 clocks
 | 
	
		
			
				|  |  |  // the fpga code has 1 clock of overhead when transitioning from deskew to
 | 
	
		
			
				|  |  |  // assert to hold
 | 
	
		
			
				|  |  | -#define SCSI_FAST10_DESKEW 2
 | 
	
		
			
				|  |  | -#define SCSI_FAST10_TIMING ((0x3 << 4) | 0x3)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -// 20MB/s
 | 
	
		
			
				|  |  | -// 2:0 Deskew count, 12ns
 | 
	
		
			
				|  |  | -// 6:4 Hold count, 17ns
 | 
	
		
			
				|  |  | -// 3:0 Assertion count, 15ns
 | 
	
		
			
				|  |  | -#define SCSI_FAST20_DESKEW 1
 | 
	
		
			
				|  |  | -#define SCSI_FAST20_TIMING ((0x2 << 4) | 0x2)
 | 
	
		
			
				|  |  | +#define SCSI_FAST10_DESKEW 2 // 25ns
 | 
	
		
			
				|  |  | +#define SCSI_FAST10_HOLD 3 // 33ns
 | 
	
		
			
				|  |  | +#define SCSI_FAST10_ASSERT 3 // 30ns
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#define syncDeskew(period) ((period) < 45 ? \
 | 
	
		
			
				|  |  | +	SCSI_FAST10_DESKEW : SCSI_FAST5_DESKEW)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#define syncHold(period) ((period) < 45 ? \
 | 
	
		
			
				|  |  | +	((period) == 25 ? SCSI_FAST10_HOLD : 4) /* 25ns/33ns */\
 | 
	
		
			
				|  |  | +	: SCSI_FAST5_HOLD)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// 3.125MB/s (80 period) to < 10MB/s sync
 | 
	
		
			
				|  |  | +// Assumes a 108MHz fpga clock. (9 ns)
 | 
	
		
			
				|  |  | +// (((period * 4) / 2) * 0.8) / 9
 | 
	
		
			
				|  |  | +// Done using 3 fixed point math.
 | 
	
		
			
				|  |  | +// 3:0 Assertion count, variable
 | 
	
		
			
				|  |  | +#define syncAssertion(period) ((((((int)period) * 177) + 750)/1000) & 0xF)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Time until we consider ourselves selected
 | 
	
		
			
				|  |  | +// 400ns at 108MHz
 | 
	
		
			
				|  |  | +#define SCSI_DEFAULT_SELECTION 43
 | 
	
		
			
				|  |  | +#define SCSI_FAST_SELECTION 5
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // Private DMA variables.
 | 
	
		
			
				|  |  |  static int dmaInProgress = 0;
 | 
	
	
		
			
				|  | @@ -440,6 +448,29 @@ void scsiEnterBusFree()
 | 
	
		
			
				|  |  |  	*SCSI_CTRL_PHASE = 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +static void
 | 
	
		
			
				|  |  | +scsiSetTiming(
 | 
	
		
			
				|  |  | +	uint8_t assertClocks,
 | 
	
		
			
				|  |  | +	uint8_t deskew,
 | 
	
		
			
				|  |  | +	uint8_t hold,
 | 
	
		
			
				|  |  | +	uint8_t glitch)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	*SCSI_CTRL_DESKEW = ((hold & 7) << 5) | (deskew & 0x1F);
 | 
	
		
			
				|  |  | +	*SCSI_CTRL_TIMING = (assertClocks & 0x3F);
 | 
	
		
			
				|  |  | +	*SCSI_CTRL_TIMING3 = (glitch & 0xF);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static void
 | 
	
		
			
				|  |  | +scsiSetDefaultTiming()
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	const uint8_t* asyncTiming = asyncTimings[3];
 | 
	
		
			
				|  |  | +	scsiSetTiming(
 | 
	
		
			
				|  |  | +		asyncTiming[0],
 | 
	
		
			
				|  |  | +		asyncTiming[1],
 | 
	
		
			
				|  |  | +		asyncTiming[2],
 | 
	
		
			
				|  |  | +		asyncTiming[3]);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  void scsiEnterPhase(int phase)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	// ANSI INCITS 362-2002 SPI-3 10.7.1:
 | 
	
	
		
			
				|  | @@ -458,22 +489,18 @@ void scsiEnterPhase(int phase)
 | 
	
		
			
				|  |  |  		if ((newPhase == DATA_IN || newPhase == DATA_OUT) &&
 | 
	
		
			
				|  |  |  			scsiDev.target->syncOffset)
 | 
	
		
			
				|  |  |  		{
 | 
	
		
			
				|  |  | -			if (scsiDev.target->syncPeriod == 12)
 | 
	
		
			
				|  |  | +			
 | 
	
		
			
				|  |  | +			if (scsiDev.target->syncPeriod <= 25)
 | 
	
		
			
				|  |  |  			{
 | 
	
		
			
				|  |  | -				// SCSI2 FAST-20 Timing. 20MB/s.
 | 
	
		
			
				|  |  | -				*SCSI_CTRL_DESKEW = SCSI_FAST20_DESKEW;
 | 
	
		
			
				|  |  | -				*SCSI_CTRL_TIMING = SCSI_FAST20_TIMING;
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			else if (scsiDev.target->syncPeriod == 25)
 | 
	
		
			
				|  |  | -			{
 | 
	
		
			
				|  |  | -				// SCSI2 FAST Timing. 10MB/s.
 | 
	
		
			
				|  |  | -				*SCSI_CTRL_DESKEW = SCSI_FAST10_DESKEW;
 | 
	
		
			
				|  |  | -				*SCSI_CTRL_TIMING = SCSI_FAST10_TIMING;
 | 
	
		
			
				|  |  | +				scsiSetTiming(SCSI_FAST10_ASSERT, SCSI_FAST10_DESKEW, SCSI_FAST10_HOLD, 1);
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  			else
 | 
	
		
			
				|  |  |  			{
 | 
	
		
			
				|  |  | -				*SCSI_CTRL_DESKEW = SCSI_SYNC_DESKEW(scsiDev.target->syncPeriod);
 | 
	
		
			
				|  |  | -				*SCSI_CTRL_TIMING = SCSI_SYNC_TIMING(scsiDev.target->syncPeriod);
 | 
	
		
			
				|  |  | +				scsiSetTiming(
 | 
	
		
			
				|  |  | +					syncAssertion(scsiDev.target->syncPeriod),
 | 
	
		
			
				|  |  | +					syncDeskew(scsiDev.target->syncPeriod),
 | 
	
		
			
				|  |  | +					syncHold(scsiDev.target->syncPeriod),
 | 
	
		
			
				|  |  | +					scsiDev.target->syncPeriod < 45 ? 1 : 5);
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  			// See note 26 in SCSI 2 standard: SCSI 1 implementations may assume
 | 
	
	
		
			
				|  | @@ -487,12 +514,29 @@ void scsiEnterPhase(int phase)
 | 
	
		
			
				|  |  |  			} else {
 | 
	
		
			
				|  |  |  				*SCSI_CTRL_SYNC_OFFSET = scsiDev.target->syncOffset;
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  | -		} else {
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		else
 | 
	
		
			
				|  |  | +		{
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  			*SCSI_CTRL_SYNC_OFFSET = 0;
 | 
	
		
			
				|  |  | +			const uint8_t* asyncTiming;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			if (scsiDev.boardCfg.scsiSpeed == S2S_CFG_SPEED_NoLimit ||
 | 
	
		
			
				|  |  | +				scsiDev.boardCfg.scsiSpeed >= S2S_CFG_SPEED_ASYNC_50) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +				asyncTiming = asyncTimings[SCSI_ASYNC_50];
 | 
	
		
			
				|  |  | +			} else if (scsiDev.boardCfg.scsiSpeed >= S2S_CFG_SPEED_ASYNC_33) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -			// 5MB/s Timing
 | 
	
		
			
				|  |  | -			*SCSI_CTRL_DESKEW = SCSI_DEFAULT_DESKEW;
 | 
	
		
			
				|  |  | -			*SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;
 | 
	
		
			
				|  |  | +				asyncTiming = asyncTimings[SCSI_ASYNC_33];
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +			} else {
 | 
	
		
			
				|  |  | +				asyncTiming = asyncTimings[SCSI_ASYNC_15];
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			scsiSetTiming(
 | 
	
		
			
				|  |  | +				asyncTiming[0],
 | 
	
		
			
				|  |  | +				asyncTiming[1],
 | 
	
		
			
				|  |  | +				asyncTiming[2],
 | 
	
		
			
				|  |  | +				asyncTiming[3]);
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		*SCSI_CTRL_PHASE = newPhase;
 | 
	
	
		
			
				|  | @@ -527,8 +571,7 @@ void scsiPhyReset()
 | 
	
		
			
				|  |  |  	*SCSI_CTRL_DBX = 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	*SCSI_CTRL_SYNC_OFFSET = 0;
 | 
	
		
			
				|  |  | -	*SCSI_CTRL_DESKEW = SCSI_DEFAULT_DESKEW;
 | 
	
		
			
				|  |  | -	*SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;
 | 
	
		
			
				|  |  | +	scsiSetDefaultTiming();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	// DMA Benchmark code
 | 
	
		
			
				|  |  |  	// Currently 11MB/s.
 | 
	
	
		
			
				|  | @@ -638,8 +681,7 @@ void scsiPhyInit()
 | 
	
		
			
				|  |  |  	*SCSI_CTRL_DBX = 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	*SCSI_CTRL_SYNC_OFFSET = 0;
 | 
	
		
			
				|  |  | -	*SCSI_CTRL_DESKEW = SCSI_DEFAULT_DESKEW;
 | 
	
		
			
				|  |  | -	*SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;
 | 
	
		
			
				|  |  | +	scsiSetDefaultTiming();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	*SCSI_CTRL_SEL_TIMING = SCSI_DEFAULT_SELECTION;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -725,7 +767,8 @@ int scsiSelfTest()
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  |  		*SCSI_CTRL_DBX = i;
 | 
	
		
			
				|  |  |  		busSettleDelay();
 | 
	
		
			
				|  |  | -		if (*SCSI_STS_DBX != (i & 0xff))
 | 
	
		
			
				|  |  | +		// STS_DBX is 16 bit!
 | 
	
		
			
				|  |  | +		if ((*SCSI_STS_DBX & 0xff) != (i & 0xff))
 | 
	
		
			
				|  |  |  		{
 | 
	
		
			
				|  |  |  			result |= 1;
 | 
	
		
			
				|  |  |  		}
 |