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

📄 pdd.c

📁 Windows CE 6.0 BSP for the Beagle Board.
💻 C
📖 第 1 页 / 共 5 页
字号:
    }

    // Deattach device
    CLRREG32(&pUSBDRegs->SYSCON1, USBD_SYSCON1_PULLUP_EN);

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

    // Done
    return ERROR_SUCCESS;
}


//------------------------------------------------------------------------------
//
//  Function:  UfnPdd_DeinitEndpoint
//
//  This function is called when pipe to endpoint is closed. For OMAP7XX we
//  will stop points in UfnPdd_DeregisterDevice.
//
DWORD WINAPI UfnPdd_DeinitEndpoint(VOID *pPddContext, DWORD endPoint)
{
    USBFN_PDD          *pPdd      = pPddContext;
    OMAP2420_USBD_REGS *pUSBDRegs = pPdd->pUSBDRegs;
    DWORD               epNum;


    DEBUGMSG(ZONE_PDD, (L"UfnPdd_DeinitEndpoint: %d\r\n", endPoint));

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

    // Clear EP
    OUTREG32(&pUSBDRegs->CTRL, USBD_CTRL_CLR_EP);

    // Deselect EP
    DeselectEp(pPdd, epNum);

    // Done
    return ERROR_SUCCESS;
}


//------------------------------------------------------------------------------
//
//  Function:  UfnPdd_InitEndpoint
//
//  This function is called when pipe to endpoint is created. For OMAP7XX
//  all initialization must be done in UfnPdd_RegisterDevice.
//
DWORD WINAPI UfnPdd_InitEndpoint(VOID *pContext,
                                 DWORD endPoint,
                                 UFN_BUS_SPEED speed,
                                 USB_ENDPOINT_DESCRIPTOR *pEPDesc,
                                 VOID *pReserved,
                                 UCHAR configValue,
                                 UCHAR interfaceNumber,
                                 UCHAR alternateSetting)
{
    DEBUGMSG(ZONE_PDD, (L"UfnPdd_InitEndpoint: %d\r\n", endPoint));
    return ERROR_SUCCESS;
}


//------------------------------------------------------------------------------
//
//  Function:  UfnPdd_SetAddress
//
//  This function is called by MDD when configuration process assigned address
//  to device. For OMAP7xx this is managed by hardware.
//
DWORD WINAPI UfnPdd_SetAddress(VOID *pPddContext, UCHAR address)
{
    DEBUGMSG(ZONE_PDD, (L"UfnPdd_SetAddress(0x%08X, 0x%02X)\r\n", pPddContext, address));
    return ERROR_SUCCESS;
}


//------------------------------------------------------------------------------
//
//  Function:  UfnPdd_Start
//
//  This function is called after UfnPdd_RegisterDevice. It should attach
//  device to USB bus.
//
DWORD WINAPI UfnPdd_Start(VOID *pPddContext)
{
    DWORD rv;
    
    DEBUGMSG(ZONE_FUNCTION, (L"UfnPdd_Start() - START\r\n"));

    if (pPddContext == NULL)
    {
        DEBUGMSG(ZONE_ERROR, (L"UfnPdd_Start() - "
            L"Invalid Parameter: pPddContext is NULL\r\n"));
        rv = ERROR_INVALID_PARAMETER;
    }
    else
    {
        USBFN_PDD          * pPdd           = pPddContext;
        OMAP2420_USBD_REGS * pUSBDRegs      = pPdd->pUSBDRegs;


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

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

        // Attach device to bus (it has no effect when OTG controller is used)
        SETREG32(&pUSBDRegs->SYSCON1, USBD_SYSCON1_PULLUP_EN);

        // Set fake device change flag which on first interrupt force
        // device state change handler even if it isn't indicated by hardware
        pPdd->fakeDsChange = TRUE;

        rv = ERROR_SUCCESS;
    }
    

    DEBUGMSG(ZONE_FUNCTION, (L"UfnPdd_Start() - END\r\n"));

    // Done
    return rv;
}


