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

📄 chw.hpp

📁 Intel PXA270 Wince5.0 BSP
💻 HPP
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// 
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// 
// Module Name:  
//     CHW.hpp
// 
// Abstract: Provides interface to UHCI host controller
// 
// Notes: 
//

#ifndef __CHW_HPP__
#define __CHW_HPP__

#include "globals.hpp"
#include "cphysmem.hpp"

class CHW;

typedef const DWORD C_DWORD;

struct HcRegisters {
    struct {
        DWORD REV:8;            // OHCI revision. Must be 0x10.
        DWORD :24;
    } const HcRevision;
    struct HcControl {          // All fields default to zero at reset.
        DWORD CBSR:2;           // Control/Bulk Service Ratio (CBSR+1):1
        DWORD PLE:1;            // Periodic List Enable
        DWORD IE:1;             // Isochronous Enable
        DWORD CLE:1;            // Control List Enable
        DWORD BLE:1;            // Bulk List Enable
        DWORD HCFS:2;           // Host Controller Functional State
        enum { HCFS_RESET=0, HCFS_RESUME=1, HCFS_OPERATIONAL=2, HCFS_SUSPEND=3 };
        DWORD IR:1;             // Interrupt Routing (unused)
        DWORD RWC:1;            // Remote Wakeup Connected (unusable - see spec)
        DWORD RWE:1;            // Remote Wakeup Enable (unused)
        DWORD :21;
    } HcControl;
    struct {                    // All fields default to zero at reset.
        DWORD HCR:1;            // Host Controller Reset (auto-clear)
        DWORD CLF:1;            // Control List Filled
        DWORD BLF:1;            // Bulk List Filled
        DWORD OCR:1;            // Ownership Change Request (unused)
        DWORD :12;
        DWORD SOC:2;            // Scheduling Overrun Count
        DWORD :14;
    } HcCommandStatus;
    union HcInterruptStatus {
        struct {                // Write 1 to clear each condition bit.
            DWORD SO:1;         // Scheduling Overrun
            DWORD WDH:1;        // Writeback DoneHead
            DWORD SF:1;         // Start of Frame
            DWORD RD:1;         // Resume Detected
            DWORD UE:1;         // Unrecoverable Error
            DWORD FNO:1;        // Frame Number Overflow
            DWORD RHSC:1;       // Root Hub Status Change
            DWORD :23;
            DWORD OC:1;         // Ownership Change (unused)
            DWORD :1;
        };
        DWORD reg;              // the entire register at once
    } HcInterruptStatus;
    struct OHCI_Ints {          // Write 1 to enable each interrupt.
        DWORD SO:1;             // Scheduling Overrun
        DWORD WDH:1;            // Writeback DoneHead
        DWORD SF:1;             // Start of Frame
        DWORD RD:1;             // Resume Detected
        DWORD UE:1;             // Unrecoverable Error
        DWORD FNO:1;            // Frame Number Overflow
        DWORD RHSC:1;           // Root Hub Status Change
        DWORD :23;
        DWORD OC:1;             // Ownership Change (unused)
        DWORD MIE:1;            // Master Interrupt Enable
    } HcInterruptEnable;
    struct OHCI_Ints            // Write 1 to diable each interrupt
      HcInterruptDisable;

    DWORD HcHCCA;               // PAddr of the HCCA. Must be 256-byte aligned.
    DWORD HcPeriodCurrentED;    // PAddr of current Isoch or Intr ED. 16-byte aligned.
    DWORD HcControlHeadED;      // PAddr of first Control ED. 16-byte aligned.
    DWORD HcControlCurrentED;   // PAddr of current Control ED. 16-byte aligned.
    DWORD HcBulkHeadED;         // Like Control but for Bulk.
    DWORD HcBulkCurrentED;      // Like Control but for Bulk.
    C_DWORD HcDoneHead;         // PAddr of last completed TD.
    
    struct HcFmInterval {
        DWORD FI:14;            // Frame Interval (nominally 11999 or 0x2EDF)
        DWORD :2;
        DWORD FSMPS:15;         // FS Largest Data Packet (see OHCI section 5.4)
        DWORD FIT:1;            // Frame Interval Toggle
    } HcFmInterval;
    C_DWORD HcFmRemaining;      // (unused)
    struct {
        C_DWORD FN:16;          // Frame Number (LSW)
        C_DWORD :16;
    } HcFmNumber;
    struct {
        DWORD PS:14;            // Periodic Start
        DWORD :18;
    } HcPeriodicStart;
    struct {
        C_DWORD LST:11;         // Low Speed Threshold (nominally 0x628)
        C_DWORD :21;
    } HcLSThreshold;

