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

📄 hwctxt.cpp

📁 S3C2440 base Wince USB_gadget driver
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	RETAILMSG(MDSMSG, (TEXT("UDGContext::StartInterruptThread()\r\n")));
	DWORD dwRet;
	BOOL fIntInitialized = FALSE;
	PCTRLR_CONTEXT pContext = (PCTRLR_CONTEXT)pvContext;

	//
    // Create the interrupt event
    //
	pContext->hevInterrupt = CreateEvent(0, FALSE, FALSE, NULL);	//reset=auto, bInitialState=non-signaled
    if (pContext->hevInterrupt == NULL) {
        dwRet = GetLastError();
		RETAILMSG(MDSMSG, (TEXT("UDGContext::StartInterruptThread() - Error creating interrupt event. Error = %d\r\n"), dwRet));
		goto EXIT;
    }
		
    fIntInitialized = InterruptInitialize(pContext->dwSysIntr, pContext->hevInterrupt, NULL, 0);
    if (fIntInitialized == FALSE) {
        dwRet = ERROR_GEN_FAILURE;
		RETAILMSG(MDSMSG, (TEXT("UDGContext::StartInterruptThread() - interrupt initialization failed\r\n")));
        goto EXIT;
    }

	InterruptDone(pContext->dwSysIntr);
	pContext->fExitIST = FALSE;
 
	//
	// Create the read pending release event
	//
	pContext->hevReadPending = CreateEvent(0, TRUE, FALSE, NULL);	//reset=manual, bInitialState=non-signaled
    if (pContext->hevReadPending == NULL) {
        dwRet = GetLastError();
		RETAILMSG(MDSMSG, (TEXT("UDGContext::StartInterruptThread() - Error creating read pending event. Error = %d\r\n"), dwRet));
		goto EXIT;
    }

	pContext->hIST = CreateThread((LPSECURITY_ATTRIBUTES) NULL,
						0,
						(LPTHREAD_START_ROUTINE) CallISTMain, 
						this,
						0,
						NULL); 
	
	if (pContext->hIST == NULL) {
		RETAILMSG(MDSMSG, (TEXT("UDGContext::StartInterruptThread() - IST creation failed\r\n")));
		dwRet = GetLastError();
		goto EXIT;
	}
	pContext->fRunning = TRUE;
    dwRet = ERROR_SUCCESS;

	CeSetThreadPriority(pContext->hIST, pContext->dwISTPriority);

EXIT:
    if (pContext->fRunning == FALSE) {
        if (fIntInitialized) InterruptDisable(pContext->dwSysIntr);
        if (pContext->hevInterrupt) CloseHandle(pContext->hevInterrupt);
		if (pContext->hevReadPending) CloseHandle(pContext->hevReadPending);
		pContext->hevInterrupt = NULL;
		pContext->hevReadPending=NULL;
    }
    return dwRet;
}

DWORD
UDGContext::StopInterruptThread(PVOID pvContext)
{
	RETAILMSG(MDSMSG, (TEXT("UDGContext::StopInterruptThread()\r\n")));

	PCTRLR_CONTEXT pContext = (PCTRLR_CONTEXT)pvContext;
   
	//
    // Stop the IST
    //
	pContext->fExitIST = TRUE;
    InterruptDisable(pContext->dwSysIntr);
    SetEvent(pContext->hevInterrupt);
    WaitForSingleObject(pContext->hIST, INFINITE);
    CloseHandle(pContext->hevInterrupt);
	CloseHandle(pContext->hevReadPending);
    CloseHandle(pContext->hIST);
    pContext->hIST = NULL;
    pContext->hevInterrupt = NULL;
	pContext->hevReadPending = NULL;

    ResetDevice();
    pContext->fRunning = FALSE;

    RETAILMSG(MDSMSG, (TEXT("UDGContext::StopInterruptThread() - interrupt thread stop\r\n")));

    return ERROR_SUCCESS;
}

