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

📄 usbdbgpdd.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft
// premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license
// agreement, you are not authorized to use this source code.
// For the terms of the license, please see the license agreement
// signed by you and Microsoft.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
#include <windows.h>
#include <usb200.h>
#include <usbtypes.h>
#include <oal.h>
#include <bsp.h>
#include <usbdbgddsi.h>
#include <usbdbgutils.h>
#include "Otgdev.h"


///=============================================================================
/// Discussions
///=============================================================================
/* Interrupt mode - USBDBG mode always runs in polling mode. Interrupt mode
// means interrupts will inform kernel kitl code that a packet has been received
// on a usb endpoint. Implementing interrupt mode improves kitl driver
// performance.
//
// To enable interrupt mode:
// 1. Enable interrupts for
//      a. changes to bus state (reset, suspend, resume, attach, detach)
//      b. setup packet on control endpoint, EP0
//      c. OUT endpoints, EP3 (receiving endpoint)
// 2. Tie the USB function controller interrupt to KITL sysintr (kernel KITL
//    code will then call Rndis_RecvFrame in usbdbgrndismdd to receive the
//    packet).
*/
///

///=============================================================================
/// Global defines
///=============================================================================
// mandatory (refer usbdbgddsi.h for available zones)
UINT32 g_UsbDbgZones =  USBDBG_ZONE_ERROR | USBDBG_ZONE_WARN |
                        USBDBG_ZONE_INFO;// | USBDBG_ZONE_RECV | USBDBG_ZONE_SEND | USBDBG_ZONE_VERBOSE |
                        //USBDBG_ZONE_FUNC;

DWORD g_LastRxPktStatus;


///=============================================================================
/// Macros
///=============================================================================
                      


///=============================================================================
/// Local defines
///=============================================================================

// define product specific strings
#define MANUFACTURER    L"Samsung"
#define PRODUCT         L"USBDBG KITL for SMDK6410"


///=============================================================================
/// External functions
///=============================================================================



///=============================================================================
/// Static variables
///=============================================================================
static const USB_STRING m_Manufacturer =
{
    sizeof(MANUFACTURER) + 2,
    USB_STRING_DESCRIPTOR_TYPE,
    MANUFACTURER
};

static const USB_STRING m_Product =
{
    sizeof(PRODUCT) + 2,
    USB_STRING_DESCRIPTOR_TYPE,
    PRODUCT
};


///=============================================================================
/// Private Functions
///=============================================================================

///=============================================================================
/// Private Functions
///=============================================================================

#ifdef DEBUG
// print a setup packet request
static
void
PrintUDR(
    USB_DEVICE_REQUEST* udr
    )
{
    USBDBGMSG(USBDBG_ZONE_VERBOSE, (
        L"usbpdd: Endpoint Zero Request bmRequestType = 0x%x, bRequest=0x%x,"
        L"wValue=0x%x,wIndex=0x%x,wLength=0x%x\r\n",
        udr->bmRequestType,
        udr->bRequest,
        udr->wValue,
        udr->wIndex,
        udr->wLength
    ));

}
#endif

static
void
DevStatChangeEvent(
    DWORD source,
    USBDBG_MSG* msg,
    BYTE* msgBuf
    )
{
    // Attach
    if ((source & INT_CONN_ID_STS_CNG) != 0)
    {
        USBDBGMSG(USBDBG_ZONE_VERBOSE, (L"usbpdd: Device attach detected.\r\n"));

        // Clear source bit
        OUTREG32(GINTSTS, INT_CONN_ID_STS_CNG);
    }

    // Detach
    if ((source & INT_DISCONN) != 0)
    {
        USBDBGMSG(USBDBG_ZONE_VERBOSE, (L"usbpdd:Device detach detected.\r\n"));

        // Clear source bit
        OUTREG32(GINTSTS, INT_DISCONN);
        
        *msg = USBDBG_MSG_BUS_EVENT_DETACH;
        goto clean;
    }

    // Reset
    if ((source & INT_RESET) != 0)
    {
        USBDBGMSG(USBDBG_ZONE_VERBOSE, (L"usbpdd: Reset detected.\r\n"));

        // Clear source bit
        OUTREG32(GINTSTS, INT_RESET);

        // Send the reset event only after the enumeration is done
        // This way the MDD can query the current packet sizes selected
        // based on the enumerated speed.
        
        OTGDevice_HandleReset();
        
        goto clean;
    }

    // Suspend
    if ((source & INT_SUSPEND) != 0)
    {
        USBDBGMSG(USBDBG_ZONE_VERBOSE, (L"usbpdd: Suspend detected.\r\n"));

        // Clear source bit
        OUTREG32(GINTSTS, INT_SUSPEND);

        *msg = USBDBG_MSG_BUS_EVENT_SUSPEND;
        goto clean;
    }

    // Resume
    if ((source & INT_RESUME) != 0)
    {
        USBDBGMSG(USBDBG_ZONE_VERBOSE, (L"usbpdd: Resume detected.\r\n")); 

        // Clear source bit
        OUTREG32(GINTSTS, INT_RESUME);

        // In the middle of a reset don't process other changes
        *msg = USBDBG_MSG_BUS_EVENT_RESUME;
        goto clean;
    }
    
    // Enum Done
    if ((source & INT_ENUMDONE) != 0)
    {
        USBDBGMSG(USBDBG_ZONE_VERBOSE, (L"usbpdd:Device enumeration completed.\r\n"));

        OTGDevice_HandleEnumDone();

        // Clear source bit
        OUTREG32(GINTSTS, INT_ENUMDONE);

        // Signal the reset (and enum done) event to MDD
        *msg = USBDBG_MSG_BUS_EVENT_RESET;
        
        goto clean;
    }

clean:
    return;
}


static
void
ProcessSetupEvent(
    USBDBG_MSG* msg,
    BYTE* msgBuf
    )
{
    DWORD data[2];
    USB_DEVICE_REQUEST *pSetup = (USB_DEVICE_REQUEST*)data;
    
    data[0] = INREG32(EP_FIFO[0]);
    data[1] = INREG32(EP_FIFO[0]);

#ifdef DEBUG
    PrintUDR(pSetup);
#endif

    // MDD doesn't call PDD back on these messages
    if (pSetup->bmRequestType == 0)
    {
        switch(pSetup->bRequest)
        {
            case USB_REQUEST_SET_CONFIGURATION:
                if (pSetup->wValue != 0)
                {
                    // device is now in configured state
                    oOtgDev.m_uIsUsbOtgSetConfiguration = 1;
                }
                else
                {
                    oOtgDev.m_uIsUsbOtgSetConfiguration = 0;
                }
                break;

            case USB_REQUEST_SET_ADDRESS:
                OTGDevice_SetAddress(pSetup->wValue);
                break;
        }
    }

    *msg = USBDBG_MSG_SETUP_PACKET;
    memcpy(msgBuf, data, sizeof(data));
}



static
void
WaitForSetupXferDone()
{
    DWORD iStatusRetry = 0;
    DWORD LastCTLRegVal=0;
    DWORD LastINTRegVal=0;
    DWORD LastStatRegVal=0;
    DWORD CTLRegVal=0;
    DWORD INTRegVal=0;
    DWORD StatRegVal=0;
    DWORD pktsize;
    DWORD i=0;
    
    LastCTLRegVal = INREG32(DOEPCTL0);
    LastINTRegVal = INREG32(DOEPINT0);
    
    do
    {
        INTRegVal = INREG32(GINTSTS);
        if (INTRegVal & INT_RX_FIFO_NOT_EMPTY)
        {
            StatRegVal = INREG32(GRXSTSR);
            if ((StatRegVal & PKT_STATUS_MASK) == OUT_XFR_COMPLETED)
            {
                // status entry notifying completion of an earlier OUT transfer
                // just pop it and drop, otherwise we will never get to the Setup Xfer completed status 
                StatRegVal = INREG32(GRXSTSP);
                g_LastRxPktStatus = StatRegVal;

                pktsize = (g_LastRxPktStatus & 0x7ff0)>>4;
                if (pktsize > 0)
                {
                    USBDBGMSG(USBDBG_ZONE_WARN, (L"UsbDbgPdd_RecvData: Waitloop: dwGrxStatus=0x%x (OUT_XFR_COMPLETED) Non zero packet size\r\n", g_LastRxPktStatus));
                }
            } 

            if ((StatRegVal & PKT_STATUS_MASK) == OUT_PKT_RECEIVED)
            {
                break;
            }

            if ((StatRegVal & PKT_STATUS_MASK) == SETUP_XFR_COMPLETED)
            {
                StatRegVal = INREG32(GRXSTSP);
                g_LastRxPktStatus = StatRegVal;

                pktsize = (g_LastRxPktStatus & 0x7ff0)>>4;
                if (pktsize > 0)
                {
                    USBDBGMSG(USBDBG_ZONE_WARN, (L"UsbDbgPdd_RecvData: Waitloop: dwGrxStatus=0x%x (SETUP_XFR_COMPLETED) Non zero packet size\r\n", g_LastRxPktStatus));
                }
                
                break;
            }
        }
        iStatusRetry++;
    } while (iStatusRetry < 10000);
    
    
    CTLRegVal = INREG32(DOEPCTL0);
    INTRegVal = INREG32(DOEPINT0);

    if (!(INTRegVal & 0x8) && iStatusRetry < 10000)
    {
        do
        {
            INTRegVal = INREG32(DOEPINT0);
            if(INTRegVal & 0x8)
            {
                break;
            }
            iStatusRetry++;
        } while (iStatusRetry < 10000);
    }

}



static
void
PowerOff(
    )
{

}

static
void
PowerOn(
    )
{

}



///=============================================================================
/// USBDBG_PDD DDSI (mdd/pdd) interface
///=============================================================================

//==============================================================================
// Description: Called by MDD when KITL or DLE call its pfnDeInit
//
// Arguments:
//
// Return Value:
//
extern "C"
void
UsbDbgPdd_DeInit(
    )
{
    // Disconnect hardware
    OTGDevice_SetSoftDisconnect();

    OTGDevice_DeInit();
}


//==============================================================================
// Description: Called by MDD during initialization to attach to USB bus.
//
// Arguments:   Device descriptor returned by MDD to Host
//
// Return Value: TRUE if success else FALSE 
// 
extern "C"
BOOL
UsbDbgPdd_Connect(
    USBDBG_DEVICE_DESCRIPTOR* pDeviceDesc
    )
{
    BOOL rc = FALSE;
    
    USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbpdd: +UsbDbgPdd_Connect\r\n"));

    // Connect the line
    OTGDevice_ClearSoftDisconnect();

    USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbpdd: -UsbDbgPdd_Connect\r\n"));
    return rc;

}

//==============================================================================
// Description: Called by MDD to disconnect from USB bus
//
// Arguments:  None
//
// Return Value: TRUE if success else FALSE 
// 
extern "C"
BOOL
UsbDbgPdd_Disconnect(
    )
{
    USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbpdd: +UsbDbgPdd_Disconnect\r\n"));
    
    // Disconnect hardware
    OTGDevice_SetSoftDisconnect();

    USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbpdd: -UsbDbgPdd_Disconnect\r\n"));

    return TRUE;

}


//==============================================================================
// Description: Called by MDD to get some PDD specific properties. Look at
//              USBDBG_PDD_IOCTL in file usbdbgifc.h
//
// Arguments:   see below
//
// Ret Value:   TRUE if IOCTL is supported else return FALSE. MDD will use
//              the default implementation of an IOCTL if PDD returns FALSE.
// 
extern "C"
BOOL
UsbDbgPdd_Ioctl(
    DWORD ioControlCode,        /* USBDBG_PDD_IOCTL */
    LPVOID lpInBuffer,          /* incoming buffer */
    DWORD  cbInBufferSize,      /* incoming buffer size */
    LPVOID lpOutBuffer,         /* outgoing buffer */
    DWORD  cbOutBufferSize,     /* outgoing buffer size */
    LPDWORD lpBytesReturned     /* outgoing buffer filled */
    )
{
    switch (ioControlCode)
    {
        // return maxpacket size for an endpoint
        case USBDBG_PDD_IOCTL_ENDPT_MAXPACKETSIZE:
            if (lpInBuffer && lpOutBuffer)
            {
                DWORD endPtNum = *((DWORD*)lpInBuffer);
                if (endPtNum == 0)
                {
                    *((UINT32*)lpOutBuffer) = oOtgDev.m_uControlEPMaxPktSize;
                }
                else
                {
                    *((UINT32*)lpOutBuffer) = oOtgDev.m_uBulkInEPMaxPktSize;
                }
            }            
            return TRUE;
            break;

        case USBDBG_PDD_IOCTL_MANUFACTURER_STRING:
        {
            // lpOutBuffer = USB_STRING** ppManufacturer
            if (lpOutBuffer)
                *((USB_STRING**)(lpOutBuffer)) = (USB_STRING*) &m_Manufacturer;
            return TRUE;
            break;
        }
        case USBDBG_PDD_IOCTL_PRODUCT_STRING:
        {
            // lpOutBuffer = USB_STRING** ppProduct
            if (lpOutBuffer)
                *((USB_STRING**)(lpOutBuffer)) = (USB_STRING*) &m_Product;

            return TRUE;
            break;
        }
    }

    // for rest of the properties use MDD's default    
    return FALSE;
}


//==============================================================================
// Description: MDD calls this API repeatedly to receive updates on USB bus
//              states, receive, transmit complete events on endpoints and setup
//              packet on Endpoint 0.
//
// Arguments:   msg. (OUT) set to the appropriate USBDBG_MSG* defined in
//                   usbdbgddsi.h
//              msgBuf. (OUT) set to setup packet or the endpoint number
//                  [64 bytes in length]
//
// Ret Value:   ERROR_SUCCESS if no error else return error code.
// 
extern "C"
DWORD
UsbDbgPdd_EventHandler(
    USBDBG_MSG* msg,
    BYTE* msgBuf
    )
{
    DWORD source;
    DWORD epNum;
    DWORD epIntNum;
    DWORD pktsize;

⌨️ 快捷键说明

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