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

📄 s3c6410otgdevice.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                        WriteEPSpecificReg(dwEndpoint, DOEPDMA, pContext->pPAddrEP[dwEndpoint][pContext->dwPipelinedStrIdx]);
                        WriteEPSpecificReg(dwEndpoint, DOEPTSIZ, pContext->dwPipelinedPktCnt<<PACKET_COUTNT_IDX | pContext->dwPipelinedXferSize);
                        WriteEPSpecificReg(dwEndpoint, DOEPCTL, EP_ENABLE | CLEAR_NAK | SET_TYPE_BULK | USB_ACT_EP | peps->dwPacketSizeAssigned);
                    }
                    
                    CompleteTransfer(pContext, peps, UFN_NO_ERROR);
                }
            }
            else
            {
                DWORD dwPktcnt, dwBytes;
                dwPktcnt = pTransfer->cbBuffer / peps->dwPacketSizeAssigned;
                dwBytes = pTransfer->cbBuffer % peps->dwPacketSizeAssigned;
                if (dwBytes) dwPktcnt++;        

                pContext->dwPipelinedXferSize = pTransfer->cbBuffer;
                EnableEndpointInterrupt(pContext, dwEndpoint, peps->dwDirectionAssigned);
                WriteEPSpecificReg(dwEndpoint, DOEPDMA, pContext->pPAddrEP[dwEndpoint][pContext->dwPipelinedStrIdx]);
                WriteEPSpecificReg(dwEndpoint, DOEPTSIZ, dwPktcnt<<PACKET_COUTNT_IDX | pTransfer->cbBuffer);
                WriteEPSpecificReg(dwEndpoint, DOEPCTL, EP_ENABLE | CLEAR_NAK | SET_TYPE_BULK | USB_ACT_EP | peps->dwPacketSizeAssigned);
            }
        }        
    }

    UNLOCK_ENDPOINT(peps);
    FUNCTION_LEAVE_MSG();
}


DWORD
WINAPI
UfnPdd_IssueTransfer(
    PVOID          pvPddContext,
    DWORD          dwEndpoint,
    PSTransfer     pTransfer
    )
{
    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->bInitialized);
    DEBUGCHK(pTransfer->cbTransferred == 0);

    DWORD dwRet = ERROR_SUCCESS;

    DEBUGCHK(peps->pTransfer == NULL);
    StartTransfer(pContext, peps, pTransfer);

    FUNCTION_LEAVE_MSG();

    return dwRet;
}


DWORD
WINAPI
UfnPdd_AbortTransfer(
    PVOID       pvPddContext,
    DWORD       dwEndpoint,
    PSTransfer    pTransfer
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    PREFAST_DEBUGCHK(pTransfer);
    DEBUGCHK(EP_VALID(dwEndpoint));

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

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

    ValidateTransferDirection(pContext, peps, pTransfer);

    DEBUGCHK(pTransfer == peps->pTransfer);
    CompleteTransfer(pContext, peps, UFN_CANCELED_ERROR);

    if (dwEndpoint == 0)
    {
        pContext->Ep0State = EP0_STATE_IDLE;
    }

    ResetEndpoint(pContext,peps);
    
    DisableEndpointInterrupt(pContext, 0, USB_IN_TRANSFER);
    DisableEndpointInterrupt(pContext, 0, USB_OUT_TRANSFER);
    
    UNLOCK_ENDPOINT(peps);

    FUNCTION_LEAVE_MSG();

    return ERROR_SUCCESS;
}


BOOL 
SetOtgDevicePower (
    PCTRLR_PDD_CONTEXT         pContext,
    CEDEVICE_POWER_STATE    cpsNew
    )
{
    if (cpsNew == D0)
    {
        RETAILMSG(UFN_ZONE_POWER,(_T("[UFNPDD] USB_POWER : D0\r\n")));
        InterruptDone(pContext->dwSysIntr);

        pContext->pSYSCONregs->HCLK_GATE |= OTG_HCLK_EN;     //OTG HClk enable
            SetAllOutEpNak();
        ClearSoftDisconnect();
        ResetDevice(pContext);        
            ClearAllOutEpNak();      

        pContext->IsFirstReset = TRUE;
        DWORD dwGOTGCTL = ReadReg(GOTGCTL);
        if(!(dwGOTGCTL & (B_SESSION_VALID)))
        {
            Delay(100);      //for OTG cable detahced state.
        }
    }

    else if (cpsNew == D4)
    {
        RETAILMSG(UFN_ZONE_POWER,(_T("[UFNPDD] USB_POWER : D4\r\n")));
        SetSoftDisconnect();        
        
        pContext->pSYSCONregs->HCLK_GATE &= ~OTG_HCLK_EN;    //OTG HClk disable
    }
    return TRUE;
}


