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

📄 s3c6410otgdevice.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    FUNCTION_ENTER_MSG();
    ValidateContext(pContext);
#if TEST_MODE_SUPPORT
    volatile DWORD dwDCTL;
#endif

    DWORD dwGintsts = ReadReg(GINTSTS);
    DWORD dwDaint = ReadReg(DAINT);
    DWORD dwDaintMsk = ReadReg(DAINTMSK);

    if (dwGintsts & (INT_RESUME | INT_EPMIS | INT_SDE | INT_RESET | INT_SUSPEND | INT_OTG))
    {
        HandleUSBBusIrq(pContext, dwGintsts);
    }

    if (dwGintsts & INT_OUT_EP)
    {    
        if (dwDaint & EP0_OUT_INT)
        {            
            volatile DWORD dwDoepint0 = ReadReg(DOEPINT0);
            WriteReg(DOEPINT0, dwDoepint0);

            if (dwDoepint0 & XFER_COMPLETE)
            {
                HandleEndpoint0Event(pContext);
            }
            
            if (dwDoepint0 & SETUP_PHASE_DONE)
            {
                HandleEndpoint0Event(pContext);
            }
        }
        for(DWORD dwEndpoint = 1; dwEndpoint < ENDPOINT_COUNT; ++ dwEndpoint)
        {
            DWORD dwEpBit = EpToIrqStatBit(dwEndpoint) << ENDPOINT_COUNT;
            if (dwDaint & dwEpBit)
            {
                volatile DWORD dwDoepint = ReadEPSpecificReg(dwEndpoint, DOEPINT);
                WriteEPSpecificReg(dwEndpoint, DOEPINT, dwDoepint);

                if (dwDoepint & XFER_COMPLETE)
                {                
                    HandleOutEvent(pContext, dwEndpoint);
                }
            }
        }        
    }

    if (dwGintsts & INT_IN_EP)
    {            
        if (dwDaint & EP0_IN_INT)
        {
            volatile DWORD dwDiepint0 = ReadReg(DIEPINT0);
            WriteReg(DIEPINT0, dwDiepint0);

            if (dwDiepint0 & XFER_COMPLETE)
            {            
                HandleEndpoint0Event(pContext);
            }
            
            if (dwDiepint0 & TIMEOUT_CONDITION)
            {
                RETAILMSG(UFN_ZONE_WARNING,(_T("[UFNPDD] Time Out EP0\r\n")));
                SetClearReg(DCTL, CLEAR_GNPINNAK, SET);
            }
        }
        for(DWORD dwEndpoint = 1; dwEndpoint < ENDPOINT_COUNT; ++ dwEndpoint)
        {
            DWORD dwEpBit = EpToIrqStatBit(dwEndpoint);
            if ((dwDaint & dwEpBit) && (dwDaintMsk & (0x1<<dwEndpoint)))
            {
                volatile DWORD dwDiepint = ReadEPSpecificReg(dwEndpoint, DIEPINT);
                WriteEPSpecificReg(dwEndpoint, DIEPINT, dwDiepint);

                if (dwDiepint & IN_TKN_RECEIVED)
                {
                    HandleInEvent(pContext, dwEndpoint);
                }
                if (dwDiepint & XFER_COMPLETE)
                {
                    PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
                    LOCK_ENDPOINT(peps);
                    pContext->dwXmittingEP &= ~(1<<dwEndpoint);
                    peps->pTransfer->cbTransferred += peps->pTransfer->cbBuffer;
                    DisableEndpointInterrupt(pContext, peps->dwEndpointNumber, peps->dwDirectionAssigned);
                    CompleteTransfer(pContext, peps, UFN_NO_ERROR);
                    UNLOCK_ENDPOINT(peps);
                }
                if (dwDiepint & TIMEOUT_CONDITION)
                {
                    RETAILMSG(UFN_ZONE_WARNING,(_T("[UFNPDD] Time Out EP%d\r\n"),dwEndpoint));
                    RETAILMSG(UFN_ZONE_WARNING,(_T("[UFNPDD] Transmit Ready Count : %d\r\n"), pContext->dwXmitReadyCnt));
                    RETAILMSG(UFN_ZONE_WARNING,(_T("[UFNPDD] Transmitting EP 0x%x : %d\r\n"), dwEndpoint, pContext->dwXmittingEP));
                    for(DWORD dwEndpoint = 0; dwEndpoint < ENDPOINT_COUNT; ++dwEndpoint)
                    {
                        if(pContext->dwInEPRunning[dwEndpoint])
                        {
                            RETAILMSG(UFN_ZONE_WARNING,(_T("[UFNPDD]EP%d is running\r\n"),dwEndpoint));
                        }
                    }
                    
                    SetClearReg(DCTL, CLEAR_GNPINNAK, SET);
                }
            }
        }
    }

