Hello,
I’m Jean-Marc and I’m working as firmware engineer for an optical transport company. I’m working on a board with a LPC4337 and an external PHY USB USB3300 connected to the USB1 port. For the moment, I’m using the USB1 as a device port connected to my computer. The computer just detects the new device but can’t identify it.
I succeed to read/write PHY registers with the ULPI interface so I suppose my ULPI configuration is good. I’m trying to adapt my firmware with your recommendations, but without success.
Did you have some informations to this issue by NXP since 2016 ? Could you exactly send me your sequences of commands to the PHY registers, please ? Sorry to bother you with these old issues. Jean-Marc
#define _BIT(n) (1 << (n))
#define ULPIWU _BIT(31)
#define ULPIRW _BIT(29)
#define ULPIRUN _BIT(30)
#define ULPISS _BIT(27)
#define ULPIADDR(x) (uint32_t)((x) << 16 )
#define ULPIDATRD(x) (uint8_t)((x) >> 8 & 0xff)
inline bool UlpiIsReady()
{
return ( LPC_USB1->ULPIVIEWPORT & ULPISS );
}
inline void UlpiWakeUp()
{
LPC_USB1->ULPIVIEWPORT = 0x0 | ULPIWU;
while ( (LPC_USB1->ULPIVIEWPORT & ULPIWU) ) {}; // wait for wake up
}
inline uint8_t UlpiRegRead(uint8_t regAddr )
{
uint32_t tmp = ULPIADDR(regAddr) | ULPIRUN;
LPC_USB1->ULPIVIEWPORT = tmp;
while ( LPC_USB1->ULPIVIEWPORT & ULPIRUN ) {}; //wait for completion
return ULPIDATRD(LPC_USB1->ULPIVIEWPORT);
}
inline void UlpiRegWrite(uint8_t regAddr, uint8_t data)
{
LPC_USB1->ULPIVIEWPORT = ULPIADDR(regAddr) | data | ULPIRW | ULPIRUN;
while ( LPC_USB1->ULPIVIEWPORT & ULPIRUN ) {}; //wait for completion
return ULPIDATRD(LPC_USB1->ULPIVIEWPORT);
}
uint8_t ulpiRegs[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x07, 0x0A, 0x0D, 0x10, 0x13, 0x14, 0x15, 0x16, 0x19, 0x1D, 0x20, 0x21, 0x31, 0x32, 0x33, 0x36, 0x39 };
uint8_t regVals[sizeof(ulpiRegs)];
unsigned inti;
if ( ! UlpiIsReady() )
UlpiWakeUp();
for (i=0;i < sizeof(ulpiRegs);i++)
{
regVals = UlpiRegRead(ulpiRegs);
}
for (i=0;i < sizeof(ulpiRegs);i++)
{
printf("UlpiReg[0x%02X]=0x%02X\n",ulpiRegs,regVals);
}
|
STATIC const PINMUX_GRP_T usb1pinmuxing[] = {
/* USB1-ULPI pin group */
{0x8, 5, (SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC1)}, // ULPI_D0
{0x8, 4, (SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC1)}, // ULPI_D1
{0x8, 3, (SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC1)}, // ULPI_D2
{0xB, 6, (SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC1)}, // ULPI_D3
{0xB, 5, (SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC1)}, // ULPI_D4
{0xB, 4, (SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC1)}, // ULPI_D5
{0xB, 3, (SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC1)}, // ULPI_D6
{0xB, 2, (SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC1)}, // ULPI_D7
{0x8, 6, (SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC1)}, // ULPI_NXT
{0xB, 1, (SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC1)}, // ULPI_DIR
{0x8, 7, (SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC1)}, // ULPI_STP
{0x8, 8, (SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC1)}, // ULPI_CLK
};
void Ulpi_USB1_Init(void)
{
uint32_t portsc;
/* Setup and enable the PLL else we cant't access the USB Clock registers !! */
Chip_Clock_EnableBaseClock(CLK_BASE_USB1);
/* disable USB1_CLOCK, it's clock will be provided by the PHY */
LPC_CCU1->CLKCCU[CLK_USB1].CFG &= ~1;
/* ULPI pin setup is done prior to setting up clocking */
Chip_SCU_SetPinMuxing(usb1pinmuxing, sizeof(usb1pinmuxing) / sizeof(PINMUX_GRP_T));
/* switch to ulpi phy and turn on the power to phy*/
// Clear PFSC (bit24) to prevent the port from forcing a high speed connection
portsc = LPC_USB1->PORTSC1_D & 0x00FFFFFF;
//portsc |= _BIT(24); // force full speed connection OR
portsc &= ~_BIT(24); // clear PFSC to allow any speed connect
portsc |= 0x80000000; // PTS select, bit 31:30, 0x2 = ULPI
LPC_USB1->PORTSC1_D = portsc;
/* reset the controller */
LPC_USB1->USBCMD_D = _BIT(1);
/* wait for reset to complete */
while (LPC_USB1->USBCMD_D & _BIT(1));
/* Program the controller to be the USB device mode */
LPC_USB1->USBMODE_D = 0x02 | _BIT(3);
}
STATIC INLINE void Chip_SCU_SetPinMuxing(const PINMUX_GRP_T *pinArray, uint32_t arrayLength)
{
uint32_t ix;
for (ix = 0; ix < arrayLength; ix++ ) {
Chip_SCU_PinMuxSet(pinArray[ix].pingrp, pinArray[ix].pinnum, pinArray[ix].modefunc);
}
}
STATIC INLINE void Chip_SCU_PinMuxSet(uint8_t port, uint8_t pin, uint16_t modefunc)
{
LPC_SCU->SFSP[port][pin] = modefunc;
}
|