|  | @@ -129,12 +129,14 @@ static void sdClearStatus()
 | 
	
		
			
				|  |  |  void sdPrepareRead()
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	uint8 v;
 | 
	
		
			
				|  |  | -	uint32 len = (transfer.lba + transfer.currentBlock);
 | 
	
		
			
				|  |  | +	uint32 scsiLBA = (transfer.lba + transfer.currentBlock);
 | 
	
		
			
				|  |  | +	uint32 sdLBA = SCSISector2SD(scsiLBA);
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  |  	if (!sdDev.ccs)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  | -		len = len * SCSI_BLOCK_SIZE;
 | 
	
		
			
				|  |  | +		sdLBA = sdLBA * SD_SECTOR_SIZE;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	v = sdCommandAndResponse(SD_READ_MULTIPLE_BLOCK, len);
 | 
	
		
			
				|  |  | +	v = sdCommandAndResponse(SD_READ_MULTIPLE_BLOCK, sdLBA);
 | 
	
		
			
				|  |  |  	if (v)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  |  		scsiDiskReset();
 | 
	
	
		
			
				|  | @@ -151,7 +153,7 @@ void sdPrepareRead()
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void doReadSector()
 | 
	
		
			
				|  |  | +static void doReadSector(uint32_t numBytes)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	int prep, i, guard;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -184,12 +186,9 @@ static void doReadSector()
 | 
	
		
			
				|  |  |  	// Don't do a bus settle delay if we're already in the correct phase.
 | 
	
		
			
				|  |  |  	if (transfer.currentBlock == 0)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  | -		//scsiEnterPhase(DATA_OUT);
 | 
	
		
			
				|  |  | -		//CyDelayUs(200);
 | 
	
		
			
				|  |  |  		scsiEnterPhase(DATA_IN);
 | 
	
		
			
				|  |  | -		//CyDelayUs(200); // TODO BLOODY SLOW INTERLEAVE
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	// Quickly seed the FIFO
 | 
	
		
			
				|  |  |  	prep = 4;
 | 
	
		
			
				|  |  |  	CY_SET_REG8(SDCard_TXDATA_PTR, 0xFF); // Put a byte in the FIFO
 | 
	
	
		
			
				|  | @@ -204,7 +203,7 @@ static void doReadSector()
 | 
	
		
			
				|  |  |  	// We stream data straight from the SDCard fifos into the SCSI component
 | 
	
		
			
				|  |  |  	// FIFO's. If the loop isn't fast enough, the transmit FIFO's will empty,
 | 
	
		
			
				|  |  |  	// and performance will suffer. Every clock cycle counts.
 | 
	
		
			
				|  |  | -	while (i < SCSI_BLOCK_SIZE && !scsiDev.resetFlag)
 | 
	
		
			
				|  |  | +	while (i < numBytes && !scsiDev.resetFlag)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  |  		uint8_t sdRxStatus = CY_GET_REG8(SDCard_RX_STATUS_PTR);
 | 
	
		
			
				|  |  |  		uint8_t scsiStatus = CY_GET_REG8(scsiTarget_StatusReg__STATUS_REG);
 | 
	
	
		
			
				|  | @@ -232,7 +231,25 @@ static void doReadSector()
 | 
	
		
			
				|  |  |  		// "combined" SPIM TX and RX FIFOS to the individual FIFO size.
 | 
	
		
			
				|  |  |  		// Unlike the SCSI component, SPIM doesn't check if there's room in
 | 
	
		
			
				|  |  |  		// the output FIFO before starting to transmit.
 | 
	
		
			
				|  |  | -		if ((prep - guard < 4) && (prep < SCSI_BLOCK_SIZE))
 | 
	
		
			
				|  |  | +		if ((prep - guard < 4) && (prep < numBytes))
 | 
	
		
			
				|  |  | +		{
 | 
	
		
			
				|  |  | +			CY_SET_REG8(SDCard_TXDATA_PTR, 0xFF); // Put a byte in the FIFO
 | 
	
		
			
				|  |  | +			prep++;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// Read and discard remaining bytes.
 | 
	
		
			
				|  |  | +	while (i < SD_SECTOR_SIZE)
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		uint8_t sdRxStatus = CY_GET_REG8(SDCard_RX_STATUS_PTR);
 | 
	
		
			
				|  |  | +		if(sdRxStatus & SDCard_STS_RX_FIFO_NOT_EMPTY)
 | 
	
		
			
				|  |  | +		{
 | 
	
		
			
				|  |  | +			CY_GET_REG8(SDCard_RXDATA_PTR);
 | 
	
		
			
				|  |  | +			guard++;
 | 
	
		
			
				|  |  | +			i++;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		if ((prep - guard < 4) && (prep < SD_SECTOR_SIZE))
 | 
	
		
			
				|  |  |  		{
 | 
	
		
			
				|  |  |  			CY_SET_REG8(SDCard_TXDATA_PTR, 0xFF); // Put a byte in the FIFO
 | 
	
		
			
				|  |  |  			prep++;
 | 
	
	
		
			
				|  | @@ -241,21 +258,20 @@ static void doReadSector()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	sdSpiByte(0xFF); // CRC
 | 
	
		
			
				|  |  |  	sdSpiByte(0xFF); // CRC
 | 
	
		
			
				|  |  | -	scsiDev.dataLen = SCSI_BLOCK_SIZE;
 | 
	
		
			
				|  |  | -	scsiDev.dataPtr = SCSI_BLOCK_SIZE;
 | 
	
		
			
				|  |  | +	scsiDev.dataLen = numBytes;
 | 
	
		
			
				|  |  | +	scsiDev.dataPtr = numBytes;
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  |  	while (SCSI_ReadPin(SCSI_In_ACK) && !scsiDev.resetFlag) {}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void sdReadSectorSingle()
 | 
	
		
			
				|  |  | +static void doReadSectorSingle(uint32 sdBlock, int sdBytes)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	uint8 v;
 | 
	
		
			
				|  |  | -	uint32 len = (transfer.lba + transfer.currentBlock);
 | 
	
		
			
				|  |  |  	if (!sdDev.ccs)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  | -		len = len * SCSI_BLOCK_SIZE;
 | 
	
		
			
				|  |  | +		sdBlock = sdBlock * SD_SECTOR_SIZE;
 | 
	
		
			
				|  |  |  	}	
 | 
	
		
			
				|  |  | -	v = sdCommandAndResponse(SD_READ_SINGLE_BLOCK, len);
 | 
	
		
			
				|  |  | +	v = sdCommandAndResponse(SD_READ_SINGLE_BLOCK, sdBlock);
 | 
	
		
			
				|  |  |  	if (v)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  |  		scsiDiskReset();
 | 
	
	
		
			
				|  | @@ -268,15 +284,47 @@ void sdReadSectorSingle()
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	else
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  | -		doReadSector();
 | 
	
		
			
				|  |  | +		doReadSector(sdBytes);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void sdReadSectorSingle()
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	uint32 scsiLBA = (transfer.lba + transfer.currentBlock);
 | 
	
		
			
				|  |  | +	uint32 sdLBA = SCSISector2SD(scsiLBA);
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	int sdSectors = SDSectorsPerSCSISector();
 | 
	
		
			
				|  |  | +	int i;
 | 
	
		
			
				|  |  | +	for (i = 0; (i < sdSectors - 1) && (scsiDev.status != CHECK_CONDITION); ++i)
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		doReadSectorSingle(sdLBA + i, SD_SECTOR_SIZE);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (scsiDev.status != CHECK_CONDITION)
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		int remaining = config->bytesPerSector % SD_SECTOR_SIZE;
 | 
	
		
			
				|  |  | +		if (remaining == 0) remaining = SD_SECTOR_SIZE; // Full sector needed.
 | 
	
		
			
				|  |  | +		doReadSectorSingle(sdLBA + i, remaining);
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void sdReadSectorMulti()
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	// Pre: sdPrepareRead called.
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  | -	doReadSector();
 | 
	
		
			
				|  |  | +	int sdSectors = SDSectorsPerSCSISector();
 | 
	
		
			
				|  |  | +	int i;
 | 
	
		
			
				|  |  | +	for (i = 0; (i < sdSectors - 1) && (scsiDev.status != CHECK_CONDITION); ++i)
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		doReadSector(SD_SECTOR_SIZE);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (scsiDev.status != CHECK_CONDITION)
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		int remaining = config->bytesPerSector % SD_SECTOR_SIZE;
 | 
	
		
			
				|  |  | +		if (remaining == 0) remaining = SD_SECTOR_SIZE; // Full sector needed.
 | 
	
		
			
				|  |  | +		doReadSector(remaining);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -329,7 +377,7 @@ static void sdWaitWriteBusy()
 | 
	
		
			
				|  |  |  	} while (val != 0xFF);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -int sdWriteSector()
 | 
	
		
			
				|  |  | +static int doWriteSector(uint32_t numBytes)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	int prep, i, guard;
 | 
	
		
			
				|  |  |  	int result, maxWait;
 | 
	
	
		
			
				|  | @@ -351,7 +399,7 @@ int sdWriteSector()
 | 
	
		
			
				|  |  |  	// We stream data straight from the SCSI fifos into the SPIM component
 | 
	
		
			
				|  |  |  	// FIFO's. If the loop isn't fast enough, the transmit FIFO's will empty,
 | 
	
		
			
				|  |  |  	// and performance will suffer. Every clock cycle counts.	
 | 
	
		
			
				|  |  | -	while (i < SCSI_BLOCK_SIZE)
 | 
	
		
			
				|  |  | +	while (i < numBytes && !scsiDev.resetFlag)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  |  		uint8_t sdRxStatus = CY_GET_REG8(SDCard_RX_STATUS_PTR);
 | 
	
		
			
				|  |  |  		uint8_t scsiStatus = CY_GET_REG8(scsiTarget_StatusReg__STATUS_REG);
 | 
	
	
		
			
				|  | @@ -375,7 +423,7 @@ int sdWriteSector()
 | 
	
		
			
				|  |  |  			++i;
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		if (prep < SCSI_BLOCK_SIZE &&
 | 
	
		
			
				|  |  | +		if (prep < numBytes &&
 | 
	
		
			
				|  |  |  			(scsiDev.resetFlag || (scsiStatus & 1)) // SCSI TX FIFO NOT FULL
 | 
	
		
			
				|  |  |  			)
 | 
	
		
			
				|  |  |  		{
 | 
	
	
		
			
				|  | @@ -385,6 +433,25 @@ int sdWriteSector()
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  | +	// Write remaining bytes as 0x00
 | 
	
		
			
				|  |  | +	while (i < SD_SECTOR_SIZE)
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		uint8_t sdRxStatus = CY_GET_REG8(SDCard_RX_STATUS_PTR);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		if(guard - i < 4)
 | 
	
		
			
				|  |  | +		{
 | 
	
		
			
				|  |  | +			CY_SET_REG8(SDCard_TXDATA_PTR, 0x00);
 | 
	
		
			
				|  |  | +			guard++;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		// Byte has been sent out the SPIM interface.
 | 
	
		
			
				|  |  | +		if (sdRxStatus & SDCard_STS_RX_FIFO_NOT_EMPTY)
 | 
	
		
			
				|  |  | +		{
 | 
	
		
			
				|  |  | +			 CY_GET_REG8(SDCard_RXDATA_PTR);
 | 
	
		
			
				|  |  | +			++i;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  |  	sdSpiByte(0x00); // CRC
 | 
	
		
			
				|  |  |  	sdSpiByte(0x00); // CRC
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -438,6 +505,26 @@ int sdWriteSector()
 | 
	
		
			
				|  |  |  	return result;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +int sdWriteSector()
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	int result = 1;
 | 
	
		
			
				|  |  | +	// Pre: sdPrepareWrite called.
 | 
	
		
			
				|  |  | +	int sdSectors = SDSectorsPerSCSISector();
 | 
	
		
			
				|  |  | +	int i;
 | 
	
		
			
				|  |  | +	for (i = 0; result && (i < sdSectors - 1) && (scsiDev.status != CHECK_CONDITION); ++i)
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		result = doWriteSector(SD_SECTOR_SIZE);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (result && scsiDev.status != CHECK_CONDITION)
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		int remaining = config->bytesPerSector % SD_SECTOR_SIZE;
 | 
	
		
			
				|  |  | +		if (remaining == 0) remaining = SD_SECTOR_SIZE; // Full sector needed.
 | 
	
		
			
				|  |  | +		result = doWriteSector(remaining);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	return result;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  void sdCompleteWrite()
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	transfer.inProgress = 0;
 | 
	
	
		
			
				|  | @@ -565,7 +652,7 @@ static int sdReadCSD()
 | 
	
		
			
				|  |  |  		uint32 c_size = (((((uint32)buf[6]) & 0x3) << 16) | (((uint32)buf[7]) << 8) | buf[8]) >> 6;
 | 
	
		
			
				|  |  |  		uint32 c_mult = (((((uint32)buf[9]) & 0x3) << 8) | ((uint32)buf[0xa])) >> 7;
 | 
	
		
			
				|  |  |  		uint32 sectorSize = buf[5] & 0x0F;
 | 
	
		
			
				|  |  | -		sdDev.capacity = ((c_size+1) * ((uint64)1 << (c_mult+2)) * ((uint64)1 << sectorSize)) / SCSI_BLOCK_SIZE;
 | 
	
		
			
				|  |  | +		sdDev.capacity = ((c_size+1) * ((uint64)1 << (c_mult+2)) * ((uint64)1 << sectorSize)) / SD_SECTOR_SIZE;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	else if ((buf[0] >> 6) == 0x01)
 | 
	
		
			
				|  |  |  	{
 | 
	
	
		
			
				|  | @@ -622,7 +709,7 @@ int sdInit()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	// This command will be ignored if sdDev.ccs is set.
 | 
	
		
			
				|  |  |  	// SDHC and SDXC are always 512bytes.
 | 
	
		
			
				|  |  | -	v = sdCRCCommandAndResponse(SD_SET_BLOCKLEN, SCSI_BLOCK_SIZE); //Force sector size
 | 
	
		
			
				|  |  | +	v = sdCRCCommandAndResponse(SD_SET_BLOCKLEN, SD_SECTOR_SIZE); //Force sector size
 | 
	
		
			
				|  |  |  	if(v){goto bad;}
 | 
	
		
			
				|  |  |  	v = sdCRCCommandAndResponse(SD_CRC_ON_OFF, 0); //crc off
 | 
	
		
			
				|  |  |  	if(v){goto bad;}
 | 
	
	
		
			
				|  | @@ -671,23 +758,24 @@ out:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void sdPrepareWrite()
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -	uint32 len;
 | 
	
		
			
				|  |  |  	uint8 v;
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  |  	// Set the number of blocks to pre-erase by the multiple block write command
 | 
	
		
			
				|  |  |  	// We don't care about the response - if the command is not accepted, writes
 | 
	
		
			
				|  |  |  	// will just be a bit slower.
 | 
	
		
			
				|  |  |  	// Max 22bit parameter.
 | 
	
		
			
				|  |  | -	uint32 blocks = transfer.blocks > 0x7FFFFF ? 0x7FFFFF : transfer.blocks;
 | 
	
		
			
				|  |  | +	uint32_t sdBlocks = transfer.blocks * SDSectorsPerSCSISector();
 | 
	
		
			
				|  |  | +	uint32 blocks = sdBlocks > 0x7FFFFF ? 0x7FFFFF : sdBlocks;
 | 
	
		
			
				|  |  |  	sdCommandAndResponse(SD_APP_CMD, 0);
 | 
	
		
			
				|  |  |  	sdCommandAndResponse(SD_APP_SET_WR_BLK_ERASE_COUNT, blocks);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	len = (transfer.lba + transfer.currentBlock);
 | 
	
		
			
				|  |  | +	uint32 scsiLBA = (transfer.lba + transfer.currentBlock);
 | 
	
		
			
				|  |  | +	uint32 sdLBA = SCSISector2SD(scsiLBA);
 | 
	
		
			
				|  |  |  	if (!sdDev.ccs)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  | -		len = len * SCSI_BLOCK_SIZE;
 | 
	
		
			
				|  |  | +		sdLBA = sdLBA * SD_SECTOR_SIZE;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	v = sdCommandAndResponse(25, len);
 | 
	
		
			
				|  |  | +	v = sdCommandAndResponse(25, sdLBA);
 | 
	
		
			
				|  |  |  	if (v)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  |  		scsiDiskReset();
 |