//
// interrupt service routine.
//
DWORD  WINAPI
CallISTMain(PVOID pvContext)
{
	RETAILMSG(MDSMSG, (TEXT("CallISTMain()\r\n")));

	UDGContext *pUDGContext = (UDGContext *)pvContext;
	pUDGContext->ISTMain(pUDGContext->m_pHWContext);

	return (TRUE);
}

DWORD 
UDGContext::ISTMain(PVOID pvContext)
{
	RETAILMSG(MDSMSG, (TEXT("UDGContext::ISTMain()\r\n")));

	PCTRLR_CONTEXT pContext = (PCTRLR_CONTEXT)pvContext;

	while (!pContext->fExitIST) 
	{
        pContext->fRestartIST = FALSE;

        // Enable Suspend Mode in the Power Register
        SetClearReg(PWR_REG_OFFSET, SUSPEND_MODE_ENABLE_CTRL, SET);

		// Disable All Endpoint interrupts
        WriteReg(EP_INT_EN_REG_OFFSET, 0); // Disable All

        // Enable Device interrupts
		WriteReg(USB_INT_EN_REG_OFFSET, (USB_RESET_INTR | USB_SUSPEND_INTR));

        // Enable Endpoint interrupt 0
        BYTE irqEnBit = EpToIrqStatBit(0);

        SetClearReg(EP_INT_EN_REG_OFFSET, irqEnBit, SET);
	
        while (TRUE) {

	RETAILMSG(MDSMSG, (_T("TEST33333\r\n")));


            DWORD dwWait = WaitForSingleObject(pContext->hevInterrupt, INFINITE);

RETAILMSG(MDSMSG, (_T("TEST4\r\n")));

            if (pContext->fExitIST || pContext->fRestartIST) {
	RETAILMSG(MDSMSG, (_T("TEST5\r\n")));
                break;
            }

            if (dwWait == WAIT_OBJECT_0) {
            //    HandleUSBEvent(pContext);			..read event flag 悸且巴...
			//  InterruptDone(m_dwSysInterrupt);

		/*		RETAILMSG(MDSMSG, (_T("TEST6\r\n")));

				  const DWORD dwSetupPacketSize = ReadIndexedReg(0, OUT_FIFO_CNT1_REG_OFFSET);

	  RETAILMSG(MDSMSG, (TEXT("UDGContext::ISTMain() - dwSetupPacketSize :0x%x\r\n"), dwSetupPacketSize));


				  if(dwSetupPacketSize >0)	{

					  RETAILMSG(MDSMSG, (_T("TEST7\r\n")));

					  SetEvent(pContext->hevReadPending);
				  }
		*/	}
            else {
                RETAILMSG(MDSMSG, (_T("UDGContext::ISTMain() - %s WaitForSingleObject failed. Exiting IST.\r\n")));
                break;
            }
		}

        // Disable Device  interrupts - write Zeros to Disable
        WriteReg(USB_INT_EN_REG_OFFSET, 0);

        // Disable endpoint interrupts - write Zeros to Disable
        WriteReg(EP_INT_EN_REG_OFFSET, 0);
        
        // Clear any outstanding device & endpoint interrupts
        // USB Device Interrupt Status - Write a '1' to Clear 
        WriteReg(USB_INT_REG_OFFSET, (USB_RESET_INTR | USB_RESUME_INTR | USB_SUSPEND_INTR));
        // End point Interrupt Status - Write a '1' to Clear
        WriteReg(EP_INT_REG_OFFSET, CLEAR_ALL_EP_INTRS);
    }
	return 0;
}


// Return the irq bit for this endpoint.
inline BYTE
UDGContext::EpToIrqStatBit(DWORD dwEndpoint)
{
    return (1 << (BYTE)dwEndpoint);
}


