sc2443pdd.cpp.old

来自「smdk2443_wince50 embedd」· OLD 代码 · 共 2,284 行 · 第 1/5 页

OLD
2,284
字号
    if (pContext->Ep0State == EP0_STATE_IDLE) {
  //      if (bEP0IrqStatus & EP0RSR) {
            if (!pContext->fSpeedReported) {
		  if(bUSBBusIrqStat && HSP) {
		  	pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_SPEED,
                     BS_HIGH_SPEED);
		  }
		  else {
		  	pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_SPEED,
                     BS_FULL_SPEED);
		  }
                pContext->fSpeedReported = TRUE;
            }
            
            // New setup packet
            const DWORD cbOutFifo = ReadIndexedReg(pContext, 0, BRCR);

		// 16bit Buffer Interface
            PWORD pbUdr = (PWORD) &pContext->udr;
            volatile ULONG *pulFifoReg = _GetDataRegister(0);
            
            DWORD cbBytesRemaining = cbOutFifo;
            while (cbBytesRemaining--) {
                *pbUdr = (WORD) *pulFifoReg;
		  pbUdr ++;
            }
 
	     SetClearReg(pContext, EP0SR, EP0RSR, SET);

                
                // Determine if this is a NO Data Packet
            if (pContext->udr.wLength > 0) {
                    // Determine transfer Direction
                    if (pContext->udr.bmRequestType & USB_ENDPOINT_DIRECTION_MASK) {
                        // Start the SW OUT State Machine
                        pContext->Ep0State = EP0_STATE_IN_DATA_PHASE;     
	     RETAILMSG(DBG, (_T("%s EP0_STATE_IN_DATA_PHASE\r\n"), pszFname));
                    }
                    else {
                        // Start the SW OUT State Machine
                        pContext->Ep0State = EP0_STATE_OUT_DATA_PHASE;                         
                        RETAILMSG(DBG, (_T("%s EP0_STATE_OUT_DATA_PHASE\r\n"), pszFname));                        
                    }

                    pContext->sendDataEnd = FALSE;
            }
            else { // udr.wLength == 0
                    // ClientDriver will issue a SendControlStatusHandshake to 
                    // complete the transaction.
                    pContext->sendDataEnd = TRUE;

                    // Nothing left to do... stay in IDLE.
                    DEBUGCHK(pContext->Ep0State == EP0_STATE_IDLE);
            }

                fSendUdr = TRUE;
    }
	// Data Out Packet
    else if (pContext->Ep0State == EP0_STATE_OUT_DATA_PHASE) {
            
            // Check For out packet read && receive fifo not empty -> out token event
            if (cbFifo) {
                DEBUGMSG(ZONE_RECEIVE, (_T("%s out token packet on endpoint 0 \r\n"),
                    pszFname));                
                HandleRx(pContext, peps, &fCompleted, &dwStatus);
            }
            // status stage of control transfer; zero-length packet received
            else {                     
                DEBUGMSG(ZONE_RECEIVE, (_T("%s status stage of control transfer on endpoint 0\r\n"),
                    pszFname));
                pContext->Ep0State = EP0_STATE_IDLE;
            }
    }
	// Data In Packet
    else {
		
		HandleTx(pContext, peps, 0);
    }

    // Clear any interrupts
    RETAILMSG(DBG, (_T("%s Writing 0x%02x to EP0_CSR\r\n"), pszFname, bEp0CsrToWrite));
    WriteIndexedReg(pContext, 0, EP0SR, bEp0CsrToWrite);

    if (fCompleted) {
        CompleteTransfer(pContext, peps, dwStatus);
    }

    if (fSendUdr) {
        pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_SETUP_PACKET, (DWORD) &pContext->udr);
    }

    FUNCTION_LEAVE_MSG();
    UNLOCK_ENDPOINT(peps);
}