#if TEST_MODE_SUPPORT
    dwDCTL = ReadReg( DCTL);
    dwDCTL = dwDCTL & (TEST_MODE_MASK) | CLEAR_GOUTNAK;
    WriteReg(DCTL, dwDCTL);
#endif    
    SetClearReg(DCTL, CLEAR_GNPINNAK, SET);

    FUNCTION_LEAVE_MSG();
}

static
DWORD MapRegisterSet(
    PCTRLR_PDD_CONTEXT     pContext
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    
    ValidateContext(pContext);
    DEBUGCHK(g_pUDCBase == NULL);
    
    PBYTE  pVMem = NULL;
    DWORD dwRet = ERROR_SUCCESS;
    PHYSICAL_ADDRESS    ioPhysicalBase = {0,0};
    
    //System Controller registers allocation
    ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_SYSCON;
    pContext->pSYSCONregs = (volatile S3C6410_SYSCON_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_SYSCON_REG), FALSE);
    if (pContext->pSYSCONregs == NULL)
    {
        dwRet = GetLastError();
        RETAILMSG(UFN_ZONE_ERROR, (_T("%s MmMapIoSpace: FAILED\r\n"), pszFname));
        goto CleanUp;
    }

    // OTG LINK registers.
    ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_USBOTG_LINK;   
    pVMem = (PBYTE)MmMapIoSpace(ioPhysicalBase, OTG_LINK_REG_SIZE, FALSE);
    if (pVMem == NULL)
    {
        dwRet = GetLastError();
        RETAILMSG(UFN_ZONE_ERROR, (_T("%s MmMapIoSpace: FAILED\r\n"), pszFname));
        goto CleanUp;
    }

    g_pUDCBase = pVMem + BASE_REGISTER_OFFSET;
    DEBUGMSG(UFN_ZONE_INIT, (_T("%s MmMapIoSpace, pVMem:%x\r\n"), pszFname, pVMem));

    ioPhysicalBase.LowPart = IMAGE_SHARE_ARGS_PA_START;  
    v_gBspArgs = (volatile BSP_ARGS *)MmMapIoSpace(ioPhysicalBase, sizeof(BSP_ARGS), FALSE);
    if (v_gBspArgs == NULL)
    {
        dwRet = GetLastError();
        RETAILMSG(UFN_ZONE_ERROR, (_T("%s MmMapIoSpace: FAILED\r\n"), pszFname));
        goto CleanUp;
    }

CleanUp:

    if (dwRet != ERROR_SUCCESS)
    {
        if (pContext->pSYSCONregs)
        {
            MmUnmapIoSpace((PVOID)pContext->pSYSCONregs, sizeof(S3C6410_SYSCON_REG));
            pContext->pSYSCONregs = NULL;
        }

        if (pVMem)
        {
            MmUnmapIoSpace((PVOID)pVMem, OTG_LINK_REG_SIZE);
            pVMem = NULL;
        }
        
        if (v_gBspArgs)
            {
            MmUnmapIoSpace((PVOID) v_gBspArgs, sizeof(BSP_ARGS));    
               v_gBspArgs = NULL;
            }
    }

    FUNCTION_LEAVE_MSG();
    return dwRet;
}


