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

📄 pdd.c

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 C
📖 第 1 页 / 共 5 页
字号:
//
//------------------------------------------------------------------------------
CEDEVICE_POWER_STATE UpdateDevicePower(USBFN_PDD *pPdd)
{
    CEDEVICE_POWER_STATE cpsNew;
    PREFAST_ASSERT(pPdd!=NULL);
    cpsNew= min (pPdd->m_CurPMPowerState, pPdd->m_CurSelfPowerState);

    DEBUGMSG(ZONE_FUNCTION, (_T("UpdateDevicePower Going from D%d to D%d\r\n"), pPdd->m_CurActualPowerState , cpsNew));

    if ( (cpsNew < pPdd->m_CurActualPowerState) && pPdd->hParentBus)
    {
        BOOL bBusSucceed = SetDevicePowerState(pPdd->hParentBus, cpsNew, NULL);
        if (bBusSucceed && 
            (pPdd->m_CurActualPowerState==D3 || pPdd->m_CurActualPowerState==D4))
        {            
            UfnPdd_PowerUp((PVOID)pPdd);
        }
    }

    if ( (cpsNew > pPdd->m_CurActualPowerState ) && pPdd->hParentBus  )
    {
        BOOL bBusSucceed = SetDevicePowerState(pPdd->hParentBus, cpsNew, NULL);
        if (bBusSucceed && (cpsNew == D4 ||cpsNew == D3 ))
        {
            RETAILMSG(1, (TEXT("UpdateDevicePower to powerdown\r\n")));
            UfnPdd_PowerDown((PVOID)pPdd);
        }
    }
    pPdd->m_CurActualPowerState = cpsNew ;
    return (cpsNew) ;
}


//------------------------------------------------------------------------------
//
//  Function:  SetupInterrupt
//
//  This function handles setup packet interrupts.
//
//  Parameter : 
//      pPdd - Pointer to USBFN_PDD
//
//  Return:
//      NULL
//
//--------------------------------------------------------------------------------
static VOID SetupEvent(USBFN_PDD *pPdd)
{
    CSP_USB_REGS*pUSBDRegs = pPdd->pUSBDRegs;
    DWORD data[2];
    USB_DEVICE_REQUEST *pSetup = (USB_DEVICE_REQUEST*)data;

    LOCK();
    if (pPdd->devState==0) // Why no bit set in PORTSC???
    {
        // Let MDD process change
        USB_PORTSC_T state;
        DWORD * t1;
        int i;

        DEBUGMSG(ZONE_PDD, (L"Device Attach\r\n"));

        //
        // Get device state & change
        t1=(DWORD *)&state; 
        *t1 = INREG32(&pUSBDRegs->OTG.PORTSC[USBD_PORT_NUM]);

        pPdd->devState=1;

        UNLOCK();               
        pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_EVENTS, UFN_ATTACH);
        LOCK();

        if (state.PSPD==0x2) 
        {
            UNLOCK();
            pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_SPEED, BS_HIGH_SPEED);
            DEBUGMSG(1,(_T(" BS_HIGH_SPEED   %x\r\n"),BS_HIGH_SPEED) );

            LOCK();
        }
        else
        {
            UNLOCK();
            pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_SPEED, BS_FULL_SPEED);
            DEBUGMSG(1,(_T(" BS_FULL_SPEED   %x\r\n"),BS_FULL_SPEED) );
            LOCK();
        }

        UNLOCK();               
        pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_EVENTS, UFN_RESET);
        LOCK();
        
        DEBUGMSG(1,(_T(" state.PSPD %x\r\n"),state.PSPD) );

        if (state.PSPD==2)
        {
            pPdd->highspeed=1;
            for (i=0;i<USBD_EP_COUNT;i++)
                pPdd->ep[i]=&pPdd->eph[i];
        }
        else
        {
            pPdd->highspeed=0;    
            for (i=0;i<USBD_EP_COUNT;i++)
                pPdd->ep[i]=&pPdd->epf[i];
        }
    }

    GetSetupPacket(pPdd, data);
    // DEBUGMSG(ZONE_PDD,(_T("Setup: %x %x\r\n"),data[0],data[1]) );
    DEBUGMSG(1,(_T("Setup: %x %x\r\n"),data[0],data[1]) );
 
    UNLOCK();

    pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_SETUP_PACKET, (DWORD)data);
}

