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

📄 pdd.c

📁 Windows CE 6.0 BSP for the Beagle Board.
💻 C
📖 第 1 页 / 共 5 页
字号:
                    L"USB Device is Self-Powered\r\n"));
                SETREG32(&pUSBDRegs->SYSCON1, USBD_SYSCON1_SELF_PWR);
            }
            else
            {
                DEBUGMSG(ZONE_INIT, (L"USBD SetupEvent() - "
                    L"USB Device is NOT Self-Powered\r\n"));
                CLRREG32(&pUSBDRegs->SYSCON1, USBD_SYSCON1_SELF_PWR);
            }
        }
        else
        {
            DEBUGMSG(ZONE_INIT, (L"USBD SetupEvent() - "
                L"Changing USB Device state to Addressed\r\n"));
            OUTREG32(&pUSBDRegs->SYSCON2, USBD_SYSCON2_CLR_CFG);
        }
    }

    // Let MDD process message
    pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_SETUP_PACKET, (DWORD)data);

}

//------------------------------------------------------------------------------
//
//  Function:  IssueTxTransfer
//
//  This function sends next packet from transaction buffer. It is called from
//  interrupt thread and UfnPdd_IssueTransfer.
//
static VOID IssueTxTransfer(USBFN_PDD *pPdd, DWORD endPoint)
{
    OMAP2420_USBD_REGS *pUSBDRegs = pPdd->pUSBDRegs;
    STransfer *pTransfer;
    BOOL complete = FALSE;
    DWORD stat, space, count, remain;
    UCHAR *pBuffer;
    DWORD data;
    DWORD epNum;

    // Get active transfer
    pTransfer = pPdd->ep[endPoint].pTransfer;

    DEBUGMSG(ZONE_TRANSFER, (L"USBD IssueTxTransfer() - "
        L"EP %d pTransfer 0x%08X (%d, %d, %d)\r\n",
                 endPoint,
                 pTransfer,
                 pTransfer != NULL ? pTransfer->cbBuffer : 0,
                 pTransfer != NULL ? pTransfer->cbTransferred : 0,
                 pTransfer != NULL ? pTransfer->dwUsbError : -1));

    // Select EP
    epNum = (USBD_EP_NUM & endPoint) | USBD_EP_NUM_DIRIN;
    SelectEp(pPdd, epNum);


    // Get EP status
    stat = INREG32(&pUSBDRegs->STAT_FLG);

    // Depending on EP status
    if ((stat & USBD_STAT_STALL) != 0)
    {
        // We issued stall, remove it...
        OUTREG32(&pUSBDRegs->CTRL, USBD_CTRL_CLR_HALT);
    }
    else
    {
        // When transfer is NULL it is handshake ACK
        if (pTransfer != NULL)
        {
            // Is this final interrupt of transfer?
            if ((pTransfer->cbTransferred == pTransfer->cbBuffer) && (!pPdd->ep[endPoint].fZeroLengthNeeded))
            {
                pTransfer->dwUsbError = UFN_NO_ERROR;
                complete = TRUE;
            }
            else
            {
                __try
                {
                    pBuffer = (UCHAR*)pTransfer->pvBuffer + pTransfer->cbTransferred;
                    space   = pTransfer->cbBuffer - pTransfer->cbTransferred;

                    if (endPoint != 0)
                    {
                        // Non Zero Endpoint: No zero length padding needed.
                        pPdd->ep[endPoint].fZeroLengthNeeded  = FALSE;
                    }
                    else
                    {
                        // Zero endpoint: Zero length padding needed if last packet is maxPacketSize.
                        pPdd->ep[endPoint].fZeroLengthNeeded = ((space == pPdd->ep[endPoint].maxPacketSize) && (pPdd->setupCount > pTransfer->cbBuffer));
                    }

                    // How many bytes we can send just now?
                    count = pPdd->ep[endPoint].maxPacketSize;

                    if (count > space)
                    {
                        count = space;
                    }

                    // Write data to FIFO
                    remain = count;
                    while (remain > 1)
                    {
                        data = (pBuffer[1] << 8) | pBuffer[0];
                        OUTREG16((UINT16*)&pUSBDRegs->DATA, data);

                        pBuffer += 2;
                        space   -= 2;
                        remain  -= 2;
                    }

                    if (remain > 0)
                    {
                        OUTREG8((UINT8*)&pUSBDRegs->DATA, *pBuffer);

                        pBuffer += 1;
                        space   -= 1;
                        remain  -= 1;
                    }

                    DEBUGMSG(ZONE_TRANSFER, (L"USBD IssueTxTransfer() - "
                        L"Transfered %d bytes on ep 0x%02X", count, endPoint));

                    // Enable FIFO
                    OUTREG32(&pUSBDRegs->CTRL, USBD_CTRL_FIFO_EN);

                    // We transfered some data
                    pTransfer->cbTransferred = pTransfer->cbBuffer - space;

                }
                __except(EXCEPTION_EXECUTE_HANDLER)
                {
                    pTransfer->dwUsbError = UFN_CLIENT_BUFFER_ERROR;
                    complete = TRUE;
                }
            }
        }
        else
        {
            DEBUGMSG(ZONE_TRANSFER, (L"USBD IssueTxTransfer() - "
                L"pTransfer is NULL; HandShake ACK."));
        }
    }

    // Deselect EP
    DeselectEp(pPdd, epNum);

    // If transaction is complete we should tell MDD
    if (complete)
    {
        DEBUGMSG(ZONE_TRANSFER, (L"USBD IssueTxTransfer() - "
            L"Notifying MDD that transfer is complete."));

        pPdd->ep[endPoint].pTransfer = NULL;
        pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_TRANSFER_COMPLETE, (DWORD)pTransfer);
    }
}

