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

📄 pdd.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                    
                    UNLOCK();
                    UfnPdd_IssueTransfer(pPdd, i,pTransfer);
                    LOCK();
                }
                else
                {
                        pTransfer->dwUsbError=UFN_NO_ERROR;
                }
                
                pPdd->qhbuffer->bPrimed[i] = FALSE;
                                
                if (pTransfer->dwUsbError != UFN_MORE_DATA )
                {
                    CacheSync(CACHE_SYNC_DISCARD);
                    
                    //CacheRangeFlush(pTransfer->pvBuffer, pTransfer->cbBuffer, CACHE_SYNC_DISCARD);
                    
                    if ( pPdd->ep[i]->bPagesLocked )
                    {
                        DEBUGCHK( pPdd->ep[i]->pMappedBufPtr != NULL );
                        UnlockPages(pPdd->ep[i]->pMappedBufPtr, pTransfer->cbBuffer);
                        pPdd->ep[i]->bPagesLocked = 0;
                    }
                    
                    pPdd->ep[i]->pTransfer=NULL;

                    UNLOCK();
                    pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_TRANSFER_COMPLETE, (DWORD)pTransfer);

/*                    RETAILMSG(1, (TEXT("OUT %s Completed for endpoint %d\r\n"), 
                                pTransfer->dwUsbError == UFN_NO_ERROR ? TEXT("Normal") : TEXT("Cancel"),
                                i)); */
                    LOCK();
                }
            }
            else //(pTransfer&&pPdd->qhbuffer->qh[i*2].dtd.status!=0x80)
            {
                RETAILMSG(0, (TEXT("############# ENDPTCOMPLETE %x NULL pTransfer or bad status (0x%x)!\r\n"),
                            (1<<i), 
                            pPdd->qhbuffer->qh[i*2].dtd.status
                            ));
                OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), (1<<i));  
            }
            
        }
        else // Endpoint 0 OUT Transaction if (i)
        {
            DWORD len;
            
            // OUT transcation of endpoint 0
            //   pTransfer=pPdd->ep[USBD_EP_COUNT-1]->pTransfer;
            
            pTransfer=pPdd->ep[0]->pTransfer;
            if (pTransfer)
            {
                
                len=pTransfer->cbBuffer-pPdd->qhbuffer->td[0].tb;
                if (len)
                {
                    pTransfer->cbTransferred+=len;
                    
                    pPdd->qhbuffer->bPrimed[0] = FALSE;
                    if (pTransfer->cbTransferred < pTransfer->cbBuffer)
                    {
                        /* RETAILMSG(1,(L"##### more data to receive on EP0 (status=0x%x)",
                         * pPdd->qhbuffer->td[0].status));
                         */
                        
                        OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), 1);    

                        UNLOCK();
                        UfnPdd_IssueTransfer(pPdd, 0,pTransfer);
                        LOCK();
                        
                        // EP0 is treated just like any other EP at this point (no setup phase ready)
                    }
                    else
                    {
                            pTransfer->dwUsbError=UFN_NO_ERROR;
                        
                        OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), 1);    
                        
                        CacheSync(CACHE_SYNC_DISCARD);
                        
                        if ( pPdd->ep[0]->bPagesLocked && pTransfer->pvBuffer )
                        {
                            DEBUGCHK( pPdd->ep[0]->pMappedBufPtr != NULL );
                            UnlockPages(pPdd->ep[0]->pMappedBufPtr, pTransfer->cbBuffer);
                            pPdd->ep[0]->bPagesLocked = 0;
                        }
                        
                        pPdd->ep[0]->pTransfer=NULL;
                        
                        /* RETAILMSG(1, (TEXT("CheckEndpoint:EP0 OUT %d bytes notify (%s)\r\n"), 
                                    pTransfer->cbTransferred,
                                    (pTransfer->dwUsbError == UFN_NO_ERROR) ? TEXT("Normal") : TEXT("Cancel")
                                    ) ); */
                        
                        UNLOCK();
                        pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_TRANSFER_COMPLETE, (DWORD)pTransfer);
                        LOCK();
                    }
                }
                else
                {
                    OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), 1);    
                }
                
                // RETAILMSG(1, (_T("CheckEndpoint:EP0 OUT %d bytes completed\r\n"), pTransfer->cbTransferred) );
            }
            else // if (pTransfer)
            {
                OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), 1);    
                // RETAILMSG(1, (_T("CheckEndpoint:EP0 OUT NULL transfer complete\r\n")) );
            }
            
        } // if (pTransfer&&pPdd->qhbuffer->qh[i*2].dtd.status!=0x80)
    } //  if (edptcomp.ERCE&(1<<i))  
    
    
    // IN packet transcation
    if (edptcomp.ETCE&(1<<i))
    {
        DWORD mapped_epNum = i;
        
        if (i == 0) 
        {
        /*
        * If this is the completion of a SetAddress (the status handshake part is an "IN") then
        * we should set the address now.  We only set the address after the command.
        * Address is & 0x80 as a flag to tell us to set the address.
            */
            if (pPdd->addr & 0x80)
            {
                DWORD addr;
                pPdd->addr&=0x7f;
                addr=pPdd->addr;
                addr<<=25;    
                
                OUTREG32(&pPdd->pUSBDRegs->OTG.T_154H.USBADR, addr);
                
                //RETAILMSG(1, (L"CheckEndpoint:Set Address: %x(%x), USBADR(%x)=%x \r\n", 
                //addr, pPdd->addr, offset(CSP_USB_REG, T_154H.USBADR) , 
                //INREG32(&pPdd->pUSBDRegs->OTG.T_154H.USBADR))); 
            }
            
            mapped_epNum = USBD_EP_COUNT-1;
        }
        
        pTransfer=pPdd->ep[mapped_epNum]->pTransfer;
        
        if (pPdd->qhbuffer->qh[i*2+1].dtd.status)
            RETAILMSG(1,(L"Status is not 0 on sent %x =%x\r\n",i,pPdd->qhbuffer->qh[i*2+1].dtd.status));
        
        if (pTransfer && pPdd->qhbuffer->qh[i*2+1].dtd.status!=0x80)
        {
            // calculate how much we were trying to transfer
            int len=pTransfer->cbBuffer-pTransfer->cbTransferred;
            if (len>MAX_SIZE_PER_TD)
                len=MAX_SIZE_PER_TD;
            
            len -= pPdd->qhbuffer->qh[i*2+1].dtd.tb; // reduce by what's still to go in the TD
            
            pTransfer->cbTransferred += len;  
            
            pPdd->qhbuffer->bPrimed[mapped_epNum] = FALSE;
            if (pPdd->qhbuffer->qh[i*2+1].dtd.tb)
            {
                RETAILMSG(1,(L"Send error?? len=%x, status=%x, tb=%x\r\n",
                    pTransfer->cbBuffer, pPdd->qhbuffer->qh[i*2+1].dtd.status, pPdd->qhbuffer->qh[i*2+1].dtd.tb));
                pTransfer->cbTransferred=pTransfer->cbBuffer;
            }
            
            if (pTransfer->cbTransferred<pTransfer->cbBuffer)
            {
                pTransfer->dwUsbError=UFN_MORE_DATA;  
                OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), (0x10000UL<<i));   

                UNLOCK();
                UfnPdd_IssueTransfer(pPdd, i, pTransfer); 
                LOCK();
            }
            else
            {
                    pTransfer->dwUsbError=UFN_NO_ERROR;
                
                OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), (0x10000UL<<i));    
                
                if ( pPdd->ep[mapped_epNum]->bPagesLocked )
                {
                    DEBUGCHK( pPdd->ep[mapped_epNum]->pMappedBufPtr != NULL );
                    UnlockPages(pPdd->ep[mapped_epNum]->pMappedBufPtr, pTransfer->cbBuffer);
                    pPdd->ep[mapped_epNum]->bPagesLocked = 0;
                }
                
                pPdd->ep[mapped_epNum]->pTransfer=NULL;
                UNLOCK();
                pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_TRANSFER_COMPLETE, (DWORD)pTransfer);
                LOCK();
                
                /* RETAILMSG(1, (TEXT("IN %s Completed at ep %d\r\n"), 
                            pTransfer->dwUsbError == UFN_NO_ERROR ? TEXT("Normal") : TEXT("Cancel"),
                            i)); */
            }
        }
        else // (pTransfer&&pPdd->qhbuffer->qh[i*2+1].dtd.status!=0x80)
        {
            OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), (0x10000UL<<i));  
        }
        
    } // else if (edptcomp.ETCE&(1<<i))
    
    UNLOCK();
}

