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

📄 pdd.c

📁 Windows CE 6.0 BSP for the Beagle Board.
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//
// Copyright (c) Intrinsyc Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Intrinsyc end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
//  File:  pdd.c
//
//  This file contains USB function PDD implementation. Actual implementation
//  doesn't use DMA transfers and it doesn't support ISO endpoints.
//
#include <windows.h>
#include <nkintr.h>
#include <pm.h>
#include <ceddk.h>
#include <ceddkex.h>
#include <cebus.h>
#include <usbfntypes.h>
#include <usbfn.h>
#include <omap2420.h>
#include <devload.h>
#include <oal_intr.h>

extern BOOL InitializeHardware();
void PDD_Dump(OMAP2420_USBD_REGS * pPddRegs);
static void printUsbdDriverSettings();


//------------------------------------------------------------------------------
//
//  Define:  USBD_IRQ_MASK
//
//  This is composite interrupt mask used in driver.
//
#define USBD_IRQ_MASK  (USBD_IRQ_EN_EP_RX | USBD_IRQ_EN_EP_TX | USBD_IRQ_EN_DS_CHG | USBD_IRQ_EN_EP0)

//------------------------------------------------------------------------------
//
//  Type:  USBFN_EP
//
//  Internal PDD structure which holds info about endpoint direction,
//  max packet size and active transfer.
//
typedef struct
{
    WORD       maxPacketSize;
    BOOL       dirRx;
    BOOL       fZeroLengthNeeded;
    STransfer *pTransfer;
} USBFN_EP;

//------------------------------------------------------------------------------
//
//  Type:  USBFN_PDD
//
//  Internal PDD context structure.
//
typedef struct
{
    DWORD memBase;
    DWORD memLen;
    DWORD priority256;
    DWORD irq[3];

    VOID *pMddContext;
    PFN_UFN_MDD_NOTIFY pfnNotify;

    HANDLE hParentBus;
    OMAP2420_USBD_REGS *pUSBDRegs;

    DWORD sysIntr;
    HANDLE hIntrEvent;
    BOOL exitIntrThread;
    HANDLE hIntrThread;

    CEDEVICE_POWER_STATE m_NewPowerState;
    CEDEVICE_POWER_STATE m_CurrentPowerState;

    DWORD devState;
    BOOL selfPowered;

    BOOL setupDirRx;
    WORD setupCount;
    HANDLE hSetupEvent;

    CRITICAL_SECTION epCS;
    USBFN_EP ep[USBD_EP_COUNT];

    BOOL fakeDsChange;                  // To workaround MDD problem

} USBFN_PDD;

//------------------------------------------------------------------------------
//  Device registry parameters

static const DEVICE_REGISTRY_PARAM g_deviceRegParams[] = {
    {
        L"MemBase", PARAM_DWORD, TRUE, offset(USBFN_PDD, memBase),
        fieldsize(USBFN_PDD, memBase), NULL
    }, {
        L"MemLen", PARAM_DWORD, TRUE, offset(USBFN_PDD, memLen),
        fieldsize(USBFN_PDD, memLen), NULL
    }, {
        L"Irq", PARAM_MULTIDWORD, TRUE, offset(USBFN_PDD, irq),
        fieldsize(USBFN_PDD, irq), NULL
    }, {
        L"Priority256", PARAM_DWORD, FALSE, offset(USBFN_PDD, priority256),
        fieldsize(USBFN_PDD, priority256), (void *)101
    }
};

//------------------------------------------------------------------------------
//
//  Global:  dpCurSettings
//

#ifdef DEBUG

#define ZONE_INTERRUPTS         DEBUGZONE(8)
#define ZONE_POWER              DEBUGZONE(9)
#define ZONE_PDD                DEBUGZONE(15)

extern DBGPARAM dpCurSettings = {
    L"UsbFn", {
        L"Error",       L"Warning",     L"Init",        L"Transfer",
        L"Pipe",        L"Send",        L"Receive",     L"USB Events",
        L"Interrupts",  L"Power",       L"",            L"",
        L"Function",    L"Comments",    L"",            L"PDD"
    },
    DBG_ERROR|DBG_INIT
};

#endif

//------------------------------------------------------------------------------
//
//  Function:  Log2
//
//  Trivial log with base 2 function used in EP configuration.
//
static DWORD Log2(DWORD value)
{
    DWORD rc = 0;

    while (value != 0)
    {
        value >>= 1;
        rc++;
    }

    if (rc > 0)
    {
        rc--;
    }

    return rc;
}


// Routines to synchronize access to the indexed endpoint registers.
#ifdef DEBUG
static int InEp = 0;
#endif // DEBUG

