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

📄 u_device.c

📁 EPSON USB DEVICE MASS-STORAGE CLASS driver, BULK ONLY on Ram disk
💻 C
字号:
/****************************************************************************
 * File name   : device.c
 * Module name : Device module
 * Author	   : Hiromichi Kondo
 *---------------------------------------------------------------------------
 * $Id: device.c,v 1.2 2003/05/13 11:02:05 9551619 Exp $
 ****************************************************************************/

#include "c33l17.h"
#include "u_ram_data.h"
#include "u_rom_data.h"
#include "u_regNikka.h"
#include "u_value.h"

#include "usbmedia.h"

/*--- Function Prototype ---------------------------------------------------*/
void DeviceProc(void);
void WaitRcvCommand(void);
void CommandCheck(void);
void SetStatus(void);
void WaitCSWCmp(void);
void CBWCheck(void);
void CSWSet(void);
void InitDeviceWorkArea(void);
void MasterDMAStop(void);
void MasterDMAStart(void);
void MasterDMAXferEndProc(void);

/*****************************************************************************	
 * Device table
 *****************************************************************************/
void (*const device_tbl[])() = {
	WaitRcvCommand,
	CommandCheck,
	SetStatus,
	WaitCSWCmp
};

void DeviceProc(void)
{
	if( usb_state == CONFIGURED_STATE)
	{
		if (device_state > DEV_WAIT_CSW_CMP)
			panic(5);

		device_tbl[device_state]();
	}
}

/*****************************************************************************	
 * WaitRcvCommand
 *****************************************************************************/
void WaitRcvCommand(void)
{
	if( device_flag.RcvCommand )
	{
		device_flag.RcvCommand = 0;
		device_state = DEV_CMD_CHECK;
	}
	else
	{
		if( device_flag.WaitCBW )
		{
			if( tran_flag.XferCmp )
			{
				device_flag.WaitCBW = 0;
				tran_flag.XferCmp = 0;
				CBWCheck();
			}
		}
		else
		{
			device_flag.WaitCBW = 1;
			tran_flag.DMA = 0;

			bulk_actual_tran_cnt = 31;
			bulk_tran_start_addr = cbw;
			bulk_out_state = BULK_OUT_DATA_GET;
		}
	}
}

/*****************************************************************************	
 * CommandCheck
 *****************************************************************************/
void CommandCheck(void)
{
	int ret;
	int fifo_remain;

	if( cmd_block[0] != 0x00 )
	{
		test_unit_ready_cnt = 0;
	}
	
	switch( cmd_block[0] ){
		case 0x00:			/* Test Unit Ready */
			ret = TestUnitReady();
			break;
		case 0x03:			/* Request Sense */
			ret = RequestSense();
			break;
		case 0x12:			/* Inquiry */
			ret = Inquiry();
			break;
		case 0x1B:			/* Start Stop Unit */
			ret = StartStopUnit();
			break;
		case 0x1E:			/* Prevent/Allow Medium Removal */
			ret = Prevent();
			break;
		case 0x23:			/* Read Format Capacity */
			ret = ReadFormatCapacity();
			break;
		case 0x25:			/* Read Capacity */
			ret = ReadCapacity();
			break;
		case 0x28:			/* Read(10) */
			ret = Read10();
			break;
		case 0x2A:			/* Write(10) */
			ret = Write10();
			break;
		case 0x2B:			/* Seek */
			ret = Seek();
			break;
		case 0x2F:			/* Verify */
			ret = Verify();
			break;
		case 0x55:			/* Mode Select */
			ret = ModeSelect();
			break;
		case 0x5A:			/* Mode Sense */
			ret = ModeSense();
			break;
		default:
			ret = CmdError();
	}

	if( ret == RC_OK )
	{
		if( bulk_total_tran_cnt == 0 )
		{
			protocol_phase = STATUS_PHASE;
			tran_flag.XferCmp = 1;
		}
		else
		{
			protocol_phase = DATA_PHASE;
			bulk_actual_tran_cnt = bulk_total_tran_cnt;
			
			if( tran_flag.DMA )
				MasterDMAStart();

			if( tran_flag.Direction == DIR_IN )
				bulk_in_state = BULK_IN_DATA_SET;
			else
				bulk_out_state = BULK_OUT_DATA_GET;
		}
	}
	else
	{
		if( bulk_req_tran_cnt == 0 )
		{
			protocol_phase = STATUS_PHASE;
			tran_flag.XferCmp = 1;
		}
		else
		{
			bulk_total_tran_cnt = 0;
			protocol_phase = DATA_PHASE;
			
			if( tran_flag.Direction == DIR_OUT )
			{
				rEPbControl_BP.ForceNAK = 1;
				
                timer0_Wait(1);

				rCPU_JoinRd_BP.JoinEPbRd = 1;
				fifo_remain = MKWORD(rEPnRdRemain_H, rEPnRdRemain_L);
				rCPU_JoinRd_BP.JoinEPbRd = 0;

				if( bulk_req_tran_cnt <= fifo_remain )
				{
					rEPrFIFO_Clr_BP.EPbFIFO_Clr = 1;
					
					protocol_phase = STATUS_PHASE;
					tran_flag.XferCmp = 1;
				}
				else
				{
					rEPbControl_BP.ForceSTALL = 1;
					bulk_out_state = BULK_OUT_STALL;
				}

			}
			else
			{
				rEPaControl_BP.ForceSTALL = 1;
				bulk_in_state = BULK_IN_STALL;
			}
		}
	}
	device_state = DEV_SET_STATUS;
}

