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

📄 sc2440_usb_hw.c

📁 wince 下的bsp测试wince_bspSMDK2440_L35T32.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
 
  When the packet is accepted we return the number of bytes and grab the 
  next packet (or portion thereof).
 
*************************************************************************/
//:-)
void SC2440_USB_TxIntHandler( PSER_INFO pHWHead,
			      PUCHAR pTxBuffer,
			      ULONG *pBuffLen ) 
{
	unsigned int i;
	UCHAR ucLen;
	BYTE saveIndex;
	
	//DEBUGMSG(1, (TEXT("++SC2440_USB_TxIntHandler\r\n")));

	//USBDMSG(1, (TEXT("<T:%d>"),*pBuffLen));
	
	usbdShMem->usbdEir&=~USBDEIR_EP1;

	// Endpoint 1 mode
	saveIndex=*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX;
	UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0x1);
    //pHWHead->pUSBCtrlAddr->INDEX.index=0x1; //:-)
	
	pHWHead->CommErrors &= ~CE_TXFULL;

	// If nothing to send, just return after clearing interrupt.
	if (! *pBuffLen ) 
	{
		//DEBUGMSG (1, (TEXT("[TX:nothing to send]")));    
		*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=saveIndex;
		return;
	}
    		      	
	// Don't try to send more than EP1 can handle.
	if( *pBuffLen > EP1Len )
    		ucLen = EP1Len;
	else {

		// If we end exactly on a packet boundary, the host doesn't
		// realize there is no more data.  So if we exactly fill the final 
		// packet, truncate it so we can send a short packet next frame
		// indicating end of the transmission
		if( *pBuffLen == EP1Len ) 
		{
			//USBDMSG (1, (TEXT("Tx breaking packet\r\n")));            
			ucLen = EP1Len - 2;
		} else {
			ucLen = (UCHAR)*pBuffLen;
		}

	}

	if (!pHWHead->pUSBCtrlAddr->EP0ICSR1.opr_ipr)
	{
		// Write to the FIFO directly to send the bytes.
		for (i=0; i < ucLen; i++) 
		{
			IOW_REG_FIELD(struct EP1FBits, 
				&pHWHead->pUSBCtrlAddr->EP1F, fifo_data, *pTxBuffer++);
		}

		// Return number of bytes transmitted via pBuffLen.
		*pBuffLen = ucLen;
		UDC_REG_WRITE(struct EP0ICSR1Bits, &pHWHead->pUSBCtrlAddr->EP0ICSR1, opr_ipr, 1);
	} else {
		// Transmit already in progress.  Just return and wait for current
		// transmission to complete before sending more.
		//USBDMSG(0, (TEXT("Write Pend !!!\r\n")));
		*pBuffLen = 0; 
	}

	//DEBUGMSG(0, (TEXT("--SC2440_USB_TxIntHandler\r\n")));
	*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=saveIndex;
}



BOOL
HW_PowerOff(
    PSER_INFO pHWHead 
    )
{
	pHWHead->State = OFF;
	// cache the interrupt regs
	pHWHead->cIntStat_uir = *(BYTE *)&pHWHead->pUSBCtrlAddr->UIR;
	pHWHead->cIntStat_eir = *(BYTE *)&pHWHead->pUSBCtrlAddr->EIR;
    
	// disable the USB Clocks
	EnterCriticalSection(&pHWHead->HwRegCritSec);
	//DEBUGMSG(1, (TEXT("USB:HW_PowerOff()\r\n")));
	//RETAILMSG(1, (TEXT("USB:HW_PowerOff()\r\n")));
	HW_USBClocks(pHWHead);
	LeaveCriticalSection(&pHWHead->HwRegCritSec);

    return TRUE;
}


BOOL 
HW_PowerOn(
    PSER_INFO pHWHead
    )
{
		
	pHWHead->State = RESUME;

	// enable the USB Clocks
	EnterCriticalSection(&pHWHead->HwRegCritSec);
	//DEBUGMSG(1, (TEXT("USB:HW_PowerOn()\r\n")));
	//RETAILMSG(1, (TEXT("USB:HW_PowerOn()\r\n")));
	HW_USBClocks(pHWHead);
	LeaveCriticalSection(&pHWHead->HwRegCritSec);

	SetInterruptEvent(pHWHead->pHWObj->dwIntID); 		
    
    return TRUE;
}



