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

📄 hwinit.c

📁 Windows CE 6.0 BSP for the Beagle Board.
💻 C
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//
// Copyright (c) Intrinsyc Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Intrinsyc 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.
//
//------------------------------------------------------------------------------
//
//  File:  Hwinit.c
//
#include <windows.h>
#include <oal.h>
#include <omap2420.h>
#include <ceddkex.h>

#ifdef DEBUG

#define ZONE_ERROR              DEBUGZONE(0)
#define ZONE_FUNCTION           DEBUGZONE(12)
#define ZONE_INTERRUPTS         DEBUGZONE(8)
#define ZONE_POWER              DEBUGZONE(9)
#define ZONE_PDD                DEBUGZONE(15)

#endif

#if 0
#undef DEBUGMSG
#define DEBUGMSG RETAILMSG
#define ZONE_ERROR              1
#define ZONE_FUNCTION           1
#define ZONE_INTERRUPTS         1
#define ZONE_POWER              1
#define ZONE_PDD                1
#endif


#ifdef BSP_NOOTG
#define USE_USB_DEVICE_PORT 1
#endif

BOOL InitializeHardware()
{
    PHYSICAL_ADDRESS      pa;
    BOOL                  rv = TRUE;
    OMAP2420_SYSC1_REGS * pSysConRegs = NULL;
    OMAP2420_PRCM_REGS  * pPRCMRegs   = NULL;
    OMAP2420_OTG_REGS   * pOTGRegs    = NULL;
    DWORD                 otgSysCon1  = 0x00000000;
    DWORD                 otgSysCon2  = 0x00000000;
    DWORD                 regBit      = 0x00000000;
    DWORD                 cbRet       = 0x00000000;
    DWORD                 temp        = 0x00000000;
    DWORD                 mode        = 0x00000000;


    DEBUGMSG(ZONE_FUNCTION, (L"USBD InitializeHardware() - "
        L"START\r\n"));

    // Note: MUX setting should be done in boot loader

    ////////////////////////////////////////////////////////////////////////////
    //  Map memory blocks for the registers we need to configure.             //
    ////////////////////////////////////////////////////////////////////////////

   // Map OTG registers
   pa.QuadPart = OMAP3_SCM_REGS_PA;
   pSysConRegs = (OMAP2420_SYSC1_REGS *)MmMapIoSpace(pa, sizeof(OMAP2420_SYSC1_REGS), FALSE);

   if (pSysConRegs == NULL)
   {
       DEBUGMSG(ZONE_ERROR, (L"USBD InitializeHardware() - "
			L"ERROR: Could not map System Control Registers\r\n"));
       rv = FALSE;
       goto clean;
   }

   // Map Power, Reset, and Clock Manager (PRCM) Registers
   pa.QuadPart = OMAP2420_PRCM_REGS_PA;
   pPRCMRegs   = (OMAP2420_PRCM_REGS *)MmMapIoSpace(pa, sizeof(OMAP2420_PRCM_REGS), FALSE);

   if (pPRCMRegs == NULL)
   {
        DEBUGMSG(ZONE_ERROR, (L"USBD InitializeHardware() - "
            L"ERROR: Could not map PRCM Registers\r\n"));
        rv = FALSE;
        goto clean;
    }

    // Map OTG registers
    pa.QuadPart   = OMAP2420_OTG_REGS_PA;
    if ((pOTGRegs = (OMAP2420_OTG_REGS *)MmMapIoSpace(pa, sizeof(OMAP2420_OTG_REGS), FALSE)) == NULL)
    {
        DEBUGMSG(ZONE_ERROR, (L"USBD InitializeHardware() - "
            L"ERROR: Could not map USB OTG Registers\r\n"));
        rv = FALSE;
        goto clean;
    }

    ////////////////////////////////////////////////////////////////////////
    //  Configure PRCM Registers                                          //
    ////////////////////////////////////////////////////////////////////////

    // Bit Mask used to control USBD Clocks
    regBit = 0x00000001;

    // Disable the USB Interface clock so we can change its speed
    KernelIoControl(IOCTL_ICLK2_DIS, (VOID *)&regBit, sizeof(DWORD), NULL, 0, &cbRet);

    // Configure the USB Interface Clock Speed
    // Note: Clear previous value, then set new value
    CLRREG32(&pPRCMRegs->ulCM_CLKSEL1_CORE, 0x0E000000);
    SETREG32(&pPRCMRegs->ulCM_CLKSEL1_CORE, 0x04000000);

    // Ensure that the USB Interface clock remains active when the MPU enters Idle Mode.
    KernelIoControl(IOCTL_AIDLE2_DIS, (VOID *)&regBit, sizeof(DWORD), NULL, 0, &cbRet);

    // Enable the USB Interface and Functional clocks
    KernelIoControl(IOCTL_ICLK2_ENB,  (VOID *)&regBit, sizeof(DWORD), NULL, 0, &cbRet);
    KernelIoControl(IOCTL_FCLK2_ENB,  (VOID *)&regBit, sizeof(DWORD), NULL, 0, &cbRet);

    // Enable USB Wake-Up
    SETREG32(&pPRCMRegs->ulPM_WKEN2_CORE, 0x00000001);

    ////////////////////////////////////////////////////////////////////////
    //  Display the modified PRCM Registers                               //
    ////////////////////////////////////////////////////////////////////////
    DEBUGMSG(ZONE_POWER, (L"USBD InitializeHardware() - Modified PRCM Register Values:\r\n"));
    DEBUGMSG(ZONE_POWER, (L"   CM_ICLKEN2_CORE:   0x%08X\r\n", pPRCMRegs->ulCM_ICLKEN2_CORE));
    DEBUGMSG(ZONE_POWER, (L"   CM_FCLKEN2_CORE:   0x%08X\r\n", pPRCMRegs->ulCM_FCLKEN2_CORE));
    DEBUGMSG(ZONE_POWER, (L"   CM_CLKSEL1_CORE:   0x%08X\r\n", pPRCMRegs->ulCM_CLKSEL1_CORE));
    DEBUGMSG(ZONE_POWER, (L"   CM_AUTOIDLE2_CORE: 0x%08X\r\n", pPRCMRegs->ulCM_AUTOIDLE2_CORE));
    DEBUGMSG(ZONE_POWER, (L"   CM_PM_WKEN2_CORE:  0x%08X\r\n", pPRCMRegs->ulPM_WKEN2_CORE));

    ////////////////////////////////////////////////////////////////////////
    //  Configure OTG Registers                                           //
    ////////////////////////////////////////////////////////////////////////

    // Reset all USB controllers
    OUTREG32(&pOTGRegs->SYSCON_1, OTG_SYSCON_1_SOFT_RESET);

    // Wait for the reset to complete.
    while ((INREG32(&pOTGRegs->SYSCON_1) & OTG_SYSCON_1_RESET_DONE) == 0);

    otgSysCon1 = INREG32(&pOTGRegs->SYSCON_1);

    // Clear USB0_TRX_MODE
    otgSysCon1 &= 0xFFFCFFFF;

    // Set USB0_TRX_MODE
    // Note that the H4 System's two USB transceivers will only work in
    // one of the three available transceiver modes. The USB OTG transceiver
    // (ISP1301BS) will only work in the 3-pin bidirectional mode. The USB
    // Device Transceiver will only work in the 6-pin unidirectional mode.
#ifndef BSP_NOOTG
    // otgSysCon1 |= (1 << 16);  // 4-pin bidirectional (VP_VM) transceiver signalling
    otgSysCon1 |= (2 << 16);  // 3-pin bidirectional (DAT_SE0) transceiver signalling
#else
    otgSysCon1 |= (3 << 16);     // 6-pin unidirectional transceiver signalling
#endif

#if USE_USB_DEVICE_PORT
    // Set OTG_IDLE_EN
    otgSysCon1 |= 0x00008000;

    // Clear DEV_IDLE_EN
    otgSysCon1 &= 0xFFFFDFFF;
#else
    // Clear OTG_IDLE_EN
    otgSysCon1 &= 0xFFFF7FFF;

    // Set DEV_IDLE_EN
    otgSysCon1 |= 0x00002000;
#endif

#ifdef BSP_NOOTG
    // Set HST_IDLE_EN
    otgSysCon1 |= 0x00004000;
#endif
    OUTREG32(&pOTGRegs->SYSCON_1, otgSysCon1);

    // Ensure USB On-The Go is enabled.
//        otgSysCon2 = INREG32(&pOTGRegs->SYSCON_2);
//        otgSysCon2 |= OTG_SYSCON_2_SYNCHRO;
//      otgSysCon2 |= (4 << 16); // B_ASE0_BRST
//      otgSysCon2 |= OTG_SYSCON_2_UHOST_EN;

#ifdef BSP_NOOTG
    otgSysCon2 &= ~(OTG_SYSCON_2_OTG_EN);
    otgSysCon2 |= OTG_SYSCON_2_SYNCHRO;
    otgSysCon2 &= ~(OTG_SYSCON_2_OTG_MST16);
    otgSysCon2 |= 0x03000000;   // SRP_GPUVBUS
    otgSysCon2 |= 0x00200000;   // A_WAIT_VRISE
    otgSysCon2 |= 0x00040000;   // B_ASE0_BRST
    otgSysCon2 &= ~(OTG_SYSCON_2_SRP_DPW);
    otgSysCon2 &= ~(OTG_SYSCON_2_SRP_DATA);
    otgSysCon2 &= ~(OTG_SYSCON_2_SRP_VBUS);
    otgSysCon2 &= ~(OTG_SYSCON_2_OTG_PADEN);
    otgSysCon2 &= ~(OTG_SYSCON_2_HMC_PADEN);
    otgSysCon2 &= ~(OTG_SYSCON_2_UHOST_EN);
    otgSysCon2 |= OTG_SYSCON_2_HMC_TLLSPEED;
    otgSysCon2 &= ~(OTG_SYSCON_2_HMC_TLLATTACH);
    otgSysCon2 &= 0xFFFFFFC0;   // HMC_MODE
#else
    otgSysCon2 |= OTG_SYSCON_2_OTG_EN;
    otgSysCon2 |= OTG_SYSCON_2_SRP_DATA;
    otgSysCon2 |= OTG_SYSCON_2_SRP_VBUS;
#endif
    otgSysCon2 |= OTG_SYSCON_2_SRP_GPDATA;
    otgSysCon2 |= OTG_SYSCON_2_SRP_GPDVBUS;      
//      otgSysCon2 |= (3 << 24); //  SRP_GPUVBUS = 3 (During SRP generation, VBUS is charged for 2ms nominal)
//      otgSysCon2 |= OTG_SYSCON_2_HMC_TLLSPEED;     
    
    OUTREG32(&pOTGRegs->SYSCON_2, otgSysCon2);

    // Clear OTG interrupts
    OUTREG32(&pOTGRegs->IRQ_EN, 0x00000000);
    OUTREG32(&pOTGRegs->IRQ_SRC, 0x00000000);

    CLRREG32(&pOTGRegs->CTRL, OTG_CTRL_BSESSEND);

    // We don't get any interrupts from the USB Device unless this bit
    // is set. Unfortunately, setting this bit also sets the "USB
    // Cable Attached" bit, which remains set regardless of whether or
    // not a cable is actually attached, and thus prevents us from
    // being able to properly tell when a USB cable is connected to or
    // disconnected from the device.
    // The OMAP2420 TRM suggest having an additional hardware mechanism
    // that would allow the driver to detect when a cable is connected
    // and then set the BSESSVLD bit as appropriate. The H4 System
    // design lacks this feature, so we'll have to use a workaround in
    // the USB Driver PDD to compensate for this.
    SETREG32(&pOTGRegs->CTRL, OTG_CTRL_BSESSVLD);

    ////////////////////////////////////////////////////////////////////////
    //  Display the modified OTG Registers                                //
    ////////////////////////////////////////////////////////////////////////
    DEBUGMSG(ZONE_PDD, (L"USBD InitializeHardware() - Modified OTG Register Values:\r\n"));
    DEBUGMSG(ZONE_PDD, (L"   REV:      0x%08X\r\n", pOTGRegs->REV));
    DEBUGMSG(ZONE_PDD, (L"   SYSCON_1: 0x%08X\r\n", pOTGRegs->SYSCON_1));
    DEBUGMSG(ZONE_PDD, (L"   SYSCON_2: 0x%08X\r\n", pOTGRegs->SYSCON_2));
    DEBUGMSG(ZONE_PDD, (L"   CTRL:     0x%08X\r\n", pOTGRegs->CTRL));
    DEBUGMSG(ZONE_PDD, (L"   IRQ_EN:   0x%04X\r\n", pOTGRegs->IRQ_EN));
    DEBUGMSG(ZONE_PDD, (L"   IRQ_SRC:  0x%04X\r\n", pOTGRegs->IRQ_SRC));
    DEBUGMSG(ZONE_PDD, (L"   OUTCTRL:  0x%04X\r\n", pOTGRegs->OUTCTRL));
    DEBUGMSG(ZONE_PDD, (L"   TEST:     0x%04X\r\n", pOTGRegs->TEST));
    DEBUGMSG(ZONE_PDD, (L"   VC:       0x%08X\r\n", pOTGRegs->VC));


    ////////////////////////////////////////////////////////////////////////
    //  Configure System Control Registers                                //
    ////////////////////////////////////////////////////////////////////////

    temp = INREG32(&pSysConRegs->ulCONTROL_DEVCONF);

    mode = ((otgSysCon1 & 0x00070000) >> 16);

    // Clear USBT0WRIMODEI. This places the USB Controls in Unidirectional Mode
    temp &= 0xFF3FFFFF;

    // Set the Transceiver Interface Mode for USB Port 0
    if ((mode == 0x01) || (mode == 0x02))
    {
        // Change the mode to Bidirectional.
        temp |= 0x00800000;
    }

    // Make sure the USB Enable signal is being used as an Active-High signal
    temp &= 0xFFFEFFFF;

    // Make sure the USB module standby signal is not asserted
    temp &= 0xFFFF7FFF;

    OUTREG32(&pSysConRegs->ulCONTROL_DEVCONF, temp);

    ////////////////////////////////////////////////////////////////////////
    //  Display the modified System Control Registers                     //
    ////////////////////////////////////////////////////////////////////////
    DEBUGMSG(ZONE_FUNCTION, (L"USBD InitializeHardware() - Modified System Control Register Values:\r\n"));
    DEBUGMSG(ZONE_FUNCTION, (L"   CONTROL_DEVCONF: 0x%08X\r\n", pSysConRegs->ulCONTROL_DEVCONF));

    ////////////////////////////////////////////////////////////////////////////
    //  Unmap the memory mapped above.                                        //
    ////////////////////////////////////////////////////////////////////////////

clean:
    // Unmap the memory for the System Control Registers
    if (pSysConRegs)
    {
        MmUnmapIoSpace((VOID*)pSysConRegs, sizeof(OMAP2420_SYSC1_REGS));
    }

    // Unmap the memory for the PRCM Registers
    if (pPRCMRegs)
    {
        MmUnmapIoSpace((VOID*)pPRCMRegs, sizeof(OMAP2420_PRCM_REGS));
    }

    // Unmap the memory for the OTG Registers
    if (pOTGRegs)
    {
        MmUnmapIoSpace((VOID*)pOTGRegs, sizeof(OMAP2420_OTG_REGS));
    }

    DEBUGMSG(ZONE_FUNCTION, (L"USBD InitializeHardware() - "
        L"END\r\n"));

    // Done
    return rv;
}

⌨️ 快捷键说明

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