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

📄 chw.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 5 页
字号:

        // Testing for full speed
        //rtSc.bit.PFSC = 0x1;
        //portSc.bit.TestControl = 0x6;
        //RETAILMSG(1, (TEXT("Power On PortSC b/f =0x%x\r\n"), portSc.ul));
            
        Write_PORTSC(dwPort,portSc);         
        portSc = Read_PORTSC( dwPort);
        //RETAILMSG(1, (TEXT("Power On PortSC after =0x%x\r\n"), portSc.ul));

    }

    Sleep(50);
    return TRUE;
}

//**********************************************************
void CHW::WriteAsyncListAddr(IN const DWORD addr) 
//
// Purpose: Setup the address of next asynchronous queue head to be executed.
//
// Parameters:  addr - asynchronous address
//
// Returns: Nothing
//
// Notes: 
// ******************************************************************
{ 
    Write_EHCIRegister(ASYNCLISTADDR,addr);
}
// *****************************************************************
BOOL CHW::ConfigureHS()
//
//  Purpose: Configure the Host Controller i.e. it would be used for
//           OTG transceiver
//
//  Parameters: 
//
//  Returns:  TRUE - success, FALSE - failure
// *****************************************************************
{
    {
        USBCMD usbcmd=Read_USBCMD();

        usbcmd.bit.HCReset=1;
        Write_USBCMD(usbcmd);
        for (DWORD dwCount=0;dwCount<50 && (Read_USBCMD().bit.HCReset!=0);dwCount++)
            Sleep( 20 );
        usbcmd=Read_USBCMD();
        if (usbcmd.bit.HCReset!=0) // If can not reset within 1 second, we assume this is bad device.
            return FALSE;

        //Add specific for tdi
            //Check the value of USB MODE
        // In OTG case, the USBMODE need to set again after reset.
        {
            DWORD value;
            value = Read_EHCIRegister(USBMODE);
            //RETAILMSG(1, (TEXT("USBMODE = 0x%x\r\n"), value));
            if ((value & 0x3) != 0x3)
            {
                Write_EHCIRegister(USBMODE, value|0x3);
                while ((Read_EHCIRegister(USBMODE) & 0x3) != 0x3);
            }
        }

        //usbcmd.bit.FrameListSize=0;// We use 1k for Periodic List.
        usbcmd.bit.FrameListSize=1024;// We use 1k for Periodic List.
        m_FrameListMask = 0x3ff;  // Available Bit in 
        Write_USBCMD(usbcmd);
    }
    DEBUGMSG(ZONE_INIT && ZONE_REGISTERS, (TEXT("CHW::Initialize - end signalling global reset\n")));
    DEBUGMSG(ZONE_INIT && ZONE_REGISTERS, (TEXT("CHW::Initialize - setting USBINTR to all interrupts on\n")));

    {
        USBINTR usbint;
        // initialize interrupt register - set all interrupts to enabled
        usbint.ul=(DWORD)0x457;
        usbint.bit.Reserved=0;
        Write_USBINTR(usbint );
    }

    DEBUGMSG(ZONE_INIT && ZONE_REGISTERS && ZONE_VERBOSE, (TEXT("CHW::Initialize - setting FRNUM = 0\n")));
    // initialize FRNUM register with index 0 of frame list
    {
        FRINDEX frindex;
        frindex.ul=0;
        Write_FRINDEX(frindex);
    }
    Write_EHCIRegister(CTLDSSEGMENT,0);//We only support 32-bit address space now.

    // initialize FLBASEADD with address of frame list
    {
        ULONG frameListPhysAddr = m_cPeriodicMgr.GetFrameListPhysAddr();
        DEBUGMSG(ZONE_INIT && ZONE_REGISTERS && ZONE_VERBOSE, (TEXT("CHW::Initialize - setting FLBASEADD = 0x%X\n"), frameListPhysAddr));
        DEBUGCHK( frameListPhysAddr != 0 );
        // frame list should be aligned on a 4Kb boundary
        DEBUGCHK( (frameListPhysAddr & EHCD_FLBASEADD_MASK) == frameListPhysAddr );
        Write_EHCIRegister(PERIODICLISTBASE,frameListPhysAddr);
        // Follow the rule in 4.8 EHCI
        USBCMD usbcmd=Read_USBCMD();
        while (usbcmd.bit.PSchedEnable!= Read_USBSTS().bit.PSStatus)
            Sleep(1);
        if (usbcmd.bit.PSchedEnable!=1) {
            usbcmd.bit.PSchedEnable=1;
            Write_USBCMD(usbcmd);
        }
    }
    // Initial Async Shedule to Enable.
    DEBUGMSG(ZONE_INIT && ZONE_REGISTERS && ZONE_VERBOSE, (TEXT("CHW::Initialize - Enable Async Sched \n")));
    {
        Write_EHCIRegister(ASYNCLISTADDR,m_cAsyncMgr.GetPhysAddr());
#ifdef ASYNC_PARK_MODE
        if (Read_HHCCP_CAP().bit.Async_Park) {
            USBCMD usbcmd=Read_USBCMD();
            usbcmd.bit.ASchedPMEnable=1;
            usbcmd.bit.ASchedPMCount =3;
            Write_USBCMD(usbcmd);
        }
#else
        RETAILMSG(1, (TEXT("NO ASYNC_PARK_MODE\r\n")));
#endif
        USBCMD usbcmd=Read_USBCMD();
        // Follow the rule in 4.8 EHCI
        while (usbcmd.bit.ASchedEnable!= Read_USBSTS().bit.ASStatus)
            Sleep(1);
        if (usbcmd.bit.ASchedEnable!=1) {
            usbcmd.bit.ASchedEnable=1;
            Write_USBCMD(usbcmd);
        }
    }    


    {
        TXFILLTUNING txft = Read_TXFILLTUNING();   
        txft.bit.txfifothres = 0x4;
        Write_TXFILLTUNING(txft);
        txft = Read_TXFILLTUNING();    
    }

    return TRUE;
}

