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

📄 hwinit.c

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 C
字号:
//------------------------------------------------------------------------------
//
// Copyright (C) 2005-2006, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------ 
//
//  File:  hwinit.c
//  This file contains the functions used to configure the MUX, CPLD and initialize 
//  the USB registers for the USB client driver
//
//
#pragma optimize( "", off )
#include <windows.h>
#include <Winbase.h>
#include <ceddk.h>
#include "bsp.h"
#include "mx31_usbname.h"
#include "mx31_usbcommon.h"

#define HIGH_SPEED      1
#define FULL_SPEED      2

//extern void SetULPIDeviceModePwr(CSP_USB_REGS*pRegs, BOOL fSuspend);
//#define FREESCALE_DEBUG
//-----------------------------------------------------------------------------
//
//  Function: BSPGetUSBControllerType
//
//  This is used by the public common CSP library to be used to return the USB controller
//  currently using.
//
//  Parameters:
//      None.
//
//  Returns:
//      USB_SEL_OTG, USB_SEL_H2 or USB_SEL_H1. In this case, it would be USB_SEL_OTG
//
//-----------------------------------------------------------------------------
WORD BSPGetUSBControllerType(void)
{
    return USB_SEL_OTG;
}

//-----------------------------------------------------------------------------
//
//  Function: InitializeMux
//
//  This function is to configure the IOMUX
//  can safely share access.
//
//  Parameters:
//     speed - the speed of the device to configure as OTG can be configured as 
//     HS or FS .  Currently only HS is used and as such the parameter is not used.
//
//  Returns:
//      TRUE - success, FALSE - failure.
//
//-----------------------------------------------------------------------------
static BOOL InitializeMux(int speed)
{
    UNREFERENCED_PARAMETER(speed);
    //RETAILMSG(1, (TEXT("InitializeMux\r\n")));
    //usb_otg_iomux_connection();
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA7, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA6, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA5, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA4, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA3, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA2, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA1, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA0, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_NXT, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_STP, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DIR, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_CLK, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USB_PWR, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);

    return TRUE;
}

//-----------------------------------------------------------------------------
//
//  Function: dumpCPLD
//
//  This function is to dump the CPLD information
//
//  Parameters:
//     cpld - Pointer to Mapped CPLD Register
//
//  Returns:
//      None
//
//-----------------------------------------------------------------------------
void dumpCPLD(PCSP_PBC_REGS cpld)
{
    RETAILMSG(1,(L"Dump PBC registers:\r\n"));
    RETAILMSG(1,(L"\tVERSION=%x\r\n", INREG16(&cpld->VERSION)));
    RETAILMSG(1,(L"\tBSTAT2=%x\r\n", INREG16(&cpld->BSTAT2)));
    RETAILMSG(1,(L"\tBCTRL1_SET=%x\r\n", INREG16(&cpld->BCTRL1_SET)));
    RETAILMSG(1,(L"\tBCTRL1_CLEAR=%x\r\n", INREG16(&cpld->BCTRL1_CLEAR)));
    RETAILMSG(1,(L"\tBCTRL2_SET=%x\r\n", INREG16(&cpld->BCTRL2_SET)));
    RETAILMSG(1,(L"\tBCTRL2_CLEAR=%x\r\n", INREG16(&cpld->BCTRL2_CLEAR)));
    RETAILMSG(1,(L"\tBCTRL3_SET=%x\r\n", INREG16(&cpld->BCTRL3_SET)));
    RETAILMSG(1,(L"\tBCTRL3_CLEAR=%x\r\n", INREG16(&cpld->BCTRL3_CLEAR)));
    RETAILMSG(1,(L"\tBCTRL4_SET=%x\r\n", INREG16(&cpld->BCTRL4_SET)));
    RETAILMSG(1,(L"\tBCTRL4_CLEAR=%x\r\n", INREG16(&cpld->BCTRL4_CLEAR)));
    RETAILMSG(1,(L"\tBSTAT1=%x\r\n", INREG16(&cpld->BSTAT1)));
    RETAILMSG(1,(L"\tINT_STATUS=%x\r\n", INREG16(&cpld->INT_STATUS)));
    RETAILMSG(1,(L"\tINT_CUR_STATUS=%x\r\n", INREG16(&cpld->INT_CUR_STATUS)));
    RETAILMSG(1,(L"\tINT_MASK_SET=%x\r\n", INREG16(&cpld->INT_MASK_SET)));
    RETAILMSG(1,(L"\tINT_MASK_CLEAR=%x\r\n", INREG16(&cpld->INT_MASK_CLEAR)));
}

