try to enable ohci for lpc55 but not working, probably clock issue

This commit is contained in:
hathach
2025-10-10 12:33:41 +07:00
parent 87523f2494
commit 83baf13dcb
14 changed files with 158 additions and 96 deletions

View File

@@ -160,7 +160,7 @@ Supported CPUs
| +-----------------------------+--------+------+-----------+------------------------+-------------------+
| | NUC505 | ✔ | | ✔ | nuc505 | |
+--------------+---------+-------------------+--------+------+-----------+------------------------+-------------------+
| NXP | iMXRT | RT 10xx, 11xx | ✔ | ✔ | ✔ | ci_hs | |
| NXP | iMXRT | RT 10xx, 11xx | ✔ | ✔ | ✔ | ci_hs, ehci | |
| +---------+-------------------+--------+------+-----------+------------------------+-------------------+
| | Kinetis | KL | ✔ | ⚠ | ✖ | ci_fs, khci | |
| | +-------------------+--------+------+-----------+------------------------+-------------------+
@@ -168,15 +168,15 @@ Supported CPUs
| +---------+-------------------+--------+------+-----------+------------------------+-------------------+
| | LPC | 11u, 13, 15 | ✔ | ✖ | ✖ | lpc_ip3511 | |
| | +-------------------+--------+------+-----------+------------------------+-------------------+
| | | 17, 40 | ✔ | ⚠ | ✖ | lpc17_40 | |
| | | 17, 40 | ✔ | ⚠ | ✖ | lpc17_40, ohci | |
| | +-------------------+--------+------+-----------+------------------------+-------------------+
| | | 18, 43 | ✔ | ✔ | ✔ | ci_hs | |
| | | 18, 43 | ✔ | ✔ | ✔ | ci_hs, ehci | |
| | +-------------------+--------+------+-----------+------------------------+-------------------+
| | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | |
| | +-------------------+--------+------+-----------+------------------------+-------------------+
| | | 54, 55 | ✔ | | ✔ | lpc_ip3511 | |
| +---------+-------------------+--------+------+-----------+------------------------+-------------------+
| | MCX | N9 | ✔ | | ✔ | ci_fs, ci_hs | |
| | MCX | N9 | ✔ | | ✔ | ci_fs, ci_hs, ehci | |
| | +-------------------+--------+------+-----------+------------------------+-------------------+
| | | A15 | ✔ | | | ci_fs | |
+--------------+---------+-------------------+--------+------+-----------+------------------------+-------------------+

View File

@@ -89,7 +89,6 @@ function(family_configure_example TARGET RTOS)
family_add_tinyusb(${TARGET} OPT_MCU_LPC175X_6X)
target_sources(${TARGET} PUBLIC
${TOP}/src/portable/nxp/lpc17_40/dcd_lpc17_40.c
${TOP}/src/portable/nxp/lpc17_40/hcd_lpc17_40.c
${TOP}/src/portable/ohci/ohci.c
)
target_link_libraries(${TARGET} PUBLIC board_${BOARD})

View File

@@ -20,7 +20,6 @@ LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs
SRC_C += \
src/portable/nxp/lpc17_40/dcd_lpc17_40.c \
src/portable/nxp/lpc17_40/hcd_lpc17_40.c \
src/portable/ohci/ohci.c \
$(MCU_DIR)/../gcc/cr_startup_lpc175x_6x.c \
$(MCU_DIR)/src/chip_17xx_40xx.c \

View File

@@ -90,7 +90,6 @@ function(family_configure_example TARGET RTOS)
family_add_tinyusb(${TARGET} OPT_MCU_LPC40XX)
target_sources(${TARGET} PUBLIC
${TOP}/src/portable/nxp/lpc17_40/dcd_lpc17_40.c
${TOP}/src/portable/nxp/lpc17_40/hcd_lpc17_40.c
${TOP}/src/portable/ohci/ohci.c
)
target_link_libraries(${TARGET} PUBLIC board_${BOARD})

View File

@@ -18,7 +18,6 @@ LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs
# All source paths should be relative to the top level.
SRC_C += \
src/portable/nxp/lpc17_40/dcd_lpc17_40.c \
src/portable/nxp/lpc17_40/hcd_lpc17_40.c \
src/portable/ohci/ohci.c \
$(MCU_DIR)/../gcc/cr_startup_lpc40xx.c \
$(MCU_DIR)/src/chip_17xx_40xx.c \

View File

@@ -7,11 +7,6 @@ set(NXPLINK_DEVICE LPC55S69:LPCXpresso55S69)
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/LPC55S69_cm33_core0_uf2.ld)
# Device port default to PORT1 Highspeed
if (NOT DEFINED PORT)
set(PORT 1)
endif()
function(update_board TARGET)
target_compile_definitions(${TARGET} PUBLIC
CPU_LPC55S69JBD100_cm33_core0

View File

@@ -5,11 +5,6 @@ set(JLINK_DEVICE LPC55S28)
set(PYOCD_TARGET LPC55S28)
set(NXPLINK_DEVICE LPC55S28:LPCXpresso55S28)
# Device port default to PORT1 Highspeed
if (NOT DEFINED PORT)
set(PORT 1)
endif()
function(update_board TARGET)
target_compile_definitions(${TARGET} PUBLIC
CPU_LPC55S28JBD100

View File

@@ -5,11 +5,6 @@ set(JLINK_DEVICE LPC55S69_M33_0)
set(PYOCD_TARGET LPC55S69)
set(NXPLINK_DEVICE LPC55S69:LPCXpresso55S69)
# Device port default to PORT1 Highspeed
if (NOT DEFINED PORT)
set(PORT 1)
endif()
function(update_board TARGET)
target_compile_definitions(${TARGET} PUBLIC
CPU_LPC55S69JBD100_cm33_core0

View File

@@ -55,6 +55,7 @@
#define IOCON_PIO_MODE_INACT 0x00u // No addition pin function
#define IOCON_PIO_OPENDRAIN_DI 0x00u // Open drain is disabled
#define IOCON_PIO_SLEW_STANDARD 0x00u // Standard mode, output slew rate control is enabled
#define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */
#define IOCON_PIO_DIG_FUNC0_EN (IOCON_PIO_DIGITAL_EN | IOCON_PIO_FUNC0) // Digital pin function 0 enabled
#define IOCON_PIO_DIG_FUNC1_EN (IOCON_PIO_DIGITAL_EN | IOCON_PIO_FUNC1) // Digital pin function 1 enabled
@@ -197,13 +198,14 @@ void board_init(void) {
USART_Init(UART_DEV, &uart_config, 12000000);
#endif
// USB VBUS
#if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 0) || (CFG_TUH_ENABLED && BOARD_TUH_RHPORT == 0)
/* PORT0 PIN22 configured as USB0_VBUS */
IOCON_PinMuxSet(IOCON, 0U, 22U, IOCON_PIO_DIG_FUNC7_EN);
#if defined(BOARD_TUD_RHPORT) && BOARD_TUD_RHPORT == 0
// Port0 is Full Speed
NVIC_ClearPendingIRQ(USB0_IRQn);
NVIC_ClearPendingIRQ(USB0_NEEDCLK_IRQn);
/* Turn on USB0 Phy */
POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY);
@@ -212,21 +214,55 @@ void board_init(void) {
RESET_PeripheralReset(kUSB0HSL_RST_SHIFT_RSTn);
RESET_PeripheralReset(kUSB0HMR_RST_SHIFT_RSTn);
// Enable USB Clock Adjustments to trim the FRO for the full speed controller
ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_USBCLKADJ_MASK;
CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false);
CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
if (BOARD_TUD_RHPORT == 0) {
// Enable USB Clock Adjustments to trim the FRO for the full speed controller
ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_USBCLKADJ_MASK;
CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false);
CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
/*According to reference manual, device mode setting has to be set by access usb host register */
CLOCK_EnableClock(kCLOCK_Usbhsl0); // enable usb0 host clock
USBFSH->PORTMODE |= USBFSH_PORTMODE_DEV_ENABLE_MASK;
CLOCK_DisableClock(kCLOCK_Usbhsl0); // disable usb0 host clock
/*According to reference manual, device mode setting has to be set by access usb host register */
CLOCK_EnableClock(kCLOCK_Usbhsl0); // enable usb0 host clock
USBFSH->PORTMODE |= USBFSH_PORTMODE_DEV_ENABLE_MASK;
CLOCK_DisableClock(kCLOCK_Usbhsl0); // disable usb0 host clock
/* enable USB Device clock */
CLOCK_EnableUsbfs0DeviceClock(kCLOCK_UsbfsSrcFro, CLOCK_GetFreq(kCLOCK_FroHf));
} else {
const uint32_t port1_pin12_config = (/* Pin is configured as USB0_PORTPWRN */
IOCON_PIO_FUNC4 |
/* Selects pull-up function */
IOCON_PIO_MODE_PULLUP |
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_SLEW_STANDARD |
/* Input function is not inverted */
IOCON_PIO_INV_DI |
/* Enables digital function */
IOCON_PIO_DIGITAL_EN |
/* Open drain is disabled */
IOCON_PIO_OPENDRAIN_DI);
/* PORT1 PIN12 (coords: 67) is configured as USB0_PORTPWRN */
IOCON_PinMuxSet(IOCON, 1U, 12U, port1_pin12_config);
/* enable USB Device clock */
CLOCK_EnableUsbfs0DeviceClock(kCLOCK_UsbfsSrcFro, CLOCK_GetFreq(kCLOCK_FroHf));
const uint32_t port0_pin28_config = (/* Pin is configured as USB0_OVERCURRENTN */
IOCON_PIO_FUNC7 |
/* Selects pull-up function */
IOCON_PIO_MODE_PULLUP |
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_SLEW_STANDARD |
/* Input function is not inverted */
IOCON_PIO_INV_DI |
/* Enables digital function */
IOCON_PIO_DIGITAL_EN |
/* Open drain is disabled */
IOCON_PIO_OPENDRAIN_DI);
/* PORT0 PIN28 (coords: 66) is configured as USB0_OVERCURRENTN */
IOCON_PinMuxSet(IOCON, 0U, 28U, port0_pin28_config);
CLOCK_EnableUsbfs0HostClock(kCLOCK_UsbfsSrcPll1, 48000000U);
USBFSH->PORTMODE &= ~USBFSH_PORTMODE_DEV_ENABLE_MASK;
}
#endif
#if defined(BOARD_TUD_RHPORT) && BOARD_TUD_RHPORT == 1
#if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 1) || (CFG_TUH_ENABLED && BOARD_TUH_RHPORT == 1)
// Port1 is High Speed
/* Turn on USB1 Phy */
@@ -266,9 +302,9 @@ void board_init(void) {
// phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06);
// USBPHY->TX = phytx;
ARM_MPU_SetMemAttr(0, 0x44); // Normal memory, non-cacheable (inner and outer)
ARM_MPU_SetRegion(0, ARM_MPU_RBAR(0x40100000, ARM_MPU_SH_NON, 0, 1, 1), ARM_MPU_RLAR(0x40104000, 0));
ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk);
ARM_MPU_SetMemAttr(0, 0x44); // Normal memory, non-cacheable (inner and outer)
ARM_MPU_SetRegion(0, ARM_MPU_RBAR(0x40100000, ARM_MPU_SH_NON, 0, 1, 1), ARM_MPU_RLAR(0x40104000, 0));
ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk);
#endif
}