// ******************************************************************
BOOL CHW::Initialize( )
// Purpose: Reset and Configure the Host Controller with the schedule.
//
// Parameters: portBase - base address for host controller registers
//
//             dwSysIntr - system interrupt number to use for USB
//                         interrupts from host controller
//
//             frameListPhysAddr - physical address of frame list index
//                                 maintained by CPipe class
//
//             pvUhcdPddObject - PDD specific structure used during suspend/resume
//
// Returns: TRUE if initialization succeeded, else FALSE
//
// Notes: This function is only called from the CUhcd::Initialize routine.
//
//        This function is static
// ******************************************************************
{
    DEBUGMSG( ZONE_INIT, (TEXT("+CHW::Initialize\n")));

    DEBUGCHK( m_frameCounterLowPart == 0 &&
              m_frameCounterHighPart == 0 );

    // set up the frame list area.
    if ( m_portBase == 0 || 
            m_cPeriodicMgr.Init()==FALSE ||
            m_cAsyncMgr.Init() == FALSE ||
            m_cBusyPipeList.Init()==FALSE) {
        DEBUGMSG( ZONE_ERROR, (TEXT("-CHW::Initialize - zero Register Base or CeriodicMgr or CAsyncMgr fails\n")));
        ASSERT(FALSE);
        return FALSE;
    }
    DEBUGMSG(ZONE_INIT && ZONE_REGISTERS, (TEXT("CHW::Initialize - signalling global reset\n")));

    // Create a file mapping for USB clock state
    USBClockCreateFileMapping();

    ConfigureHS();

    // m_hUsbInterrupt - Auto Reset, and Initial State = non-signaled
    DEBUGCHK( m_hUsbInterruptEvent == NULL );
    m_hUsbInterruptEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
    m_hUsbHubChangeEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
    if ( m_hUsbInterruptEvent == NULL || m_hUsbHubChangeEvent==NULL ) {
        DEBUGMSG(ZONE_ERROR, (TEXT("-CHW::Initialize. Error creating USBInterrupt or USBHubInterrupt event\n")));
        return FALSE;
    }

    InterruptDisable( m_dwSysIntr ); // Just to make sure this is really ours.
    // Initialize Interrupt. When interrupt id # m_sysIntr is triggered,
    // m_hUsbInterruptEvent will be signaled. Last 2 params must be NULL
    if ( !InterruptInitialize( m_dwSysIntr, m_hUsbInterruptEvent, NULL, NULL) ) {
        DEBUGMSG(ZONE_ERROR, (TEXT("-CHW::Initialize. Error on InterruptInitialize\r\n")));
        return FALSE;
    }

    if (m_dwOTGSupport)
        InterruptDisable(m_dwSysIntr);
    else 
    {
        KernelIoControl(IOCTL_HAL_ENABLE_WAKE, &m_dwSysIntr, sizeof(m_dwSysIntr), NULL, 0, NULL);
    }

    // Start up our IST - the parameter passed to the thread
    // is unused for now
    DEBUGCHK( m_hUsbInterruptThread == NULL &&
              m_fUsbInterruptThreadClosing == FALSE );
    if (m_hUsbInterruptThread==NULL)
        m_hUsbInterruptThread = CreateThread( 0, 0, UsbInterruptThreadStub, this, 0, NULL );
    if ( m_hUsbInterruptThread == NULL ) {
        DEBUGMSG(ZONE_ERROR, (TEXT("-CHW::Initialize. Error creating IST\n")));
        return FALSE;
    }
    CeSetThreadPriority( m_hUsbInterruptThread, g_IstThreadPriority );
    // Initial All port route to this host.
    DEBUGMSG(ZONE_INIT && ZONE_REGISTERS && ZONE_VERBOSE, (TEXT("CHW::Initialize - Initial All port route \n")));
    
    PowerOnAllPorts();

    EnableAsyncSchedule();

    DEBUGMSG( ZONE_INIT, (TEXT("-CHW::Initialize, success!\n")));
    return TRUE;
}
// ******************************************************************
void CHW::DeInitialize( void )
//
// Purpose: Delete any resources associated with static members
//
// Parameters: none
//
// Returns: nothing
//
// Notes: This function is only called from the ~CUhcd() routine.
//
//        This function is static
// ******************************************************************
{
    m_fUsbInterruptThreadClosing = TRUE; // tell USBInterruptThread that we are closing
    // m_hAdjustDoneCallbackEvent <- don't need to do anything to this
    // m_uNewFrameLength <- don't need to do anything to this

    // Wake up the interrupt thread and give it time to die.
    if ( m_hUsbInterruptEvent ) {
        SetEvent(m_hUsbInterruptEvent);
        if ( m_hUsbInterruptThread ) {
            DWORD dwWaitReturn = WaitForSingleObject(m_hUsbInterruptThread, 1000);
            if ( dwWaitReturn != WAIT_OBJECT_0 ) {
                DEBUGCHK( 0 );
#pragma prefast(suppress: 258, "Try to recover gracefully from a pathological failure")
                TerminateThread(m_hUsbInterruptThread, DWORD(-1));
            }
            CloseHandle(m_hUsbInterruptThread);
            m_hUsbInterruptThread = NULL;
        }
        // we have to close our interrupt before closing the event!
        InterruptDisable( m_dwSysIntr );

        CloseHandle(m_hUsbInterruptEvent);
        m_hUsbInterruptEvent = NULL;
    } else {
        InterruptDisable( m_dwSysIntr );
    }
    // Stop The Controller.
    {
        USBCMD usbcmd=Read_USBCMD();
        usbcmd.bit.RunStop=0;
        Write_USBCMD(usbcmd);
        while( Read_USBSTS().bit.HCHalted == 0 ) //Wait until it stop.
            Sleep(1);
    }
    m_cPeriodicMgr.DeInit();
    m_cAsyncMgr.DeInit();
    m_cBusyPipeList.DeInit();
    // no need to free the frame list; the entire pool will be freed as a unit.
    m_pFrameList = 0;
    m_fUsbInterruptThreadClosing = FALSE;
    m_frameCounterLowPart = 0;
    m_frameCounterHighPart = 0;

    // Remove file mapping from it
    USBClockDeleteFileMapping();
}

