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

📄 usbdbgpdd.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    DWORD epIntStatus;
    BOOL fProcessed = FALSE;
    
    *msg = USBDBG_MSG_NOMSG;           //no msg by default

    // Get interrupt source and clear it
    source = INREG32(GINTSTS);

    if (source == 0)
        goto clean;

    // Device state change?
    if ((source & (INT_RESET | INT_RESUME | INT_SUSPEND | INT_DISCONN | INT_CONN_ID_STS_CNG | INT_ENUMDONE)) != 0)
    {
        // Handle device state change
        DevStatChangeEvent(source, msg, msgBuf);
        
        // don't process other interrupts
        goto clean;
    }
    
    
    // RX interrupt
    if (source & INT_RX_FIFO_NOT_EMPTY)
    {
        // Pop packet status
        g_LastRxPktStatus = INREG32(GRXSTSP);

        if (((g_LastRxPktStatus & PKT_STATUS_MASK) == SETUP_XFR_COMPLETED))
        {
            pktsize = (g_LastRxPktStatus & 0x7ff0)>>4;
            if (pktsize > 0)
            {
                USBDBGMSG(USBDBG_ZONE_WARN, (L"UsbDbgPdd_EventHandler: RX_FIFO_NOT_EMPTY dwGrxStatus=0x%x (SETUP Completed) Non zero packet size\r\n", g_LastRxPktStatus));
            }
        }
        else if ((g_LastRxPktStatus & PKT_STATUS_MASK) == OUT_PKT_RECEIVED)
        {
            // get endpoint
            epNum = g_LastRxPktStatus & 0xF;

            // tell MDD pkt received on EPn
            *msg = USBDBG_MSG_EP_RX_PKT;
            *((DWORD*)(msgBuf)) = epNum;

            fProcessed = TRUE;
        }
        else if ((g_LastRxPktStatus & PKT_STATUS_MASK) == SETUP_PKT_RECEIVED)
        {
            // Setup Packet
            ProcessSetupEvent(msg, msgBuf);
            fProcessed = TRUE;
        }

        if (fProcessed)
        {
            goto clean; 
        }
    }

    // IN Endpoint interrupt
    if (source & INT_IN_EP)
    {
        // Find the endpoint number
        epIntNum = INREG32(DAINT);
        epNum = 0;
        while(!(epIntNum & 1))
        {
            epIntNum = epIntNum >> 1;
            epNum++;
        }
        epIntStatus = INREG32(DIEPINT[epNum]);

        if ((epIntStatus & TRANSFER_DONE) &&
            (EndPointsInfo[epNum].EndPtAttributes != 3)) // Need not indicate TRANSFER_DONE for INT IN ep
        {
            // tell MDD pkt transmitted on EPn
            *msg = USBDBG_MSG_EP_TX_PKT;
            *((DWORD*)(msgBuf)) = epNum;
        }

        // Clear source bit
        OUTREG32(DIEPINT[epNum], epIntStatus);
        goto clean;
    }

    // OUT Endpoint interrupt
    if (source & INT_OUT_EP)
    {
        // Find the endpoint number
        epIntNum = INREG32(DAINT);
        epIntNum = epIntNum >> 16; 
        epNum = 0;
        while(!(epIntNum & 1))
        {
            epIntNum = epIntNum >> 1;
            epNum++;
        }
        epIntStatus = INREG32(DOEPINT[epNum]);

        // Clear source bit
        OUTREG32(DOEPINT[epNum], epIntStatus);
        goto clean;
    }


clean:           

    return ERROR_SUCCESS;  

}



//==============================================================================
// Description: MDD calls this function to 
//              1) start a receive transfer on an endpoint
//              2) receive data from an endpoint after getting endpoint rx 
//                 interrupt via UsbDbgPdd_EventsHandler
//
//              Start a receive transfer: when transferFlags = 
//              USBDBG_MDD_TRANSFER_START, start a receive transfer on the 
//              endpt. Do not read value from the receive FIFO yet.
//
//              Receive data: when transferFlags != USBDBG_MDD_TRANSFER_START,
//              read the data from FIFO and write to pBuffer.
//              If buffer is filled up completely or a short packet (packet size
//              smaller than maxpktsize) is received, disable the receive FIFO
//              else reenable the FIFO.
//
// Arguments:   epNum. endpt to receive data on.
//                  USBDBGRNDISMDD endpts: 0, 1: INT IN, 2: BULK IN, 3: BULK OUT
//                  USBDBGSERMDD endpts:   0, 1: BULK OUT, 2: BULK IN
//              pBuffer. buffer data is received in. 
//              cbBufLen. size of pBuffer. If buffer is completely filled 
//                  disable the RX FIFO and set pTransferStatus = 
//                  USBDBG_PDD_TRANSFER_COMPLETE. If a short packet is received,
//                  disable RX FIFO and set pTransferStatus = 
//                  USBDBG_PDD_TRANSFER_COMPLETE. Else reenable the FIFO for
//                  next packet.
//              transferFlags. Bitwise OR of flags.
//                  if transferFlags == USBDBG_MDD_TRANSFER_START start the
//                  transfer. do not return data.
//                  USBDBG_MDD_EP0_STATUS_STAGE marks a receive for EP0 status
//                  stage.
//              pTransferStatus. OUT. set pTransferStatus = 
//                  USBDBG_PDD_TRANSFER_COMPLETE when pBuffer is filled up or
//                  a short packet is received.
//
// Ret Value:   count in bytes of data received. return -1 if error (MDD cancels
//              the transfer if -1 is returned)
// 
extern "C"
DWORD
UsbDbgPdd_RecvData(
    DWORD epNum,
    PBYTE pBuffer,
    DWORD cbBufLen,
    DWORD transferFlags,
    DWORD* pTransferStatus
    )
{
    DWORD count, remain;
    DWORD dwData;
    DWORD index;
    DWORD cbRecvd = 0;
    DWORD cbFullPkt = 0;
    DWORD GrxStatus;

    // just enable RX FIFO and return if transfer is starting
    // MDD is not expecting data at this time
    if (transferFlags & USBDBG_MDD_TRANSFER_START)
    {
        if (((g_LastRxPktStatus & PKT_STATUS_MASK) == SETUP_PKT_RECEIVED) &&
            (epNum == 0))
        {
            // MDD is expecting an OUT packet on EP0 right after receiving a setup packet.
            // This happens for USB RNDIS because the SEND_ENCAPSULATED_COMMAND message is
            // sent as a SETUP packet with the command details coming in as OUT packets on EP0
            // Let's wait here to ensure that the setup transaction is completed and/or OUT EP is ready
            // Otherwise, some data munching is observed on Rx FIFO

            WaitForSetupXferDone();
        }
        
        // set transfer sizes
        OTGDevice_SetOutEpXferSize(epNum, 1); // 1 packet
        
        // Enable endpoint, clear NAK bit
        SETREG32(DOEPCTL[epNum], (DEPCTL_EPENA |DEPCTL_CNAK)); 
        
        goto clean;
    }

    // We get to this point because a packet was RX on epNum
    // (HW automatically disables RX FIFO after receiving packet)
    
    GrxStatus = g_LastRxPktStatus;
    
    ASSERT((GrxStatus & OUT_PKT_RECEIVED) == OUT_PKT_RECEIVED);
    if((GrxStatus & OUT_PKT_RECEIVED) != OUT_PKT_RECEIVED)
        USBDBGMSG(USBDBG_ZONE_WARN, (L"usbpdd:UsbDbgPdd_RecvData: !OUT_PKT_RECEIVED\r\n"));
    
    count = (GrxStatus & 0x7ff0)>>4;

    // if expected data = 0 bytes, we just received it.
    // do not read FIFO. return. ?? since MDD buffer is full disable RX FIFO
    if (cbBufLen == 0) 
    {
        if(count != 0)
            USBDBGMSG(USBDBG_ZONE_WARN, (L"usbpdd:UsbDbgPdd_RecvData: count != 0 for a zero byte packet\r\n"));
        goto clean;
    }

    // Read data
    remain = count;
    while (remain > 4)
    {
        dwData = INREG32(EP_FIFO[epNum]);
        pBuffer[0] = (UCHAR)dwData;
        pBuffer[1] = (UCHAR)(dwData >> 8);
        pBuffer[2] = (UCHAR)(dwData >> 16);
        pBuffer[3] = (UCHAR)(dwData >> 24);
        pBuffer += 4;
        remain -= 4;
    }
    
    if (remain > 0)
    {
        dwData = INREG32(EP_FIFO[epNum]);
        for (index=0; index<remain; index++)
        {
            pBuffer[index] = (UCHAR)(dwData >> (index*8));
        }
    }

    // set number of bytes received
    cbRecvd = count;

    // check to make sure data recvd < buffer length (should not happen)
    if (cbRecvd > cbBufLen)
    {
        USBDBGMSG(USBDBG_ZONE_ERROR, (
            L"usbpdd:ERROR: rx %d bytes > buflen=%d bytes\r\n",
            cbRecvd, cbBufLen));
        cbRecvd = 0;
        goto clean;
    }

    // enable RX FIFO/endpoint if MDD receive buffer is not full
    // and short packet not received
    cbFullPkt = (epNum == 0) ? oOtgDev.m_uControlEPMaxPktSize : oOtgDev.m_uBulkOutEPMaxPktSize;
    if ((cbBufLen > cbRecvd) && (cbRecvd == cbFullPkt))
    {
        // set transfer sizes
        OTGDevice_SetOutEpXferSize(epNum, 1); // 1 packet
        
        // Enable endpoint
        SETREG32(DOEPCTL[epNum], (DEPCTL_EPENA |DEPCTL_CNAK));
    }
    else
    {
        *pTransferStatus |= USBDBG_PDD_TRANSFER_COMPLETE;
    }

clean:

    USBDBGMSG(USBDBG_ZONE_FUNC, (
            L"usbpdd:ep%d recv %d bytes flags=0x%x\r\n",
            epNum, cbRecvd, transferFlags
        ));

    return cbRecvd;
}



//==============================================================================
// Description: MDD calls this function to send data over an endpoint. Send 
//              max data over the endpoint and return cb of data sent.
//
// Arguments:   epNum. endpt to send data on.
//                  USBDBGRNDISMDD endpts: 0, 1: INT IN, 2: BULK IN, 3: BULK OUT 
//                  USBDBGSERMDD endpts:   0, 1: BULK OUT, 2: BULK IN
//              pBuffer. buffered data to send. Note: **this is not aligned.**
//              cbBufLen. size of pBuffer.
//              transferFlags. Bitwise OR. 
//                  USBDBG_EP0_STATUS_STAGE marks a send for EP0 status
//                  stage.
//              pTransferStatus. OUT. set pTransferStatus = 
//                  USBDBG_PDD_TRANSFER_COMPLETE when MDD should not wait for a
//                  TX interrupt which signals that this packet has been
//                  transferred
//
// Ret Value:   count in bytes of data sent. if error returns -1 (current
//              transfer will be cancelled).
//
extern "C"
DWORD
UsbDbgPdd_SendData(
    DWORD epNum,
    PBYTE pBuffer,
    DWORD cbLength,
    DWORD transferFlags,
    DWORD* pTransferStatus
    )
{
    DWORD data;
    DWORD index;
    volatile DWORD dwRegVal;
    DWORD maxpkt = (epNum == 0) ? oOtgDev.m_uControlEPMaxPktSize : oOtgDev.m_uBulkInEPMaxPktSize;
    DWORD pktCount = 0;
    DWORD cbDataToSend = cbLength > maxpkt ? maxpkt : cbLength;
    DWORD cbDataSent = cbDataToSend;

    USBDBGMSG(USBDBG_ZONE_FUNC, (
            L"usbpdd (++):ep%d To send %d bytes flags=0x%x maxpkt=%d\r\n",
            epNum, cbLength, transferFlags, maxpkt
        ));
   
    // clear all interrupts for this endpoint
    dwRegVal = INREG32(DIEPINT[epNum]);
    OUTREG32(DIEPINT[epNum], dwRegVal);

    // Set the transfer sizes
    OUTREG32(DIEPTSIZ[epNum], (1<<19)|(cbDataToSend<<0)); // packet count = 1, xfr size

    // Enable endpoint, clear NAK bit
    SETREG32(DIEPCTL[epNum], (DEPCTL_EPENA |DEPCTL_CNAK)); 

    
    // Write data to FIFO
    while (cbDataSent >= 4) 
    {
        data = (pBuffer[3] << 24) | (pBuffer[2] << 16) | (pBuffer[1] << 8) | pBuffer[0];
        OUTREG32(EP_FIFO[epNum], data);
        pBuffer += 4;
        cbDataSent -= 4;
    }

    if (cbDataSent > 0)
    {
        data = 0;
        for (index=0; index<cbDataSent; index++)
        {
            data |= (pBuffer[0] << (index*8));
            pBuffer++;
        }
        OUTREG32(EP_FIFO[epNum], data);
    }

    // for interrupt IN EP, indicate completion now.
    if (EndPointsInfo[epNum].EndPtAttributes == 3)
    {
        *pTransferStatus |= USBDBG_PDD_TRANSFER_COMPLETE;
    }

    // issued a transfer on ENDPTN
    USBDBGMSG(USBDBG_ZONE_FUNC, (
            L"usbpdd (--):ep%d send %d bytes flags=0x%x\r\n",
            epNum, cbDataToSend, transferFlags
        ));

    return cbDataToSend;
}


//==============================================================================
// Description: MDD calls this function to send miscellaneous commands to pdd.
//              Look at usbdbgddsi.h for USBDBG_CMD_* commands
//
// Arguments:   cmd: an USBDBG_CMD_* command
//              epNum: logical endpoint number
//              epDir: endpoint direction (ENDPT_DIR_IN or ENDPT_DIR_OUT)
//
// Ret Value:   Ignored.
//
extern "C"
DWORD
UsbDbgPdd_SendCmd(
    USBDBG_CMD cmd,
    DWORD epNum,
    USBDBG_ENDPTDIR epDir
    )
{
    DWORD dwRegVal;

    USBDBGMSG(USBDBG_ZONE_FUNC, (L"+UsbDbgPdd_SendCmd\r\n"));
    
    switch (cmd)
    {
        // abort transfer on an endpt
        case USBDBG_CMD_TRANSFER_ABORT:
        {
            if (epNum != 0)
            {
                if (epDir == ENDPT_DIR_IN)
                {
                     if (INREG32(DIEPCTL[epNum]) & DEPCTL_EPENA)
                     {
                        OUTREG32(DIEPCTL[epNum], DEPCTL_EPDIS);
                        do
                        {
                            dwRegVal = INREG32(DIEPINT[epNum]);
                        }while( (dwRegVal & 0x2) == 0);
                     }
                }
                else
                {
                    if (INREG32(DOEPCTL[epNum]) & DEPCTL_EPENA)
                    {
                        OUTREG32(DOEPCTL[epNum], DEPCTL_EPDIS);
                        do
                        {
                            dwRegVal = INREG32(DIEPINT[epNum]);
                        }while( (dwRegVal & 0x2) == 0);
                     }
                }
            }
            break;
        }

        default:
            break;
    }

    USBDBGMSG(USBDBG_ZONE_FUNC, (L"-UsbDbgPdd_SendCmd\r\n"));
    return ERROR_SUCCESS;
}

//==============================================================================
// Description: MDD calls this function when OAL calls IOCTL_KITL_POWER_CALL to
//              suspend or resume the device. When OAL calls suspend, 
//              fPowerOff=TRUE. When OAL calls resume, fPowerOff=FALSE. 
//              PDD should take appropriate action here to tear down the USB
//              debug connection (can be as simple as logically detaching USB
//              cable) or reenable the USB Debug connection (can be as simple
//              as logically attaching USB cable).
//
// Arguments:   When OAL calls suspend, fPowerOff=TRUE.
//              When OAL calls resume, fPowerOff=FALSE.
//
// Ret Value:  
//
extern "C"
void
UsbDbgPdd_SetPower(
    BOOL fPowerOff
    )
{
    if (fPowerOff)
        PowerOff();
    else
        PowerOn();
}

//==============================================================================
// Description: PDD should always implement this function. MDD calls it during
//              initialization to fill up the function table with rest of the
//              DDSI functions.
//
// Arguments:   pMddIfc (with MDD's version number)
//              pPddIfc (the function table to be filled)
//              pDeviceDesc (usb device descriptor)
//
// Ret Value:   ERROR_SUCCESS.
//
extern "C"
DWORD
UsbDbgPdd_Init(
    USBDBG_MDD_INTERFACE_INFO* pMddIfc,
    USBDBG_PDD_INTERFACE_INFO* pPddIfc,
    USBDBG_DEVICE_DESCRIPTOR* pDeviceDesc
    )
{
    DWORD rc = E_FAIL;
    
    USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbpdd: +UsbDbgPdd_Init\r\n"));

    //1. fill up pddifc table
    //
    pPddIfc->version = 2;
    pPddIfc->pfnDeinit = UsbDbgPdd_DeInit;
    pPddIfc->pfnConnect = UsbDbgPdd_Connect;
    pPddIfc->pfnDisconnect = UsbDbgPdd_Disconnect;
    pPddIfc->pfnIoctl = UsbDbgPdd_Ioctl;
    pPddIfc->pfnEventHandler = UsbDbgPdd_EventHandler;
    pPddIfc->pfnRecvData = UsbDbgPdd_RecvData;
    pPddIfc->pfnSendData = UsbDbgPdd_SendData;
    pPddIfc->pfnSendCmd = UsbDbgPdd_SendCmd;
    pPddIfc->pfnSetPower = UsbDbgPdd_SetPower;

    //2. init local variables
    //
    g_LastRxPktStatus = 0;
    
    //3. initialize hardware
    //
    OTGDevice_Init();

    //4. init end points
    //
    if (!OTGDevice_InitEndPts(pDeviceDesc))
        goto clean;

    rc = ERROR_SUCCESS;

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

    return rc;
}

⌨️ 快捷键说明

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