    struct {
        DWORD NDP:8;            // Number of Downstream Ports
        DWORD PSM:1;            // Power Switching Mode
        DWORD NPS:1;            // No Power Switching
        DWORD DT:1;             // Device Type (must be zero)
        DWORD OCPM:1;           // Over-Current Protection Mode
        DWORD NOCP:1;           // No Over-Current Protection
        DWORD :11;
        DWORD POTPGT:8;         // Power-On to Power-Good Time (2ms units)
    } HcRhDescriptorA;
    struct {
        DWORD DR:16;            // Device Removable (bitmask, b0 reserved)
        DWORD PPCM:16;          // Port Power Control Mask (ditto)
    } HcRhDescriptorB;
    struct HcRhStatus {
        DWORD LPS:1;            // Local Power Status / Clear Global Power
        DWORD OCI:1;            // Over Current Indicator
        DWORD :13;
        DWORD DRWE:1;           // Device Remote Wakeup Enable / Set Remote Wakeup Enable
        DWORD LPSC:1;           // Local Power Status Change / Set Global Power
        DWORD OCIC:1;           // Over Current Indicator Change
        DWORD :13;
        DWORD CRWE:1;           // Clear Remote Wakeup Enable
    } HcRhStatus;
    union HcRhPortStatus {
        // for writing, we generally set only one bit at a time.
        enum { CPE=0x00000001, SPE=0x00000002, SPS=0x00000004, CPS=0x00000008,
               SPR=0x00000010,
               SPP=0x00000100, CPP=0x00000200,
               CCSC=0x00010000, CPESC=0x00020000, CPSSC=0x00040000, COCIC=0x00080000,
               CPRSC=0x00100000
        };
        struct {
            DWORD CCS:1;        // Current Connect Status / Clear Port Enable
            DWORD PES:1;        // Port Enable Status / Set Port Enable
            DWORD PSS:1;        // Port Suspend Status / Set Port Suspend
            DWORD POCI:1;       // Port Over-Current Indicator / Clear Port Suspend
            DWORD PRS:1;        // Port Reset Status / Set Port Reset
            DWORD :3;
            DWORD PPS:1;        // Port Power Status / Set Port Power
            DWORD LSDA:1;       // Low Speed Device Attached / Clear Port Power
            DWORD :6;
            DWORD CSC:1;        // Connect Status Change / clear CSC
            DWORD PESC:1;       // Port Enable Status Change / clear PESC
            DWORD PSSC:1;       // Port Suspend Status Change / clear PSSC
            DWORD OCIC:1;       // Over-Current Indicator Change / clear OCIC
            DWORD PRSC:1;       // Port Reset Status Change / clear PRSC
            DWORD :11;
        };
        DWORD reg;
    } HcRhPortStatus[15];
};

struct HCCA {
    DWORD HccaInterruptTable[32];
    WORD  HccaFrameNumber;
    WORD  HccaPad1;             // unused
    DWORD HccaDoneHead;         // PAddr of first TD in Done Queue. 16-byte aligned. LSb special.
    // remainder is reserved so we can ignore it.
};


// this class is an encapsulation of UHCI hardware registers.
class CHW
{
public:
    // ****************************************************
    // public Functions
    // ****************************************************

    // 
    // Hardware Init/Deinit routines
    //
    static BOOL   Initialize( IN const REGISTER portBase,
                              IN const DWORD dwSysIntr,
                              IN CPhysMem * const pCPhysMem,
                              IN LPVOID pvUhcdPddObject );

    static void   DeInitialize( void );

    static void   EnterOperationalState(void);

    static void   StopHostController(void);

    enum { LIST_CONTROL=1, LIST_BULK=2, LIST_INTERRUPT=4, LIST_ISOCH=8, LIST_ALL=15 };
    static void   ListControl( IN const DWORD bfList,
                               IN const BOOL  bEnable,
                               IN const BOOL  bFill );

    //
    // Functions to Query frame values
    //
    static DWORD  GetFrameNumber( void );

    static USHORT GetFrameLength( void );

    static BOOL SetFrameLength( IN HANDLE hEvent,
                                IN const USHORT uFrameLength );
    
    static BOOL StopAdjustingFrame( void );

    static BOOL WaitOneFrame( void );

    //
    // Root Hub Queries
    //
    static BOOL DidPortStatusChange( IN const UCHAR port );

    static BOOL GetPortStatus( IN const UCHAR port,
                               OUT USB_HUB_AND_PORT_STATUS& rStatus );

    static void GetRootHubDescriptor( OUT USB_HUB_DESCRIPTOR& descriptor );

    static BOOL RootHubFeature( IN const UCHAR port,
                                IN const UCHAR setOrClearFeature,
                                IN const USHORT feature );

    static BOOL ResetAndEnablePort( IN const UCHAR port );

    static void DisablePort( IN const UCHAR port );

    // ****************************************************
    // public Variables
    // ****************************************************
    static PDWORD m_pControlHead;
    static PDWORD m_pBulkHead;
    static PDWORD m_pInterruptTable;

private:
    // ****************************************************
    // private Functions
    // ****************************************************
    CHW() {};  // default constructor is not callable

    static DWORD CALLBACK UsbInterruptThreadStub( IN PVOID context );

    static DWORD CALLBACK UsbAdjustFrameLengthThread( IN PVOID context );

    static void   UpdateFrameCounter( void );

#ifdef DEBUG
    // Query Host Controller for registers, and prints contents
    static void DumpAllRegisters(void);
#endif

    // ****************************************************
    // Private Variables
    // ****************************************************

    static volatile HcRegisters *m_portBase;
    static volatile HCCA *m_pHCCA;

    // internal frame counter variables
    static CRITICAL_SECTION m_csFrameCounter;
    static WORD    m_wFrameHigh;

    // interrupt thread variables
    static DWORD    m_dwSysIntr;
    static HANDLE   m_hUsbInterruptEvent;
    static HANDLE   m_hUsbInterruptThread;
    static BOOL     m_fUsbInterruptThreadClosing;

    // frame length adjustment variables
    // note - use LONG because we need to use InterlockedTestExchange
    static LONG     m_fFrameLengthIsBeingAdjusted;
    static LONG     m_fStopAdjustingFrameLength;
    static HANDLE   m_hAdjustDoneCallbackEvent;
    static USHORT   m_uNewFrameLength;
};
#endif // __CHW_HPP__

⌨️ 快捷键说明

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