//------------------------------------------------------------------------------
//
//  Function:  UfnPdd_RegisterDevice
//
//  This function is called by MDD after device configuration was sucessfully
//  verified by UfnPdd_IsEndpointSupportable and
//  UfnPdd_IsConfigurationSupportable. It should initialize hardware for given
//  configuration. Depending on hardware endpoints can be initialized later in
//  UfnPdd_InitEndpoint. For OMAP7xx it isn't a case, so we should do all
//  initialization there.
//
DWORD WINAPI UfnPdd_RegisterDevice(VOID                               *pPddContext,
                                   const USB_DEVICE_DESCRIPTOR        *pHighSpeedDeviceDesc,
                                   const UFN_CONFIGURATION            *pHighSpeedConfig,
                                   const USB_CONFIGURATION_DESCRIPTOR *pHighSpeedConfigDesc,
                                   const USB_DEVICE_DESCRIPTOR        *pFullSpeedDeviceDesc,
                                   const UFN_CONFIGURATION            *pFullSpeedConfig,
                                   const USB_CONFIGURATION_DESCRIPTOR *pFullSpeedConfigDesc,
                                   const UFN_STRING_SET               *pStringSets,
                                   DWORD stringSets)
{
    DWORD rc = ERROR_INVALID_PARAMETER;
    USBFN_PDD *pPdd = pPddContext;
    OMAP2420_USBD_REGS *pUSBDRegs = pPdd->pUSBDRegs;
    UFN_INTERFACE *pIFC;
    UFN_ENDPOINT  *pEP;
    DWORD offset, ep;
    DWORD ifc, epx;
    DWORD cfg;


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

    // Remember self powered flag
    pPdd->selfPowered = ((pFullSpeedConfig->Descriptor.bmAttributes & 0x20) != 0);

    // Unlock configuration
    CLRREG32(&pUSBDRegs->SYSCON1, USBD_SYSCON1_CFG_LOCK);

    DEBUGMSG(ZONE_PDD, (L"UfnPdd_RegisterDevice() - "
        L"Configuring EndPoint 00 (RX)\r\n"));

    // Configure EP0
    offset = 8;
    cfg  = (Log2(pFullSpeedDeviceDesc->bMaxPacketSize0 >> 3) << 12);
    cfg |= offset >> 3;

    OUTREG32(&pUSBDRegs->EP0, cfg);

    pPdd->ep[0].maxPacketSize = pFullSpeedDeviceDesc->bMaxPacketSize0;
    offset += pFullSpeedDeviceDesc->bMaxPacketSize0;

    // Configure Rx EPs
    for (ifc = 0; ifc < pFullSpeedConfig->Descriptor.bNumInterfaces; ifc++)
    {
        // For each endpoint in interface...
        pIFC = &pFullSpeedConfig->pInterfaces[ifc];
        for (epx = 0; epx < pIFC->Descriptor.bNumEndpoints; epx++)
        {
            pEP = &pIFC->pEndpoints[epx];

            // If it is Tx EP skip it
            if ((pEP->Descriptor.bEndpointAddress & 0x80) != 0)
            {
                continue;
            }

            DEBUGMSG(ZONE_PDD, (L"UfnPdd_RegisterDevice() - "
                L"Configuring Interface %02u EndPoint %02u (RX)\r\n", ifc, epx));

            // Get EP address
            ep = pEP->Descriptor.bEndpointAddress & 0x0F;

            // Save max packet size & direction
            pPdd->ep[ep].maxPacketSize = pEP->Descriptor.wMaxPacketSize;
            pPdd->ep[ep].dirRx = TRUE;

            // Create EP config
            cfg  = USBD_EP_VALID;
            cfg |= (Log2(pEP->Descriptor.wMaxPacketSize >> 3) << 12);

            if ((pEP->Descriptor.bmAttributes & 0x03) == 0x01)
            {
                cfg |= USBD_EP_ISO;
            }

            cfg |= offset >> 3;

            if (ep > 0)
                OUTREG32(&pUSBDRegs->EP_RX[ep - 1], cfg);
            else
                DEBUGMSG(ZONE_PDD, (L"USBFN:: UfnPdd_RegisterDevice EP_RX = %d\r\n", ep - 1));

            // Update offset
            offset += pEP->Descriptor.wMaxPacketSize;
        }
    }

    // Configure Tx EPs
    for (ifc = 0; ifc < pFullSpeedConfig->Descriptor.bNumInterfaces; ifc++)
    {
        // For each endpoint in interface
        pIFC = &pFullSpeedConfig->pInterfaces[ifc];
        for (epx = 0; epx < pIFC->Descriptor.bNumEndpoints; epx++)
        {
            pEP = &pIFC->pEndpoints[epx];

            // If it is Rx EP skip it
            if ((pEP->Descriptor.bEndpointAddress & 0x80) == 0)
            {
                continue;
            }

            DEBUGMSG(ZONE_PDD, (L"UfnPdd_RegisterDevice() - "
                L"Configuring Interface %02u EndPoint %02u (TX)\r\n", ifc, epx));

            // Get EP address
            ep = pEP->Descriptor.bEndpointAddress & 0x0F;

            // Save max packet size & direction
            pPdd->ep[ep].maxPacketSize = pEP->Descriptor.wMaxPacketSize;
            pPdd->ep[ep].dirRx = FALSE;

            // Create EP config
            cfg  = USBD_EP_VALID;

            cfg |= (Log2(pEP->Descriptor.wMaxPacketSize >> 3) << 12);

            if ((pEP->Descriptor.bmAttributes & 0x03) == 0x01)
            {
                cfg |= USBD_EP_ISO;
            }

            cfg |= offset >> 3;

            if (ep > 0)
                OUTREG32(&pUSBDRegs->EP_TX[ep - 1], cfg);
            else
                DEBUGMSG(ZONE_PDD, (L"USBFN:: UfnPdd_RegisterDevice "
                    L"EP_TX = %d\r\n", ep - 1));


            // Update offset
            offset += pEP->Descriptor.wMaxPacketSize;
        }
    }

    // Lock configuration
    SETREG32(&pUSBDRegs->SYSCON1, USBD_SYSCON1_CFG_LOCK);

    DEBUGMSG(ZONE_PDD, (L"UfnPdd_RegisterDevice() - END\r\n"));

    // Done
    return ERROR_SUCCESS;
}


//------------------------------------------------------------------------------
//
//  Function:  UfnPdd_IsEndpointSupportable
//
//  This function is called by MDD to verify if EP can be supported on
//  hardware. It is called after UfnPdd_IsConfigurationSupportable. We must
//  verify configuration in this function, so we already know that EPs
//  are valid. Only information we can update there is maximal packet
//  size for EP0.
//
DWORD WINAPI UfnPdd_IsEndpointSupportable(VOID *pPddContext,
                                          DWORD endPoint,
                                          UFN_BUS_SPEED speed,
                                          USB_ENDPOINT_DESCRIPTOR *pEPDesc,
                                          UCHAR configurationValue,
                                          UCHAR interfaceNumber,
                                          UCHAR alternateSetting)
{
    USBFN_PDD *pPdd = pPddContext;


    // Update maximal packet size for EP0
    if (endPoint == 0)
    {
        DEBUGCHK(pEPDesc->wMaxPacketSize <= 64);
        DEBUGCHK(pEPDesc->bmAttributes == USB_ENDPOINT_TYPE_CONTROL);
        pEPDesc->wMaxPacketSize = 64;
    }

    // Done
    return ERROR_SUCCESS;
}


//------------------------------------------------------------------------------
//
//  Function:  UfnPdd_IsConfigurationSupportable
//
//  This function is called before UfnPdd_RegisterDevice. It should verify
//  that USB device configuration can be supported on hardware. Function can
//  modify EP size and/or EP address.
//
//  For OMAP7xx we should check if total descriptor size is smaller
/// than 2040 bytes and round EP sizes. Unfortunately we don't get information
//  about EP0 max packet size. So we will assume maximal 64 byte size.
//
DWORD WINAPI UfnPdd_IsConfigurationSupportable(VOID              * pPddContext,
                                               UFN_BUS_SPEED       speed,
                                               UFN_CONFIGURATION * pConfig)
{
    DWORD rc = ERROR_INVALID_PARAMETER;
    USBFN_PDD *pPdd = pPddContext;
    UFN_INTERFACE *pIFC;
    UFN_ENDPOINT *pEP;
    DWORD ifc, epx, count;
    DWORD offset, size;


    // TODO: Update self power bit & maxPower

    // We must start with offset 8 + 64 (config plus EP0 size)
    offset = 8 + 64;

    // Clear number of end points
    count = 0;

    // For each interface in configuration
    for (ifc = 0; ifc < pConfig->Descriptor.bNumInterfaces; ifc++)
    {
        // For each endpoint in interface
        pIFC = &pConfig->pInterfaces[ifc];

        for (epx = 0; epx < pIFC->Descriptor.bNumEndpoints; epx++)
        {
            pEP = &pIFC->pEndpoints[epx];

            // We support maximal sizes 8, 16, 32 and 64 bytes for non-ISO
            size = pEP->Descriptor.wMaxPacketSize;

            // First round size to supported sizes
            size = 1 << Log2(size);

            // Is it ISO end point?
            if ((pEP->Descriptor.bmAttributes & 0x03) != 0x01)
            {
                // Non-ISO, max size is 64 bytes
                if (size > 64)
                {
                    size = 64;
                }
            }
            else
            {
                // ISO edpoint, maximal size is 512 bytes
                if (size > 512)
                {
                    size = 512;
                }
            }

            // Update EP size
            pEP->Descriptor.wMaxPacketSize = (USHORT)size;

            // Calculate total buffer size
            offset += size;
        }

        // Add number of end points to total count
        count += pIFC->Descriptor.bNumEndpoints;
    }

    // Can we support this configuration?
    if (count < USBD_EP_COUNT && offset <= 2048)
    {
        rc = ERROR_SUCCESS;
    }

    // Done
    return rc;
}


//------------------------------------------------------------------------------
//
//  Function:  UfnPdd_Init
//
//  This function is called by MDD on driver load. It should reset driver,
//  fill PDD interface structure. It can also get SYSINTR, initialize interrupt
//  threa

⌨️ 快捷键说明

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