/*****************************************************************************	
 * SetStatus
 *****************************************************************************/
void SetStatus(void)
{
	if( tran_flag.XferCmp )
	{
		if( protocol_phase == STATUS_PHASE )
		{
			tran_flag.XferCmp = 0;
			rEPbControl_BP.ForceNAK = 1;
			
			if( cmd_block[0] == 0x55 )
				ModeSelParaCheck();					/* Mode Select */
			
			CSWSet();
			device_state = DEV_WAIT_CSW_CMP;
		}
	}
}

/*****************************************************************************	
 * WaitCSWCmp
 *****************************************************************************/
void WaitCSWCmp(void)
{
	if( tran_flag.XferCmp )
	{
		tran_flag.XferCmp = 0;
		device_state = DEV_WAIT_RCV_CMD;
	}
}

/*****************************************************************************
 * CBWCheck
 *****************************************************************************/
void CBWCheck(void)
{
	int i, j;
	
	if (cbw[0] != 0x55 || cbw[1] != 0x53 || cbw[2] != 0x42 || cbw[3] != 0x43)
	{ 
		rEPnControl_BP.EPrForceSTALL = 1;
		bulk_in_state  = BULK_IN_STALL;
		bulk_out_state = BULK_OUT_STALL;
		protocol_phase = RESET_WAIT;
	}
	else
	{
		bulk_req_tran_cnt = MKDWORD(cbw[11], cbw[10], cbw[9], cbw[8]);

		tran_flag.Direction = ((cbw[12] & 0x80)? DIR_IN : DIR_OUT);

		if (cbw[13])
		{
			rEPnControl_BP.EPrForceSTALL = 1;
			bulk_in_state  = BULK_IN_STALL;
			bulk_out_state = BULK_OUT_STALL;
			protocol_phase = RESET_WAIT;
		}
		else
		{
			for( i=0, j=15; i<cbw[14]; i++, j++ )
			{
				cmd_block[i] = cbw[j];
			}
			device_flag.RcvCommand = 1;
		}
	}
}

/*****************************************************************************
 * CSWSet
 *****************************************************************************/