// ******************************************************************
void CHW::EnterOperationalState( void )
//
// Purpose: Signal the host controller to start processing the schedule
//
// Parameters: None
//
// Returns: Nothing.
//
// Notes: This function is only called from the CUhcd::Initialize routine.
//        It assumes that CPipe::Initialize and CHW::Initialize
//        have already been called.
//
//        This function is static
// ******************************************************************
{
    DEBUGMSG( ZONE_INIT, (TEXT("+CHW::EnterOperationalState\n")));
    DWORD dwIntThreshCtrl = EHCI_REG_IntThreshCtrl_DEFAULT;
    if (!(m_deviceReg.IsKeyOpened() && m_deviceReg.GetRegValue(EHCI_REG_IntThreshCtrl, (LPBYTE)&dwIntThreshCtrl, sizeof(dwIntThreshCtrl)))) {
        dwIntThreshCtrl = EHCI_REG_IntThreshCtrl_DEFAULT;
    }
    DEBUGMSG(ZONE_INIT && ZONE_REGISTERS && ZONE_VERBOSE, (TEXT("CHW::EnterOperationalState - clearing status reg\n")));
    Clear_USBSTS( );
    USBCMD usbcmd=Read_USBCMD();

    DEBUGMSG(ZONE_INIT && ZONE_REGISTERS && ZONE_VERBOSE, (TEXT("CHW::EnterOperationalState - setting USBCMD run bit\n")));
    usbcmd.bit.FrameListSize = 0; // 1k Flame Entry. Sync with Initialization.
    usbcmd.bit.IntThreshCtrl = dwIntThreshCtrl; // Setup by registry.
    usbcmd.bit.RunStop = 1;
    Write_USBCMD( usbcmd );

    // According to 21.13.1 of Freescale, set CONFIGFLAG after RUN
    Write_EHCIRegister(CONFIGFLAG,1);

    // Just for safety, make sure those flags must set properly after enter into operation state
    m_bUSBClockStop = FALSE;
    m_bUSBPanicMode = TRUE;

    DEBUGMSG( ZONE_INIT, (TEXT("-CHW::EnterOperationalState\n")));
}