//-----------------------------------------------------------------------------
//
//  Function: InitializeCPLD
//
//  This function is to configure the CPLD to corresponding USB core
//
//  Parameters:
//     sel - the value in which USB core to configure. Since FS OTG doesn't need 
//     to support, this parameter is not used.
//     
//  Returns:
//     Speed of the USB core - HIGH_SPEED or FULL_SPEED
//
//-----------------------------------------------------------------------------
static int InitializeCPLD(WORD * sel)
{
    volatile PCSP_PBC_REGS  cpld;
        PHYSICAL_ADDRESS phyAddr;
    int r;

    UNREFERENCED_PARAMETER(sel);
    phyAddr.QuadPart = BSP_BASE_REG_PA_PBC_BASE;
    cpld = (PCSP_PBC_REGS) MmMapIoSpace(phyAddr, sizeof(CSP_PBC_REGS), FALSE);
        if (cpld == NULL)
        {
            return FALSE;
        }       
    OUTREG16(&cpld->BCTRL3_SET, (1<<PBC_BCTRL3_OTG_HS_EN));//bit 7: OTG_HS_EN (disabled)
    OUTREG16(&cpld->BCTRL3_SET, (1<<PBC_BCTRL3_OTG_FS_EN)); //bit 1: OTG_FS_EN (disabled)
//  The configuration of Full Speed USB client is commented out and to be used
//  in the future when Full Speed USB OTG client need to be supported.
//  if ((INREG16(&cpld->BSTAT2))&(1<<4)) 
//    {
//        RETAILMSG(1, (L"Full speed USB client\r\n"));
//        OUTREG16(&cpld->BCTRL3_CLEAR, (1<<PBC_BCTRL3_OTG_FS_EN));
//        OUTREG16(&cpld->BCTRL3_SET, (1<<PBC_BCTRL3_OTG_FS_SEL));
//        *sel=INREG16(&cpld->BCTRL3_SET)&(1<<PBC_BCTRL3_OTG_FS_SEL);
//        r=FULL_SPEED;
//    }
//  else
    {
        DEBUGMSG(1, (L"High speed USB client\r\n"));
        OUTREG16(&cpld->BCTRL3_CLEAR, (1<<PBC_BCTRL3_OTG_HS_EN)); //Clear_Bit_BCTRL3(7)
        //OUTREG16(&cpld->BCTRL3_SET, (1<<PBC_BCTRL3_HSH_SEL)); //Set_Bit_BCTRL3(4); //Rev C has a bug conflict with ATA
        r=HIGH_SPEED;
    }

    //dumpCPLD(cpld);   

    //OUTREG16(cpld->BCTRL3_CLEAR, 1<<PBC_BCTRL3_OTG_FS_EN);
    MmUnmapIoSpace(cpld, sizeof(CSP_PBC_REGS));
    return r;
}

extern BOOL Initialize1301(CSP_USB_REGS * regs);
extern void HardwarePullupDP1301(CSP_USB_REGS * regs);
extern BOOL Initialize1504(CSP_USB_REGS * regs);
extern BOOL HardwarePullupDP1504(CSP_USB_REGS * regs);

//-----------------------------------------------------------------------------
//
//  Function: InitializeTransceiver
//
//  This function is to configure the USB core
//
//  Parameters:
//     regs - pointer to the registers for all three USB core
//     speed - the speed of the OTG USB Core to be configured.
//     if full speed, it is using the ISP1301, otherwise it is ISP1504
//     
//  Returns:
//     TRUE - success, FALSE - failure
//
//-----------------------------------------------------------------------------
static BOOL InitializeTransceiver(CSP_USB_REGS* regs, int speed)
{
    DWORD r=TRUE;
  
    //Sleep(5000); //Not work
    {
        USB_USBMODE_T mode;
        DWORD * temp;
        USB_HCSPARAMS_T hcs;
        USB_USBCMD_T cmd;
        USB_PORTSC_T port;
      
        // Enable power for OTG on port 1
        temp=(DWORD *)&hcs;
        *temp=INREG32(&regs->OTG.HCSPARAMS);
        if (hcs.PPC) {
            WORD USB_OTG_PORTSC1_Write_MASK = (0x1<<1)+(0x1<<3)+(0x1<<5);   
            *temp=INREG32(&regs->OTG.PORTSC[0]);
            *temp&=~USB_OTG_PORTSC1_Write_MASK;
            *temp|=1<<12;
            SETREG32(&regs->OTG.PORTSC[0], *temp);
            // note: SETREG32 reads and ORs extra bits from temp.  So what's done above doesn't seem to
            // do as intended (seems it wanted to leave 1, 3, and 5 as they were; they are write-to-clear)
            // I haven't changed this because of code lock-down
        }
        
        //Sleep(5000);  // Not work
        // reset the usb otg        
        SETREG32(&regs->OTG.USBCMD, (1<<1));
        while((INREG32(&regs->OTG.USBCMD) & (0x1<<1)) == (0x1<<1))
        {
            Sleep(100);
        }

        //Sleep(5000); //Work
        // Set USB Mode 
        temp=(DWORD *)&mode;
        *temp=0;

        //RETAILMSG(1, (TEXT("Set USB Mode to 2\r\n")));
        mode.CM=2;
        mode.SLOM=1;        // 2.3 hardware and later
        OUTREG32(&regs->OTG.USBMODE, *temp);       

        // otg_itc_setup(0);
        temp=(DWORD *)&cmd;
        *temp=INREG32(&regs->OTG.USBCMD);
        cmd.ITC=0;
        OUTREG32(&regs->OTG.USBCMD, *temp);

        // otg_frindex_setup(1);
        OUTREG32(&regs->OTG.FRINDEX, 1);

        // otg_set_configflag_on();
        OUTREG32(&regs->OTG.CONFIGFLAG, 1);
        
        // Port reset
        temp=(DWORD *)&port;
        *temp=INREG32(&regs->OTG.PORTSC[0]);
        while (port.PR) {
            *temp=0; port.PR=1;
            CLRREG32(&regs->OTG.PORTSC[0], *temp);
            *temp=INREG32(&regs->OTG.PORTSC[0]);
        }

    }

    if (speed==FULL_SPEED)
        r=Initialize1301(regs);
    else
        r=Initialize1504(regs);
    
    //DumpULPIRegs(regs);
    //DEBUGMSG(1, (TEXT("InitializeTransceiver done\r\n")));
    return r;
}



