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

📄 sc2410_usb_hw.c

📁 wince4.2 USB function driver for magic eye mmsp2 platform
💻 C
📖 第 1 页 / 共 4 页
字号:
			// MDD will recall RxIntHandler by chekcing SC2400_USB_GetInterruptType().
			// So, usbdShMem->usbdEir:USBDEIR_EP3 must not be cleared	//:-) 
		//Sleep(100);
		
		*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=saveIndex;
		return fRXFlag;
	}
	usbdShMem->usbdEir&=~USBDEIR_EP4;
	DEBUGMSG(1, (TEXT("--SC2400_USB_RxIntHandler\r\n")));
	
	*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=saveIndex;
	return fRXFlag;
#else
	saveCnt= cnt = pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_low | pHWHead->pUSBCtrlAddr->OFCR2.out_cnt_high << 8; 
	
	if (buflen <(INT)saveCnt) 
	{
		DEBUGMSG(1, (TEXT("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r\n")));
		cnt= buflen;
	}
	
	if (saveCnt == 0) // No data to read
	{ 
		USBDMSG(1, (TEXT("[R0]")));
	}	 
	else
	{
//		USBDMSG(1, (TEXT("Copying <%d>"),cnt));
		(*pBuffLen)=cnt;
		while(cnt--) 
		{
			*pRxBuffer++ = cRxChar = (BYTE)pHWHead->pUSBCtrlAddr->EP4F.fifo_data;
			if( cRxChar == cEvtChar )	fRXFlag = TRUE;
		}
	}

    //not be needed. Only for test
	if(pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_low==0 ) 
		if(pHWHead->pUSBCtrlAddr->OCSR1.out_pkt_rdy==1)
		{
		    USBDMSG(1, (TEXT("__OPR__(NEVER EXECUTED)")));
			UDC_REG_BITSET(struct OCSR1Bits,&pHWHead->pUSBCtrlAddr->OCSR1, out_pkt_rdy, 0);
		}

	if ( buflen<(INT)saveCnt)	usbdShMem->usbdEir|=USBDEIR_EP4; 
	else {
		usbdShMem->usbdEir&=~USBDEIR_EP4;
		DEBUGMSG(1, (TEXT("--SC2400_USB_RxIntHandler\r\n")));
	}
	*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=saveIndex;
	return fRXFlag;
#endif
}




/*************************************************************************
  SC2400_USB_TxIntHandler
 
  Send the next packet to the USB. The first packet gets sent by directly
  calling this function (via dispatch table) from the MDD. After the first
  call the interrupt mechanism will keep things going.
 
  We return the actual number of bytes we've queued to the UDC. Note that
  until the next interrupt we wont know if it has been transmitted. We'll
  deal with the failure by saving the original packet and retransmitting if
  we get an error. In that case we'll return 0 as the number of bytes sent
  since no new bytes have been consumed from the caller's buffer.
 
  When the packet is accepted we return the number of bytes and grab the 
  next packet (or portion thereof).
 
*************************************************************************/
//:-)
void SC2400_USB_TxIntHandler( PSER_INFO pHWHead,
			      PUCHAR pTxBuffer,
			      ULONG *pBuffLen ) 
{
	unsigned int i;
	UCHAR ucLen;
	BYTE saveIndex;
	
	DEBUGMSG(1, (TEXT("++SC2400_USB_TxIntHandler\r\n")));

	USBDMSG(1, (TEXT("<T:%d>\r\n"),*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]\r\n")));    
		*(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++) 
		{
			pHWHead->pUSBCtrlAddr->EP1F.fifo_data = *pTxBuffer++;
//			by Neo : Align Problem
//			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);	by Neo : Align Problem
		pHWHead->pUSBCtrlAddr->EP0ICSR1.opr_ipr= 1;
	} else {
		// Transmit already in progress.  Just return and wait for current
		// transmission to complete before sending more.
		USBDMSG(1, (TEXT("Write Pend !!!\r\n")));
		*pBuffLen = 0; 
	}

	DEBUGMSG(1, (TEXT("--SC2400_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
        // Fin=12MHz, Fout=48MHz
	}
	else if (pHWHead->State == OFF) 
	{
		DEBUGMSG(1, (TEXT("HW_USBClocks::OFF\r\n")));
        //
        // Disable the USB Clocks
        // 
        // Fin=12MHz, Fout=48MHz
        // MISCCR: USBD Pads, Suspend mode
	}
}


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

BOOL InitUsbdDriverGlobals(PSER_INFO pHWHead)
{
	BOOL	Ret;
	int i;

	if ( v_pDriverGlobals == NULL )
	{
		DEBUGMSG(1, (TEXT("Before VirtualAlloc:%08x\r\n"), DRIVER_GLOBALS_PHYSICAL_MEMORY_START));
		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+0x20000000),
						   DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
						   PAGE_READWRITE | PAGE_NOCACHE
						   );
		v_pDriverGlobals = (PDRIVER_GLOBALS) (DRIVER_GLOBALS_PHYSICAL_MEMORY_START+0x20000000);

		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 );
		}
	}
	
	DEBUGMSG( 1, (TEXT("v_pDriverGlobals: %x\r\n"), (ULONG)(&(v_pDriverGlobals->usbd))) );
	
	usbdShMem=&(v_pDriverGlobals->usbd);	

	DEBUGMSG( 1, (TEXT("Before Clear Global\r\n")));
    for(i=0;i<USBD_GLOBALS_BUF_SIZE;i++)
    {
        usbdShMem->usbdRxBuf[i]=0x0;
		//usbdShMem->usbdTxBuf[i]=0x0;
    }
	DEBUGMSG( 1, (TEXT("Before Setting Global\r\n")));
	usbdShMem->usbBaseAddress	= pHWHead->dwIOBase	;
	usbdShMem->usbIRQ			= pHWHead->dwIRQ	;
	usbdShMem->usbDMANum		= pHWHead->dwDMANum	;
    
	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)
{
	BOOL	Result;
	DWORD	PhysBase, VirtualBase;
	DWORD	Return;
	MES_DEVINFO	DevInfo;
	int		i;
	
	USBDMSG( 1, (TEXT("USBD:UsbdAllocateVm\r\n")) );

	//*************************************************************************
	// DMA Initialize 
	//*************************************************************************
//	DMA_GetDeviceInfo ( &DevInfo );
	PhysBase= 0xc0000000;
	USBDMSG( 1, (TEXT("DevInfo.pDevName : %s\r\n"), DevInfo.pDevName) );
    Result = KernelIoControl(IOCTL_CODE_GET_VIRTUAL_ADDR, 
                            &PhysBase, 4, 
                            &VirtualBase, 4,
                            &Return);
	if (Result==FALSE) USBDMSG(1, (TEXT("FALSE")));
	DMA_Initialize ( VirtualBase + 0x20000000 );

	//*************************************************************************
	// Interrupt Initialize
	//*************************************************************************
	
	// GPIO PAD Selection Register : USB PAD3 -> USB Device
	*(volatile short *)(0xb0001120) |= 0x2;
	
	USBDMSG( 1, (TEXT("USBD:VirtualBase:%08x\r\n"), VirtualBase) );

	return TRUE;
}



