www.pudn.com > arm_uDisk.rar > USBOUT.C


/**************************************************************** 
 NAME: usbout.c 
 DESC: USB bulk-OUT operation related functions 
 HISTORY: 
 Mar.25.2002:purnnamu: ported for S3C2410X. 
 Mar.27.2002:purnnamu: DMA is enabled. 
 ****************************************************************/ 
  
#include  
#include "option.h" 
#include "2410addr.h" 
#include "2410lib.h" 
#include "def.h" 
 
#include "2410usb.h" 
#include "usbmain.h" 
#include "usb.h" 
#include "usblib.h" 
#include "usbsetup.h" 
#include "usbout.h" 
 
#include "Globe.h" 
 
 
//static void PrintEpoPkt(U8 *pt,int cnt); 
static void RdPktEp3_CheckSum(U8 *buf,int num); 
 
 
 
// =================================================================== 
// All following commands will operate in case  
// - out_csr3 is valid. 
// =================================================================== 
 
  
 
#define CLR_EP3_OUT_PKT_READY() rOUT_CSR1_REG= ( out_csr3 &(~ EPO_WR_BITS)\ 
					&(~EPO_OUT_PKT_READY) )  
#define SET_EP3_SEND_STALL()	rOUT_CSR1_REG= ( out_csr3 & (~EPO_WR_BITS)\ 
					| EPO_SEND_STALL) ) 
#define CLR_EP3_SENT_STALL()	rOUT_CSR1_REG= ( out_csr3 & (~EPO_WR_BITS)\ 
					&(~EPO_SENT_STALL) ) 
#define FLUSH_EP3_FIFO() 	rOUT_CSR1_REG= ( out_csr3 & (~EPO_WR_BITS)\ 
					|EPO_FIFO_FLUSH) ) 
 
// *************************** 
// *** VERY IMPORTANT NOTE *** 
// *************************** 
// Prepare for the packit size constraint!!! 
 
// EP3 = OUT end point.  
 
U8 ep3Buf[EP3_PKT_SIZE]; 
static U8 tempBuf[64+1]; 
static U8 TempMem[16];//Save address from PC 
 
#ifdef _FOR_UDISK_ 
#include "f_type.h" 
#include "F_driver.h" 
#include "MASS_STORAGE.H" 
u8 CBWTable[31] = {0}; 
u8 CBW_flg = 0;//0:none; 1:CBW; 2:PC out data; 3:PC in data 
u8 Data_flg = 0;//0:non; 1:Data; 2:CSW; 3:write10 CSW 
u8 Data_loop = 0; 
u8 tempbuf[64] = {0}; 
u8 CSWbuf[13] = {0}; 
u8 *buffer; 
int bufLen; 
 