//------------------------------------------------------------------------------
//
//  Function:  IssueRxTransfer
//
//  This function receives packet to transaction buffer. It is called from
//  interrupt thread.
//
static VOID IssueRxTransfer(USBFN_PDD *pPdd, DWORD endPoint)
{
    OMAP2420_USBD_REGS *pUSBDRegs = pPdd->pUSBDRegs;
    STransfer *pTransfer;
    BOOL complete = FALSE;
    DWORD space, remain;
    UCHAR *pBuffer;
    DWORD data;
    DWORD stat;
    DWORD epNum;
    DWORD count;
    DWORD maxSize;

    // Get active transfer
    pTransfer = pPdd->ep[endPoint].pTransfer;

    DEBUGMSG(ZONE_TRANSFER, (L"USBD IssueRxTransfer() - "
        L"EP %d pTransfer 0x%08X (%d, %d, %d)\r\n",
                 endPoint,
                 pTransfer,
                 pTransfer != NULL ? pTransfer->cbBuffer : 0,
                 pTransfer != NULL ? pTransfer->cbTransferred : 0,
                 pTransfer != NULL ? pTransfer->dwUsbError : -1));

    // Select EP
    epNum = USBD_EP_NUM & endPoint;
    SelectEp(pPdd, epNum);

    // Get EP status
    stat = INREG32(&pUSBDRegs->STAT_FLG);

    // Depending on EP status
    if ((stat & USBD_STAT_STALL) != 0)
    {
        // We issued stall, remove it...
        OUTREG32(&pUSBDRegs->CTRL, USBD_CTRL_CLR_HALT);
    }
    else
    {
        // When transfer is NULL it is handshake ACK
        if (pTransfer != NULL)
        {
            // Get maxPacketSize
            maxSize = pPdd->ep[endPoint].maxPacketSize;

            __try
            {
                pBuffer = (UCHAR*)pTransfer->pvBuffer + pTransfer->cbTransferred;
                space = pTransfer->cbBuffer - pTransfer->cbTransferred;

                // Get EP status flag
                stat = INREG32(&pUSBDRegs->STAT_FLG);

                // Get number of bytes in FIFO
                if ((stat & USBD_STAT_FIFO_EMPTY) != 0)
                {
                    count = 0;
                }
                else if ((stat & USBD_STAT_FIFO_FULL) != 0)
                {
                    count = maxSize;
                }
                else
                {
                    count = INREG32(&pUSBDRegs->RXFSTAT) & USBD_RFXSTAT_COUNT;
                }

                // Read data
                remain = count;
                while (remain > 1)
                {
                    data = (WORD)INREG16(&pUSBDRegs->DATA);
                    if (space > 1)
                    {
                        pBuffer[0] = (UCHAR)data;
                        pBuffer[1] = (UCHAR)(data >> 8);
                        pBuffer += 2;
                        space -= 2;
                    }
                    remain -= 2;
                }

                if (remain > 0)
                {
                    data = (WORD)INREG16(&pUSBDRegs->DATA);
                    if (space > 0)
                    {
                        *pBuffer = (UCHAR)data;
                        pBuffer += 1;
                        space   -= 1;
                    }
                    remain -= 1;
                }

                // We transfered some data
                pTransfer->cbTransferred = pTransfer->cbBuffer - space;

                DEBUGMSG(ZONE_TRANSFER, (L"USBD IssueRxTransfer() - "
                    L"Transfered %d bytes on ep 0x%02X", pTransfer->cbTransferred, epNum));

                // Is this end of transfer?
                if ((pTransfer->cbTransferred == pTransfer->cbBuffer) || (count < maxSize))
                {
                    // Yes, set return code
                    pTransfer->dwUsbError = UFN_NO_ERROR;

                    // And complete flag
                    complete = TRUE;
                }
                else
                {
                    // No, enable FIFO for next packet
                    OUTREG32(&pUSBDRegs->CTRL, USBD_CTRL_FIFO_EN);
                }

            }
            __except(EXCEPTION_EXECUTE_HANDLER)
            {
                pTransfer->dwUsbError = UFN_CLIENT_BUFFER_ERROR;
                complete = TRUE;
            }
        }
    }

    // Deselect EP
    Deselect(pPdd, epNum);

    // If transaction is complete we should tell MDD
    if (complete)
    {
        pPdd->ep[endPoint].pTransfer = NULL;
        pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_TRANSFER_COMPLETE, (DWORD)pTransfer);
    }
}


