📄 isp1504.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: Isp1504.c
// Purpose: Contains configuration routines specific to the ISP 1504 transceiver
#pragma optimize( "", off )
#include <windows.h>
#include <Winbase.h>
#include <ceddk.h>
#include "bsp.h"
#include "mx31_usbcommon.h"
#ifdef FORCE_FULLSPEED
#undef FORCE_FULLSPEED
//#define FORCE_FULLSPEED 1
#endif
//-----------------------------------------------------------------------------
//
// Function: Initialize1504
//
// This function is to configure the ISP1504 transceiver and corresponding
// USB OTG Core. This function is called by InitializeTransceiver in hwinit.c
//
// Parameters:
// regs - Pointer to the 3 USB Core registers.
//
// Returns:
// TRUE - success, FALSE - failure
//
//-----------------------------------------------------------------------------
BOOL Initialize1504(CSP_USB_REGS * regs)
{
//
DWORD * temp;
//Sleep(5000);
DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DATA0, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DATA1, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DATA2, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DATA3, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DATA4, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DATA5, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DATA6, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DATA7, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_STP, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_NXT, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DIR, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_CLK, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
//Sleep(5000); // Work
// usb_otg_ulpi_interface_config()
{
USB_PORTSC_T portsc;
temp=(DWORD *)&portsc;
*temp=INREG32(®s->OTG.PORTSC);
// Set PORTSC
portsc.PTS=2; //Parallel Transeiver to ULPI
#ifdef FORCE_FULLSPEED
portsc.PFSC=1; //Port Force Full Speed Connect, test only
#endif
//portsc.WKDC = 1; // Wake on disconnect enable
//portsc.WKCN = 1; // Wake on connect cable
*temp|=(2<<10);
INSREG32(®s->OTG.PORTSC,(3<<30),*temp);
}
//Sleep(5000); // Failed
//usb_otg_ulpi_interrupt_enable() && usb_otg_power_mask_enable()
{
USB_CTRL_T ctrl;
temp=(DWORD *)&ctrl;
*temp=INREG32(®s->USB_CTRL);
ctrl.OUIE=0; // OUIE -- OTG ULPI interrupt enable
ctrl.OPM=1; // OTG Power Mask
ctrl.OWIE = 0;
SETREG32(®s->USB_CTRL, *temp);
}
// otg_power_on_port1()
{
USB_HCSPARAMS_T hcs;
temp=(DWORD *)&hcs;
*temp=INREG32(®s->OTG.HCSPARAMS);
if (hcs.PPC) {
USB_PORTSC_T portsc;
temp=(DWORD *)&portsc;
*temp=0;
portsc.CSC=1; portsc.PEC=1; portsc.OCC=1;
*temp=(~*(temp))&INREG32(®s->OTG.PORTSC);
portsc.PP=1;
SETREG32(®s->OTG.PORTSC, *temp);
}
}
// usb cmd
{
USB_USBCMD_T cmd;
temp=(DWORD *)&cmd;
*temp=INREG32(®s->OTG.USBCMD);
cmd.ITC=0x08;
SETREG32(®s->OTG.USBCMD, *temp);
}
{
USB_ULPI_VIEWPORT_T ulpi;
temp=(DWORD *)&ulpi;
*temp=0;
#ifdef FORCE_FULLSPEED
// Wake up ULPI
*temp=INREG32(®s->OTG.ULPI_VIEWPORT);
ulpi.ULPIWU=1;
OUTREG32(®s->OTG.ULPI_VIEWPORT, *temp);
while (INREG32(®s->OTG.ULPI_VIEWPORT) & 0x80000000);
*temp=INREG32(®s->OTG.ULPI_VIEWPORT);
#endif
}
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: HardwarePullupDP1504
//
// This function is being called by HardwarePullupDP in hwinit.c
//
// Parameters:
// regs - Pointer to the 3 USB Core registers.
//
// Returns:
// NONE
//
//-----------------------------------------------------------------------------
BOOL HardwarePullupDP1504(CSP_USB_REGS * regs)
{
BOOL fSuccess = TRUE;
DEBUGMSG(1, (TEXT("Access PHY set to client mode - USBD\r\n")));
// Execute Reset
fSuccess = ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_FUNCTION_CTRL_S, 0x20);
if (fSuccess == FALSE)
goto cleanup;
fSuccess = ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_OTG_CTRL_S, 0x1); // ID_PULLUP
if (fSuccess == FALSE)
goto cleanup;
// disable external vbus supply
// onboard power supply MC13783 feeds through MAX4787 current limit switch
fSuccess = ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_OTG_CTRL_C, 0x40); // DRV_VBUS_EXT
if (fSuccess == FALSE)
goto cleanup;
// disable vbus (internal)
// use external VBus power supply from MC17383 DC-DC converter
fSuccess = ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_OTG_CTRL_C, 0x20); // DRV_VBUS
if (fSuccess == FALSE)
goto cleanup;
// disable external vbus (fault) indicator
// use MAX4787 fault flag to indicate over current condition
fSuccess = ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_OTG_CTRL_S, 0x80); // USE_EXT_VBUS_IND
if (fSuccess == FALSE)
goto cleanup;
// Discharge VBus
fSuccess = ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_OTG_CTRL_S, 0x08); // Discharge VBUS Bit
if (fSuccess == FALSE)
goto cleanup;
// disable the ULPI interrupt
//ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_INTR_RISING_C, 0xF);
//ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_INTR_FALLING_C, 0xF);
// ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_FUNCTION_CTRL_C, 0xff);
// Full speed setting
#ifdef FORCE_FULLSPEED
ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_OTG_CTRL_C, 0x0);
ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_FUNCTION_CTRL_C, 0x65);
#endif
//DEBUGMSG(1, (TEXT("HardwarePullUpDP1504 done\r\n")));
//DumpULPIRegs(regs);
cleanup:
return fSuccess;
}
//-----------------------------------------------------------------------------
//
// Function: SetULPIToClientMode
//
// This function is called by CSP public module to configure the ULPI to client
// mode before putting the ULPI to suspend mode.
//
// Parameters:
// regs - Pointer to the 3 USB Core registers.
//
// Returns:
// NONE
//
//-----------------------------------------------------------------------------
void SetULPIToClientMode(CSP_USB_REGS *regs)
{
DWORD temp;
DEBUGMSG(1, (TEXT("+SetULPIToClientMode\r\n")));
// resetting the PHY doesn't reset the ULPI. It does seem to reset the state though.
//
// Transceiver reset
// DEBUGMSG(1, (TEXT("RESET the PHY\r\n")));
// ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_FUNCTION_CTRL_S, 0x20);
temp = ISP1504_ReadReg(®s->OTG.ULPI_VIEWPORT, ISP1504_OTG_CTRL_RW);
// RETAILMSG(1, (TEXT("OTG_CTRL register = 0x%x\r\n"), temp));
// enable ID pull up - this may not be required, but it works like that
// since day one, we keep that.
if ((temp & 0x1) == 0)
ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_OTG_CTRL_S, 0x1); // ID_PULLUP
// disable external vbus supply
// onboard power supply MC13783 feeds through MAX4787 current limit switch
if (temp & 0x40)
ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_OTG_CTRL_C, 0x40); // DRV_VBUS_EXT
// disable vbus (internal)
// use external VBus power supply from MC17383 DC-DC converter
if (temp & 0x20)
ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_OTG_CTRL_C, 0x20); // DRV_VBUS
// disable external vbus (fault) indicator
// use MAX4787 fault flag to indicate over current condition
if ((temp & 0x80) == 0)
ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_OTG_CTRL_S, 0x80); // USE_EXT_VBUS_IND
// Discharge VBus
if ((temp & 0x08) == 0)
ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_OTG_CTRL_S, 0x08); // USE_EXT_VBUS_IND
if (temp & 0x4) // DM_PULL DOWN on
ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_OTG_CTRL_S, 0x4);
if (temp & 0x2)// DP_PULL DOWN off
ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_OTG_CTRL_C, 0x2);
temp = ISP1504_ReadReg(®s->OTG.ULPI_VIEWPORT, ISP1504_FUNCTION_CTRL_RW);
//RETAILMSG(1, (TEXT("OTG_FUNCTION register = 0x%x\r\n"), temp));
// Term select
if ((temp & 0x4) == 0)
ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_FUNCTION_CTRL_S, 0x4);
// disable the ULPI interrupt
temp = ISP1504_ReadReg(®s->OTG.ULPI_VIEWPORT, ISP1504_INTR_RISING_RW);
//RETAILMSG(1, (TEXT("OTG_INTR_RISING register = 0x%x\r\n"), temp));
if (temp & 0xF)
ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_INTR_RISING_C, 0xF);
temp = ISP1504_ReadReg(®s->OTG.ULPI_VIEWPORT, ISP1504_INTR_FALLING_RW);
//RETAILMSG(1, (TEXT("OTG_INTR_FALLING register = 0x%x\r\n"), temp));
if (temp & 0xF)
ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_INTR_FALLING_C, 0xF);
//ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_INTR_RISING_C, 0x2);
//ISP1504_WriteReg(®s->OTG.ULPI_VIEWPORT, ISP1504_INTR_FALLING_C, 0x2);
//RETAILMSG(1, (TEXT("-SetULPIToClientMode\r\n")));
//DumpULPIRegs(regs);
}
#pragma optimize( "", on )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -