ports/stm32: Update ULPI code. (#2656)
Some checks failed
🔎 Check Code Formatting / formatting-check (push) Has been cancelled
🔥 Firmware Build / build-firmware (ARDUINO_GIGA) (push) Has been cancelled
🔥 Firmware Build / build-firmware (ARDUINO_NANO_33_BLE_SENSE) (push) Has been cancelled
🔥 Firmware Build / build-firmware (ARDUINO_NANO_RP2040_CONNECT) (push) Has been cancelled
🔥 Firmware Build / build-firmware (ARDUINO_NICLA_VISION) (push) Has been cancelled
🔥 Firmware Build / build-firmware (ARDUINO_PORTENTA_H7) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV2) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV3) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV4) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV4P) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMVPT) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV_AE3) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV_RT1060) (push) Has been cancelled
🔥 Firmware Build / code-size-report (push) Has been cancelled
🔥 Firmware Build / stable-release (push) Has been cancelled
🔥 Firmware Build / development-release (push) Has been cancelled

- Add support for reset to recover ULPI.
- Clean up formatting, comments.

Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
This commit is contained in:
Ibrahim Abdelkader 2025-04-12 09:21:36 +02:00 committed by GitHub
parent 4d4d29c2f2
commit d4f2689e92
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -38,19 +38,21 @@
#include "ulpi.h"
#include "omv_gpio.h"
#if defined(STM32H7)
#define GPIO_AF10_OTG_HS (GPIO_AF10_OTG2_HS)
#endif
#define USBULPI_PHYCR ((uint32_t) (0x40040000 + 0x034))
#define USBULPI_D07 ((uint32_t) 0x000000FF)
#define USBULPI_New ((uint32_t) 0x02000000)
#define USBULPI_RW ((uint32_t) 0x00400000)
#define USBULPI_S_BUSY ((uint32_t) 0x04000000)
#define USBULPI_S_DONE ((uint32_t) 0x08000000)
#define USBULPI_TIMEOUT_COUNT (500)
#define USB_OTG_READ_REG32(reg) (*(__IO uint32_t *) (reg))
#define USB_OTG_WRITE_REG32(reg, value) (*(__IO uint32_t *) (reg) = (value))
#if defined(STM32H7)
#define GPIO_AF10_OTG_HS (GPIO_AF10_OTG2_HS)
#endif
extern void __fatal_error(const char *msg);
@ -61,7 +63,7 @@ extern void __fatal_error(const char *msg);
*/
static uint32_t USB_ULPI_Read(uint32_t Addr) {
__IO uint32_t val = 0;
__IO uint32_t timeout = 100; /* Can be tuned based on the Clock or etc... */
__IO uint32_t timeout = USBULPI_TIMEOUT_COUNT;
USB_OTG_WRITE_REG32(USBULPI_PHYCR, USBULPI_New | (Addr << 16));
val = USB_OTG_READ_REG32(USBULPI_PHYCR);
@ -69,7 +71,7 @@ static uint32_t USB_ULPI_Read(uint32_t Addr) {
val = USB_OTG_READ_REG32(USBULPI_PHYCR);
}
val = USB_OTG_READ_REG32(USBULPI_PHYCR);
return (val & 0x000000ff);
return val & 0x000000ff;
}
/**
@ -80,7 +82,7 @@ static uint32_t USB_ULPI_Read(uint32_t Addr) {
*/
static uint32_t USB_ULPI_Write(uint32_t Addr, uint32_t Data) {
__IO uint32_t val;
__IO uint32_t timeout = 10; /* Can be tuned based on the Clock or etc... */
__IO uint32_t timeout = USBULPI_TIMEOUT_COUNT;
USB_OTG_WRITE_REG32(USBULPI_PHYCR, USBULPI_New | USBULPI_RW | (Addr << 16) | (Data & 0x000000ff));
val = USB_OTG_READ_REG32(USBULPI_PHYCR);
@ -92,6 +94,17 @@ static uint32_t USB_ULPI_Write(uint32_t Addr, uint32_t Data) {
return 0;
}
#ifdef OMV_USB_ULPI_RST_PIN
void ulpi_reset(void) {
omv_gpio_clock_enable(OMV_USB_ULPI_RST_PIN, true);
omv_gpio_config(OMV_USB_ULPI_RST_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_LOW, -1);
omv_gpio_write(OMV_USB_ULPI_RST_PIN, 0);
HAL_Delay(10);
omv_gpio_write(OMV_USB_ULPI_RST_PIN, 1);
HAL_Delay(100);
}
#endif
/**
* @brief This function configures the USB PHY to enter the low power mode
* @param None
@ -100,8 +113,8 @@ static uint32_t USB_ULPI_Write(uint32_t Addr, uint32_t Data) {
void ulpi_enter_low_power(void) {
__IO uint32_t regval = 0;
/* disable ULPI_CLK by accessing ULPI_PHY */
/* read Vendor ID : (Low, High) 0x24,0x04 for USB3300 */
// Disable ULPI_CLK by accessing ULPI_PHY
// Read Vendor ID : (Low, High) 0x24,0x04 for USB3300
regval = USB_ULPI_Read(0x00);
if (regval != 0x24) {
__fatal_error("ULPI Error 0x00 != 0x24");
@ -112,7 +125,7 @@ void ulpi_enter_low_power(void) {
__fatal_error("ULPI Error 0x01 != 0x04");
}
/* read Product ID */
// Read Product ID
regval = USB_ULPI_Read(0x02);
if (regval != 0x07) {
__fatal_error("ULPI Error 0x02 != 0x07");
@ -123,34 +136,36 @@ void ulpi_enter_low_power(void) {
__fatal_error("ULPI Error 0x03 != 0x00");
}
/* Write to scratch register the pattern 0x55 */
// Write to scratch register the pattern 0x55
USB_ULPI_Write(0x16, 0x55);
/* Read to scratch Register and check-it again the written Pattern */
// Read to scratch Register and check-it again the written Pattern
regval = USB_ULPI_Read(0x16);
if (regval != 0x55) {
__fatal_error("ULPI Error 0x16 != 0x55");
}
/* Write to scratch register the pattern 0xAA */
// Write to scratch register the pattern 0xAA
USB_ULPI_Write(0x16, 0xAA);
/* Read to scratch Register and check-it again the written Pattern */
// Read to scratch Register and check-it again the written Pattern
regval = USB_ULPI_Read(0x16);
if (regval != 0xAA) {
__fatal_error("ULPI Error 0x16 != 0xAA");
}
/* read InterfaceControl reg */
// Read InterfaceControl reg
regval = USB_ULPI_Read(0x07);
/* write InterfaceControl reg,to disable PullUp on stp,
to avoid USB_PHY wake up when MCU entering standby */
// Write InterfaceControl reg,to disable PullUp on stp,
// to avoid USB_PHY wake up when MCU entering standby
USB_ULPI_Write(0x07, regval | 0x80);
/* read InterfaceControl reg */
//Read InterfaceControl reg
regval = USB_ULPI_Read(0x07);
if (regval != 0x80) {
__fatal_error("ULPI Error 0x07 != 0x80");
}
/* read FunctionControl reg */
// Read FunctionControl reg
regval = USB_ULPI_Read(0x04);
// Reg 0x40 has a different value if USB is disconnected.
@ -158,16 +173,15 @@ void ulpi_enter_low_power(void) {
__fatal_error("ULPI Error 0x04 != 0x40 || 0x45");
}
/* write FunctionControl reg,to put PHY into LowPower mode */
// Write FunctionControl reg,to put PHY into LowPower mode
USB_ULPI_Write(0x04, regval & (~0x40));
/* read FunctionControl reg again */
// Read FunctionControl reg again
regval = USB_ULPI_Read(0x04);
if (regval != 0x00) {
__fatal_error("ULPI Error 0x04 != 0x00");
}
/* Delay 4 ms */
HAL_Delay(10);
}
@ -177,25 +191,32 @@ void ulpi_enter_low_power(void) {
* @retval None
*/
void ulpi_leave_low_power(void) {
/* Enable GPIO clock for OTG USB STP pin */
// Configure STP as an output pin
omv_gpio_clock_enable(OMV_USB_ULPI_STP_PIN, true);
omv_gpio_clock_enable(OMV_USB_ULPI_DIR_PIN, true);
/* Configure OTG STP and DIR pin as GP Output */
omv_gpio_config(OMV_USB_ULPI_STP_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_LOW, -1);
// Configure DIR as an input pin
omv_gpio_clock_enable(OMV_USB_ULPI_DIR_PIN, true);
omv_gpio_config(OMV_USB_ULPI_DIR_PIN, OMV_GPIO_MODE_INPUT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_LOW, -1);
/* Set OTG STP pin to High */
// Set STP pin high
omv_gpio_write(OMV_USB_ULPI_STP_PIN, 1);
/* Wait for DIR to go low */
for (uint32_t ticks = HAL_GetTick();
((HAL_GetTick() - ticks) < 500)
&& omv_gpio_read(OMV_USB_ULPI_DIR_PIN);) {
__WFI();
// Wait for DIR to go low
for (uint32_t i = 0; i < 1000; i++, HAL_Delay(1)) {
if (!omv_gpio_read(OMV_USB_ULPI_DIR_PIN)) {
break;
}
}
/* Configure OTG STP and DIR pin as USB AF */
#ifdef OMV_USB_ULPI_RST_PIN
if (omv_gpio_read(OMV_USB_ULPI_DIR_PIN)) {
// Failed to exit suspend mode, reset the ULPI.
ulpi_reset();
}
#endif
// Configure OTG STP and DIR pin as USB AF
omv_gpio_config(OMV_USB_ULPI_STP_PIN, OMV_GPIO_MODE_ALT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_MAX, -1);
omv_gpio_config(OMV_USB_ULPI_DIR_PIN, OMV_GPIO_MODE_ALT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_MAX, -1);
}