//----------------------------------------------------------------
// 
//  Function:  DumpDeviceState
//
//  Dump the connection status based on the PORTSC register
//
//  Parameter:
//     state - Pointer to PORTSC register
//
//  Return
//     NULL
//
//----------------------------------------------------------------
void DumpDeviceState( USB_PORTSC_T * state)    
{
    if (state->CCS)
        RETAILMSG(1, (L"\t\tCurrent Connect Status: Attached\r\n"));
    if (state->CSC)
        RETAILMSG(1, (L"\t\tConnect Status Change: Changed\r\n"));
    if (state->PE)
        RETAILMSG(1, (L"\t\tPort Enabled\r\n"));
    if (state->PEC)
        RETAILMSG(1, (L"\t\tPort Enable/Disable Change\r\n"));
    if (state->OCA)
        RETAILMSG(1, (L"\t\tOver-current Active\r\n"));
    if (state->OCC)
        RETAILMSG(1, (L"\t\tOver-current Change\r\n"));
    if (state->FPR)
        RETAILMSG(1, (L"\t\tForce Port Resume\r\n"));
    if (state->SUSP)
        RETAILMSG(1, (L"\t\tSuspend\r\n"));
    if (state->PR)
        RETAILMSG(1, (L"\t\tPort Reset\r\n"));
    if (state->HSP)
        RETAILMSG(1, (L"\t\tHigh-Speed Port \r\n"));

    RETAILMSG(1, (L"\t\tLine Status: %x", state->LS));
    switch (state->LS)
    {
    case 0:
        RETAILMSG(1, (L"\t\t\tSE0\r\n"));
        break;

    case 1:
        RETAILMSG(1, (L"\t\t\tJ-state\r\n"));
        break;

    case 2:
        RETAILMSG(1, (L"\t\t\tK-state\r\n"));
        break;

    case 3:   
    default:
        RETAILMSG(1, (L"\t\t\tUndefined\r\n"));
        break;    
    }

    if (state->PP)
        RETAILMSG(1, (L"\t\t??? Should be 0 for device\r\n"));

    if (state->PO)
        RETAILMSG(1, (L"\t\tPort Owner\r\n"));

    if (state->PIC)
    {
        RETAILMSG(1, (L"\t\tPort Indicator Control"));
        switch (state->PIC)
        {
        case 1:
            RETAILMSG(1, (L"\t\t\tAmber\r\n"));
            break;

        case 2:
            RETAILMSG(1, (L"\t\t\tGreen\r\n"));
            break;

        case 3:
        default:
            RETAILMSG(1, (L"\t\t\tUndefined\r\n"));
            break;
        }
    }    
    if (state->PTC) 
        RETAILMSG(1, (L"\t\tPort Test Control: %x\r\n", state->PTC));

    if (state->WKCN) 
        RETAILMSG(1, (L"\t\tWake on Connect Enable (WKCNNT_E)\r\n"));

    if (state->WKDC) 
        RETAILMSG(1, (L"\t\tWake on Disconnect Enable (WKDSCNNT_E) \r\n"));

    if (state->WKOC) 
        RETAILMSG(1, (L"\t\tWake on Over-current Enable (WKOC_E) \r\n"));

    if (state->PHCD) 
        RETAILMSG(1, (L"\t\tPHY Low Power Suspend - Clock Disable (PLPSCD) \r\n"));

    if (state->PFSC) 
        RETAILMSG(1, (L"\t\tPort Force Full Speed Connect \r\n"));

    RETAILMSG(1, (L"\t\tPort Speed: %x->", state->PSPD));
    switch (state->PSPD)
    {
    case 0:
        RETAILMSG(1, (L"\t\t\tFull Speed\r\n"));
        break;

    case 1:
        RETAILMSG(1, (L"\t\t\tLow Speed\r\n"));
        break;

    case 2:
        RETAILMSG(1, (L"\t\t\tHigh Speed\r\n"));
        break;

    case 3:
    default:
        RETAILMSG(1, (L"\t\t\tUndefined\r\n"));
        break;
    }
    RETAILMSG(1, (L"\t\tParallel Transceiver Width:%x->", state->PTW));
    if (state->PTW) 
        RETAILMSG(1, (L"\t\t\t16 bits\r\n"));
    else
        RETAILMSG(1, (L"\t\t\t8 bits\r\n"));

    if (state->STS) 
        RETAILMSG(1, (L"\t\tSerial Transceiver Select \r\n"));

    RETAILMSG(1, (L"\t\tParallel Transceiver Select:%x->", state->PTS));
    switch (state->PTS)
    {
    case 0:
        RETAILMSG(1, (L"\t\t\tUTMI/UTMI+\r\n"));
        break;

    case 1:
        RETAILMSG(1, (L"\t\t\tPhilips Classic\r\n"));
        break;

    case 2:
        RETAILMSG(1, (L"\t\t\tULPI\r\n"));
        break;

    case 3:
        RETAILMSG(1, (L"\t\t\tSerial/1.1 PHY (FS Only)\r\n"));
        break;
    default:
        RETAILMSG(1, (L"\t\t\tUndefined\r\n"));
        break;

    }                    
}