VOID
HW_USBClocks(PSER_INFO pHWHead)
{
	if ((pHWHead->State == IDLE) || (pHWHead->State == RESUME))
	{
		DEBUGMSG(1, (TEXT("HW_USBClocks::IDLE\r\n")));
        //
        // Enable the USB Clocks
        //
        pHWHead->pCLKPWR->rCLKCON |= (1<<7);
        DEBUGMSG(ZONE_INIT, (TEXT("rCLKCON: 0x%X\r\n"), pHWHead->pCLKPWR->rCLKCON));
        
        // Fin=12MHz, Fout=48MHz
        //pHWHead->pCLKPWR->rUPLLCON = 0x48032;   // ((0x48 << 12) + (0x3 << 4) + 0x2)
        //DEBUGMSG(ZONE_INIT, (TEXT("rUPLLCON: 0x%X\r\n"), pHWHead->pCLKPWR->rUPLLCON));

        //
        // MISCCR: USBD Pads, Normal mode
        //
        pHWHead->pIrqCtrlAddr->rMISCCR &= ~((3 << 12) | (1 << 3));

        // TO DO :
        // Enable USB_PULLUP on GPIO PIN (tied to USB D+) & set high
        //

        //pHWHead->pIrqCtrlAddr->rGPBCON &= ~(3 << 18);    // clear GPE15
        //pHWHead->pIrqCtrlAddr->rGPBCON |=  (1 << 18);    // config as output
        //pHWHead->pIrqCtrlAddr->rGPBUP  &= ~(1 << 9);    // pullup disabled
        //pHWHead->pIrqCtrlAddr->rGPBDAT |=  (1 << 9);    // set high

        pHWHead->pIrqCtrlAddr->rGPGCON &= ~(3 << 24);    // clear GPE15
        pHWHead->pIrqCtrlAddr->rGPGCON |=  (1 << 24);    // config as output
        pHWHead->pIrqCtrlAddr->rGPGUP  &= ~(1 << 12);    // pullup disabled
        pHWHead->pIrqCtrlAddr->rGPGDAT |=  (1 << 12);    // set high

        DEBUGMSG(ZONE_INIT, (TEXT("rGPDCON: 0x%X\r\n"), pHWHead->pIrqCtrlAddr->rGPDCON));
        DEBUGMSG(ZONE_INIT, (TEXT("rGPDUP: 0x%X\r\n"),  pHWHead->pIrqCtrlAddr->rGPDUP));
        DEBUGMSG(ZONE_INIT, (TEXT("rGPDDAT: 0x%X\r\n"), pHWHead->pIrqCtrlAddr->rGPDDAT));
	}
	else if (pHWHead->State == OFF) 
	{
		DEBUGMSG(1, (TEXT("HW_USBClocks::OFF\r\n")));
        //
        // Disable the USB Clocks
        //
        pHWHead->pCLKPWR->rCLKCON &= ~(1<<7);

        DEBUGMSG(ZONE_INIT, (TEXT("rCLKCON: 0x%X\r\n"), pHWHead->pCLKPWR->rCLKCON));
        
        // Fin=12MHz, Fout=48MHz
        //pHWHead->pCLKPWR->rUPLLCON = 0;
        // MISCCR: USBD Pads, Suspend mode
        pHWHead->pIrqCtrlAddr->rMISCCR |= (3 << 12);

        // TO DO :
        // Disable USB_PULLUP to remove us from the bus
        

        //pHWHead->pIrqCtrlAddr->rGPBCON &= ~(3 << 18);    // clear GPE15
        //pHWHead->pIrqCtrlAddr->rGPBCON |=  (1 << 18);    // config as output
        //pHWHead->pIrqCtrlAddr->rGPBUP  |=  (1 << 9);    // pullup disabled
        //pHWHead->pIrqCtrlAddr->rGPBDAT &= ~(1 << 9);    // set low
        
		pHWHead->pIrqCtrlAddr->rGPGCON &= ~(3 << 24);    // clear GPE15
        pHWHead->pIrqCtrlAddr->rGPGCON |=  (1 << 24);    // config as output
        pHWHead->pIrqCtrlAddr->rGPGUP  |=  (1 << 12);    // pullup disabled
        pHWHead->pIrqCtrlAddr->rGPGDAT &= ~(1 << 12);    // set low

		DEBUGMSG(ZONE_INIT, (TEXT("rUPLLCON: 0x%X\r\n"), pHWHead->pCLKPWR->rUPLLCON));
	}
}