//------------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
//  Function: HardwareInitialize
//
//  This function is being called by CSP code to initialize the transceiver, USB core
//  and CPLD
//
//  Parameters:
//     regs - Pointer to the 3 USB Core registers.
//     
//  Returns:
//     TRUE - success, FALSE - failure
//
//-----------------------------------------------------------------------------

BOOL HardwareInitialize(CSP_USB_REGS * regs)
{
    int r;
    WORD sel;
    
    r=InitializeCPLD(&sel);
    if (r==0)
        return FALSE;
    if (USBClockInit() && 
         InitializeMux(r)  && InitializeTransceiver(regs,r))
        return TRUE;
    else 
        return FALSE;
}

//-----------------------------------------------------------------------------
//
//  Function: HardwarePullupDP
//
//  This function is being called by CSP code to pull up the D+ if necessary.
//
//  Parameters:
//     regs - Pointer to the 3 USB Core registers.
//     
//  Returns:
//     TRUE - success, FALSE - failure
//
//-----------------------------------------------------------------------------
BOOL HardwarePullupDP(CSP_USB_REGS * regs)
{
    BOOL fSuccess = FALSE;
    USB_PORTSC_T portsc;

    DWORD * temp=(DWORD*)&portsc;
    *temp=INREG32(&regs->OTG.PORTSC[0]);
    if (portsc.PTS==2) {
        // Stop USB Controller first
        USB_USBCMD_T cmd;           
        DWORD * temp = (DWORD *)&cmd;
        *temp = INREG32(&regs->OTG.USBCMD);
        cmd.RS = 0;
        OUTREG32(&regs->OTG.USBCMD, *temp);
        while ((INREG32(&regs->OTG.USBCMD) & 0x1) == 0x1){
            //RETAILMSG(1, (TEXT("USBCMD= 0x%x\r\n"), (INREG32(&(*regs)->OTG.USBCMD))));
            Sleep(100);
        }


        fSuccess = HardwarePullupDP1504(regs);

        DEBUGMSG(1, (L"ISP1504 High Speed used with success %d\r\n", fSuccess));
        // Start USB Controller first
        if (fSuccess)
        {
            temp = (DWORD *)&cmd;
            *temp = INREG32(&regs->OTG.USBCMD);
            cmd.RS = 1;
            OUTREG32(&regs->OTG.USBCMD, *temp);
            while ((INREG32(&regs->OTG.USBCMD) & 0x1) == 0x0){
                //RETAILMSG(1, (TEXT("USBCMD= 0x%x\r\n"), (INREG32(&(*regs)->OTG.USBCMD))));
                Sleep(100);
            }
        }
    }
    else {
        fSuccess = TRUE;
        HardwarePullupDP1301(regs);
        RETAILMSG(1, (L"ISP1301 Full Speed used\r\n"));
    }

    //DumpUSBRegs(regs, 2);
    return fSuccess;
}

//-----------------------------------------------------------------------------
//
//  Function: GetSysIntr
//
//  This function is to return the SYSINTR value being used by OTG USB core
//
//  Parameters:
//     NONE
//     
//  Returns:
//     SYSINTR being used
//
//-----------------------------------------------------------------------------

DWORD GetSysIntr(void)
{
    return SYSINTR_USBOTG;
}

#pragma optimize( "", on )

//------------------------------------------------------------------------------




⌨️ 快捷键说明

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