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; } |