View File

@@ -12,12 +12,29 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOL
set(FAMILY_MCUS LPC55 CACHE INTERNAL "")
if (NOT DEFINED PORT)
set(PORT 0)
endif()
# ----------------------
# Port & Speed Selection
# ----------------------
# Host port will be the other port if available
set(HOST_PORT $<NOT:${PORT}>)
# default device port to USB1 highspeed, host to USB0 fullspeed
if (NOT DEFINED RHPORT_DEVICE)
set(RHPORT_DEVICE 1)
endif ()
if (NOT DEFINED RHPORT_HOST)
set(RHPORT_HOST 0)
endif ()
# port 0 is fullspeed, port 1 is highspeed
set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED)
if (NOT DEFINED RHPORT_DEVICE_SPEED)
list(GET RHPORT_SPEED ${RHPORT_DEVICE} RHPORT_DEVICE_SPEED)
endif ()
if (NOT DEFINED RHPORT_HOST_SPEED)
list(GET RHPORT_SPEED ${RHPORT_HOST} RHPORT_HOST_SPEED)
endif ()
cmake_print_variables(RHPORT_DEVICE RHPORT_DEVICE_SPEED RHPORT_HOST RHPORT_HOST_SPEED)
#------------------------------------
# BOARD_TARGET
@@ -67,22 +84,20 @@ function(add_board_target BOARD_TARGET)
)
target_compile_definitions(${BOARD_TARGET} PUBLIC
CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\)
BOARD_TUD_RHPORT=${PORT}
BOARD_TUH_RHPORT=${HOST_PORT}
BOARD_TUD_RHPORT=${RHPORT_DEVICE}
BOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED}
BOARD_TUH_RHPORT=${RHPORT_HOST}
BOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED}
__STARTUP_CLEAR_BSS
)
# Port 0 is Fullspeed, Port 1 is Highspeed. Port1 controller can only access USB_SRAM
if (PORT EQUAL 1)
if (RHPORT_DEVICE EQUAL 1)
target_compile_definitions(${BOARD_TARGET} PUBLIC
BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
BOARD_TUH_MAX_SPEED=OPT_MODE_FULL_SPEED
CFG_TUD_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\)
)
else ()
elseif (RHPORT_HOST EQUAL 1)
target_compile_definitions(${BOARD_TARGET} PUBLIC
BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED
BOARD_TUH_MAX_SPEED=OPT_MODE_HIGH_SPEED
CFG_TUH_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\)
)
endif ()
@@ -143,11 +158,10 @@ function(family_configure_example TARGET RTOS)
family_add_tinyusb(${TARGET} OPT_MCU_LPC55)
target_sources(${TARGET} PUBLIC
${TOP}/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c
${TOP}/src/portable/ohci/ohci.c
)
target_link_libraries(${TARGET} PUBLIC board_${BOARD})
# Flashing
family_add_bin_hex(${TARGET})
family_flash_jlink(${TARGET})

