⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 idedma_if.c

📁 epson usb2.0 控制芯片 S1R72V05 固件程序。
💻 C
字号:
/*
 * description : ATA/ATAPI Interface
 * Maker	   : Hideyuki Nekoshima
 * Copyright   : (C)2003,SEIKO EPSON Corp. All Rights Reserved.
 */


#include "SPRDEF.h"
#include "SPRSTS.h"
#include "IDEDMA_IF.h"

#include "Reg72V05.h"



#define BIT_ON					0x01							/* Bit */
#define BIT_OFF					0x00							/* Bit */


#define IDE_DMA_PIO0			0xFF							/* IDE DMA PIO Mode0 Rate */
#define IDE_DMA_PIO1			0x88							/* IDE DMA PIO Mode1 Rate */
#define IDE_DMA_PIO2			0x44							/* IDE DMA PIO Mode2 Rate */
#define IDE_DMA_PIO3			0x22							/* IDE DMA PIO Mode3 Rate */
#define IDE_DMA_PIO4			0x10							/* IDE DMA PIO Mode4 Rate */

#define IDE_DMA_MULTI0			0xBB							/* IDE MultiWord DMA Mode0 Rate */
#define IDE_DMA_MULTI1			0x20							/* IDE MultiWord DMA Mode1 Rate */
#define IDE_DMA_MULTI2			0x10							/* IDE MultiWord DMA Mode2 Rate */

#define IDE_DMA_ULTRA0			0x06							/* IDE Ultra DMA Mode0 Rate */
#define IDE_DMA_ULTRA1			0x04							/* IDE Ultra DMA Mode1 Rate */
#define IDE_DMA_ULTRA2			0x03							/* IDE Ultra DMA Mode2 Rate */
#define IDE_DMA_ULTRA3			0x02							/* IDE Ultra DMA Mode3 Rate */
#define IDE_DMA_ULTRA4			0x01							/* IDE Ultra DMA Mode3 Rate */
#define IDE_DMA_ULTRA5			0x00							/* IDE Ultra DMA Mode3 Rate */


static UCHAR IDEDmaPortLock[IDEDMA_IF_MAX_PORT];					/* PORT LOCK Flag */
static UCHAR IDEDmaPortExecFlag[IDEDMA_IF_MAX_PORT];			/* PORT Execution Flag */

static UCHAR IDEDmaPioCyc[IDEDMA_IF_MAX_PORT];					/* PIO DMA Cycle */
static UCHAR IDEDmaMultiCyc[IDEDMA_IF_MAX_PORT];					/* MultiWord DMA Cycle */
static UCHAR IDEDmaUltraCyc[IDEDMA_IF_MAX_PORT];					/* Ultra DMA Cycle */

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFReset
//
// description	: Initialize IDE DMA Interface Module.
//
//				: Initialize the internal variables in IDE DMA Interface Module,
//				  and intialize the hard ware.
//
// argument		: none
//
// return		: LONG status 			Processing result
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFReset( void )
{
	UCHAR	i;

	/* PORT Execution Flag Clear */
	for(i=0; i<IDEDMA_IF_MAX_PORT; i++){
		IDEDmaPortLock[i] = IDEDMA_IF_PORT_UNLOCK;
		IDEDmaPortExecFlag[i] = IDEDMA_IF_STOP;
		IDEDmaPioCyc[i] = 0x00;
		IDEDmaMultiCyc[i] = 0x00;
		IDEDmaUltraCyc[i] = 0x00;
	}

										/* IDE DMA Stop						*/
	RegClear( REG08_IDE_Control, BIT_IDE_Go );
										/* Activate IDE Bus					*/
	RegSet( REG08_IDE_Config_1, BIT_ActiveIDE );
	RegWrite( REG08_IDE_Rmod, 0x00 );	/* IDE Register Mode				*/
	RegWrite( REG08_IDE_Tmod, 0x00 );	/* IDE Transfer Mode				*/
	RegWrite( REG08_IDE_Umod, 0x00 );	/* IDE Ultra-DMA Transfer Mode Clear*/

	/* Complete */
	return STATUS_SUCCESS;
}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFOpen
//
// description	: Open IDEDMA Interface Module.
//
//				  Open the IDEDMA Interface Module, Enter the usable state.
//				  In the case that open is not executed,API processing in Module is not done.
//
// argument		: non
//
// return		: LONG status 			Processing result
//
// flag			: UCHAR OpenFlag PASS	Indicate if the Interface Module is usable.
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFOpen( void )
{
	UCHAR	i;

	/* PORT Execution Flag Clear */
	for(i=0; i<IDEDMA_IF_MAX_PORT; i++){
		IDEDmaPortLock[i] = IDEDMA_IF_PORT_UNLOCK;
		IDEDmaPortExecFlag[i] = IDEDMA_IF_STOP;
		IDEDmaPioCyc[i] = 0x00;				/* IDE PIO Access Cycle Clear */
		IDEDmaMultiCyc[i] = 0x00;			/* IDE MultiWord DMA Access Cycle Clear */
		IDEDmaUltraCyc[i] = 0x00;			/* IDE UltraDMA Access Cycle Clear */
	}

	/* Complete */
	return STATUS_SUCCESS;
}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFInitPort
//
// description	: Initialize the specified port.
//				  Unlock the port.
//
//
// argument		: USHORT portNumber	   Initialized port No
//
// return		: LONG status 			Processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFInitPort( USHORT portNumber )
{

										/* IDE DMA Stop						*/
	RegClear( REG08_IDE_Control, BIT_IDE_Go );
										/* InActivated IDE Bus				*/
	RegClear( REG08_IDE_Config_1, BIT_ActiveIDE );
	RegWrite( REG08_IDE_Rmod, 0x00 );	/* IDE Register Mode				*/
	RegWrite( REG08_IDE_Tmod, 0x00 );	/* IDE Transfer Mode				*/
	RegWrite( REG08_IDE_Umod, 0x00 );	/* IDE Ultra-DMA Transfer Mode Clear*/

	IDEDmaPortLock[portNumber] = IDEDMA_IF_PORT_UNLOCK;

	/* Complete */
	return STATUS_SUCCESS;
}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFLockPort
//
// description	: Lock the cpecified port.
//
//				: As long as the port is not locked,can not do the serials
//				  functions below.
//
// argument		: USHORT portNumber	   Port No. to lock
//
// return		: LONG status 		   Processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFLockPort( USHORT portNumber )
{

	if( IDEDmaPortLock[portNumber] == IDEDMA_IF_PORT_LOCK ){
		/* The specified port is already locked  */
		return STATUS_LOCKED_PORT;
	}

	IDEDmaPortLock[portNumber] = IDEDMA_IF_PORT_LOCK;
	/* ALL Device Reset */

										/* Activate IDE Bus					*/
	RegSet( REG08_IDE_Config_1, BIT_ActiveIDE );

	/* Compelte */
	return STATUS_SUCCESS;
}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFUnlockPort
//
// description	: Unlock the specified port.
//				: When the port is released, can not do the serials
//				  functions below.
//
// argument		: USHORT portNumber		Device No. to be unlocked
//
// return		: LONG status 			processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFUnlockPort( USHORT portNumber )
{

	if( IDEDmaPortLock[portNumber] == IDEDMA_IF_PORT_UNLOCK ){
		/* The specified port had not been locked. */
		return STATUS_UNLOCK_PORT;
	}

	if( IDEDmaPortExecFlag[portNumber] == IDEDMA_IF_EXEC ){
		/* The specified port is in operating */
		return STATUS_EXECUTION_PORT;
	}

	IDEDmaPortLock[portNumber] = IDEDMA_IF_PORT_UNLOCK;
	/* ALL Device Reset */

	/* Compelte */
	return STATUS_SUCCESS;
}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFSetTransferRate
//
// description	: Set the transfer rate for the specifed port.
//				  Once the transfer rate is set,it will maintained until the unlock
//				  and the parameter is set again.
//
// argument		: USHORT portNumber		Port No. to Unlock
//
// return		: LONG status 			processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFSetTransferRate( USHORT portNumber, UCHAR pioRate, UCHAR multiRate, UCHAR ultraRate )
{

	if( IDEDmaPortLock[portNumber] == IDEDMA_IF_PORT_UNLOCK ){
		/* The specified port had not been locked. */
		return STATUS_UNLOCK_PORT;
	}

	if( IDEDmaPortExecFlag[portNumber] == IDEDMA_IF_EXEC ){
		/* The specified port is in operating */
		return STATUS_EXECUTION_PORT;
	}

	/* PIO Transfer Rate Set */
	switch( pioRate ){
		case IDEDMA_IF_PIO_MODE0:
			IDEDmaPioCyc[portNumber] = IDE_DMA_PIO0;
			break;

		case IDEDMA_IF_PIO_MODE1:
			IDEDmaPioCyc[portNumber] = IDE_DMA_PIO1;
			break;

		case IDEDMA_IF_PIO_MODE2:
			IDEDmaPioCyc[portNumber] = IDE_DMA_PIO2;
			break;

		case IDEDMA_IF_PIO_MODE3:
			IDEDmaPioCyc[portNumber] = IDE_DMA_PIO3;
			break;

		case IDEDMA_IF_PIO_MODE4:
			IDEDmaPioCyc[portNumber] = IDE_DMA_PIO4;
			break;

		default:
			/* Parameter error */
			return STATUS_INVALID_PARAMETER;
	}

	/* Multi Word DMA Transfer Rate Set */
	switch( multiRate ){
		case IDEDMA_IF_MULTI_MODE0:
			IDEDmaMultiCyc[portNumber] = IDE_DMA_MULTI0;
			break;

		case IDEDMA_IF_MULTI_MODE1:
			IDEDmaMultiCyc[portNumber] = IDE_DMA_MULTI1;
			break;

		case IDEDMA_IF_MULTI_MODE2:
			IDEDmaMultiCyc[portNumber] = IDE_DMA_MULTI2;
			break;

		default:
			/* Parameter error */
			return STATUS_INVALID_PARAMETER;
	}

	/* Ultra DMA Transfer Rate Set */
	switch( ultraRate ){
		case IDEDMA_IF_ULTRA_MODE0:
			IDEDmaUltraCyc[portNumber] = IDE_DMA_ULTRA0;
			break;

		case IDEDMA_IF_ULTRA_MODE1:
			IDEDmaUltraCyc[portNumber] = IDE_DMA_ULTRA1;
			break;

		case IDEDMA_IF_ULTRA_MODE2:
			IDEDmaUltraCyc[portNumber] = IDE_DMA_ULTRA2;
			break;

		case IDEDMA_IF_ULTRA_MODE3:
			IDEDmaUltraCyc[portNumber] = IDE_DMA_ULTRA3;
			break;

		case IDEDMA_IF_ULTRA_MODE4:
			IDEDmaUltraCyc[portNumber] = IDE_DMA_ULTRA4;
			break;

		case IDEDMA_IF_ULTRA_MODE5:
		case IDEDMA_IF_ULTRA_MODE6:
			IDEDmaUltraCyc[portNumber] = IDE_DMA_ULTRA5;
			break;

		default:
			/* Parameter error */
			return STATUS_INVALID_PARAMETER;
	}

	/* Compelte */
	return STATUS_SUCCESS;
}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFTransferStartA
//
// description	: Start the data transfer of the specified port.
//				  After start the transfer,the control returns to the upperlayer at once.
//
// argument		: USHORT portNumber		The prot No. that executes the data transfer
//				  UCHAR	 direction		Data transfer direction
//				  UCHAR	 transferMode	Data transfer mode
//				  ULONG  transferLba	Start LBA of data transfer
//
// return		: LONG status 			processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFTransferStartA( USHORT portNumber, UCHAR direction, UCHAR transferMode, ULONG transferSize, ULONG transferLba )
{

	if( IDEDmaPortLock[portNumber] == IDEDMA_IF_PORT_UNLOCK ){
		/* The specified port had not been locked. */
		return STATUS_UNLOCK_PORT;
	}

	if( IDEDmaPortExecFlag[portNumber] == IDEDMA_IF_EXEC ){
		/* The specified port is in operating */
		return STATUS_EXECUTION_PORT;
	}

	switch(transferMode ){
		case IDEDMA_IF_PIO:
			RegWrite( REG08_IDE_Tmod, IDEDmaPioCyc[portNumber] );
			RegModify( REG08_IDE_Config_0, MASK_UltraMulti, BIT_PIO );
			break;

		case IDEDMA_IF_MULTI:
			RegWrite( REG08_IDE_Tmod, IDEDmaMultiCyc[portNumber] );
			RegModify( REG08_IDE_Config_0, MASK_UltraMulti, BIT_Multi );
			break;

		case IDEDMA_IF_ULTRA:
			RegWrite( REG08_IDE_Umod, IDEDmaUltraCyc[portNumber] );
			RegModify( REG08_IDE_Config_0, MASK_UltraMulti, BIT_Ultra );
			break;

		default:
			/* Parameter error */
			return STATUS_INVALID_PARAMETER;
	}


	if( direction > IDEDMA_IF_IDE_OUT ){
		return STATUS_INVALID_PARAMETER;
	}

// Because SWAPbit is lost
// So revive the SWAP bit
// IDE SWAP correspondence(SWAP Bit is ON by default)
#ifdef IDE_SWAP_BIT_OFF
	RegSet( REG08_IDE_Config_1, BIT_Swap_None );
#endif
	RegWrite( REG08_IDE_Count_H, (UCHAR)( transferSize / 0x10000 ) );
	RegWrite( REG08_IDE_Count_M, (UCHAR)( transferSize / 0x100 ) );
	RegWrite( REG08_IDE_Count_L, (UCHAR)( transferSize ) );

	if (direction == IDEDMA_IF_IDE_IN) {
		RegModify( REG08_IDE_Control, MASK_IDE_Dir, BIT_IDEtoFIFO);
	} else {
		RegModify( REG08_IDE_Control, MASK_IDE_Dir, BIT_FIFOtoIDE);
	}

	/* When join,make sure to set the transfer direction */

	IDEDmaPortExecFlag[portNumber] = IDEDMA_IF_EXEC;

										/* IDE DMA Go						*/
	RegSet( REG08_IDE_Control, BIT_IDE_Go );

	/* Compelte */
	return STATUS_SUCCESS;
}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFTransferStop
//
// description	: Stop the data transfer of the specified port.
//
// argument		: USHORT portNumber		Port No where data transfer is stopped