void UsbdDeallocateVm(void)
{
	USBDMSG( 1, (TEXT("USBD:UsbdDeallocateVm\r\n")) );
/*	
	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 UsbdInitDma(int DmaNum, int bufIndex,int bufOffset)
{
	TDMAC_ChannelData	ChData;
//	ULONG	realPhysicalAddr_UsbdRxBuf;


	USBDMSG( 1, (TEXT("UsbdInitDma .... \r\n")));

	// If DMA15 is Turned on, DMA15 should be tunred off.
	if ( DMA_IsRunChannel ( usbdShMem->usbDMANum ) )
	{
		USBDMSG( 1, (TEXT("[DMA15 is stopped]\r\n")));
		DMA_StopChannel ( usbdShMem->usbDMANum );
		while ( DMA_IsRunChannel ( usbdShMem->usbDMANum ) ) NULL;
		USBDMSG( 1, (TEXT("[DMA15 is stopped]\r\n")));
	}
	
	// DMA Set Channel	
	realPhysicalAddr_UsbdRxBuf = \
		(ULONG)&((DRIVER_GLOBALS *)DRIVER_GLOBALS_PHYSICAL_MEMORY_START)->usbd.usbdRxBuf \
		- VA_RAM_BASE;
//		- DMA_BUFFER_BASE + DMA_PHYSICAL_BASE;	
	USBDMSG( 1, (TEXT( "[USBD:RPA_URxBuf=%x]"),realPhysicalAddr_UsbdRxBuf) );
	DEBUGMSG(1, (TEXT( "%08x\r\n"), (ULONG)&((DRIVER_GLOBALS *)DRIVER_GLOBALS_PHYSICAL_MEMORY_START)->usbd.usbdRxBuf));
#if USB_DMAMODE
	DEBUGMSG(1, (TEXT( "DMA_BUFFER_BASE : %08x\r\n"), DMA_BUFFER_BASE));
	DEBUGMSG(1, (TEXT( "DMA_PHYSICAL_BASE : %08x\r\n"), DMA_PHYSICAL_BASE));
#endif
	if(bufIndex==0)
	{
		ChData.Target.dwAddr	= realPhysicalAddr_UsbdRxBuf + 0 + bufOffset;
	}
	else
	{
		ChData.Target.dwAddr	= realPhysicalAddr_UsbdRxBuf+(USBD_GLOBALS_BUF_SIZE/2)+bufOffset;
	}

	ChData.iChannel			= usbdShMem->usbDMANum;
	ChData.Source.dwType	= DMA_MEMTYPE_IO_BYTE;
	ChData.Source.iStep		= 0;
	ChData.Source.dwAddr	= 0xC0000000;						// Base Address of Peripheral
	ChData.Source.bFlyBy	= FALSE;
	ChData.Source.IOIndex	= DMA_PERIPHERAL_INDEX_USBD_EP4;
	ChData.Target.dwType	= DMA_MEMTYPE_MEM_WORD;
	ChData.Target.iStep		= 1;
	ChData.Target.bFlyBy	= FALSE;
	ChData.Target.IOIndex	= 0;
	ChData.dwDataSize 		= (U16)(USBD_GLOBALS_BUF_SIZE-bufOffset)-1;
	ChData.dwBurstType 		= DMA_BURSTTYPE_NOBURST;
	ChData.dwIntType 		= DMA_INTTYPE_END;
	
	DMA_SetChannel ( &ChData );
	DMA_ClrInterruptPend( usbdShMem->usbDMANum );

	DMA_RunChannel ( usbdShMem->usbDMANum );

	USBDMSG( 0, (TEXT("UsbdInitDma .... : DMA Run \r\n")));
}

⌨️ 快捷键说明

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