/*
 *      Function : USBControllerRun
 *
 *      Description: This sets USB controller to either run or halted
 *
 *      Input :
 *            BOOL   bRunMode  -- if TRUE, then set running, else set stopped
 *
 *       Output:
 *            void
 *       
 *       Return:
 *            ERROR_SUCCESS - okay, mode set
 *            ERROR_GEN_FAILURE -- couldn't set the mode for some reason
 *
 *
 *       Function waits until controller is stopped or started.
 */

static DWORD USBControllerRun( CSP_USB_REGS *pRegs, BOOL bRunMode )
{
        USB_USBCMD_T cmd;
        USB_USBMODE_T mode;
        DWORD *pTmpCmd = (DWORD*)&cmd;
        DWORD *pTmpMode = (DWORD*)&mode;

        *pTmpCmd = INREG32(&pRegs->OTG.USBCMD);
        if ( bRunMode )
        {
            DEBUGMSG(1,(TEXT("Start USB controller (RS=%d -> RS=1)\r\n"), cmd.RS));
            cmd.RS = 1;
        }
        else
        {
            DEBUGMSG(1,(TEXT("Stop USB controller (RS=%d -> RS=0)\r\n"), cmd.RS));
            cmd.RS = 0;
        }

        OUTREG32(&pRegs->OTG.USBCMD,*pTmpCmd);

        *pTmpMode = INREG32(&pRegs->OTG.USBMODE);
        if ( mode.CM == 0x3 )
        {
            // in host mode, make sure HCH (halted) already, and that mode does change to halted (or not)
            USB_USBSTS_T stat;
            DWORD *pTmpStat = (DWORD*)&stat;
            int iAttempts;

            if ( bRunMode )
            {
                *pTmpStat = INREG32(&pRegs->OTG.USBSTS);
                if ( stat.HCH == 0)
                {
                    RETAILMSG(1,(TEXT("USBControllerRun(1): ERROR ############ HCH=0 (stat=0x%x)\r\n"),*pTmpStat));
                    return ERROR_GEN_FAILURE;
                }
            }

            // wait for mode to change
            iAttempts = 0;
            do {
                *pTmpStat = INREG32(&pRegs->OTG.USBSTS);
                if ( (!bRunMode && stat.HCH) || (bRunMode && (stat.HCH == 0)) )
                    return ERROR_SUCCESS;

                Sleep(1);
            } while ( iAttempts++ < 50 );

            RETAILMSG(1,(TEXT("USBControllerRun(%d): failed to set/clear RS\r\n"),bRunMode));
            return ERROR_GEN_FAILURE;
        }

        return ERROR_SUCCESS;
}