static VOID Select(USBFN_PDD *pPdd, DWORD dwVal)
{
    EnterCriticalSection(&pPdd->epCS);
    ASSERT(InEp++ >= 0);
    OUTREG32(&pPdd->pUSBDRegs->EP_NUM, dwVal);
}


static VOID SelectSetup(USBFN_PDD *pPdd)
{
    // Select setup FIFO (this clears USBD_INT_SETUP flag)
    Select(pPdd, USBD_EP_NUM_SETUP);
}


static VOID SelectEp(USBFN_PDD *pPdd, DWORD epNum)
{
    Select(pPdd, USBD_EP_NUM_SEL | epNum);
}


static VOID Deselect(USBFN_PDD *pPdd, DWORD dwValue)
{
    OUTREG32(&pPdd->pUSBDRegs->EP_NUM, dwValue);
    ASSERT(--InEp >= 0);
    LeaveCriticalSection(&pPdd->epCS);
}


static VOID DeselectSetup(USBFN_PDD *pPdd)
{
    Deselect(pPdd, 0);
}


static VOID DeselectEp(USBFN_PDD *pPdd, DWORD epNum)
{
    Deselect(pPdd, epNum);
}


//------------------------------------------------------------------------------
//
//  Function:  UfnPdd_PowerDown
//
//  LEGACY FUNCTION: Do not use!
//
//  This function is provided for backwards compatibility only.
//  It is included in the USB Client Driver's function table (which gets
//  exported to the rest of the operating system), and thus other modules
//  may be expecting it to be a callable function.
//
VOID WINAPI UfnPdd_PowerDown(VOID *pPddContext)
{
}


//------------------------------------------------------------------------------
//
//  Function:  UfnPdd_PowerUp
//
//  LEGACY FUNCTION: Do not use!
//
//  This function is provided for backwards compatibility only.
//  It is included in the USB Client Driver's function table (which gets
//  exported to the rest of the operating system), and thus other modules
//  may be expecting it to be a callable function.
//
VOID WINAPI UfnPdd_PowerUp(VOID *pPddContext)
{
}


////////////////////////////////////////////////////////////////////////////////
//
// Function:   UpdateDevicePower()
//
// Purpose:    Puts the USB Client Device in the Power State provided in *pPdd
//
// Parameters: pPdd = Pointer to USBFN_PDD Structure containing device info
//
// Returns:    TRUE if the power state was successfully updated,
//             or FALSE if it was not.
//
// Notes:      Power States D0, D1, and D2 are considered "on".
//             Power States D3 and D4 are considered "off".
//
////////////////////////////////////////////////////////////////////////////////
//
BOOL UpdateDevicePower(USBFN_PDD * pPdd)
{
    BOOL  bRV    = TRUE;
    DWORD regBit = 0x00000001;
    DWORD cbRet  = 0x00000000;


    if (pPdd != NULL)
    {
        DEBUGMSG(ZONE_POWER, (L"USBD UpdateDevicePower() - "
            L"Changing Power State from D%u to D%u\r\n", (int)(pPdd->m_CurrentPowerState), (int)(pPdd->m_NewPowerState)));

        switch (pPdd->m_CurrentPowerState)
        {
            case D0:
            case D1:
            case D2:
                if (SetDevicePowerState(pPdd->hParentBus, pPdd->m_NewPowerState, NULL))
                {
                    if ((pPdd->m_NewPowerState == D3) || (pPdd->m_NewPowerState == D4))
                    {
                        DEBUGMSG(ZONE_POWER, (L"USBD UpdateDevicePower() - "
                            L"Turning the Power Off\r\n"));

                        // Disable the USBD Transceiver
                        if (pPdd->pUSBDRegs)
                        {
                            CLRREG32(&pPdd->pUSBDRegs->SYSCON1, USBD_SYSCON1_PULLUP_EN);
                        }

                        // Turn off the USBD Clocks
                        KernelIoControl(IOCTL_ICLK2_DIS, (VOID *)&regBit, sizeof(DWORD), NULL, 0, &cbRet);
                        KernelIoControl(IOCTL_FCLK2_DIS, (VOID *)&regBit, sizeof(DWORD), NULL, 0, &cbRet);
                    }
                }
                else
                {
                    bRV = FALSE;
                }
                break;

            case D3:
            case D4:
                if (SetDevicePowerState(pPdd->hParentBus, pPdd->m_NewPowerState, NULL))
                {
                    if ((pPdd->m_NewPowerState == D0) || (pPdd->m_NewPowerState == D1) || (pPdd->m_NewPowerState == D2))
                    {
                        DEBUGMSG(ZONE_POWER, (L"USBD UpdateDevicePower() - "
                            L"Turning the Power On\r\n"));

                        // Turn on the USBD Clocks
                        KernelIoControl(IOCTL_ICLK2_ENB, (VOID *)&regBit, sizeof(DWORD), NULL, 0, &cbRet);
                        KernelIoControl(IOCTL_FCLK2_ENB, (VOID *)&regBit, sizeof(DWORD), NULL, 0, &cbRet);

                        // Enable the USBD Transceiver
                        if (pPdd->pUSBDRegs)
                        {
                            SETREG32(&pPdd->pUSBDRegs->SYSCON1, USBD_SYSCON1_PULLUP_EN);
                        }
                    }
                }
                else
                {
                    bRV = FALSE;
                }
                break;

            default:
                bRV = FALSE;
                break;
        }

        if (bRV)
        {
            pPdd->m_CurrentPowerState = pPdd->m_NewPowerState;
        }
    }

    return bRV;
}

//------------------------------------------------------------------------------
//
//  Function:  SetupEvent
//
//  This function handles setup packet interrupts.
//
static VOID SetupEvent(USBFN_PDD *pPdd)
{
    OMAP2420_USBD_REGS *pUSBDRegs = pPdd->pUSBDRegs;
    DWORD rawFifoData = 0x00000000;
    WORD data[4];
    USB_DEVICE_REQUEST *pSetup = (USB_DEVICE_REQUEST*)data;


    do {
        // Select setup FIFO (this clears USBD_INT_SETUP flag)
        SelectSetup(pPdd);

        // Read setup data
        rawFifoData = INREG32(&pUSBDRegs->DATA);
        data[0]     = (WORD)(rawFifoData & 0x0000FFFF);

        rawFifoData = INREG32(&pUSBDRegs->DATA);
        data[1]     = (WORD)(rawFifoData & 0x0000FFFF);

        rawFifoData = INREG32(&pUSBDRegs->DATA);
        data[2]     = (WORD)(rawFifoData & 0x0000FFFF);

        rawFifoData = INREG32(&pUSBDRegs->DATA);
        data[3]     = (WORD)(rawFifoData & 0x0000FFFF);

        // Deselect setup FIFO
        DeselectSetup(pPdd);
    } while ((INREG32(&pUSBDRegs->IRQ_SRC) & USBD_INT_SETUP) != 0);
/*
    DEBUGMSG(ZONE_INIT, (L"USBD SetupEvent() - data[0] = 0x%04X\r\n", data[0]));
    DEBUGMSG(ZONE_INIT, (L"USBD SetupEvent() - data[1] = 0x%04X\r\n", data[1]));
    DEBUGMSG(ZONE_INIT, (L"USBD SetupEvent() - data[2] = 0x%04X\r\n", data[2]));
    DEBUGMSG(ZONE_INIT, (L"USBD SetupEvent() - data[3] = 0x%04X\r\n", data[3]));

    // Make sure we are interpreting the above data correctly.
    DEBUGMSG(ZONE_INIT, (L"USBD SetupEvent() - pSetup->bmRequestType = 0x%02X\r\n", pSetup->bmRequestType));
    DEBUGMSG(ZONE_INIT, (L"USBD SetupEvent() - pSetup->bRequest      = 0x%02X\r\n", pSetup->bRequest));
    DEBUGMSG(ZONE_INIT, (L"USBD SetupEvent() - pSetup->wValue        = 0x%04X\r\n", pSetup->wValue));
    DEBUGMSG(ZONE_INIT, (L"USBD SetupEvent() - pSetup->wIndex        = 0x%04X\r\n", pSetup->wIndex));
    DEBUGMSG(ZONE_INIT, (L"USBD SetupEvent() - pSetup->wLength       = 0x%04X\r\n", pSetup->wLength));
*/
    // Save setup packet direction & size for later use
    pPdd->setupDirRx = (pSetup->bmRequestType & 0x80) == 0;
    pPdd->setupCount = pSetup->wLength;

    // MDD doesn't call PDD back on configure message
    if ((pSetup->bmRequestType == 0) && (pSetup->bRequest == USB_REQUEST_SET_CONFIGURATION))
    {
        if (pSetup->wValue != 0)
        {
            DEBUGMSG(ZONE_INIT, (L"USBD SetupEvent() - "
                L"Changing USB Device state to Configured\r\n"));

            // Move device to configured state
            OUTREG32(&pUSBDRegs->SYSCON2, USBD_SYSCON2_DEV_CFG);

            // Set self powered flag
            if (pPdd->selfPowered)
            {
                DEBUGMSG(ZONE_INIT, (L"USBD SetupEvent() - "

⌨️ 快捷键说明

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