// :-)
/***************************************
  Added routines for USBD Rx:DMA Tx:ISR
 ***************************************/

BOOL InitUsbdDriverGlobals(void)
{
	BOOL	Ret;
	int i;

	if ( v_pDriverGlobals == NULL )
	{
		v_pDriverGlobals =(PDRIVER_GLOBALS)VirtualAlloc( 0,
						DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
						MEM_RESERVE,
						PAGE_NOACCESS);
		if ( v_pDriverGlobals == NULL )
		{
		    USBDMSG( 1, (TEXT( "InitUsbdDriverGlobals : VirtualAlloc failed!\r\n")) );
			return ( FALSE );
		}

		Ret = VirtualCopy( (LPVOID)v_pDriverGlobals,
						   (LPVOID)DRIVER_GLOBALS_PHYSICAL_MEMORY_START,
						   DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
						   PAGE_READWRITE | PAGE_NOCACHE
						   );

		if ( Ret == FALSE )
		{
			DEBUGMSG( ZONE_ERROR, (TEXT( "InitUsbdDriverGlobals: VirtualCopy failed!\r\n")) );
			if ( v_pDriverGlobals )
			{
				VirtualFree( v_pDriverGlobals,
							 DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE ,
							 MEM_RELEASE
							);
				v_pDriverGlobals = NULL;
			} 
			return ( FALSE );
		}
	}
	
	usbdShMem=&(v_pDriverGlobals->usbd);	

    for(i=0;i<USBD_GLOBALS_BUF_SIZE;i++)
    {
        usbdShMem->usbdRxBuf[i]=0x0;
		//usbdShMem->usbdTxBuf[i]=0x0;
    }
	usbdShMem->usbdRxRdPt=0;
	usbdShMem->usbdRxWrPt=0;
	usbdShMem->usbdRxCnt=0;
	//usbdShMem->usbdTxRdPt=0;
	//usbdShMem->usbdTxWrPt=0;
	//usbdShMem->usbdTxCnt=0;
	usbdShMem->usbdEir=0;
 	usbdShMem->usbdUir=0;
	usbdShMem->usbdDma3Int=0; 
	//usbdShMem->usbdMddRxCnt=0;
	USBDMSG( 1, (TEXT( "USBD:DRIVER_GLOBALS is initialized\r\n")) );
	return( TRUE ); 
}



BOOL UsbdAllocateVm(void)
{
	if(v_pDMAregs == NULL) 
	{
		v_pDMAregs = (volatile DMAreg *) 
			VirtualAlloc(0,sizeof(DMAreg),MEM_RESERVE, PAGE_NOACCESS);
		if(v_pDMAregs == NULL)
		{
			ERRORMSG(1,(TEXT("For DMAreg: VirtualAlloc failed!\r\n")));
			return (FALSE);
		}
		else 
		{
			if(!VirtualCopy((PVOID)v_pDMAregs,(PVOID)(DMA_BASE),sizeof(DMAreg),
				PAGE_READWRITE | PAGE_NOCACHE )) 
			{
				ERRORMSG(1,(TEXT("For pIOPregs: VirtualCopy failed!\r\n")));
				UsbdDeallocateVm();
				return (FALSE);
			}
		}
	}

	if(v_pINTregs == NULL)
	{
    	v_pINTregs = (volatile INTreg *) 
	    		VirtualAlloc(0,sizeof(INTreg),MEM_RESERVE, PAGE_NOACCESS);
   		if(v_pINTregs == NULL)
		{
	   		ERRORMSG(1,(TEXT("For INTreg: VirtualAlloc failed!\r\n")));
			return (FALSE);
	   	}
    	else 
		{
	    	if(!VirtualCopy((PVOID)v_pINTregs,(PVOID)(INT_BASE),sizeof(INTreg),
		    	   PAGE_READWRITE | PAGE_NOCACHE ))
		   	{
				ERRORMSG(1,(TEXT("For INTreg: VirtualCopy failed!\r\n")));
    				return (FALSE);
	    	}
	   	}
	}
	
	return TRUE;
}