/*++
Enable the interrupt of an endpoint.

Arguments:		dwEndpoint - the target endpoint
Return Value:	None.
--*/
inline VOID
UDGContext::EnableEndpointInterrupt(DWORD dwEndpoint)
{    
	FUNCTION_ENTER_MSG(dwEndpoint);

    // End Point Zero is always enabled (after Run)
    if (dwEndpoint == 0) {
        FUNCTION_LEAVE_MSG(dwEndpoint);
        return;
    }

    // Enable the Endpoint Interrupt
    BYTE irqEnBit = EpToIrqStatBit(dwEndpoint);
    SetClearReg(EP_INT_EN_REG_OFFSET, irqEnBit, SET);

	FUNCTION_LEAVE_MSG(dwEndpoint);   
        
} // _EnableEpInterrupt


/*++
Disable the interrupt of an endpoint.

Arguments:		dwEndpoint - the target endpoint
Return Value:	None.
--*/
inline VOID
UDGContext::DisableEndpointInterrupt(DWORD dwEndpoint)
{    
//	FUNCTION_ENTER_MSG(dwEndpoint);

    // End Point Zero is always enabled (after Run)
    if (dwEndpoint == 0) {
        FUNCTION_LEAVE_MSG(dwEndpoint);
        return;
    }

    // Disable the Endpoint Interrupt
    BYTE irqEnBit = EpToIrqStatBit(dwEndpoint);
    SetClearReg(EP_INT_EN_REG_OFFSET, irqEnBit, CLEAR);

//	FUNCTION_LEAVE_MSG(dwEndpoint);
} // DisableEndpointInterrupt

/*++
Clear the interrupt status register index of an endpoint.

Arguments:		dwEndpoint - the target endpoint
Return Value:	None.
--*/
inline VOID
UDGContext::ClearEndpointInterrupt(DWORD dwEndpoint)
{    
    FUNCTION_ENTER_MSG(dwEndpoint);
  
    // Clear the Endpoint Interrupt
    BYTE bIntBit = EpToIrqStatBit(dwEndpoint);
    WriteReg(EP_INT_REG_OFFSET, bIntBit);

    FUNCTION_LEAVE_MSG(dwEndpoint);
} // _ClearInterrupt


// Reset an endpoint
inline VOID
UDGContext::ResetEndpoint(DWORD dwEndpointNumber)
{
    FUNCTION_ENTER_MSG(dwEndpointNumber);

    // Since Reset can be called before/after an Endpoint has been configured,
    // it is best to clear all IN and OUT bits associated with endpoint. 
    DWORD dwEndpoint = dwEndpointNumber;
	
    if(dwEndpoint == 0 ){
        // Clear all EP0 Status bits
        WriteIndexedReg(0, IN_CSR1_REG_OFFSET, (SERVICED_OUT_PKY_RDY | SERVICED_SETUP_END));
    }
    else if(dwEndpoint < ENDPOINT_COUNT)
	{
        // Clear the desired Endpoint - Clear both the In & Out Status bits
        BYTE bRegIn;
        BYTE bRegOut;
        if(m_fInitialized){
             // First Read the CSR2 Reg bit so that it can be restored
            bRegIn = ReadIndexedReg(dwEndpoint, IN_CSR2_REG_OFFSET);
            bRegOut = ReadIndexedReg(dwEndpoint, OUT_CSR2_REG_OFFSET);
        }
        // Clear the in register - Must set the Mode_in to IN
        WriteIndexedReg(dwEndpoint, IN_CSR2_REG_OFFSET,(SET_MODE_IN | IN_DMA_INT_DISABLE));
        WriteIndexedReg(dwEndpoint, IN_CSR1_REG_OFFSET, ( FLUSH_IN_FIFO | IN_CLR_DATA_TOGGLE));

        // Clear the Out register  - Must set the Mode_in to OUT
        //WriteIndexedReg(pContext, dwEndpoint, IN_CSR2_REG_OFFSET, (IN_DMA_INT_DISABLE)); // mode_in bit = OUT 
        WriteIndexedReg(dwEndpoint, OUT_CSR1_REG_OFFSET, (FLUSH_OUT_FIFO | OUT_CLR_DATA_TOGGLE));
        WriteIndexedReg(dwEndpoint,  OUT_CSR2_REG_OFFSET, OUT_DMA_INT_DISABLE);

        if(m_fInitialized){
            // Set the Mode_In, ISO and other Modality type bits back to the way it was - this allows 
            // ResetEndpoint to be called without having to re-init the endpoint.
            WriteIndexedReg(dwEndpoint, IN_CSR2_REG_OFFSET, bRegIn);
            WriteIndexedReg(dwEndpoint, OUT_CSR2_REG_OFFSET, bRegOut);
        }
    }
    else {
       FUNCTION_LEAVE_MSG(dwEndpointNumber);
    }
    
    // Clear any outstanding Interrupts
    // Note that Endpoint 0 WILL NOT BE DISABLED
     DisableEndpointInterrupt(dwEndpointNumber);

	 FUNCTION_LEAVE_MSG(dwEndpointNumber);
}


// Reset the device and EP0.
inline VOID
UDGContext::ResetDevice(VOID)
{
	// Disable Device  interrupts - write Zeros to Disable
    WriteReg(USB_INT_EN_REG_OFFSET, 0);

    // Disable endpoint interrupts - write Zeros to Disable
    WriteReg(EP_INT_EN_REG_OFFSET, 0);

    // Clear any outstanding device & endpoint interrupts
    // USB Device Interrupt Status - Write a '1' to Clear 
    WriteReg(USB_INT_REG_OFFSET, (USB_RESET_INTR | USB_RESUME_INTR | USB_SUSPEND_INTR));
    // End point Interrupt Status - Write a '1' to Clear
    WriteReg(EP_INT_REG_OFFSET, CLEAR_ALL_EP_INTRS);

    // Reset all endpoints -> ENDPOINT_COUNT == 5(HLP)
    for (DWORD dwEpIdx = 0; dwEpIdx < ENDPOINT_COUNT; ++dwEpIdx) {
        ResetEndpoint(dwEpIdx);
    }
}


// Write data to an endpoint.
DWORD 
UDGContext::WriteEndpoint(DWORD dwEndpoint,
					  LPVOID pBuffer, 
					  DWORD dwCount,
					  BOOL fEnableInterrupts)
{
	BOOL fCompleted = FALSE;
	DEBUGCHK(m_bInitialized);
	DWORD dwWritten=0, dwRetWritten=0;
	ULONG i=0;

	__try {
		volatile ULONG *pulFifoReg = GetDataRegister(dwEndpoint);
		SetClearIndexedReg(dwEndpoint, IN_CSR2_REG_OFFSET, SET_MODE_IN, SET);	//IN
		BYTE *pbuf = (BYTE *) pBuffer;
	
		RETAILMSG(MDSMSG, (_T("UDGContext::WriteEndpoint() - Endpoint Address: %x, dwCount: %d\r\n"),
			pulFifoReg, dwCount));

		for(i=0; i< (dwCount / FIFO_IN_PACKET_MAX_SIZE); i++)
		{
			RETAILMSG(MDSMSG, (_T("UDGContext::WriteEndpoint() - loop: %d\r\n"), i+1));

//			if(fEnableInterrupts) EnableEndpointInterrupt(dwEndpoint);

			// Write to the FIFO directly to send the bytes.
			for (dwWritten = 0; dwWritten <FIFO_IN_PACKET_MAX_SIZE; dwWritten++) {
				*pulFifoReg = (ULONG) *pbuf++;
			}
			
			dwRetWritten += dwWritten;

//			DisableEndpointInterrupt(dwEndpoint);
//			ClearEndpointInterrupt(dwEndpoint);

			SetClearIndexedReg(dwEndpoint, IN_CSR1_REG_OFFSET, IN_PACKET_READY, SET);
//			DisableEndpointInterrupt(dwEndpoint);
		}
	}
	__except(EXCEPTION_EXECUTE_HANDLER) {
		RETAILMSG(MDSMSG, (_T("UDGContext::WriteEndpoint() - EXCEPTION_EXECUTE_HANDLER\r\n")));
	}
	
	return dwRetWritten;
}


// Read data from an endpoint.
DWORD
UDGContext::ReadEndpoint(DWORD dwEndpoint,
					 LPVOID pBuffer, 
					 DWORD dwCount)
{
	BOOL fCompleted = FALSE;
	DWORD dwBytesRead=0, dwRetBytesRead=0;
	ULONG i=0; 

	__try {
		volatile ULONG *pulFifoReg = GetDataRegister(dwEndpoint);
		BYTE *pbuf = (BYTE *) pBuffer;
			
		RETAILMSG(MDSMSG, (_T("UDGContext::ReadEndpoint() - Endpoint Address: %x, dwCount: %d\r\n"),
			pulFifoReg, dwCount));

		for(i=0; i< (dwCount / FIFO_OUT_PACKET_MAX_SIZE); i++)
		{
//			RETAILMSG(MDSMSG, (_T("UDGContext::ReadEndpoint() - loop: %d\r\n"), i+1));

			// Read From the FIFO
			for(dwBytesRead = 0; dwBytesRead < FIFO_OUT_PACKET_MAX_SIZE; dwBytesRead++) {
				pbuf[dwBytesRead] = (UCHAR) *pulFifoReg;
			}

RETAILMSG(MDSMSG, (_T("UDGContext::ReadEndpoint() - %s \r\n"), pbuf));

			dwRetBytesRead += dwBytesRead;

			if(dwEndpoint != 0)	{
				//Clear Receive Packet Complete - Allow next packet to come in.  
				BYTE bEpIrqStat = ReadIndexedReg(dwEndpoint, OUT_CSR1_REG_OFFSET);

				if (bEpIrqStat & OUT_PACKET_READY) {
					SetClearIndexedReg( dwEndpoint, OUT_CSR1_REG_OFFSET, OUT_PACKET_READY, CLEAR);
				}
			}
		}
	}
	__except(EXCEPTION_EXECUTE_HANDLER) {
		RETAILMSG(MDSMSG, (_T("UDGContext::ReadEndpoint() - EXCEPTION_EXECUTE_HANDLER\r\n")));
	}
	
	return dwRetBytesRead;
}


DWORD
UDGContext::StartTransfer(PVOID pvContext,
						  LPVOID pBuffer, 
						  DWORD dwCount,
						  DWORD dwEndpoint)
{
	LOCK_ENDPOINT(dwEndpoint);
	DWORD dwRet=0;
  
	PCTRLR_CONTEXT pContext = (PCTRLR_CONTEXT)pvContext;

    if (IN_TRANSFER == dwEndpoint) {		//send
       	dwRet = WriteEndpoint(dwEndpoint, pBuffer, dwCount, FALSE);
    }

	else if (OUT_TRANSFER == dwEndpoint) {	//receive
	    // Set the Max Packet Size Register
		WriteIndexedReg(dwEndpoint, MAX_PKT_SIZE_REG_OFFSET, 4);//(FIFO_OUT_PACKET_MAX_SIZE >> 3));  //0x4(32byte)

		EnableEndpointInterrupt(dwEndpoint);
		
		/////////////
RETAILMSG(MDSMSG, (_T("TEST11111\r\n")));

		WaitForSingleObject(pContext->hevReadPending, INFINITE);

	///////
        
		// There may be a packet available.  If so process it...
		BYTE bEpIrqStat = ReadIndexedReg(dwEndpoint, OUT_CSR1_REG_OFFSET);
		if (bEpIrqStat & OUT_PACKET_READY) {
            dwRet = ReadEndpoint(dwEndpoint, pBuffer, dwCount);
        }

		/////////
		InterruptDone(pContext->dwSysIntr);	
		ResetEvent(pContext->hevReadPending);
		///////////
    }
	UNLOCK_ENDPOINT(dwEndpoint);

	return dwRet;
}

⌨️ 快捷键说明

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