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

📄 sc2410_usb_hw.c

📁 wince4.2 USB function driver for magic eye mmsp2 platform
💻 C
📖 第 1 页 / 共 4 页
字号:
			break;
	
		case SET_FEATURE:
			DEBUGMSG(1, (TEXT("SET_FEATURE %d\r\n"), pHWHead->dReq.bmRequest));
	
			if (pHWHead->dReq.bmRequest == 0x02) {
				switch (pHWHead->dReq.wIndex & 15) {
				// Control endpoint. Not suggested.
				case 0:
					break;
	
				/* OUT endpoint. Set sendstall to force stall condition
				*/
				case 1:
					UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0x4); 
					UDC_REG_BITSET(struct OCSR1Bits,
						&pHWHead->pUSBCtrlAddr->OCSR1, send_stall, 1); // STALL
					break;
	
				/* IN endpoint. Set sendstall to force stall condition
				*/
				case 2:
				//case 3:
				case 4:
					UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0x1); 
					UDC_REG_BITSET(struct EP0ICSR1Bits, 
						&pHWHead->pUSBCtrlAddr->EP0ICSR1, se_sds, 1); // STALL
					break;
				}
				UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0);
			}
	
			// Command is complete
			sendDone(pHWHead,0);
			//RETAILMSG(1, (TEXT("SF[0x%X]\r\n"), pHWHead->dReq.wIndex & 0xFF));
			break;
	
		case SET_ADDRESS:
			DEBUGMSG(1, (TEXT("SET_ADDRESS - 0x%X\r\n"), pHWHead->dReq.wValue));
			
			pHWHead->dAddress = (BYTE)pHWHead->dReq.wValue;
	
			// Note, this write needs to be started here but it will not read back
			// until the command completes. There is no retry mechanism.
			setAddress(pHWHead, pHWHead->dAddress);
	
			// Command is complete
			sendDone(pHWHead,0);
			break;
	
		case GET_DESCRIPTOR:
			switch ((BYTE)(pHWHead->dReq.wValue>>8)) {
			case DEVICE:	// 0x01
				DEBUGMSG(1, (TEXT("GET_DESCRIPTOR:DEVICE 0x%X, 0x%X\r\n"), 
						uStd[0], pHWHead->dReq.wLength));
				//sendCommandDone(pHWHead);
				p = (PUCHAR)uStd;
				len = (BYTE)min(uStd[0],pHWHead->dReq.wLength);
				totLen = uStd[0];
				break;
	
			case CONFIGURATION:	// 0x02
				DEBUGMSG(1,(TEXT("GET_DESCRIPTOR:CONFIGURATION\r\n")));
				//sendCommandDone(pHWHead);
				p = (PUCHAR)&uStd[iCONF];
				len = (BYTE)min(CFGLEN,pHWHead->dReq.wLength);
				totLen = CFGLEN;
				break;
	
			case STRING:	// 0x03
				DEBUGMSG(1,(TEXT("GET_DESCRIPTOR:STRING\r\n")));
				//sendCommandDone(pHWHead);
				p = NULL;
				len = 0;
				totLen = 0;
				break;
	
			default:
				DEBUGMSG(1,(TEXT("GET_DESCRIPTOR:Unknown %d\r\n"),
					(pHWHead->dReq.wValue>>8) ));
				sendCommandDone(pHWHead);
				p = NULL;
				len = 0;
				totLen = 0;
				break;		
	
			}
	
			// Clear the OPR bit and start the data phase
			sendCommandDone(pHWHead);
	
			// Send the reply data.
			sendData(pHWHead, p, len, totLen);
			DEBUGMSG(1,(TEXT("GET_DESCRIPTOR:EP0ICSR1 status value = 0x%x\r\n"), pHWHead->pUSBCtrlAddr->EP0ICSR1));
			break;
	
		case GET_CONFIG:
			DEBUGMSG(1, (TEXT("GET_CONFIG\r\n")));
	
			// Clear the OPR bit and start the data phase
			sendCommandDone(pHWHead);
	
			// Send the reply data.
			sendData(pHWHead, &pHWHead->dConfIdx, 1, 1);
			break;
	
		case GET_INTERFACE:
			DEBUGMSG(1,(TEXT("GET_INTERFACE\r\n")));
	
			// Clear the OPR bit and start the data phase
			sendCommandDone(pHWHead);
	
			// Send the reply data.
			sendData(pHWHead, &pHWHead->dInterface, 1, 1);
			break; 
	
		case SET_CONFIG:
			DEBUGMSG(1,(TEXT("SET_CONFIG %d\r\n"),
				pHWHead->dReq.wValue));
			pHWHead->dConfIdx = (BYTE)pHWHead->dReq.wValue;
	
			// Command done
			sendDone(pHWHead,0);
			break;
	
		case SET_DESCRIPTOR:
			DEBUGMSG(1, (TEXT("SET_DESCRIPTOR\r\n")));
	
			// Command done
			sendDone(pHWHead,0);
			break;
	
		case SET_INTERFACE:
			DEBUGMSG(1,(TEXT("SET_INTERFACE : %d,%d\r\n"),
				pHWHead->dReq.wIndex,
				pHWHead->dReq.wValue));
			pHWHead->dInterface = (BYTE)pHWHead->dReq.wIndex;
			pHWHead->dSetting = (BYTE)pHWHead->dReq.wValue;
	
			// Command done
			sendDone(pHWHead,0);
			break;
	
		default:
			DEBUGMSG(1,(TEXT("Unhandled Command : %d\r\n"),
				pHWHead->dReq.bRequest));
	
			// Command done
			sendDone(pHWHead,0);
			break;
		}
	}
	
	DEBUGMSG(1, (TEXT("--SC2400_USB_DoEndpoint0\r\n")));
}