/*++
Routine Description:
Deallocate register space.

Arguments:
None.

Return Value:
None.
--*/
static
VOID
UnmapRegisterSet(
    PCTRLR_PDD_CONTEXT     pContext
    )
{
    // Unmap any memory areas that we may have mapped.

    if (pContext->pSYSCONregs)
    {
        MmUnmapIoSpace((PVOID)pContext->pSYSCONregs, sizeof(S3C6410_SYSCON_REG));
        pContext->pSYSCONregs = NULL;
    }

    if (g_pUDCBase)
    {
        MmUnmapIoSpace((PVOID)(g_pUDCBase - BASE_REGISTER_OFFSET), OTG_LINK_REG_SIZE);
        g_pUDCBase = NULL;
    }    

    if (v_gBspArgs)
    {
        MmUnmapIoSpace((PVOID) v_gBspArgs, sizeof(BSP_ARGS));    
        v_gBspArgs = NULL;
    }
}


// Interrupt thread routine.
static
DWORD
WINAPI
ISTMain(
    LPVOID    lpParameter
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) lpParameter;
    ValidateContext(pContext);

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

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

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

        // Clear any outstanding device & endpoint interrupts
        // USB Device Interrupt Status - Write a '1' to Clear
        WriteReg(GINTSTS, INT_RESUME | INT_EPMIS | INT_SDE | INT_RESET | INT_SUSPEND); 

        // Enable Device General interrupts
        WriteReg(GINTMSK, INT_RESUME | INT_OUT_EP | INT_IN_EP | INT_EPMIS | INT_SDE | INT_RESET | INT_SUSPEND | INT_OTG);    

        // Enable Endpoint0 interrupt
        EnableEndpointInterrupt(pContext, 0, USB_IN_TRANSFER);
        EnableEndpointInterrupt(pContext, 0, USB_OUT_TRANSFER);

        while (TRUE)
        {
            DWORD dwWait = WaitForSingleObject(pContext->hevInterrupt, INFINITE);
            if (pContext->fExitIST || pContext->fRestartIST)
            {
                break;
            }

            if (dwWait == WAIT_OBJECT_0)
            {
                HandleUSBEvent(pContext);
                InterruptDone(pContext->dwSysIntr);
            }
            else
            {
                DEBUGMSG(UFN_ZONE_INIT, (_T("%s WaitForMultipleObjects failed. Exiting IST.\r\n"), pszFname));
                break;
            }
        }

        // Notify Detach Event to MDD
        pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_DETACH);
        
        pContext->fSpeedReported = FALSE;
        pContext->attachedState = UFN_DETACH;

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

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

    }

    FUNCTION_LEAVE_MSG();

    return 0;
}