// Process an endpoint interrupt.  Call interrupt-specific handler.
static
VOID
HandleEndpointEvent(
                    PCTRLR_PDD_CONTEXT  pContext,
                    DWORD               dwEndpoint,
                    DWORD               epIrqStat
                    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    ValidateContext(pContext);
    DEBUGCHK(pContext->fRunning);
    DEBUGCHK(dwEndpoint != 0);

    DWORD dwPendingEvents = 0;
    EP_STATUS *peps = GetEpStatus(pContext, dwEndpoint);
    PREFAST_DEBUGCHK(peps);

    LOCK_ENDPOINT(peps);

    ClearEndpointInterrupt(pContext, dwEndpoint);

    WORD bEpIrqStat;
    bEpIrqStat = ReadIndexedReg(pContext, dwEndpoint, ESR);

    if (peps->dwDirectionAssigned == USB_IN_TRANSFER) {
        // Stall "acknowledged" from Host
        if (bEpIrqStat & FSC) {
            USB_DEVICE_REQUEST udr;
            udr.bmRequestType = USB_REQUEST_FOR_ENDPOINT;
            udr.bRequest = USB_REQUEST_CLEAR_FEATURE;
            udr.wValue = USB_FEATURE_ENDPOINT_STALL;
            udr.wIndex = USB_ENDPOINT_DIRECTION_MASK | (BYTE) dwEndpoint;
            udr.wLength = 0;

            DisableEndpointInterrupt(pContext, dwEndpoint);

            DEBUGMSG(ZONE_PIPE, (_T("%s Got IN_SENT_STALL EP%u \r\n"), 
                pszFname, dwEndpoint));

            pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_SETUP_PACKET, (DWORD) &udr);
            // Must Clear both Send and Sent Stall
            SetClearIndexedReg(pContext, dwEndpoint, ESR, FSC, SET);
        }

	if (bEpIrqStat & TPS) {
        // Must Clear Tx Packet Success
        WriteIndexedReg(pContext, dwEndpoint, ESR, bEpIrqStat);
	} 

	if( !(bEpIrqStat & (0x1 << 2))){
		dwPendingEvents = IN_TRANSFER;
	}
    }
    else {
        // Stall "acknowledged" from Host
        if (bEpIrqStat & FSC) {
            USB_DEVICE_REQUEST udr;
            udr.bmRequestType = USB_REQUEST_FOR_ENDPOINT;
            udr.bRequest = USB_REQUEST_CLEAR_FEATURE;
            udr.wValue = USB_FEATURE_ENDPOINT_STALL;
            PREFAST_SUPPRESS(12006, "Buffer access index expression 'udr.wIndex=(USHORT)dwEndpoint' is being truncated in a shortening cast.");
            udr.wIndex = (USHORT) dwEndpoint;
            udr.wLength = 0;
            
            DisableEndpointInterrupt(pContext, dwEndpoint);

            DEBUGMSG(ZONE_PIPE, (_T("%s Got OUT_SENT_STALL EP%u \r\n"), 
                pszFname, dwEndpoint));

            pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_SETUP_PACKET, (DWORD) &udr);
            // Must Clear both Send and Sent Stall
            SetClearIndexedReg(pContext, dwEndpoint, ESR, FSC, SET);
        }

	 if (bEpIrqStat & FFS) {
        // Must Clear FIFO Flushed
        SetClearReg(pContext, ESR, FFS, SET);
	 } 
	if (bEpIrqStat & RPS) {
        // Rx Packet Success is automatically cleared when MCU reads all packets
	dwPendingEvents = OUT_TRANSFER;
	 } 
		
    }

    BOOL fCompleted = FALSE;
    DWORD dwStatus;

    if (dwPendingEvents == IN_TRANSFER) {
        HandleTx(pContext, peps, 0); 
    }

    else if (dwPendingEvents == OUT_TRANSFER) {
        HandleRx(pContext, peps, &fCompleted, &dwStatus);
    }

    if (fCompleted) {
        // Disable transfer interrupts until another transfer is issued.
        DisableEndpointInterrupt(pContext, peps->dwEndpointNumber);
	}

    if (fCompleted) {
        CompleteTransfer(pContext, peps, dwStatus);
	}

    FUNCTION_LEAVE_MSG();
    UNLOCK_ENDPOINT(peps);
}


// Process USB Bus interrupt

VOID
HandleUSBBusIrq(
                    PCTRLR_PDD_CONTEXT  pContext,
                    WORD                bUSBBusIrqStat
                    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    
	 if (bUSBBusIrqStat & VBUSON) {
            SetClearReg(pContext, SSR, VBUSON, SET);          
        }

	 if (bUSBBusIrqStat & SSRINTERR) {
            SetClearReg(pContext, SSR, SSRINTERR, SET);          
        }

	 if (bUSBBusIrqStat & SDE) {
            SetClearReg(pContext, SSR, SDE, SET); 
	     if(bUSBBusIrqStat & HSP){

	     }
	     else {

	     }
        }
	
        if (bUSBBusIrqStat & HFSUSP) {
            SetClearReg(pContext, SSR, HFSUSP, SET);
            
            SetClearReg(pContext, SCR, HSUSPE, CLEAR);

            SetClearReg(pContext, SCR, (RRDE | MFRM), SET);

            if (pContext->attachedState == UFN_ATTACH) {
                DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Suspend\r\n"), pszFname));

                pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_DETACH);
                pContext->attachedState = UFN_DETACH;
            }
        }

        if (bUSBBusIrqStat & HFRM) {
            SetClearReg(pContext, SSR, HFRM, SET);
            
            SetClearReg(pContext, SCR, MFRM, CLEAR);

            // Enable suspend interrupt
            SetClearReg(pContext, SCR, (RRDE | HSUSPE), SET);
			
            if (pContext->attachedState == UFN_DETACH) {
                DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Resume\r\n"), pszFname));
                pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_ATTACH);
                pContext->attachedState = UFN_ATTACH;
            }
        }

        if (bUSBBusIrqStat & HFRES) {
            SetClearReg(pContext, SSR, HFRES, SET);
            
            DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Reset\r\n"), pszFname));
            
            pContext->fSpeedReported = FALSE;

            if (pContext->attachedState == UFN_DETACH){
                pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_ATTACH);
                pContext->attachedState = UFN_ATTACH;
            }
            
            pContext->Ep0State = EP0_STATE_IDLE;
            pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_RESET);

        }

    FUNCTION_LEAVE_MSG();
}