u8 DiskIndex; 
u32 LBA_START,dCBWDaTrLen; 
u16 LBA_Length; 
u8 SCSICommand; 
u8 buffer1[512*8];//it is very importent 
extern void Mass_acces(void); 
void Mass_acces(void) 
{ 
	u32 i; 
	u32 j; 
	 
	if(CBW_flg == 1) 
	{ 
		CBW_flg = 0; 
		GetCBWTable(CBWTable, &DiskIndex,&LBA_START, &LBA_Length, &SCSICommand); 
		dCBWDaTrLen=(u32)(((u32)(CBWTable[11]<<8)+(CBWTable[10]))<<15); 
       	dCBWDaTrLen=(dCBWDaTrLen<<1)+(u32)((u32)(CBWTable[9]<<8)+(CBWTable[8])) ; // copmpute the length 
       	 
       	//Uart_Printf("SCSICommand: 0x%x\n",SCSICommand); 
		switch(SCSICommand) 
		{ 
			case Format_Unit://0x04 
				Uart_Printf("SCSICommand: 0x%x\n",SCSICommand); 
				break; 
			case Inquiry://0x12 
				//Uart_Printf("dCBWDaTrLen:%d\n",dCBWDaTrLen); 
				FillInquiryTable(tempbuf); 
				FillCSWTable(CSWbuf); 
				Data_flg = 2; 
				PrepareEp1Fifo_1(tempbuf,36); 
				//PrepareEp1Fifo_1(DISK_INF,36); 
				break; 
			case Read_10://0x28 
				//Uart_Printf("1.LBA_START: %d\tLBA_Length: %d\n",LBA_START,LBA_Length); 
				F_ReadSector(hFile,LBA_START,1,buffer1); 
				bufLen = LBA_Length*512-EP1_PKT_SIZE; 
				for(j=0;jEP3_PKT_SIZE) 
	    		{ 
	    			for(i=0;iEP1_PKT_SIZE*/(LBA_Length>(Data_loop+1)/8))//one sector read 
				{ 
					F_WriteSector(hFile,LBA_START,1,buffer1); 
					LBA_START++; 
					buffer = buffer1; 
				} 
				else  
					buffer+=EP3_PKT_SIZE; 
				 
				Data_loop ++; 
	    		} 
			else 
			{ 
	    			for(i=0;i(Data_loop+1)/8))//one sector read 
				{ 
					F_WriteSector(hFile,LBA_START,1,buffer1); 
					LBA_START++; 
					buffer = buffer1; 
				} 
				for(j=4;j<8;j++)//TAG 
				{ 
					CSWbuf[j] = CBWTable[j]; 
				} 
				Data_flg = 3; 
				PrepareEp1Fifo_1(CSWbuf,13); 
			} 
	    	} 
	} 
	else if(CBW_flg == 3) 
	{ 
		CBW_flg = 0; 
		//Uart_Printf("read10\n"); 
		if(Data_flg==1) 
	    	{ 
			Data_loop ++; 
	    		if(bufLen>EP1_PKT_SIZE) 
	    		{ 
	    			for(i=0;iEP1_PKT_SIZE*/(LBA_Length>(Data_loop+1)/8))//one sector read 
				{ 
					LBA_START++; 
					F_ReadSector(hFile,LBA_START/*+((Data_loop+1)/8)*/,1,buffer1); 
					buffer = buffer1; 
				} 
				else  
					buffer+=EP1_PKT_SIZE; 
	    			PrepareEp1Fifo_1(tempbuf,EP1_PKT_SIZE);  
	    		} 
			else 
			{ 
	    			for(i=0;i"); 
				#endif     
				RdPktEp3_CheckSum((U8 *)downPt,fifoCnt); 	     
				downPt+=fifoCnt;//fifoCnt=32 
			} 
			#endif 
 
	   		CLR_EP3_OUT_PKT_READY(); 
			return; 
	    }//End of if(out_csr3 & EPO_OUT_PKT_READY) 
	} 
	else if(USBD_flg==1) 
	{ 
		if(out_csr3 & EPO_OUT_PKT_READY) 
		 { 
		 	fifoCnt=rOUT_FIFO_CNT1_REG;  
 
			RdPktEp3(ep3Buf,fifoCnt); 
			if(!CheckCBWTable(ep3Buf))//CBW 
			{ 
				u8 j; 
				for(j=0;j<31;j++) 
				{ 
					CBWTable[j] = ep3Buf[j]; 
				} 
				CBW_flg = 1; 
			} 
			else//PC write data 
			{ 
				CBW_flg = 2; 
			} 
			Mass_acces(); 
			return; 
		 } 
	} 
#else 
	if(out_csr3 & EPO_OUT_PKT_READY) 
    	{    
		fifoCnt=rOUT_FIFO_CNT1_REG;  
 
		#if 0 
		RdPktEp3(ep3Buf,fifoCnt); 
		//PrintEpoPkt(ep3Buf,fifoCnt); 
		#else 
 
		if(DownloadFileSize==0) 
		{ 
			downPt=TempMem; 
   			RdPktEp3((U8 *)downPt,8); 	 
			downPt=TempMem;  	     
   			if(DownLoadOK==1) 
   			{ 
				DownloadAddress=TempDownloadAddress; 
			} 
			else 
			{	//extern volatile U32 DownloadAddress, 
				 
	    		DownloadAddress=	 
				 *((U8 *)(downPt+0))+ 
				(*((U8 *)(downPt+1))<<8)+ 
				(*((U8 *)(downPt+2))<<16)+ 
				(*((U8 *)(downPt+3))<<24); 
			} 
			DownloadFileSize= 
			 *((U8 *)(downPt+4))+ 
			(*((U8 *)(downPt+5))<<8)+ 
			(*((U8 *)(downPt+6))<<16)+ 
			(*((U8 *)(downPt+7))<<24); 
 
			checkSum=0;//extern volatile U16 checkSum; 
			downPt=(U8 *)DownloadAddress; 
 
  			RdPktEp3_CheckSum((U8 *)downPt,fifoCnt-8);//The first 8-bytes are deleted (have been read).	     
  			downPt+=fifoCnt-8;   
  			 
  			#if USBDMA 
     			//CLR_EP3_OUT_PKT_READY() is not executed.  
     			//So, USBD may generate NAK until DMA2 is configured for USB_EP3; 
     			rINTMSK|=BIT_USBD;//for debug 
      			return;	 
  			#endif	 
		} 
		else 
		{ 
			#if USBDMA    	 
//				Uart_Printf(""); 
			#endif     
			RdPktEp3_CheckSum((U8 *)downPt,fifoCnt); 	     
			downPt+=fifoCnt;//fifoCnt=32 
		} 
		#endif 
 
   		CLR_EP3_OUT_PKT_READY(); 
		return; 
    	}//End of if(out_csr3 & EPO_OUT_PKT_READY) 
#endif   
 
    //I think that EPO_SENT_STALL will not be set to 1. 
    if(out_csr3 & EPO_SENT_STALL) 
    {    
   		//DbgPrintf("[STALL]"); 
   		CLR_EP3_SENT_STALL(); 
   		return; 
    }	 
} 
 
void RdPktEp3_CheckSum(U8 *buf,int num) 
{ 
    int i; 
    	 
    for(i=0;i=DownloadFileSize)// is last? 
    { 
    	totalDmaCount=DownloadFileSize; 
	 
    	ConfigEp3IntMode();	 
 
    	if(out_csr3& EPO_OUT_PKT_READY) 
    	{ 
   	    	CLR_EP3_OUT_PKT_READY(); 
		} 
        rINTMSK|=BIT_DMA2;   
        rINTMSK&=~(BIT_USBD);   
    } 
    else 
    { 
    	if((totalDmaCount+0x80000)