//------------------------------------------------------------------------------
//
//  Function:  InterruptThread
//
//  This is interrupt thread. It controls responsed to hardware interrupt. To
//  reduce code length it calls interrupt specific functions.
//
//  Parameter:
//
//      pPddContext - Pointer to USBFN_PDD
//
//  Return:
//
//      ERROR_SUCCESS
//      
//--------------------------------------------------------------------------------
static DWORD WINAPI InterruptThread(VOID *pPddContext)
{
    USBFN_PDD *pPdd = pPddContext;
    CSP_USB_REGS* pUSBDRegs = pPdd->pUSBDRegs;
    USB_USBSTS_T source;
    DWORD *temp;
    int i;
    HANDLE hFunction, hXcvr;
    ULONG WaitReturn;
    TCHAR szUSBFunctionObjectName[30];
    TCHAR szUSBXcvrObjectName[30];
    DWORD timeout = IDLE_TIMEOUT; // 3 sec

    DEBUGMSG(1, (TEXT("IsOTGSupport? %d\r\n"), pPdd->IsOTGSupport));
    if (pPdd->IsOTGSupport) 
    {                    
        lstrcpy(szUSBFunctionObjectName, USBFunctionObjectName);
        lstrcat(szUSBFunctionObjectName, pPdd->szOTGGroup);
        //RETAILMSG(1, (TEXT("USBFN: CreateEvent:%s\r\n"), szUSBFunctionObjectName));
        hFunction = CreateEvent(NULL, FALSE, FALSE, szUSBFunctionObjectName);
        if (GetLastError() == ERROR_ALREADY_EXISTS)
            DEBUGMSG(1, (TEXT("UFN: Opened an existing Func Event\r\n")));
        else
            DEBUGMSG(1, (TEXT("UFN: Created a new Func Event\r\n")));

        if (hFunction == NULL)
            DEBUGMSG(1, (TEXT("UFN: Create Event Failed for func!\r\n")));

        lstrcpy(szUSBXcvrObjectName, USBXcvrObjectName);
        lstrcat(szUSBXcvrObjectName, pPdd->szOTGGroup);
        //RETAILMSG(1, (TEXT("USBFN: CreateEvent:%s\r\n"), szUSBXcvrObjectName));

        hXcvr = CreateEvent(NULL, FALSE, FALSE, szUSBXcvrObjectName);

        if (GetLastError() == ERROR_ALREADY_EXISTS)
            DEBUGMSG(1, (TEXT("UFN: Opened an existing XCVR Event\r\n")));
        else
            DEBUGMSG(1, (TEXT("UFN: Created a new XCVR Event\r\n")));

        if (hXcvr == NULL)
            DEBUGMSG(1, (TEXT("UFN: Create Event Failed for xcvr!\r\n")));

XCVR_SIG:
        pPdd->bInUSBFN = FALSE;
        //RETAILMSG(1, (TEXT("UFN: Waiting for signal from XCVR!!!\r\n")));
        WaitReturn = WaitForSingleObject(hFunction, INFINITE);

        pPdd->bInUSBFN = TRUE;

        //RETAILMSG(1, (TEXT("UFN: Function Driver in charge now!!!\r\n")));
        if (!InterruptInitialize(pPdd->sysIntr, pPdd->hIntrEvent, NULL, 0)) 
        {
            RETAILMSG(1, (L"ERROR: UfnPdd_Init: Interrupt initialization failed\r\n"));
            return -1;
        }

        //RETAILMSG(1, (TEXT("UfnPdd_Start called\r\n")));
        UfnPdd_Start(pPdd);

        // Move this part to here so that it would only handle in case
        // of OTG support
        {
            USB_OTGSC_T temp;
            DWORD       *t = (DWORD *)&temp;

            *t = INREG32(&pUSBDRegs->OTG.OTGSC);
            //RETAILMSG(1, (TEXT("OTGSC IDIE(0x%x), IDIS(0x%x), (0x%x)\r\n"), temp.IDIE, temp.IDIS, *t));
            temp.IDIE = 1;
            OUTREG32(&pUSBDRegs->OTG.OTGSC, *t);
        }


        //RETAILMSG(1, (TEXT("USBFNPDD SysIntr:0x%x, Irq:0x%x\r\n"), pPdd->sysIntr, pPdd->irq));

        // Handling of device attach
        temp=(DWORD *)&source;
        *temp = INREG32(&pUSBDRegs->OTG.USBSTS);
        // Clear source bit
        {

            do {
                if (INREG32(&pUSBDRegs->OTG.ENDPTSETUPSTAT) & 1) 
                {
                    SetupEvent(pPdd);
                }
                
                if (INREG32(&pUSBDRegs->OTG.ENDPTCOMPLETE)) 
                {
                    for (i=0;i<USBD_EP_COUNT;i++)

⌨️ 快捷键说明

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