void UsbdDeallocateVm(void)
{
	if(v_pDMAregs)
	{
		VirtualFree((void*)v_pDMAregs, sizeof(DMAreg), MEM_RELEASE);
		v_pDMAregs=NULL;
	}

	if(v_pINTregs)
	{
		VirtualFree((void*)v_pINTregs, sizeof(INTreg), MEM_RELEASE);
		v_pINTregs=NULL;
	}
}



void UsbdInitDma3(int bufIndex,int bufOffset)
{
	//ULONG usbdRxRdPt,usbdRxWrPt;

  	//If DMA3 is turned on, DMA3 should be turned off.
	if((v_pDMAregs->rDMASKTRIG3&(1<<1))!=0)
	{
		v_pDMAregs->rDMASKTRIG3=(1<<2);	//DMA3 stop
		while(v_pDMAregs->rDMASKTRIG3&(1<<1)); //wait until DMA3 stop
		usbdShMem->usbdRxRdPt=0;
		USBDMSG( 1, (TEXT("[DMA3 is stopped]\r\n")));
	}

	v_pDMAregs->rDISRCC3 = (1<<1)|(1<<0);		   //src=APB, srcAddr=fixed
	v_pDMAregs->rDISRC3 = REAL_PHYSICAL_ADDR_EP4_FIFO; //srcAddr=EP4_FIFO 
	v_pDMAregs->rDIDSTC3 = (0<<1)|(0<<0);		   //dst=AHB(memory),increase,

#if (DRIVER_GLOBALS_PHYSICAL_MEMORY_START<0xA0000000 || DMA_BUFFER_BASE<0xA0000000) 
	GENERATE_ERROR
		   	//The above two address should be non-cacheable area.
#endif  	

	realPhysicalAddr_UsbdRxBuf = \
		(ULONG)&((DRIVER_GLOBALS *)DRIVER_GLOBALS_PHYSICAL_MEMORY_START)->usbd.usbdRxBuf \
		- DMA_BUFFER_BASE + DMA_PHYSICAL_BASE;	
	//USBDMSG( 1, (TEXT( "[USBD:RPA_URxBuf=%x]"),realPhysicalAddr_UsbdRxBuf) );
	//Real physical address of usbdShMem->usbdRxBuf

	if(bufIndex==0)
	{
	   	v_pDMAregs->rDIDST3=realPhysicalAddr_UsbdRxBuf+0+bufOffset;
	}
	else
	{
		v_pDMAregs->rDIDST3=realPhysicalAddr_UsbdRxBuf+(USBD_GLOBALS_BUF_SIZE/2)+bufOffset;
	}

   	v_pDMAregs->rDCON3=(USBD_GLOBALS_BUF_SIZE-bufOffset)|(1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(4<<24)|(1<<23)|(1<<22)|(0<<20); 
	//handshake,requestor=APB,CURR_TC int enable,unit transfer,
	//single service,src=USBD,H/W request,no_autoreload,byte,CURR_TC

	v_pDMAregs->rDMASKTRIG3=(1<<1);	//DMA 3 on
	   

	USBDMSG( 1, (TEXT( "[USBD:rDIDST3=%x,rDCDST3=%x]\r\n"),v_pDMAregs->rDIDST3,v_pDMAregs->rDCDST3) );

}


⌨️ 快捷键说明

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