void CSWSet(void)
{
	int residue_cnt;

	csw[4] = cbw[4];
	csw[5] = cbw[5];
	csw[6] = cbw[6];
	csw[7] = cbw[7];

	if (cmd_status != PHASE_ERROR)
	{
		residue_cnt = bulk_req_tran_cnt - bulk_total_tran_cnt;
		csw[8]	= DWORD2BYTE_LL(residue_cnt);
		csw[9]	= DWORD2BYTE_LH(residue_cnt);
		csw[10] = DWORD2BYTE_HL(residue_cnt);
		csw[11] = DWORD2BYTE_HH(residue_cnt);
	}
	else
	{
		csw[8]	= 0x00;
		csw[9]	= 0x00;
		csw[10] = 0x00;
		csw[11] = 0x00;
	}
	csw[12] = cmd_status;
	
	tran_flag.DMA = 0;
	bulk_actual_tran_cnt = 13;
	bulk_total_tran_cnt = bulk_req_tran_cnt;
	bulk_tran_start_addr = csw;

	bulk_in_state = BULK_IN_DATA_SET;
}

/*****************************************************************************
 * InitDeviceWorkArea
 *****************************************************************************/
void InitDeviceWorkArea(void)
{
	int i;

	tran_flag.XferCmp	= 0;
	tran_flag.Direction = DIR_OUT;
	tran_flag.DMA		= 0;
	
	device_flag.RcvCommand	= 0;
	device_flag.WaitCBW 	= 0;
	
	block_size = 512;
	
	ata_lba 			= 0;
	mode_data_cnt		= 0;
	bulk_tran_start_addr = 0;
	mode_data_addr		= 0;
	mode_chg_addr		= 0;
	bulk_req_tran_cnt	 = 0;
	bulk_total_tran_cnt  = 0;
	bulk_actual_tran_cnt = 0;
	test_unit_ready_cnt = 0;
	
	for (i = 0;i < 12;i++)
		cmd_block[i] = 0;
	
	for (i = 0;i < sizeof(wk_data);i++)
		wk_data[i] = 0x00;
	
	/* bCSWSignature */
	csw[0] = 0x55;
	csw[1] = 0x53;
	csw[2] = 0x42;
	csw[3] = 0x53;
	
	/* Sense Key */
	sense_data[0] = 0x00;
	sense_data[1] = 0x00;
	sense_data[2] = 0x00;

	atten_flag.PowerOnReset = 1;
}

/*****************************************************************************
 * MasterDMAStart
 *****************************************************************************/
void MasterDMAStart(void)
{
	pHS_EN(1) = 0;				//HS1 disable

	pHS_CNTLMODE = 1;			//HSDMA ADV mode
	
	pHS_EN(1) = 0;				//HS1 disable
	HSDxS(1) = 0x0d;			//HS1 triggle src
	pHS_TF(1) = 1;				//HS1 triggle flag clear
	DUALM(1) = 1;				//HS1 dual address mode
	DMOD(1)	= 0;				//HS1 single xfer mode
	
	if ( tran_flag.Direction == DIR_IN )
	{	/* IN xfer */
		SADR_AD(1) = sram_start_addr ;
		DADR_AD(1) = 0x00300A00;
		
		SIN(1) = 3;				//HS1 src inc
		DIN(1) = 0;				//HS1 des fix
	}
	else
	{	/* OUT xfer */
		SADR_AD(1) = 0x00300A00;
		DADR_AD(1) = sram_start_addr ;

		SIN(1) = 0;				//HS1 src inc
		DIN(1) = 3;				//HS1 des fix
	}
	
	DATSIZE(1) = 0;				//HS1 byte xfer
	pHS_CNT(1) = bulk_actual_tran_cnt &0xffff;	//HS1 xfer cnt low
	TC_H(1) = (bulk_actual_tran_cnt>>16) &0xff;//HS1 xfer cnt high
	
	INT_FHDM(1) = 1;			//HS1 Int flag clear
	pHS_EN(1) = 1;				//HS1 enable
}

/*****************************************************************************
 * MasterDMAStop
 *****************************************************************************/
void MasterDMAStop(void)
{
	pHS_EN(1) = 0;				//HS1 disable
}

/*****************************************************************************
 * MasterDMAXferEndProc
 *****************************************************************************/
void MasterDMAXferEndProc(void)
{
	int retVal = media_WriteSec(ata_lba, bulk_total_tran_cnt/block_size, &usb_wk_buf[0]);

	if( retVal != 0 )
		panic(42);
}

⌨️ 快捷键说明

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