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

📄 sc2450pdd.cpp.forboardrev1

📁 SMDK2416_BSP
💻 FORBOARDREV1
📖 第 1 页 / 共 5 页
字号:
    // Write 0 to SEND_STALL and SENT_STALL to clear them, so we need to 
    // leave them unchanged by default.
    BYTE bEp0CsrToWrite = 0;

   if(StallFlag){
	RETAILMSG(1, (_T("1_after SendStall Int Gen : EP0SR:%08x bEP0CR : %08x==============\r\n"),bEP0IrqStatus,bEP0CR));
   	StallFlag = FALSE;
	}


    // Set By USB if protocol violation detected
    if (bEP0IrqStatus & EP0SHT) {
        // Must Clear both Send and Sent Stall
        SetClearReg(pContext, EP0SR, EP0SHT, SET);
        SetClearReg(pContext, EP0CR, EP0ESS, CLEAR);
	 if (bEP0IrqStatus & EP0RSR)
	 	SetClearReg(pContext, EP0SR, EP0RSR, SET);
        pContext->Ep0State = EP0_STATE_IDLE;
    }

    if (bEP0IrqStatus & EP0TST) {
        // Must Clear both Send and Sent Stall
        SetClearReg(pContext, EP0SR, EP0TST, SET);
    }


    BOOL fSendUdr = FALSE;
    
    DWORD cbFifo = ReadIndexedReg(pContext, 0, BRCR);
    BOOL fCompleted = FALSE;
    DWORD dwStatus;

	
	// setup packet
    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;
        	}
		else{
			WriteIndexedReg(pContext, 0, EP0SR, bEP0IrqStatus);//for RNDIS Class, adkim
			}
    }
	// Data Out Packet
    else if (pContext->Ep0State == EP0_STATE_OUT_DATA_PHASE) {
		if (bEP0IrqStatus & EP0RSR) {
			
            // 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;
            	}
           }
	else
		RETAILMSG(DBG, (_T("Not RST in outdataphase: 0x%08x =========\r\n"),bEP0IrqStatus ));     
    }
	// Data In Packet
    else {
		
		HandleTx(pContext, peps, 0);
    }


    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);
}

#define DBG_TEST3 1
// 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){
		 RETAILMSG(1, (_T("HIGH Speed\r\n")));
	     }
	     else {
		 RETAILMSG(1, (_T("FULL Speed\r\n")));
	     }
        }



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

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

		  RETAILMSG(1, (_T("%s Suspend\r\n"), pszFname));	
            if (pContext->attachedState == UFN_ATTACH) {
                DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Suspend\r\n"), pszFname));
		  RETAILMSG(1, (_T("%s Suspend_Detach\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);


	RETAILMSG(1, (_T("%s Resume\r\n"), pszFname));	
            if (pContext->attachedState == UFN_DETACH) {
                DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Resume\r\n"), pszFname));
		RETAILMSG(1, (_T("%s Resume_Attach\r\n"), pszFname));	
		Sleep(1000); //for MSF Class,kimsh,  on booting, to generate SD Detect INT and to to mount before storage detectetcion on BOT
                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;

	RETAILMSG(1, (_T("%s Reset\r\n"), pszFname));	

            if (pContext->attachedState == UFN_DETACH){
		RETAILMSG(1, (_T("%s Reset_Attach\r\n"), pszFname));	
                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);

   //by shkim
   WORD nStop = FALSE;
    WORD bEpIrqStat = ReadReg(pContext, EIR);
    WORD bUSBBusIrqStat = ReadReg(pContext, SSR);

    WORD bSCR = ReadReg(pContext, SCR);


  //  while (bEpIrqStat || bUSBBusIrqStat) {
        if (bUSBBusIrqStat) {
            HandleUSBBusIrq(pContext, bUSBBusIrqStat);
	// after notifying, must wait 10ms., by shkim
	// if there is no this code, EP0 Stall is generated and usb connection is failed
	// So, this code is workaround code for usb connection
 	  //   Sleep(10); 
        }

        if (bEpIrqStat) {

          if (bEpIrqStat & EP0I) {
                HandleEndpoint0Event(pContext);
            }
            else //add by shkim
            	{
	            // 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);
				nStop = TRUE; 		//by shkim
	                }
	   		if(nStop) break;
			}
            	}
        }

	// after notifying, must wait 10ms., by shkim
	// if there is no this code, EP0 Stall is generated and usb connection is failed
	// So, this code is workaround code for usb connection
	//Sleep(15);

    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.

⌨️ 快捷键说明

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