//
// return		: LONG status 			processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFTransferStop( USHORT portNumber )
{

	if( IDEDmaPortLock[portNumber] == IDEDMA_IF_PORT_UNLOCK ){
		/* The specified port had not been locked. */
		return STATUS_UNLOCK_PORT;
	}

	IDEDmaPortExecFlag[portNumber] = IDEDMA_IF_STOP;

										/* IDE DMA Stop						*/
	RegClear( REG08_IDE_Control, BIT_IDE_Go );

	/* Compelte */
	return STATUS_SUCCESS;
}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFGetTransferStatus
//
// description	: Get the IDE DMA transfer state
//
//				: Get the transfer state of the specified port
//
// argument		: USHORT portNumber			Port No where state is acquired
//				  ULONG  *pStatus			Status memory field
//
// return		: LONG status 				processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFGetTransferStatus( USHORT portNumber, ULONG *pStatus )
{

	if( IDEDmaPortLock[portNumber] == IDEDMA_IF_PORT_UNLOCK ){
		/* The specified port had not been locked. */
		return STATUS_UNLOCK_PORT;
	}

	if( IDEDmaPortExecFlag[portNumber] == IDEDMA_IF_COMP ){
		*pStatus = IDEDmaPortExecFlag[portNumber];
		IDEDmaPortExecFlag[portNumber] = IDEDMA_IF_STOP;
	}

	if( IDEDmaPortExecFlag[portNumber] == IDEDMA_IF_EXEC ){
		if( RegRead( REG08_IDE_Control ) & BIT_IDE_Go ){
			*pStatus = IDEDmaPortExecFlag[portNumber];
		}else{
			*pStatus = IDEDMA_IF_COMP;
			IDEDmaPortExecFlag[portNumber] = IDEDMA_IF_STOP;
		}
	}

	/* Compelte */
	return STATUS_SUCCESS;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -