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

📄 sc2443pdd.cpp

📁 S3C2443 WINCE6.0 BSP
💻 CPP
📖 第 1 页 / 共 5 页
字号:


    // Create the interrupt event
    pContext->hevInterrupt = CreateEvent(0, FALSE, FALSE, NULL);
    if (pContext->hevInterrupt == NULL) {
        dwRet = GetLastError();
        RETAILMSG(DBG, (_T("%s Error creating  interrupt event. Error = %d\r\n"), 
            pszFname, dwRet));
        goto EXIT;
    }

    fIntInitialized = InterruptInitialize(pContext->dwSysIntr, 
        pContext->hevInterrupt, NULL, 0);
    if (fIntInitialized == FALSE) {
        dwRet = ERROR_GEN_FAILURE;
        RETAILMSG(DBG, (_T("%s  interrupt initialization failed\r\n"),
            pszFname));
        goto EXIT;
    }
    InterruptDone(pContext->dwSysIntr);

    pContext->fExitIST = FALSE;
    pContext->hIST = CreateThread(NULL, 0, ISTMain, pContext, 0, NULL);    
    if (pContext->hIST == NULL) {
        RETAILMSG(DBG, (_T("%s IST creation failed\r\n"), pszFname));
        dwRet = GetLastError();
        goto EXIT;
    }

    pContext->fRunning = TRUE;
    dwRet = ERROR_SUCCESS;

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

    FUNCTION_LEAVE_MSG();

    return dwRet;
}


// Stop the device.
DWORD
WINAPI
UfnPdd_Stop(
            PVOID pvPddContext
            )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

RETAILMSG(DBG, (_T("%s  UfnPdd_Stop\r\n"),
            pszFname));
            
    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
    ValidateContext(pContext);

    DEBUGCHK(pContext->fRunning);

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

    ResetDevice(pContext);

    pContext->fRunning = FALSE;

    DEBUGMSG(ZONE_FUNCTION, (_T("%s Device has been stopped\r\n"), 
        pszFname));

    FUNCTION_LEAVE_MSG();

    return ERROR_SUCCESS;
}


DWORD 
WINAPI 
UfnPdd_IsConfigurationSupportable(
    PVOID                       pvPddContext,
    UFN_BUS_SPEED               Speed,
    PUFN_CONFIGURATION          pConfiguration
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

	RETAILMSG(DBG, (_T("%s  UfnPdd_IsConfigurationSupportable\r\n"),
            pszFname));

    DEBUGCHK((Speed == BS_FULL_SPEED) | (Speed == BS_HIGH_SPEED));

    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
    ValidateContext(pContext);

    // This PDD does not have any special requirements that cannot be 
    // handled through IsEndpointSupportable.
    DWORD dwRet = ERROR_SUCCESS;

    FUNCTION_LEAVE_MSG();

    return dwRet;
}


// 
// Is this endpoint supportable.
DWORD
WINAPI
UfnPdd_IsEndpointSupportable(
    PVOID                       pvPddContext,
    DWORD                       dwEndpoint,
    UFN_BUS_SPEED               Speed,
    PUSB_ENDPOINT_DESCRIPTOR    pEndpointDesc,
    BYTE                        bConfigurationValue,
    BYTE                        bInterfaceNumber,
    BYTE                        bAlternateSetting
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

RETAILMSG(DBG, (_T("%s  UfnPdd_IsEndpointSupportable\r\n"),
            pszFname));

    DEBUGCHK(EP_VALID(dwEndpoint));
    DEBUGCHK((Speed == BS_FULL_SPEED) | (Speed == BS_HIGH_SPEED));

    DWORD dwRet = ERROR_SUCCESS;
    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
    ValidateContext(pContext);

    PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);

    // Special case for endpoint 0
    if (dwEndpoint == 0) {
        DEBUGCHK(pEndpointDesc->bmAttributes == USB_ENDPOINT_TYPE_CONTROL);
        
        // Endpoint 0 only supports 8 or 16 byte packet size
        if (pEndpointDesc->wMaxPacketSize < EP_0_PACKET_SIZE) {
            RETAILMSG(DBG, (_T("%s Endpoint 0 only supports %u byte packets\r\n"),
                pszFname, EP_0_PACKET_SIZE));
            dwRet = ERROR_INVALID_PARAMETER;
        }
        else{  
            // Larger than EP 0 Max Packet Size - reduce to Max
            pEndpointDesc->wMaxPacketSize = EP_0_PACKET_SIZE;
        }
    }
    else if (dwEndpoint < ENDPOINT_COUNT) {
        BYTE bTransferType = pEndpointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
        DEBUGCHK(bTransferType != USB_ENDPOINT_TYPE_CONTROL);

        // Validate and adjust packet size
        WORD wPacketSize = 
            (pEndpointDesc->wMaxPacketSize & USB_ENDPOINT_MAX_PACKET_SIZE_MASK);

        switch(bTransferType) {

        // Isoch not currently supported by Samsung HW
        case USB_ENDPOINT_TYPE_ISOCHRONOUS:
            RETAILMSG(DBG, (_T("%s Isochronous endpoints are not supported\r\n"),
                pszFname));
            dwRet = ERROR_INVALID_PARAMETER;
            break;

        case USB_ENDPOINT_TYPE_BULK:
        case USB_ENDPOINT_TYPE_INTERRUPT:
            // HW Can only Support 8, 16, 32, 64 byte packets
            if((wPacketSize >= 8) && (wPacketSize < 16)){
                wPacketSize = 8;
            }
            else if ((wPacketSize >= 16) && (wPacketSize < 32)){
                wPacketSize = 16;
            }
            else if((wPacketSize >= 32) && (wPacketSize < 64)){
                wPacketSize = 32;
            }
            else if ((wPacketSize >= 64) && (wPacketSize < 128)){
                wPacketSize = 64;
            }
            else if((wPacketSize >= 128) && (wPacketSize < 256)){
                wPacketSize = 128;
            }
            else if ((wPacketSize >= 256) && (wPacketSize < 512)){
                wPacketSize = 256;
            }
            else if (wPacketSize >= 512){
                wPacketSize = 512; 
            }
            else{ // wPacketSize < 8
                dwRet = ERROR_INVALID_PARAMETER;
            }
            break;

        default:
            dwRet = ERROR_INVALID_PARAMETER;
            break;
        }  
        
        // If Requested Size is larger than what is supported ... change it.
        // Note only try and change it if no errors so far... meaning Ep is
        // Supportable.
        if ( (wPacketSize != (pEndpointDesc->wMaxPacketSize & USB_ENDPOINT_MAX_PACKET_SIZE_MASK)) && 
             (dwRet == ERROR_SUCCESS) ) {
            pEndpointDesc->wMaxPacketSize &= ~USB_ENDPOINT_MAX_PACKET_SIZE_MASK;
            pEndpointDesc->wMaxPacketSize |= wPacketSize;
        }

    }

    FUNCTION_LEAVE_MSG();

    return dwRet;
}


// Clear an endpoint stall.
DWORD
WINAPI
UfnPdd_ClearEndpointStall(
                          PVOID pvPddContext,
                          DWORD dwEndpoint
                          )
{
    DWORD dwRet = ERROR_SUCCESS;

    SETFNAME();
    FUNCTION_ENTER_MSG();


    DEBUGCHK(EP_VALID(dwEndpoint));

    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
    ValidateContext(pContext);

    PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
    LOCK_ENDPOINT(peps);

 
    if (dwEndpoint == 0){
// Must Clear both Transmitted Stall and Stall Set
        SetClearReg(pContext, EP0SR, EP0SHT, SET);
        SetClearReg(pContext, EP0CR, EP0ESS, CLEAR);
   }
    else 
    { 
        // Must Clear both Send and Sent Stall
        SetClearIndexedReg(pContext, dwEndpoint, ECR, ESS, SET);
        SetClearIndexedReg(pContext, dwEndpoint, ECR, ESS, CLEAR);
        SetClearIndexedReg(pContext ,dwEndpoint, ESR, FSC, SET);
    }
    

	
    UNLOCK_ENDPOINT(peps);
    FUNCTION_LEAVE_MSG();

    return ERROR_SUCCESS;
}


// Initialize an endpoint.
DWORD
WINAPI
UfnPdd_InitEndpoint(
    PVOID                       pvPddContext,
    DWORD                       dwEndpoint,
    UFN_BUS_SPEED               Speed,
    PUSB_ENDPOINT_DESCRIPTOR    pEndpointDesc,
    PVOID                       pvReserved,
    BYTE                        bConfigurationValue,
    BYTE                        bInterfaceNumber,
    BYTE                        bAlternateSetting
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DEBUGCHK(EP_VALID(dwEndpoint));
    PREFAST_DEBUGCHK(pEndpointDesc);

	RETAILMSG(DBG, (_T("%s  UfnPdd_InitEndpoint\r\n"),
            pszFname));

#ifdef DEBUG
    {
        USB_ENDPOINT_DESCRIPTOR EndpointDesc;
        memcpy(&EndpointDesc, pEndpointDesc, sizeof(EndpointDesc));
        DEBUGCHK(UfnPdd_IsEndpointSupportable(pvPddContext, dwEndpoint, Speed,
            &EndpointDesc, bConfigurationValue, bInterfaceNumber, 
            bAlternateSetting) == ERROR_SUCCESS);
        DEBUGCHK(memcmp(&EndpointDesc, pEndpointDesc, sizeof(EndpointDesc)) == 0);
    }
#endif

    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
    ValidateContext(pContext);
    BYTE bEndpointAddress = 0;

    PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
    DEBUGCHK(!peps->fInitialized);

    InitializeCriticalSection(&peps->cs);

    WORD wMaxPacketSize = 
        pEndpointDesc->wMaxPacketSize & USB_ENDPOINT_MAX_PACKET_SIZE_MASK;
    DEBUGCHK(wMaxPacketSize);
    
    // If the target is endpoint 0, then only allow the function driver 
    // to register a notification function.
    if (dwEndpoint == 0) {
       peps->dwPacketSizeAssigned = wMaxPacketSize;
       // Interrupts for endpoint 0 are enabled in ISTMain
    }
    else if (dwEndpoint < ENDPOINT_COUNT) {
        // Setup Direction (mode_in bit) 
        bEndpointAddress = pEndpointDesc->bEndpointAddress;
        BOOL fModeOut = USB_ENDPOINT_DIRECTION_OUT(bEndpointAddress);
        if (fModeOut) {
            SetClearReg(pContext, EDR, (0x1 << dwEndpoint), CLEAR);
	     peps->dwDirectionAssigned = USB_OUT_TRANSFER;
		
	     WriteIndexedReg(pContext, dwEndpoint, ECR, 0x0080);
	     WORD bECR = ReadIndexedReg(pContext, dwEndpoint, ECR);
		
        }
        else {
            SetClearReg(pContext, EDR, (0x1 << dwEndpoint), SET);
            peps->dwDirectionAssigned = USB_IN_TRANSFER;
	     WriteIndexedReg(pContext, dwEndpoint, ECR, 0x0000);
        }
        
        // Clear all Status bits and leave the Endpoint interrupt disabled
        // Clear Fifos, and all register bits
        ResetEndpoint(pContext,peps);

        // Set Transfer Type
        BYTE bTransferType = pEndpointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
        DEBUGCHK(bTransferType != USB_ENDPOINT_TYPE_CONTROL);
        switch(bTransferType) {
            case USB_ENDPOINT_TYPE_ISOCHRONOUS:
                // Set the ISO bit
                SetClearIndexedReg(pContext, dwEndpoint,ECR, 
                    IME, SET);
                break;

            case USB_ENDPOINT_TYPE_BULK:
            case USB_ENDPOINT_TYPE_INTERRUPT:
            default:
                // Clear ISO bit - Set type to Bulk
                SetClearIndexedReg(pContext, dwEndpoint,ECR, 
                    IME, CLEAR);
        }

        peps->dwEndpointType = bTransferType;
        peps->dwPacketSizeAssigned = wMaxPacketSize;
        
        // Set the Max Packet Register
        WriteIndexedReg(pContext, dwEndpoint, MPR, wMaxPacketSize); 

        UfnPdd_ClearEndpointStall(pvPddContext,dwEndpoint);

        // Clear outstanding interrupts
        ClearEndpointInterrupt(pContext, dwEndpoint);

    }
	
    peps->fInitialized = TRUE;
    FUNCTION_LEAVE_MSG();

    return ERROR_SUCCESS;
}


// Deinitialize an endpoint.
DWORD
WINAPI
UfnPdd_DeinitEndpoint(
                      PVOID pvPddContext,
                      DWORD dwEndpoint
                      )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DEBUGCHK(EP_VALID(dwEndpoint));

	RETAILMSG(DBG, (_T("%s  UfnPdd_DeinitEndpoint\r\n"),
            pszFname));

    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
    ValidateContext(pContext);

    PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
    LOCK_ENDPOINT(peps);

    DEBUGCHK(peps->fInitialized);
    DEBUGCHK(peps->pTransfer == NULL);

    // Reset and disable the endpoint 
    // Mask endpoint interrupts    
    ResetEndpoint(pContext, peps);

    // Clear endpoint interrupts
    ClearEndpointInterrupt(pContext, dwEndpoint);


    peps->fInitialized = FALSE;
    UNLOCK_ENDPOINT(peps);

    DeleteCriticalSection(&peps->cs);

    FUNCTION_LEAVE_MSG();

    return ERROR_SUCCESS;
}

DWORD
WINAPI
UfnPdd_StallEndpoint(
                     PVOID pvPddContext,
                     DWORD dwEndpoint
                     )
{
    DWORD dwRet = ERROR_SUCCESS;
    WORD bEP0CR, bECR;
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DEBUGCHK(EP_VALID(dwEndpoint));

  
    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
    ValidateContext(pContext);


    PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
    DEBUGCHK(peps->fInitialized);
    LOCK_ENDPOINT(peps);

    if (dwEndpoint == 0) {
        // Must Clear Out Packet Ready when sending Stall
        DEBUGMSG(ZONE_SEND, (_T("%s Writing 0x%02x to EP0_CSR_REG\r\n"), pszFname,
		bEp0StallBits));

	 SetClearIndexedReg(pContext, dwEndpoint, EP0CR, EP0ESS, SET);
		 
        

⌨️ 快捷键说明

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