static
CEDEVICE_POWER_STATE
SetPowerState(
    PCTRLR_PDD_CONTEXT      pContext,
    CEDEVICE_POWER_STATE    cpsNew
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    
    PREFAST_DEBUGCHK(pContext);
    DEBUGCHK(VALID_DX(cpsNew));
    ValidateContext(pContext);

    // Adjust cpsNew.
    if (cpsNew != pContext->cpsCurrent)
    {
        if (cpsNew == D1 || cpsNew == D2)
        {
            // D1 and D2 are not supported.
            cpsNew = D0;
        }
        else if (pContext->cpsCurrent == D4)
        {
            // D4 can only go to D0.
            cpsNew = D0;
        }
    }

    if (cpsNew != pContext->cpsCurrent)
    {
        DEBUGMSG(UFN_ZONE_POWER, (_T("%s Going from D%u to D%u\r\n"), pszFname, pContext->cpsCurrent, cpsNew));

        if ( (cpsNew < pContext->cpsCurrent) && pContext->hBusAccess )
        {
            SetDevicePowerState(pContext->hBusAccess, cpsNew, NULL);
        }

        switch (cpsNew)
        {
            case D0:
                SetOtgDevicePower (pContext, D0);
                KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &pContext->dwSysIntr, sizeof(pContext->dwSysIntr), NULL, 0, NULL);

                if (pContext->fRunning)
                {
                    // Cause the IST to restart.
                    pContext->fRestartIST = TRUE;
                    SetInterruptEvent(pContext->dwSysIntr);
                }
            break;

            case D3:
                KernelIoControl(IOCTL_HAL_ENABLE_WAKE, &pContext->dwSysIntr, sizeof(pContext->dwSysIntr), NULL, 0, NULL);
            break;

            case D4:
                SetOtgDevicePower (pContext, D4);
                KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &pContext->dwSysIntr, sizeof(pContext->dwSysIntr), NULL, 0, NULL);
            break;
        }

        if ( (cpsNew > pContext->cpsCurrent) && pContext->hBusAccess )
        {
            SetDevicePowerState(pContext->hBusAccess, cpsNew, NULL);
        }
        pContext->cpsCurrent = cpsNew;
    }
    
    FUNCTION_LEAVE_MSG();

    return pContext->cpsCurrent;
}


static
VOID
FreeCtrlrContext(
    PCTRLR_PDD_CONTEXT    pContext
    )
{
    PREFAST_DEBUGCHK(pContext);
    DEBUGCHK(!pContext->hevInterrupt);
    DEBUGCHK(!pContext->hIST);
    DEBUGCHK(!pContext->fRunning);
    pContext->dwSig = GARBAGE_DWORD;

    UnmapRegisterSet(pContext);

    if (pContext->hBusAccess) CloseBusAccessHandle(pContext->hBusAccess);

    if (pContext->dwSysIntr)
    {
        KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &pContext->dwSysIntr, sizeof(pContext->dwSysIntr), NULL, 0, NULL);
    }

    if (pContext->dwIrq != IRQ_UNSPECIFIED)
    {
        KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &pContext->dwSysIntr, sizeof(DWORD), NULL, 0, NULL);
    }

    DeleteCriticalSection(&pContext->csRegisterAccess);
    LocalFree(pContext);
}


DWORD
WINAPI
UfnPdd_Deinit(
    PVOID    pvPddContext
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

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

    FUNCTION_ENTER_MSG();

    FreeCtrlrContext(pContext);

    FUNCTION_LEAVE_MSG();

    return ERROR_SUCCESS;
}