// Process a SC2443 interrupt.

VOID
HandleUSBEvent(
               PCTRLR_PDD_CONTEXT pContext
               )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    ValidateContext(pContext);

    WORD bEpIrqStat = ReadReg(pContext, EIR);
    WORD bUSBBusIrqStat = ReadReg(pContext, SSR);

   RETAILMSG(DBG, (TEXT(" HandleUSBEvent\r\n")));

  //  while (bEpIrqStat || bUSBBusIrqStat) {
        if (bUSBBusIrqStat) {
           RETAILMSG(DBG, (_T("%s System_Status_REG = 0x%02x\r\n"), 
                pszFname, bUSBBusIrqStat));
            HandleUSBBusIrq(pContext, bUSBBusIrqStat);
        }

        if (bEpIrqStat) {
            RETAILMSG(DBG, (_T("%s EP_INT_REG = 0x%02x\r\n"), 
                pszFname, bEpIrqStat));

            if (bEpIrqStat & EP0I) {
                HandleEndpoint0Event(pContext);
            }
            
            // Process All Other (besides EP0) Endpoints
            for (DWORD dwEndpoint = 1; dwEndpoint < ENDPOINT_COUNT; ++dwEndpoint) {
                // Check the Interrupt Mask 
                // Check the Interrupt Status 
                BYTE bEpBit =  EpToIrqStatBit(dwEndpoint);
                if (bEpIrqStat & bEpBit) {
                    HandleEndpointEvent(pContext, dwEndpoint, bEpIrqStat);
                }
   
	        }
        }
        bEpIrqStat = ReadReg(pContext, EIR);
        bUSBBusIrqStat = ReadReg(pContext, SSR);
    
    FUNCTION_LEAVE_MSG();
}


/****************************************************************
@doc INTERNAL

@func VOID | SerUSB_InternalMapRegisterAddresses |
This routine maps the ASIC registers. 
It's an artifact of this
implementation.

@rdesc None.
****************************************************************/

DWORD MapRegisterSet(PCTRLR_PDD_CONTEXT pContext)
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    PREFAST_DEBUGCHK(pContext);

    DEBUGCHK(g_pUDCBase == NULL);

    PBYTE   pVMem;
    DWORD   dwRet = ERROR_SUCCESS;

    // Map CSR registers.
    pVMem = (PBYTE)VirtualAlloc(0, PAGE_SIZE, MEM_RESERVE, PAGE_NOACCESS);

    if (pVMem) {
        BOOL fSuccess = VirtualCopy(pVMem, (LPVOID)pContext->dwIOBase,
            pContext->dwIOLen, PAGE_READWRITE | PAGE_NOCACHE);
        if (!fSuccess) {
            VirtualFree(pVMem, 0, MEM_RELEASE);
            dwRet = GetLastError();
            RETAILMSG(DBG, (_T("%s Virtual Copy: FAILED\r\n"), pszFname));
        }
        else {
            g_pUDCBase = pVMem + BASE_REGISTER_OFFSET;

            RETAILMSG(DBG, (_T("%s VirtualCopy Succeeded, pVMem:%x\r\n"), 
                pszFname, pVMem));
        }
    } 
    else {
        dwRet = GetLastError();
        RETAILMSG(DBG, (_T("%s Virtual Alloc: FAILED\r\n"), pszFname));
    }

    FUNCTION_LEAVE_MSG();
    
    return dwRet;
}

/*++

Routine Description:

Deallocate register space.

Arguments:

None.

Return Value:

None.

--*/
static
VOID
UnmapRegisterSet(PCTRLR_PDD_CONTEXT pContext)
{
    // Unmap any memory areas that we may have mapped.
    if (g_pUDCBase) {
        VirtualFree((PVOID) g_pUDCBase, 0, MEM_RELEASE);
        g_pUDCBase = NULL;
    }
}


// interrupt service routine.

DWORD
WINAPI
ISTMain(
        LPVOID lpParameter
        )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) lpParameter;
    ValidateContext(pContext);

    CeSetThreadPriority(pContext->hIST, pContext->dwISTPriority);

    while (!pContext->fExitIST) {
        pContext->fRestartIST = FALSE;

        // Disable All Endpoint interrupts
        WriteReg(pContext, EIER, 0); // Disable All

        // Enable Device interrupts
        SetClearReg(pContext, SCR, (RRDE | HRESE | HSUSPE | MFRM), SET);

        // Enable Endpoint interrupt 0
        EnableEndpointInterrupt(pContext, 0);

        while (TRUE) {
            DWORD dwWait = WaitForSingleObject(pContext->hevInterrupt, INFINITE);
            if (pContext->fExitIST || pContext->fRestartIST) {
                break;
            }

            if (dwWait == WAIT_OBJECT_0) {
                HandleUSBEvent(pContext);
                InterruptDone(pContext->dwSysIntr);
            }
            else {
                RETAILMSG(DBG, (_T("%s WaitForMultipleObjects failed. Exiting IST.\r\n"), 
                    pszFname));

⌨️ 快捷键说明

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