/*************************************************************************
	SC2400_USB_GetInterruptType

	Determine the source of an interrupt and return flags to control 
	which function gets called to handle it. EP0 is handled as modem 
	interrupt, EP1 as TX, EP3 as RX and reset is handle as line 
	interrupt.
*************************************************************************/

INTERRUPT_TYPE SC2400_USB_GetInterruptType( PSER_INFO pHWHead) //:-)
{
	INTERRUPT_TYPE interruptFlags = 0;
	//BYTE saveIndex;

    pHWHead->wPrevSOF = pHWHead->wSOF;
    pHWHead->wSOF = (pHWHead->pUSBCtrlAddr->FNR2.fr_n2 << 8) | pHWHead->pUSBCtrlAddr->FNR1.fr_n1; 
	DEBUGMSG(1, (TEXT("SOF: %u, wPrevSOF: %u\r\n"), pHWHead->wSOF, pHWHead->wPrevSOF));
	//RETAILMSG(1, (TEXT("SOF: %u, wPrevSOF: %u\r\n"), pHWHead->wSOF, pHWHead->wPrevSOF));

	//important notes
	// 1. INDEX register should be preserved here. //:-)
	// 2. 'else if' should not be used here. //:-) 

	if (usbdShMem->usbdEir& USBDEIR_EP1)	// EP1(IN), ready to TX more data.
	{
		interruptFlags |= INTR_TX;
		USBDMSG(1, (TEXT("<EP1INT>\r\n")));
	}
 	if (usbdShMem->usbdEir& USBDEIR_EP4) // EP4(OUT), RX data ready
	{
		interruptFlags |= INTR_RX;
		USBDMSG(1, (TEXT("<EP4INT>\r\n")));
	}

	if (usbdShMem->usbdDma3Int)	// DMA3 done interrupt
	{
		interruptFlags |= INTR_RX;
		USBDMSG(1, (TEXT("<DMAInt>\r\n")));
	}

	if (usbdShMem->usbdUir& USBDUIR_RESET)// USB reset, so re-initialize our driver.
	{
		USBDMSG(1, (TEXT("RESET INT\r\n")));
		interruptFlags |= INTR_LINE;	// We use INTR_LINE to handle USB Reset 
		usbdShMem->usbdUir&=~USBDUIR_RESET;
	}	
	
	//usbdShMem->usbdUir&=~USBDUIR_RESET;
	
	if (usbdShMem->usbdEir&USBDEIR_EP0) // EP0, Control endpoint
	{
		interruptFlags |= INTR_MODEM;	// Use INTR_MODEM for EP0 interrupts
										// call SerModemIntr function	 by shim 020503
		usbdShMem->usbdEir&=~USBDEIR_EP0;
		*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=0x0;  
			//temp_kiw, should be repaired officially.
		USBDMSG(1, (TEXT("<EP0 Int>\r\n")));	
	}

#if 0
	DEBUGMSG( 1, (TEXT(" pUSBCtrlAddr: %08x\r\n"), (ULONG)(pHWHead->pUSBCtrlAddr)) );

	DEBUGMSG (1, (TEXT("udcFAR	: %04x\r\n"), *(volatile short *)(&pHWHead->pUSBCtrlAddr->udcFAR)));
	DEBUGMSG (1, (TEXT("PMR		: %04x\r\n"), *(volatile short *)(&pHWHead->pUSBCtrlAddr->PMR	)));
	DEBUGMSG (1, (TEXT("EIR		: %04x\r\n"), *(volatile short *)(&pHWHead->pUSBCtrlAddr->EIR	)));
	DEBUGMSG (1, (TEXT("UIR		: %04x\r\n"), *(volatile short *)(&pHWHead->pUSBCtrlAddr->UIR	)));
	DEBUGMSG (1, (TEXT("EIER	: %04x\r\n"), *(volatile short *)(&pHWHead->pUSBCtrlAddr->EIER	)));
	DEBUGMSG (1, (TEXT("UIER	: %04x\r\n"), *(volatile short *)(&pHWHead->pUSBCtrlAddr->UIER	)));
	DEBUGMSG (1, (TEXT("FNR1	: %04x\r\n"), *(volatile short *)(&pHWHead->pUSBCtrlAddr->FNR1	)));
	DEBUGMSG (1, (TEXT("FNR2	: %04x\r\n"), *(volatile short *)(&pHWHead->pUSBCtrlAddr->FNR2	)));

	pHWHead->pUSBCtrlAddr->INDEX.index = 0x1;	
	DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->INDEX   : %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->INDEX   )) );
    DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->MAXP   : %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->MAXP   )) );
    DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->EP0ICSR1: %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->EP0ICSR1)) );
    DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->ICSR2   : %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->ICSR2   )) );
	DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->OCSR2   : %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->OCSR2   )) );
	pHWHead->pUSBCtrlAddr->INDEX.index = 0x2;	
	DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->INDEX   : %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->INDEX   )) );
    DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->MAXP   : %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->MAXP   )) );
    DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->EP0ICSR1: %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->EP0ICSR1)) );
    DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->ICSR2   : %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->ICSR2   )) );
	DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->OCSR2   : %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->OCSR2   )) );
	pHWHead->pUSBCtrlAddr->INDEX.index = 0x3;	
	DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->INDEX   : %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->INDEX   )) );
    DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->MAXP   : %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->MAXP   )) );
    DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->EP0ICSR1: %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->EP0ICSR1)) );
    DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->ICSR2   : %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->ICSR2   )) );
	DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->OCSR2   : %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->OCSR2   )) );
	pHWHead->pUSBCtrlAddr->INDEX.index = 0x4;	
	DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->INDEX   : %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->INDEX   )) );
    DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->MAXP   : %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->MAXP   )) );
    DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->EP0ICSR1: %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->EP0ICSR1)) );
    DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->ICSR2   : %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->ICSR2   )) );
	DEBUGMSG(1, (TEXT("pHWHead->pUSBCtrlAddr->OCSR2   : %08x\r\n"), (U32)*(volatile unsigned short*)(&pHWHead->pUSBCtrlAddr->OCSR2   )) );