DWORD
WINAPI
UfnPdd_Start(
    PVOID    pvPddContext
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    UFN_CLIENT_INFO currentDriver; 
    DWORD dwRet;
    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
    ValidateContext(pContext);

    DEBUGCHK(!pContext->fRunning);

    BOOL fIntInitialized = FALSE;

    RETAILMSG(UFN_ZONE_INIT,(_T("[UFNPDD] USB DRIVER VERSION : %d\r\n"), USB_DD_VERSION));
    // Some application can change the usbfn client dirver dynamically.
    // In this case, below codes are needed.
    if (USBCurrentDriver((PUFN_CLIENT_INFO)&currentDriver)) 
    {
        if(!wcscmp(currentDriver.szName, TEXT("RNDIS")) ||!wcscmp(currentDriver.szName, TEXT("rndis")))
        {
            pContext->dwUSBClassInfo = USB_RNDIS;
            pContext->dwUsingEPCnt = 4;
            RETAILMSG(UFN_ZONE_INIT,(_T("[UFNPDD] USB RNDIS Function Class Enabled\r\n")));
        }
        else if(!wcscmp(currentDriver.szName, TEXT("Serial_Class")) ||!wcscmp(currentDriver.szName, TEXT("serial_class")))
        {
            pContext->dwUSBClassInfo = USB_SERIAL;
            pContext->dwUsingEPCnt = 3;
            RETAILMSG(UFN_ZONE_INIT,(_T("[UFNPDD] USB Serial Function Class Enabled\r\n")));
        }
        else if(!wcscmp(currentDriver.szName, TEXT("Mass_Storage_Class")) ||!wcscmp(currentDriver.szName, TEXT("mass_storage_class")))
        {
            pContext->dwUSBClassInfo = USB_MSF;
            pContext->dwUsingEPCnt = 3;
            RETAILMSG(UFN_ZONE_INIT,(_T("[UFNPDD] USB Mass Storage Function Class Enabled\r\n")));
        }
    } 
    else 
    {
        RETAILMSG(UFN_ZONE_ERROR,(_T("[UFNPDD] USB Function Class Read Error!!!!!!!\r\n")));
    }

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

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

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

        InitPDDContext(pContext);
        if(pContext->bMemoryAllocFlag == FALSE)
        {
            for(DWORD i=0; i<pContext->dwUsingEPCnt; i++)
            {
                for(DWORD j=0; j<PIPELINED_FIFO_DEPTH; j++)
                {
                    pContext->pVAddrEP[i][j] = (PDWORD)AllocPhysMem(pContext->dwPipelinedXferSize, PAGE_READWRITE, 0, 0, &pContext->pPAddrEP[i][j]);
                    memset(pContext->pVAddrEP[i][j], 0, pContext->dwPipelinedXferSize);
                    pContext->dwPipelinedXfered[i][j] = 0;
                }
            }
            pContext->bMemoryAllocFlag  = TRUE;
        }
        
        pContext->fRunning = TRUE;
        dwRet = ERROR_SUCCESS;
    }while(FALSE);
    
    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();

    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;

    WriteReg(DAINTMSK,0);                // IN, OUT EP ALL MASK

    WriteReg(DOEPMSK, 0);                // DOEP INT MASK
    WriteReg(DIEPMSK, 0);                // DIEP INT MASK

    WriteReg(GINTMSK, 0);                // GINT MASK
    WriteReg(GAHBCFG, 0);                // GLOBAL INT MASK

    WriteReg(GOTGINT, 0xE0304);            // OTG INT All CLEAR
    WriteReg(GINTSTS, INT_RESUME | INT_EPMIS | INT_SDE | INT_RESET | INT_SUSPEND); // GINT Clear

    for (DWORD dwEpIdx = 0; dwEpIdx < ENDPOINT_COUNT; ++dwEpIdx) 
    {
        EP_STATUS *peps = GetEpStatus(pContext, dwEpIdx);
        ResetEndpoint(pContext, peps);
    }

    if(pContext->bMemoryAllocFlag == TRUE)
    {
        for(DWORD i=0; i<pContext->dwUsingEPCnt; i++)
        {
            for(DWORD j=0; j<PIPELINE

⌨️ 快捷键说明

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