Esempio n. 1
0
void ClearEp3OutPktReady(void)
{
	struct s3c24x0_usb_device * const usbdevregs = s3c24x0_get_base_usb_device();
    U8 out_csr3;
    usbdevregs->INDEX_REG = 3;
    out_csr3 = usbdevregs->OUT_CSR1_REG;
    CLR_EP3_OUT_PKT_READY();
}
Esempio n. 2
0
void Ep3Handler(void)
{
	struct s3c24x0_interrupt *intregs = s3c24x0_get_base_interrupt();
	struct s3c24x0_usb_device *const usbdevregs	= s3c24x0_get_base_usb_device();
    U8 out_csr3;
    int fifoCnt;

    usbdevregs->INDEX_REG = 3;
    out_csr3 = usbdevregs->OUT_CSR1_REG;
    
    DbgPrintf("<3:%x]",out_csr3);

    if(out_csr3 & EPO_OUT_PKT_READY) {   
        fifoCnt = usbdevregs->OUT_FIFO_CNT1_REG; 

        if (downloadFileSize == 0) {
            RdPktEp3((U8 *)downPt, 8); 	

            if(download_run == 0) {
                downloadAddress = tempDownloadAddress;
            } else {
                downloadAddress = *((U32 *)downPt);
                dwUSBBufReadPtr = downloadAddress;
                dwUSBBufWritePtr = downloadAddress;
            }
            downloadFileSize = *((U32 *)(downPt + 4));
            DbgPrintf("[dwaddr = %x, dwsize = %x]\n", 
                    downloadAddress, downloadFileSize);

            checkSum = 0;
            downPt = (U8 *)downloadAddress;
            /* The first 8-bytes are deleted. */
            RdPktEp3_CheckSum((U8 *)downPt, fifoCnt-8); 	    
            downPt += fifoCnt - 8;  
  	    
#if USBDMA
            /*
             * 传输由中断发起(只接收头一个Pkg),由DMA完成.
             * 因此发生中断后就禁止USBD中断,在DMA传输完成
             * 后再次开启.
             */
     	    intregs->INTMSK |= BIT_USBD;   
      	    return;	
#endif	
        } else {
            RdPktEp3_CheckSum((U8 *)downPt, fifoCnt); 	    
            downPt += fifoCnt;     //fifoCnt = 64
        }
        CLR_EP3_OUT_PKT_READY();
        return;
    }
    
    if (out_csr3 & EPO_SENT_STALL) {   
        DbgPrintf("[STALL]");
        CLR_EP3_SENT_STALL();
        return;
    }	
}
Esempio n. 3
0
void RdPktEp3_CheckSum(U8 *buf,int num)
{
    int i;
	struct s3c24x0_usb_device *const usbdevregs = s3c24x0_get_base_usb_device();    
	
    for(i = 0; i < num; i++) {
        buf[i] = (U8)usbdevregs->fifo[3].EP_FIFO_REG;
        checkSum += buf[i];
    }
}
Esempio n. 4
0
void IsrDma2()
{
	struct s3c24x0_interrupt *intregs = s3c24x0_get_base_interrupt();
	struct s3c24x0_usb_device *usbdevregs = s3c24x0_get_base_usb_device();
    U8 out_csr3;
    U32 dwEmptyCnt;
    U8 saveIndexReg = usbdevregs->INDEX_REG;
    usbdevregs->INDEX_REG = 3;
    out_csr3 = usbdevregs->OUT_CSR1_REG;

    ClearPending_my((int)BIT_DMA2);	    

    if (!totalDmaCount) 
        totalDmaCount = dwWillDMACnt + EP3_PKT_SIZE;
    else
        totalDmaCount += dwWillDMACnt;

    dwUSBBufWritePtr = ((dwUSBBufWritePtr + dwWillDMACnt - dwUSBBufBase) % 
                        dwUSBBufSize) + dwUSBBufBase;

    if (totalDmaCount >= downloadFileSize) {    /* last */
    	totalDmaCount = downloadFileSize;
	
    	ConfigEp3IntMode();	

    	if (out_csr3 & EPO_OUT_PKT_READY) 
       	    CLR_EP3_OUT_PKT_READY();
	    /* 关闭DMA2中断并重新开启USBD中断 */ 
        intregs->INTMSK |= BIT_DMA2;    
        intregs->INTMSK &= ~(BIT_USBD);  
    } else {
    	if ((totalDmaCount + 0x80000) < downloadFileSize) 
    	    dwWillDMACnt = 0x80000;
    	else
    	    dwWillDMACnt = downloadFileSize - totalDmaCount;

        dwEmptyCnt = (dwUSBBufReadPtr - dwUSBBufWritePtr - 1 + dwUSBBufSize) % 
                     dwUSBBufSize;

        if (dwEmptyCnt >= dwWillDMACnt)
    	    ConfigEp3DmaMode(dwUSBBufWritePtr, dwWillDMACnt);
    }
    usbdevregs->INDEX_REG = saveIndexReg;
}
Esempio n. 5
0
void Ep0Handler(void)
{
	static int ep0SubState;
	U8 ep0_csr;
	struct s3c24x0_usb_device * const usbdevregs	= s3c24x0_get_base_usb_device();

	writeb(0, &usbdevregs->INDEX_REG);	
	ep0_csr = readb(&usbdevregs->EP0_CSR_IN_CSR1_REG);
    //DATAEND interrupt(ep0_csr==0x0) will be ignored 
    //because ep0State==EP0_STATE_INIT when the DATAEND interrupt is issued.

    
    if(ep0_csr & EP0_SETUP_END)
    {   
    	 // Host may end GET_DESCRIPTOR operation without completing the IN data stage.
    	 // If host does that, SETUP_END bit will be set.
    	 // OUT_PKT_RDY has to be also cleared because status stage sets OUT_PKT_RDY to 1.
//   	DbgPrintf("[SETUPEND]");
	CLR_EP0_SETUP_END();
	if(ep0_csr & EP0_OUT_PKT_READY) 
	{
	    FLUSH_EP0_FIFO(); //(???)
	    	//I think this isn't needed because EP0 flush is done automatically.   
	    CLR_EP0_OUT_PKT_RDY();
	}
	
	ep0State=EP0_STATE_INIT;
	return;
    }	

    //I think that EP0_SENT_STALL will not be set to 1.
    if(ep0_csr & EP0_SENT_STALL)
    {   
//   	DbgPrintf("[STALL]");
   	CLR_EP0_SENT_STALL();
	if(ep0_csr & EP0_OUT_PKT_READY) 
	{
	    CLR_EP0_OUT_PKT_RDY();
	}
	
	ep0State=EP0_STATE_INIT;
	return;
    }	



    if((ep0_csr & EP0_OUT_PKT_READY)) // && (ep0State==EP0_STATE_INIT))
    {	
	RdPktEp0((U8 *)&descSetup,EP0_PKT_SIZE);

//	PrintEp0Pkt((U8 *)(&descSetup)); //DEBUG
    
	switch(descSetup.bRequest)
    	{
    	case GET_DESCRIPTOR:
            switch(descSetup.bValueH)        
            {
            case DEVICE_TYPE:
// 	    	DbgPrintf("[GDD]");
 	    	CLR_EP0_OUT_PKT_RDY();
	    	ep0State=EP0_STATE_GD_DEV_0;	        
	    	break;	
	    case CONFIGURATION_TYPE:
// 	    	DbgPrintf("[GDC]");
 	    	CLR_EP0_OUT_PKT_RDY();
 	    	if((descSetup.bLengthL+(descSetup.bLengthH<<8))>0x9)
 	    	  //bLengthH should be used for bLength=0x209 at WIN2K.    	
	    	   ep0State=EP0_STATE_GD_CFG_0; //for WIN98,WIN2K
               else	    	    
  		    ep0State=EP0_STATE_GD_CFG_ONLY_0; //for WIN2K
	    	break;
   	    case STRING_TYPE:
// 	    	DbgPrintf("[GDS]");
 	    	CLR_EP0_OUT_PKT_RDY();
	    	switch(descSetup.bValueL)
	    	{
	    	    case 0:
	    	    	ep0State=EP0_STATE_GD_STR_I0;
	    	    	break;
	    	    case 1:
       	    	    	ep0State=EP0_STATE_GD_STR_I1;
	    	    	break;
	    	    case 2:	
	    	    	ep0State=EP0_STATE_GD_STR_I2;
	    	    	break;
	    	    default:
//	    		DbgPrintf("[UE:STRI?]");
	    		break;
	    	}
	    	ep0SubState=0;
	    	break;
	    case INTERFACE_TYPE:
// 	    	DbgPrintf("[GDI]");
 	    	CLR_EP0_OUT_PKT_RDY();
	    	ep0State=EP0_STATE_GD_IF_ONLY_0; //for WIN98
	    	break;
	    case ENDPOINT_TYPE:	    	
 //	    	DbgPrintf("[GDE]");
 	    	CLR_EP0_OUT_PKT_RDY();
 	    	switch(descSetup.bValueL&0xf)
	    	{
	    	case 0:
	    	    ep0State=EP0_STATE_GD_EP0_ONLY_0;
	    	    break;
	    	case 1:
       	    	    ep0State=EP0_STATE_GD_EP1_ONLY_0;
	    	    break;
	    	default:
//	    	    DbgPrintf("[UE:GDE?]");
	    	    break;
	    	}
	    	break;
	    default:
//	    	DbgPrintf("[UE:GD?]");
	    	break;
	    }	
    	    break;

    	case SET_ADDRESS:
//            DbgPrintf("[SA:%d]",descSetup.bValueL);
		writeb((descSetup.bValueL | 0x80), &usbdevregs->FUNC_ADDR_REG);
	    CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
            ep0State=EP0_STATE_INIT;
            break;
    	
	case SET_CONFIGURATION:
//            DbgPrintf("[SC]");
            ConfigSet.ConfigurationValue=descSetup.bValueL;
            CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
            ep0State=EP0_STATE_INIT;

            isUsbdSetConfiguration=1; 
            break;

    	    //////////////////////// For chapter 9 test ////////////////////

    	  case CLEAR_FEATURE:
    	  	
    	  	switch (descSetup.bmRequestType)
    	  	{
    	  	  case DEVICE_RECIPIENT:
    	  	  	if (descSetup.bValueL == 1)
    	  	  		Rwuen = FALSE;
    	  	  	
    	  	  	break;

    	  	  case ENDPOINT_RECIPIENT:
    	  	  	 if (descSetup.bValueL == 0)
    	  	  	 {
	                       if((descSetup.bIndexL & 0x7f) == 0x00){
	                        StatusGet.Endpoint0= 0;    
	                       }
	                       if((descSetup.bIndexL & 0x8f) == 0x81){           // IN  Endpoint 1
	                         StatusGet.Endpoint1= 0;           
	                        }
	                       if((descSetup.bIndexL & 0x8f) == 0x03){          // OUT Endpoint 3
	                         StatusGet.Endpoint3= 0;      
	                         }
                       }
    	  	  	 
    	  	  	 break;

    	  	  default:
    	  	  	break;
    	  	}
    	  	CLR_EP0_OUTPKTRDY_DATAEND();
    	  	ep0State=EP0_STATE_INIT;
    	  	break;

    	  case GET_CONFIGURATION:

                CLR_EP0_OUT_PKT_RDY();
	    	  ep0State=EP0_CONFIG_SET;
    	  	   
    	         break;


    	  case GET_INTERFACE:
    	  	
    	  	  CLR_EP0_OUT_PKT_RDY();
	    	  ep0State=EP0_INTERFACE_GET;
    	  	  
    	  	  break;

    	  case GET_STATUS:

    	  	switch(descSetup.bmRequestType)
    	  	{
    	  	      case  (0x80):

    	  	 		CLR_EP0_OUT_PKT_RDY();
    	  	 		StatusGet.Device=((U8)Rwuen<<1)|(U8)Selfpwr;
    	  	 		ep0State=EP0_GET_STATUS0;
    	  	 		    	  	 		
                          break;

                     case  (0x81):
                           	CLR_EP0_OUT_PKT_RDY();
    	  	 		StatusGet.Interface=0;
    	  	 		ep0State=EP0_GET_STATUS1;
                          break;

                     case  (0x82):

                     	CLR_EP0_OUT_PKT_RDY();
    	  	 		if((descSetup.bIndexL & 0x7f) == 0x00){
	                          ep0State=EP0_GET_STATUS2;
    	  	 		  }
    	  	 		
	                       if((descSetup.bIndexL & 0x8f) == 0x81){
	                          ep0State=EP0_GET_STATUS3;
	                       }
	                       
	                       if((descSetup.bIndexL & 0x8f) == 0x03){
                                ep0State=EP0_GET_STATUS4;
	                       }
                          break;

                      default:
                          	break;
    	  	}
    	  	      
    	  	break;


    	  case SET_DESCRIPTOR:
    	  	       CLR_EP0_OUTPKTRDY_DATAEND();
    	  	       ep0State=EP0_STATE_INIT;
    	  	break;


    	  case SET_FEATURE:
    	  	 
    	  	switch (descSetup.bmRequestType)
    	  	{
    	  	  case DEVICE_RECIPIENT:
    	  	  	if (descSetup.bValueL == 1)
    	  	  		Rwuen = TRUE;
    	  	  	
    	  	  	break;

    	  	  case ENDPOINT_RECIPIENT:
    	  	  	 if (descSetup.bValueL == 0)
    	  	  	 {
	                       if((descSetup.bIndexL & 0x7f) == 0x00){
	                        StatusGet.Endpoint0= 1;
	                       }
	                       if((descSetup.bIndexL & 0x8f) == 0x81){
	                         StatusGet.Endpoint1= 1;
	                       }
	                       if((descSetup.bIndexL & 0x8f) == 0x03){
	                         StatusGet.Endpoint3= 1;
	                       }
                       }
    	  	  	break;

    	  	  default:
    	  	  	break;
    	  	}
    	  	CLR_EP0_OUTPKTRDY_DATAEND();
    	  	ep0State=EP0_STATE_INIT;
    	  
    	  	break;


    	  case SET_INTERFACE:
    	  	   InterfaceGet.AlternateSetting= descSetup.bValueL;
    	  	   CLR_EP0_OUTPKTRDY_DATAEND(); 
                 ep0State=EP0_STATE_INIT;
    	  	break;

    	  case SYNCH_FRAME:
    	  	ep0State=EP0_STATE_INIT;
    	  	break;

    	  //////////////////////////////////////////////////////////////

  	default:
//	    DbgPrintf("[UE:SETUP=%x]",descSetup.bRequest);
    	    CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
	    ep0State=EP0_STATE_INIT;
	    break;
    
        }
    }
    
    switch(ep0State)
    {	
	case EP0_STATE_INIT:
	    break; 

	//=== GET_DESCRIPTOR:DEVICE ===
    	case EP0_STATE_GD_DEV_0:
//            DbgPrintf("[GDD0]");
            WrPktEp0((U8 *)&descDev+0,8); //EP0_PKT_SIZE
            SET_EP0_IN_PKT_RDY();
            ep0State=EP0_STATE_GD_DEV_1;
            break;
            
    	case EP0_STATE_GD_DEV_1:
 //           DbgPrintf("[GDD1]");
            WrPktEp0((U8 *)&descDev+0x8,8); 
            SET_EP0_IN_PKT_RDY();
            
            ep0State=EP0_STATE_GD_DEV_2;
            break;

    	case EP0_STATE_GD_DEV_2:
//            DbgPrintf("[GDD2]");
            WrPktEp0((U8 *)&descDev+0x10,2);   //8+8+2=0x12
            SET_EP0_INPKTRDY_DATAEND();
            ep0State=EP0_STATE_INIT;
            break;
    

        //=== GET_DESCRIPTOR:CONFIGURATION+INTERFACE+ENDPOINT0+ENDPOINT1 ===
        //Windows98 gets these 4 descriptors all together by issuing only a request.
        //Windows2000 gets each descriptor seperately.
    	case EP0_STATE_GD_CFG_0:
//            DbgPrintf("[GDC0]");
            WrPktEp0((U8 *)&descConf+0,8); //EP0_PKT_SIZE
            SET_EP0_IN_PKT_RDY();
            ep0State=EP0_STATE_GD_CFG_1;
            break;
    
    	case EP0_STATE_GD_CFG_1:
//            DbgPrintf("[GDC1]");
            WrPktEp0((U8 *)&descConf+8,1); 
            WrPktEp0((U8 *)&descIf+0,7); 
            SET_EP0_IN_PKT_RDY();
            ep0State=EP0_STATE_GD_CFG_2;
            break;

    	case EP0_STATE_GD_CFG_2:
//            DbgPrintf("[GDC2]");
            WrPktEp0((U8 *)&descIf+7,2); 
            WrPktEp0((U8 *)&descEndpt0+0,6); 
            SET_EP0_IN_PKT_RDY();
            ep0State=EP0_STATE_GD_CFG_3;
            break;

    	case EP0_STATE_GD_CFG_3:
 //           DbgPrintf("[GDC3]");
            WrPktEp0((U8 *)&descEndpt0+6,1); 
            WrPktEp0((U8 *)&descEndpt1+0,7); 
            SET_EP0_IN_PKT_RDY();
            ep0State=EP0_STATE_GD_CFG_4;            
            break;

    	case EP0_STATE_GD_CFG_4:
//            DbgPrintf("[GDC4]");
             //zero length data packit 
            SET_EP0_INPKTRDY_DATAEND();
            ep0State=EP0_STATE_INIT;            
            break;

        //=== GET_DESCRIPTOR:CONFIGURATION ONLY===
    	case EP0_STATE_GD_CFG_ONLY_0:
//            DbgPrintf("[GDCO0]");
            WrPktEp0((U8 *)&descConf+0,8); //EP0_PKT_SIZE
            SET_EP0_IN_PKT_RDY();
            ep0State=EP0_STATE_GD_CFG_ONLY_1;
            break;
    
    	case EP0_STATE_GD_CFG_ONLY_1:
//            DbgPrintf("[GDCO1]");
            WrPktEp0((U8 *)&descConf+8,1); 
            SET_EP0_INPKTRDY_DATAEND();
            ep0State=EP0_STATE_INIT;            
            break;

        //=== GET_DESCRIPTOR:INTERFACE ONLY===
    	case EP0_STATE_GD_IF_ONLY_0:
//            DbgPrintf("[GDI0]");
            WrPktEp0((U8 *)&descIf+0,8); 
            SET_EP0_IN_PKT_RDY();
            ep0State=EP0_STATE_GD_IF_ONLY_1;
            break;
    	case EP0_STATE_GD_IF_ONLY_1:
//           DbgPrintf("[GDI1]");
            WrPktEp0((U8 *)&descIf+8,1); 
            SET_EP0_INPKTRDY_DATAEND();
            ep0State=EP0_STATE_INIT;            
            break;

        //=== GET_DESCRIPTOR:ENDPOINT 0 ONLY===
    	case EP0_STATE_GD_EP0_ONLY_0:
//            DbgPrintf("[GDE00]");
            WrPktEp0((U8 *)&descEndpt0+0,7); 
            SET_EP0_INPKTRDY_DATAEND();
            ep0State=EP0_STATE_INIT;            
            break;
            
        //=== GET_DESCRIPTOR:ENDPOINT 1 ONLY===
    	case EP0_STATE_GD_EP1_ONLY_0:
//            DbgPrintf("[GDE10]");
            WrPktEp0((U8 *)&descEndpt1+0,7); 
            SET_EP0_INPKTRDY_DATAEND();
            ep0State=EP0_STATE_INIT;            
            break;
            
////////////////////////////////////////////

         case EP0_INTERFACE_GET:
            WrPktEp0((U8 *)&InterfaceGet+0,1);
            SET_EP0_INPKTRDY_DATAEND();
            ep0State=EP0_STATE_INIT;      
         break;

 
        //=== GET_DESCRIPTOR:STRING ===

    	case EP0_STATE_GD_STR_I0:
//            DbgPrintf("[GDS0_0]");
           WrPktEp0((U8 *)descStr0, 4 );  
	    SET_EP0_INPKTRDY_DATAEND();
	    ep0State=EP0_STATE_INIT;     
	    ep0SubState=0;
	    break;

	case EP0_STATE_GD_STR_I1:
//            DbgPrintf("[GDS1_%d]",ep0SubState);
             if( (ep0SubState*EP0_PKT_SIZE+EP0_PKT_SIZE)<sizeof(descStr1) )
            {
            	WrPktEp0((U8 *)descStr1+(ep0SubState*EP0_PKT_SIZE),EP0_PKT_SIZE); 
            	SET_EP0_IN_PKT_RDY();
            	ep0State=EP0_STATE_GD_STR_I1;
            	ep0SubState++;
            }
	    else
	    {
	    	WrPktEp0((U8 *)descStr1+(ep0SubState*EP0_PKT_SIZE),
	    		 sizeof(descStr1)-(ep0SubState*EP0_PKT_SIZE)); 
		SET_EP0_INPKTRDY_DATAEND();
		ep0State=EP0_STATE_INIT;     
		ep0SubState=0;
	    }
	    break;

	case EP0_STATE_GD_STR_I2:
//            DbgPrintf("[GDS2_%d]",ep0SubState);
             if( (ep0SubState*EP0_PKT_SIZE+EP0_PKT_SIZE)<sizeof(descStr2) )
            {
            	WrPktEp0((U8 *)descStr2+(ep0SubState*EP0_PKT_SIZE),EP0_PKT_SIZE); 
            	SET_EP0_IN_PKT_RDY();
            	ep0State=EP0_STATE_GD_STR_I2;
            	ep0SubState++;
            }
	    else
	    {
//                DbgPrintf("[E]");
	    	WrPktEp0((U8 *)descStr2+(ep0SubState*EP0_PKT_SIZE),
	    		 sizeof(descStr2)-(ep0SubState*EP0_PKT_SIZE)); 
		SET_EP0_INPKTRDY_DATAEND();
		ep0State=EP0_STATE_INIT;     
		ep0SubState=0;
	    }
	    break;

	 case EP0_CONFIG_SET:
	 	WrPktEp0((U8 *)&ConfigSet+0,1); 
            SET_EP0_INPKTRDY_DATAEND();
            ep0State=EP0_STATE_INIT;      
            break;

        case EP0_GET_STATUS0:
	     WrPktEp0((U8 *)&StatusGet+0,1);
            SET_EP0_INPKTRDY_DATAEND();
            ep0State=EP0_STATE_INIT;      
         break;

         case EP0_GET_STATUS1:
	     WrPktEp0((U8 *)&StatusGet+1,1);
            SET_EP0_INPKTRDY_DATAEND();
            ep0State=EP0_STATE_INIT;      
         break;

         case EP0_GET_STATUS2:
	     WrPktEp0((U8 *)&StatusGet+2,1);
            SET_EP0_INPKTRDY_DATAEND();
            ep0State=EP0_STATE_INIT;      
         break;

         case EP0_GET_STATUS3:
	     WrPktEp0((U8 *)&StatusGet+3,1);
            SET_EP0_INPKTRDY_DATAEND();
            ep0State=EP0_STATE_INIT;      
         break;

         case EP0_GET_STATUS4:
	     WrPktEp0((U8 *)&StatusGet+4,1);
            SET_EP0_INPKTRDY_DATAEND();
            ep0State=EP0_STATE_INIT;      
         break;

     	default:
//	    DbgPrintf("UE:G?D");
     	    break;
    }
}