View File

@@ -64,6 +64,7 @@
#elif TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX)
#define TUP_DCD_ENDPOINT_MAX 16
#define TUP_USBIP_OHCI
#define TUP_USBIP_OHCI_NXP
#define TUP_OHCI_RHPORTS 2
#elif TU_CHECK_MCU(OPT_MCU_LPC51UXX)
@@ -78,6 +79,10 @@
#elif TU_CHECK_MCU(OPT_MCU_LPC55)
// TODO USB0 has 5, USB1 has 6
#define TUP_USBIP_IP3511
#define TUP_USBIP_OHCI
#define TUP_USBIP_OHCI_NXP
#define TUP_OHCI_RHPORTS 1 // 1 downstream port
#define TUP_DCD_ENDPOINT_MAX 6
#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX)

View File

@@ -41,13 +41,16 @@
#include "host/usbh.h"
#include "ohci.h"
// TODO remove
#include "chip.h"
#if defined(TUP_USBIP_OHCI_NXP)
#include "ohci_nxp.h"
#else
#error Unsupported OHCI IP
#endif
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
#define OHCI_REG ((ohci_registers_t *) LPC_USB_BASE)
enum {
OHCI_CONTROL_FUNCSTATE_RESET = 0,
@@ -181,6 +184,8 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
(void) rhport;
(void) rh_init;
ohci_phy_init(rhport);
//------------- Data Structure init -------------//
tu_memclr(&ohci_data, sizeof(ohci_data_t));
for(uint8_t i=0; i<32; i++)

View File

@@ -192,10 +192,10 @@ typedef struct TU_ATTR_ALIGNED(256) {
//--------------------------------------------------------------------+
typedef volatile struct
{
uint32_t revision;
uint32_t revision; // 0x00
union {
uint32_t control;
uint32_t control; // 0x04
struct {
uint32_t control_bulk_service_ratio : 2;
uint32_t periodic_list_enable : 1;
@@ -211,7 +211,7 @@ typedef volatile struct
};
union {
uint32_t command_status;
uint32_t command_status; // 0x08
struct {
uint32_t controller_reset : 1;
uint32_t control_list_filled : 1;
@@ -222,26 +222,24 @@ typedef volatile struct
}command_status_bit;
};
uint32_t interrupt_status;
uint32_t interrupt_enable;
uint32_t interrupt_disable;
uint32_t hcca;
uint32_t period_current_ed;
uint32_t control_head_ed;
uint32_t control_current_ed;
uint32_t bulk_head_ed;
uint32_t bulk_current_ed;
uint32_t done_head;
uint32_t frame_interval;
uint32_t frame_remaining;
uint32_t frame_number;
uint32_t periodic_start;
uint32_t lowspeed_threshold;
uint32_t interrupt_status; // 0x0C
uint32_t interrupt_enable; // 0x10
uint32_t interrupt_disable; // 0x14
uint32_t hcca; // 0x18
uint32_t period_current_ed; // 0x1C
uint32_t control_head_ed; // 0x20
uint32_t control_current_ed; // 0x24
uint32_t bulk_head_ed; // 0x28
uint32_t bulk_current_ed; // 0x2C
uint32_t done_head; // 0x30
uint32_t frame_interval; // 0x34
uint32_t frame_remaining; // 0x38
uint32_t frame_number; // 0x3C
uint32_t periodic_start; // 0x40
uint32_t lowspeed_threshold; // 0x44
union {
uint32_t rh_descriptorA;
uint32_t rh_descriptorA; // 0x48
struct {
uint32_t number_downstream_ports : 8;
uint32_t power_switching_mode : 1;
@@ -255,7 +253,7 @@ typedef volatile struct
};
union {
uint32_t rh_descriptorB;
uint32_t rh_descriptorB; // 0x4C
struct {
uint32_t device_removable : 16;
uint32_t port_power_control_mask : 16;
@@ -263,9 +261,9 @@ typedef volatile struct
};
union {
uint32_t rh_status;
uint32_t rh_status; // 0x50
struct {
uint32_t local_power_status : 1; // read Local Power Status; write: Clear Global Power
uint32_t local_power_status : 1; // read Local Power Status; write: Clear Global Power
uint32_t over_current_indicator : 1;
uint32_t : 13;
uint32_t device_remote_wakeup_enable : 1;
@@ -277,7 +275,8 @@ typedef volatile struct
};
union {
uint32_t rhport_status[TUP_OHCI_RHPORTS];
uint32_t rhport_status[TUP_OHCI_RHPORTS]; // 0x54
struct {
uint32_t current_connect_status : 1;
uint32_t port_enable_status : 1;

View File

@@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019, Ha Thach (tinyusb.org)
* Copyright (c) 2025 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,26 +23,48 @@
*
* This file is part of the TinyUSB stack.
*/
#ifndef TUSB_OHCI_NXP_H
#define TUSB_OHCI_NXP_H
#include "tusb_option.h"
#if CFG_TUH_ENABLED && \
(CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX)
#if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX)
#include "chip.h"
#include "host/hcd.h"
#include "host/usbh.h"
#define OHCI_REG ((ohci_registers_t *) LPC_USB_BASE)
void hcd_int_enable(uint8_t rhport)
{
(void) rhport;
void hcd_int_enable(uint8_t rhport) {
(void)rhport;
NVIC_EnableIRQ(USB_IRQn);
}
void hcd_int_disable(uint8_t rhport)
{
(void) rhport;
void hcd_int_disable(uint8_t rhport) {
(void)rhport;
NVIC_DisableIRQ(USB_IRQn);
}
static void ohci_phy_init(uint8_t rhport) {
(void) rhport;
}
#else
#include "fsl_device_registers.h"
// for LPC55 USB0 controller
#define OHCI_REG ((ohci_registers_t *) USBFSH_BASE)
static void ohci_phy_init(uint8_t rhport) {
(void) rhport;
}
void hcd_int_enable(uint8_t rhport) {
(void)rhport;
NVIC_EnableIRQ(USB0_IRQn);
}
void hcd_int_disable(uint8_t rhport) {
(void)rhport;
NVIC_DisableIRQ(USB0_IRQn);
}
#endif
#endif