//------------------------------------------------------------------------------
//
//  Function:  DevStatEvent
//
//  This function handles device state change interrupts.
//
static VOID DevStatEvent(USBFN_PDD *pPdd)
{
    OMAP2420_USBD_REGS *pUSBDRegs = pPdd->pUSBDRegs;
    DWORD state, change;


    DEBUGMSG(ZONE_FUNCTION, (L"USBD DevStatEvent() - START\r\n"));

    // Get Current Device State and compare to Previous Device State
    // Store the differences in change.
    // Note: (a ^ b) == (a XOR b)
    state = INREG32(&pUSBDRegs->DEVSTAT);
    change = state ^ pPdd->devState;

    DEBUGMSG(ZONE_PDD, (L"USBD DevStatEvent() - "
        L"Previous Device State = 0x%04X\r\n", pPdd->devState));
    DEBUGMSG(ZONE_PDD, (L"USBD DevStatEvent() - "
        L"Current  Device State = 0x%04X\r\n", state));
    DEBUGMSG(ZONE_PDD, (L"USBD DevStatEvent() - "
        L"Device State Change   = 0x%04X\r\n", change));

    DEBUGMSG(ZONE_PDD, (L"UsbFnPdd!DevStatEvent: "
        L"Device State = 0x%04x, change = 0x%04X\r\n", state, change));

#ifdef USE_OLD_CABLE_DETECT_METHOD
    // Attach/deattach
    if ((change & USBD_DEVSTAT_ATT) != 0)
    {
        if ((state & USBD_DEVSTAT_ATT) != 0)
        {
            DEBUGMSG(ZONE_PDD, (L"USBD DevStatEvent() - "
                L"Detected Cable Insertion Event!\r\n"));

            // TODO: Call bus driver (OTG?) to move HW from deep sleep
            // SetSelfPowerState to D0.
            pPdd->m_CurSelfPowerState = D0;
            UpdateDevicePower(pPdd);

            // Let MDD process change
            pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_EVENTS, UFN_ATTACH);
            pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_SPEED,  BS_FULL_SPEED);
        }
        else
        {
            DEBUGMSG(ZONE_PDD, (L"USBD DevStatEvent() - "
                L"Detected Cable Removal Event!\r\n"));

            // We are not configured anymore
            OUTREG32(&pUSBDRegs->SYSCON2, USBD_SYSCON2_CLR_CFG);

            // TODO: Call bus driver (OTG?) to move HW to deep sleep
            // Let MDD process change
            pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_EVENTS, UFN_DETACH);

            // Don't process other changes (we are disconnected)

            // SetSelfPowerState to D4
            pPdd->m_CurSelfPowerState = D4; // Do we need set to D3 as wake up source?
            UpdateDevicePower(pPdd);

            goto DevStatClean;
        }
    }
#endif // USE_OLD_CABLE_DETECT_METHOD

    // Reset
    if (((change & USBD_DEVSTAT_USB_RESET) != 0) || ((change & USBD_DEVSTAT_DEF) != 0))
    {
        DEBUGMSG(ZONE_PDD, (L"USBD DevStatEvent() - "
            L"Detected USB Reset Event!\r\n"));

        pPdd->m_NewPowerState = D0;
        UpdateDevicePower(pPdd);

        if ((state & USBD_DEVSTAT_USB_RESET) == 0)
        {
            // OTG may not detect attach/detach events correctly on some platforms
            // Simulate a attach/detach event to clear any previous state on reset
            // Let MDD process change
            pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_EVENTS, UFN_DETACH);
            pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_EVENTS, UFN_ATTACH);
            pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_SPEED,  BS_FULL_SPEED);

            // Tell MDD about reset...
            pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_EVENTS, UFN_RESET);
        }

        // Enable interrupts
        OUTREG32(&pUSBDRegs->IRQ_EN, USBD_IRQ_MASK);

        // In the middle of a reset don't process other changes
        goto DevStatClean;
    }

    // Suspend/resume
    if ((change & USBD_DEVSTAT_SUS) != 0)
    {
        if ((state & USBD_DEVSTAT_SUS) != 0)
        {
            DEBUGMSG(ZONE_PDD, (L"USBD DevStatEvent() - "
                L"Detected Device Suspend Event!\r\n"));

            // Let MDD process change
            pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_EVENTS, UFN_SUSPEND);

            // Read device status
            INREG32(&pUSBDRegs->DEVSTAT);

⌨️ 快捷键说明

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