//************************************************************************
void CHW::RunStopUSBController(BOOL fRun)
//
// Purpose: Start or Stop the USB Host Controller by controlling the run/stop bit
//          in USBCMD register.
//
// Parameters: fRun - TRUE: Start to run, FALSE: stop the controller
//
// Returns: Nothing.
//
// ******************************************************************
{
    USBCMD usbcmd=Read_USBCMD();
    if (fRun)
    {
        if(usbcmd.bit.RunStop == 0) {
            // clear run bit
            usbcmd.bit.RunStop= 1;
            Write_USBCMD( usbcmd );  
            USBINTR usbIntr;
            usbIntr.ul=0x457;
            // clear all interrupts
            Write_USBINTR(usbIntr);
            // spin until the controller really is stopped
            while( Read_USBSTS().bit.HCHalted == 1 )
                Sleep(0); //Wait until it stop.
        }
    }
    else
    {
        if(usbcmd.bit.RunStop) {
            // clear run bit
            usbcmd.bit.RunStop= 0;
            Write_USBCMD( usbcmd );  
            USBINTR usbIntr;
            usbIntr.ul=0x4;  // only enable the PORTSTATUS change one.
            // clear all interrupts
            Write_USBINTR(usbIntr);
            // spin until the controller really is stopped
            while( Read_USBSTS().bit.HCHalted == 0 ) //Wait until it stop.
                Sleep(0);

⌨️ 快捷键说明

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