//------------------------------------------------------------------------------
//
//  Function:  DevStatEvent
//
//  This function handles device state change interrupts.
//
//  Called with context LOCKed
//  
//  Parameters:
//
//      pPdd - Pointer to USBFN_PDD structure
//
//  Return:
//      
//      NULL
//
//-------------------------------------------------------------------------------
static VOID DevStatEvent (USBFN_PDD *pPdd)
{
    CSP_USB_REGS *pUSBDRegs = pPdd->pUSBDRegs;
    DWORD *t1;
    USB_PORTSC_T state;

    // Get device state & change
    t1=(DWORD *)&state; 
    *t1 = INREG32(&pUSBDRegs->OTG.PORTSC[USBD_PORT_NUM]);

    //DumpDeviceState( & state);    
    //Reset

    //Deattach
    if (pPdd->devState&&state.SUSP)
    {
        // TODO: Call bus driver (OTG?) to move HW to deep sleep
        // Let MDD process change        
        DEBUGMSG(ZONE_PDD, (_T("Device Detach\r\n")));

        // Don't process other changes (we are disconnected)
        pPdd->devState=0;

        UNLOCK();
        pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_EVENTS, UFN_DETACH);        
        LOCK();

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

        OUTREG32(&pPdd->pUSBDRegs->OTG.T_154H.USBADR, 0);    
    }    
    
}


//------------------------------------------------------------------------------
//
//  Function:  CopyFromUncachedBuffer
//
//  This function copies the data from the uncached memory back to the user buffers
//
//
//  Parameters:
//
//      pPdd - Pointer to USBFN_PDD structure
//
//      EpNum - endpoint for which copy needs to be done
//
//      len - length of data to be copied
//
//  Return:
//
//      NULL
//
//-------------------------------------------------------------------------------
void CopyFromUncachedBuffer(USBFN_PDD *pPdd, int EpNum, DWORD len )
{

    DWORD dwOffset = ((DWORD)pPdd->ep[EpNum]->pMappedBufPtr) & (UserKInfo[KINX_PAGESIZE] - 1);
    DWORD TdLen, BPCount, EndDataSize, BuffLen = len;

    DEBUGMSG(1,(_T("+CopyFromUncachedBuffer(EP = %d, dwOffset = %d)\r\n"),EpNum,dwOffset));

    // Get the length transfered in the first page, from the offset
    if (len > (MAX_SIZE_PER_BP - dwOffset))
    {
        TdLen = (MAX_SIZE_PER_BP - dwOffset);
        len -= TdLen;
    }
    else
    {
        TdLen = len;
        len = 0;   // first bp contains all the data
    }

    //If first page had all the data, then need to check if offset or the length is aligned
    if ((dwOffset % 32) != 0 || ((BuffLen < (MAX_SIZE_PER_BP - dwOffset)) && ((BuffLen % 32) != 0)))
    {
        DEBUGMSG(0,(_T("Copying for bp0\r\n")));
        memcpy(pPdd->ep[EpNum]->pMappedBufPtr, ((PUCHAR)Buffer_Td1 + dwOffset), TdLen );
    }

    // If the data > 16k then need to check for the Endsize that might have been unaligned,
    // need this only if the Endsize comes in the same page where a 16k size ends.
    if(BuffLen > MAX_SIZE_PER_TD)
    {
        EndDataSize = BuffLen % MAX_SIZE_PER_TD;
        if((EndDataSize + dwOffset) <= MAX_SIZE_PER_BP)
        {
            if ((EndDataSize % 32) != 0)
            {
                memcpy((pPdd->ep[EpNum]->pMappedBufPtr + ( (pPdd->ep[EpNum]->dwNumPages - 1) * MAX_SIZE_PER_BP)), 
                        Buffer_Td2, EndDataSize );
            }
            // All the data has been checked for alignement , so no need to go in the flow.
            len = 0;
        }

⌨️ 快捷键说明

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