static
VOID
StartTransfer(
    PCTRLR_PDD_CONTEXT    pContext,
    PEP_STATUS             peps,
    PSTransfer             pTransfer
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DEBUGCHK(pContext);
    PREFAST_DEBUGCHK(peps);

    DEBUGCHK(!peps->pTransfer);
    ValidateTransferDirection(pContext, peps, pTransfer);

    LOCK_ENDPOINT(peps);

    DEBUGMSG(ZONE_TRANSFER, (_T("%s Setting up %s transfer on ep %u for %u bytes\r\n"),
    pszFname, (pTransfer->dwFlags == USB_IN_TRANSFER) ? _T("in") : _T("out"),
    peps->dwEndpointNumber, pTransfer->cbBuffer));

    // Enable transfer interrupts.
    peps->pTransfer = pTransfer;
    DWORD dwEndpoint = peps->dwEndpointNumber;

    if (pTransfer->dwFlags == USB_IN_TRANSFER)
    {
        if (dwEndpoint == 0)
        {
            DWORD dwDIEPINT0 = ReadReg(DIEPINT0);
            if (dwDIEPINT0 & XFERCOPMPL)
            {
                WriteReg(DIEPINT0, XFERCOPMPL);
            }

            memcpy( pContext->pVAddrEP[0][IN_EP] ,pTransfer->pvBuffer, pTransfer->cbBuffer);

            WatiForTxFIFOEmpty(100);    
            
            WriteReg(DIEPDMA0, pContext->pPAddrEP[0][IN_EP]);
            if(pTransfer->cbBuffer >= pContext->dwEp0MaxPktSize)
            {
                WriteReg(DIEPTSIZ0, 1<<PACKET_COUTNT_IDX | pContext->dwEp0MaxPktSize);
                WriteReg(DIEPCTL0, EP_ENABLE | CLEAR_NAK | 1<<NEXT_EP_IDX | EP0_MAX_PK_SIZ);
            }
            else
            {
                WriteReg(DIEPTSIZ0, 1<<PACKET_COUTNT_IDX | pTransfer->cbBuffer);
                WriteReg(DIEPCTL0, EP_ENABLE | CLEAR_NAK | 1<<NEXT_EP_IDX | EP0_MAX_PK_SIZ);
            }
        }
        else
        {
            DWORD dwDIEPINT = ReadEPSpecificReg(dwEndpoint, DIEPINT);

            if (dwDIEPINT & XFERCOPMPL)
            {
                WriteEPSpecificReg(dwEndpoint, DIEPINT, XFERCOPMPL);
            }
            
            memcpy(pContext->pVAddrEP[dwEndpoint][IN_EP] ,pTransfer->pvBuffer, pTransfer->cbBuffer);

            WriteReg(DIEPMSK, IN_TKN_RECEIVED | TIMEOUT_CONDITION | XFER_COMPLETE);
            EnableEndpointInterrupt(pContext, dwEndpoint, peps->dwDirectionAssigned);

            pContext->dwXmitReadyCnt++;
            pContext->dwInEPRunning[dwEndpoint] = pContext->dwXmitReadyCnt;
        }
    }
    else //USB_OUT_TRANSFER
    {
        if (dwEndpoint == 0)
        {
            WriteReg(DOEPDMA0, pContext->pPAddrEP[0][OUT_EP]);
            WriteReg(DOEPTSIZ0, 1<<PACKET_COUTNT_IDX | pContext->dwEp0MaxPktSize);
            WriteReg(DOEPCTL0, EP_ENABLE | CLEAR_NAK | EP0_MAX_PK_SIZ);
        }
        else 
        {
            pContext->dwPipelinedEP = dwEndpoint;
            EnableEndpointInterrupt(pContext, dwEndpoint, peps->dwDirectionAssigned);

            if( pContext->dwUSBClassInfo != USB_MSF)
            {
                if(pContext->bOutEPDMAStartFlag == FALSE)
                {
                    pContext->dwPipelinedXferSize = pTransfer->cbBuffer;
                    pContext->dwPipelinedPktCnt = pContext->dwPipelinedXferSize / peps->dwPacketSizeAssigned;
                    
                    pContext->bOutEPDMAStartFlag = TRUE;

                    EnableEndpointInterrupt(pContext, dwEndpoint, peps->dwDirectionAssigned);
                    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);
                }

                if(pContext->dwPipelinedXfered[dwEndpoint][pContext->dwPipelinedEndIdx])
                {
                    RETAILMSG(UFN_ZONE_WARNING,(TEXT("Ring buffer is buffering... Late processing!!!\r\n")));
                    
                    memcpy(pTransfer->pvBuffer, \
                              pContext->pVAddrEP[dwEndpoint][pContext->dwPipelinedEndIdx] , \
                              pContext->dwPipelinedXfered[dwEndpoint][pContext->dwPipelinedEndIdx]); 
                    
                    pTransfer->cbTransferred += pContext->dwPipelinedXfered[dwEndpoint][pContext->dwPipelinedEndIdx];
                    pContext->dwPipelinedXfered[dwEndpoint][pContext->dwPipelinedEndIdx] = 0;
                    pContext->dwPipelinedEndIdx = GET_NEXT_PF_IDX(pContext->dwPipelinedEndIdx);
                    pContext->dwPipelinedEP = 0;

                    if(pContext->bRingBufferFull)
                    {
                        if(pContext->dwPipelinedStrIdx != GET_PREV_PF_IDX(pContext->dwPipelinedEndIdx))
                        {
                            RETAILMSG(UFN_ZONE_WARNING,(TEXT("ERROR : Ring State is not valud(Str : %d, End : %d)\r\n"), pContext->dwPipelinedStrIdx, GET_PREV_PF_IDX(pContext->dwPipelinedEndIdx)));
                        }
                        
                        pContext->bRingBufferFull = FALSE;
                        EnableEndpointInterrupt(pContext, dwEndpoint, peps->dwDirectionAssigned);

⌨️ 快捷键说明

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