#endif
	pHWHead->pUSBCtrlAddr->INDEX.index = 0;

	return (interruptFlags);
}

/*************************************************************************
	SC2400_USB_LineIntHandler

	This handler is called for reset interrupts
*************************************************************************/
void SC2400_USB_LineIntHandler(PSER_INFO pHWHead)
{
//	DEBUGMSG(1, (TEXT("++SC2400_USB_LineIntHandler\r\n")));

	SC2400_USB_Init(pHWHead);
	UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0);

//	DEBUGMSG(1, (TEXT("--SC2400_USB_LineIntHandler\r\n")));
}

/*************************************************************************
  SC2400_USB_RxIntHandler
 
  Read characters up to the max packet length from the IN FIFO. Return the
  number of characters read in the supplied argument. The function returns
  a boolean indicating whether event characters are present.
*************************************************************************/


BOOL SC2400_USB_RxIntHandler(PSER_INFO pHWHead,
			     PUCHAR pRxBuffer,
			     ULONG *pBuffLen)
{
	BOOL fRXFlag	   = FALSE;
	UCHAR cEvtChar	   = pHWHead->dcb.EvtChar;
	int buflen		   = *pBuffLen;
	register UCHAR cRxChar;
	ULONG usbdRxRdPt=0;
	ULONG usbdRxWrPt=0;	
#if USB_DMAMODE
	ULONG usbdRxCnt;
#endif	
	BYTE* usbdRxBuf;
	ULONG cnt,saveCnt;
	int   swRdCnt=0;
	BYTE saveIndex;
	DEBUGMSG(1, (TEXT("++SC2400_USB_RxIntHandler\r\n")));
    
	usbdRxRdPt=usbdShMem->usbdRxRdPt;
	usbdRxBuf=(BYTE*)usbdShMem->usbdRxBuf;
	*pBuffLen = 0;
    
	// Endpoint 4 mode
	saveIndex=*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX;
	*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=0x4;
	

#if USB_DMAMODE
	if (usbdShMem->usbdDma3Int)
	{

		USBDMSG(1,(TEXT("[RxPt:%d]"),usbdRxRdPt));	
		if(usbdRxRdPt==0)
		{
//			DMA_ClrInterruptPend( pHWHead->dwDMANum );

			usbdShMem->usbdDma3Int=0;	
			
			USBDMSG(1,(TEXT("[D:%d"),pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_low));	
			cnt=swRdCnt=pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_low;
			
			for(cnt=0; cnt < swRdCnt; cnt++)
			{
				usbdRxBuf[cnt]=(UCHAR)pHWHead->pUSBCtrlAddr->EP4F.fifo_data;
			}
			if(pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_low==0 && 
			   pHWHead->pUSBCtrlAddr->OCSR1.out_pkt_rdy==1)
			{
				USBDMSG(1, (TEXT(",OPR CLR,")));
				UDC_REG_BITSET(struct OCSR1Bits,&pHWHead->pUSBCtrlAddr->OCSR1, out_pkt_rdy, 0);
			}

			UsbdInitDma(pHWHead->dwDMANum, 0,swRdCnt); 
			*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DTL=(USBD_GLOBALS_BUF_SIZE-swRdCnt)&0xff;
			*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DTM=((USBD_GLOBALS_BUF_SIZE-swRdCnt)>>8)&0xff;
			*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DTH=((USBD_GLOBALS_BUF_SIZE-swRdCnt)>>16)&0x0f;
			*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DC=UDMA_OUT_DMA_RUN|UDMA_DMA_MODE_EN;
		}

	}
	
	{
		ULONG	DMATargetAddr = DMA_GetTrgAddr(pHWHead->dwDMANum);
		
		usbdRxWrPt= DMATargetAddr - realPhysicalAddr_UsbdRxBuf;
		if(usbdRxWrPt==USBD_GLOBALS_BUF_SIZE)
		{
			usbdRxWrPt=swRdCnt;
			//usbdRxWrPt=0;
		}
		
		if(usbdRxRdPt<=usbdRxWrPt)
			usbdRxCnt=usbdRxWrPt-usbdRxRdPt;
		else
			usbdRxCnt=USBD_GLOBALS_BUF_SIZE-usbdRxRdPt+usbdRxWrPt;	
	
		if( buflen > usbdRxCnt)
			saveCnt=cnt=usbdRxCnt;
		else
			saveCnt=cnt=buflen;
	
		DEBUGMSG(1, (TEXT("DMA Target Addr : %08x\r\n"), DMATargetAddr));
		DEBUGMSG(1, (TEXT("Physical Addr of UsbRxBuf : %08x\r\n"), realPhysicalAddr_UsbdRxBuf));
		DEBUGMSG(1, (TEXT("usbRxWrPt       : %08x\r\n"), usbdRxWrPt));
		DEBUGMSG(1, (TEXT("usbRxRdPt       : %08x\r\n"), usbdRxRdPt));
		DEBUGMSG(1, (TEXT("buflen          : %08x\r\n"), buflen));
		DEBUGMSG(1, (TEXT("usbRxCnt        : %08x\r\n"), usbdRxCnt));
	}
	
	if (usbdRxCnt == 0) // No data to read
	{ 
		USBDMSG(1, (TEXT("[R0]")));
	}	 
	else
	{

		USBDMSG(1, (TEXT("Copying <%d>"),cnt));

		while(cnt--) 
		{
			*pRxBuffer++ = cRxChar = (UCHAR)usbdRxBuf[usbdRxRdPt++];
			RETAILMSG(1, (TEXT("[RX]:%02x, %c\r\n"), cRxChar, cRxChar ));
			if(usbdRxRdPt==USBD_GLOBALS_BUF_SIZE)
				usbdRxRdPt=0;
			if( cRxChar == cEvtChar )
				fRXFlag = TRUE;
		}

		(*pBuffLen)=saveCnt;
		usbdRxCnt-=saveCnt;

		usbdShMem->usbdRxRdPt=usbdRxRdPt;
		usbdShMem->usbdEir&=~USBDEIR_EP4;
		
		USBDMSG(1, (TEXT("usbdShMem->usbdEir:%08x\r\n"), usbdShMem->usbdEir));
	}

    //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 we didn't read the whole buffer we need to come back. Leave with
	// the interrupt still enabled so the MDD will recall.
	if (usbdRxCnt>0)
	{
		USBDMSG(1, (TEXT("[%d->MDD]"),usbdRxCnt));
		usbdShMem->usbdEir|=USBDEIR_EP4; 

⌨️ 快捷键说明

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