This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit d218334baaf6151adad764d6fadada9d910759c4 Author: Alan Carvalho de Assis <acas...@gmail.com> AuthorDate: Mon Aug 4 20:22:31 2025 -0300 boards/arcx-socket-grid: Add support to USBHOST and USBDISK This PR add support to USBHOST on iMXRT1052 ARCX-Socket-Grid board and add a USBDISK board config example. Signed-off-by: Alan C. Assis <acas...@gmail.com> --- arch/arm/src/imxrt/Kconfig | 2 + arch/arm/src/imxrt/imxrt_ehci.c | 5 +- .../arcx-socket-grid/configs/usbdisk/defconfig | 58 +++++ boards/arm/imxrt/arcx-socket-grid/include/board.h | 1 + .../arm/imxrt/arcx-socket-grid/src/CMakeLists.txt | 4 + boards/arm/imxrt/arcx-socket-grid/src/Makefile | 4 + .../imxrt/arcx-socket-grid/src/arcx-socket-grid.h | 21 +- .../arm/imxrt/arcx-socket-grid/src/imxrt_bringup.c | 23 ++ .../arm/imxrt/arcx-socket-grid/src/imxrt_usbhost.c | 249 +++++++++++++++++++++ 9 files changed, 362 insertions(+), 5 deletions(-) diff --git a/arch/arm/src/imxrt/Kconfig b/arch/arm/src/imxrt/Kconfig index 73cb2613638..44807a062ee 100644 --- a/arch/arm/src/imxrt/Kconfig +++ b/arch/arm/src/imxrt/Kconfig @@ -378,6 +378,7 @@ config IMXRT_USBOTG1 select IMXRT_USBOTG select USBHOST_HAVE_ASYNCH if USBHOST select USBHOST_ASYNCH + select USBHOST_WAITER config IMXRT_USBOTG2 bool "USB EHCI OTG2: NOT SUPPORTED YET" @@ -386,6 +387,7 @@ config IMXRT_USBOTG2 select IMXRT_USBOTG select USBHOST_HAVE_ASYNCH if USBHOST select USBHOST_ASYNCH + select USBHOST_WAITER config IMXRT_USBDEV bool "USB Device" diff --git a/arch/arm/src/imxrt/imxrt_ehci.c b/arch/arm/src/imxrt/imxrt_ehci.c index 4ffea3e4d87..fce66785477 100644 --- a/arch/arm/src/imxrt/imxrt_ehci.c +++ b/arch/arm/src/imxrt/imxrt_ehci.c @@ -50,6 +50,7 @@ #include "chip.h" #include "hardware/imxrt_usbotg.h" #include "imxrt_periphclks.h" +#include "imxrt_ehci.h" #if defined(CONFIG_IMXRT_USBOTG) && defined(CONFIG_USBHOST) @@ -459,8 +460,8 @@ static int imxrt_qh_dump(struct imxrt_qh_s *qh, uint32_t **bp, void *arg); #else # define imxrt_qtd_print(qtd) # define imxrt_qh_print(qh) -# define imxrt_qtd_dump(qtd, bp, arg) OK -# define imxrt_qh_dump(qh, bp, arg) OK +# define imxrt_qtd_dump(qtd, bp, arg) ((void)OK) +# define imxrt_qh_dump(qh, bp, arg) ((void)OK) #endif static inline uint8_t imxrt_ehci_speed(uint8_t usbspeed); diff --git a/boards/arm/imxrt/arcx-socket-grid/configs/usbdisk/defconfig b/boards/arm/imxrt/arcx-socket-grid/configs/usbdisk/defconfig new file mode 100644 index 00000000000..bc91e9320bb --- /dev/null +++ b/boards/arm/imxrt/arcx-socket-grid/configs/usbdisk/defconfig @@ -0,0 +1,58 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="arcx-socket-grid" +CONFIG_ARCH_BOARD_ARCX_SOCKET_GRID=y +CONFIG_ARCH_CHIP="imxrt" +CONFIG_ARCH_CHIP_IMXRT=y +CONFIG_ARCH_CHIP_MIMXRT1052DVL6A=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_BOARD_LOOPSPERMSEC=104926 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_FS_ERROR=y +CONFIG_DEBUG_FS_WARN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SCHED=y +CONFIG_DEBUG_SCHED_ERROR=y +CONFIG_DEBUG_SCHED_INFO=y +CONFIG_DEBUG_SCHED_WARN=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FS_FAT=y +CONFIG_FS_PROCFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_IMXRT_LPUART1=y +CONFIG_IMXRT_USBOTG1=y +CONFIG_IMXRT_USBOTG2=y +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_LINE_MAX=64 +CONFIG_LPUART1_SERIAL_CONSOLE=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_RAM_SIZE=524288 +CONFIG_RAM_START=0x20200000 +CONFIG_RAW_BINARY=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_LPWORK=y +CONFIG_START_DAY=14 +CONFIG_START_MONTH=3 +CONFIG_SYSTEM_NSH=y +CONFIG_USBHOST=y +CONFIG_USBHOST_MSC=y +CONFIG_USBHOST_TRACE=y +CONFIG_USBMONITOR=y diff --git a/boards/arm/imxrt/arcx-socket-grid/include/board.h b/boards/arm/imxrt/arcx-socket-grid/include/board.h index 06604cf7140..5642718e26e 100644 --- a/boards/arm/imxrt/arcx-socket-grid/include/board.h +++ b/boards/arm/imxrt/arcx-socket-grid/include/board.h @@ -119,6 +119,7 @@ #define IMXRT_SYS_PLL_SELECT CCM_ANALOG_PLL_SYS_DIV_SELECT_22 #define IMXRT_USB1_PLL_DIV_SELECT CCM_ANALOG_PLL_USB1_DIV_SELECT_20 +#define IMXRT_USB2_PLL_DIV_SELECT CCM_ANALOG_PLL_USB2_DIV_SELECT_20 #define BOARD_CPU_FREQUENCY \ (BOARD_XTAL_FREQUENCY * (IMXRT_ARM_PLL_DIV_SELECT / 2)) / IMXRT_ARM_PODF_DIVIDER diff --git a/boards/arm/imxrt/arcx-socket-grid/src/CMakeLists.txt b/boards/arm/imxrt/arcx-socket-grid/src/CMakeLists.txt index b755a986f92..1320f4c454a 100644 --- a/boards/arm/imxrt/arcx-socket-grid/src/CMakeLists.txt +++ b/boards/arm/imxrt/arcx-socket-grid/src/CMakeLists.txt @@ -50,6 +50,10 @@ if(CONFIG_DEV_GPIO) list(APPEND SRCS imxrt_gpio.c) endif() +if(CONFIG_IMXRT_USBOTG) + list(APPEND SRCS imxrt_usbhost.c) +endif() + if(CONFIG_IMXRT1052_SOCKET_GRID_SDRAM) list(APPEND SRCS imxrt_sdram_ini_dcd.c) endif() diff --git a/boards/arm/imxrt/arcx-socket-grid/src/Makefile b/boards/arm/imxrt/arcx-socket-grid/src/Makefile index 6190881b7ba..c4b41eb81df 100644 --- a/boards/arm/imxrt/arcx-socket-grid/src/Makefile +++ b/boards/arm/imxrt/arcx-socket-grid/src/Makefile @@ -48,6 +48,10 @@ ifeq ($(CONFIG_IMXRT_LPSPI),y) CSRCS += imxrt_spi.c endif +ifeq ($(CONFIG_IMXRT_USBOTG),y) +CSRCS += imxrt_usbhost.c +endif + ifeq ($(CONFIG_DEV_GPIO),y) CSRCS += imxrt_gpio.c endif diff --git a/boards/arm/imxrt/arcx-socket-grid/src/arcx-socket-grid.h b/boards/arm/imxrt/arcx-socket-grid/src/arcx-socket-grid.h index b559cede773..4426396fd47 100644 --- a/boards/arm/imxrt/arcx-socket-grid/src/arcx-socket-grid.h +++ b/boards/arm/imxrt/arcx-socket-grid/src/arcx-socket-grid.h @@ -71,10 +71,14 @@ #define GPIO_GOUT4 (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_GOUT_DEFAULT | \ GPIO_PIN9 | GPIO_PORT1) -/* Backlight */ +/* USB OTG1 ID Pin: GPIO_AD_B0_01 */ -#define GPIO_LCD_BL (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | GPIO_PORT2 | \ - GPIO_PIN31 | IOMUX_LCD_BL_DEFAULT) +#define GPIO_USBOTG1_ID (GPIO_USB_OTG1_ID_2 | IOMUX_USBOTG_ID_DEFAULT) /* AD_B0_01 */ + +/* USB HOST Power - GPIO_B1_15 */ + +#define USB_HOST_PWR (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | GPIO_PORT2 | \ + GPIO_PIN31 | IOMUX_USBOTG_PWR_DEFAULT) /* Ethernet */ @@ -191,5 +195,16 @@ void imxrt_autoled_initialize(void); int imxrt_gpio_initialize(void); #endif +/**************************************************************************** + * Name: imxrt_usbhost_initialize + * + * Description: + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +int imxrt_usbhost_initialize(void); +#endif + #endif /* __ASSEMBLY__ */ #endif /* __BOARDS_ARM_IMXRT_IMXRT1052_SOCKET_GRID_SRC_IMXRT1052_SOCKET_GRID_H */ diff --git a/boards/arm/imxrt/arcx-socket-grid/src/imxrt_bringup.c b/boards/arm/imxrt/arcx-socket-grid/src/imxrt_bringup.c index eab3927bd4c..eb9dc2e43da 100644 --- a/boards/arm/imxrt/arcx-socket-grid/src/imxrt_bringup.c +++ b/boards/arm/imxrt/arcx-socket-grid/src/imxrt_bringup.c @@ -40,6 +40,10 @@ # include "imxrt_usdhc.h" #endif +#ifdef CONFIG_USBMONITOR +# include <nuttx/usb/usbmonitor.h> +#endif + #include "arcx-socket-grid.h" #include <arch/board/board.h> /* Must always be included last */ @@ -122,6 +126,25 @@ int imxrt_bringup(void) } #endif +#if defined(CONFIG_IMXRT_USBOTG) || defined(CONFIG_USBHOST) + ret = imxrt_usbhost_initialize(); + if (ret != OK) + { + syslog(LOG_ERR, "ERROR: Failed to start USB host services: %d\n", ret); + return ret; + } +#endif + +#ifdef CONFIG_USBMONITOR + /* Start the USB Monitor */ + + ret = usbmonitor_start(); + if (ret != OK) + { + syslog(LOG_ERR, "ERROR: Failed to start USB monitor: %d\n", ret); + } +#endif + #ifdef CONFIG_DEV_GPIO ret = imxrt_gpio_initialize(); if (ret < 0) diff --git a/boards/arm/imxrt/arcx-socket-grid/src/imxrt_usbhost.c b/boards/arm/imxrt/arcx-socket-grid/src/imxrt_usbhost.c new file mode 100644 index 00000000000..6dad72e6755 --- /dev/null +++ b/boards/arm/imxrt/arcx-socket-grid/src/imxrt_usbhost.c @@ -0,0 +1,249 @@ +/**************************************************************************** + * boards/arm/imxrt/arcx-socket-grid/src/imxrt_usbhost.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <sched.h> +#include <errno.h> +#include <assert.h> +#include <debug.h> + +#include <nuttx/irq.h> +#include <nuttx/kthread.h> +#include <nuttx/usb/usbdev.h> +#include <nuttx/usb/usbhost.h> +#include <nuttx/usb/usbdev_trace.h> +#include <nuttx/usb/ehci.h> + +#include <imxrt_ehci.h> + +#include "hardware/imxrt_pinmux.h" +#include "hardware/imxrt_usbotg.h" +#include "imxrt_periphclks.h" +#include "arcx-socket-grid.h" + +#include <arch/board/board.h> /* Must always be included last */ + +#if defined(CONFIG_IMXRT_USBOTG) || defined(CONFIG_USBHOST) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_usbhost_initialize + * + * Description: + * Called at application startup time to initialize the USB host + * functionality. + * This function will start a thread that will monitor for device + * connection/disconnection events. + * + ****************************************************************************/ + +int imxrt_usbhost_initialize(void) +{ + struct usbhost_connection_s *ehciconn; + int ret; + + imxrt_clockall_usboh3(); + + /* Make sure we don't accidentally switch on USB bus power */ + + *((uint32_t *)IMXRT_USBNC_USB_OTG1_CTRL) = USBNC_PWR_POL; + *((uint32_t *)0x400d9030) = (1 << 21); + *((uint32_t *)0x400d9000) = 0; + + /* Setup pins, with power initially off */ + + imxrt_config_gpio(GPIO_USBOTG1_ID); + + /* Enable USB HOST POWER */ + + imxrt_config_gpio(USB_HOST_PWR); + imxrt_gpio_write(USB_HOST_PWR, true); + + /* First, register all of the class drivers needed to support the drivers + * that we care about + */ + +#ifdef CONFIG_USBHOST_HUB + /* Initialize USB hub support */ + + ret = usbhost_hub_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: usbhost_hub_initialize failed: %d\n", ret); + } +#endif + +#ifdef CONFIG_USBHOST_MSC + /* Register the USB host Mass Storage Class */ + + ret = usbhost_msc_initialize(); + if (ret != OK) + { + syslog(LOG_ERR, + "ERROR: Failed to register the mass storage class: %d\n", ret); + } +#endif + +#ifdef CONFIG_USBHOST_CDCACM + /* Register the CDC/ACM serial class */ + + ret = usbhost_cdcacm_initialize(); + if (ret != OK) + { + uerr("ERROR: Failed to register the CDC/ACM serial class\n"); + } +#endif + +#ifdef CONFIG_USBHOST_HIDKBD + /* Register the USB host HID keyboard class driver */ + + ret = usbhost_kbdinit(); + if (ret != OK) + { + uerr("ERROR: Failed to register the KBD class\n"); + } +#endif + + /* Then get an instance of the USB EHCI interface. */ + + ehciconn = imxrt_ehci_initialize(0); + if (!ehciconn) + { + uerr("ERROR: imxrt_ehci_initialize failed\n"); + return -ENODEV; + } + + /* Initialize waiter */ + + ret = usbhost_waiter_initialize(ehciconn); + if (ret < 0) + { + uerr("ERROR: Failed to create ehci_waiter task: %d\n", ret); + return -ENODEV; + } + + return OK; +} + +/**************************************************************************** + * Name: imxrt_usbhost_vbusdrive + * + * Description: + * Enable/disable driving of VBUS 5V output. This function must be + * provided by each platform that implements the OHCI or EHCI host + * interface + * + * Input Parameters: + * rhport - Selects root hub port to be powered host interface. + * Since the IMXRT has only a downstream port, zero is + * the only possible value for this parameter. + * enable - true: enable VBUS power; false: disable VBUS power + * + * Returned Value: + * None + * + ****************************************************************************/ + +#define HCOR ((volatile struct ehci_hcor_s *)IMXRT_USBOTG_HCOR_BASE) + +void imxrt_usbhost_vbusdrive(int rhport, bool enable) +{ + uint32_t regval; + + uinfo("RHPort%d: enable=%d\n", rhport + 1, enable); + + /* The IMXRT has only a single root hub port */ + + if (rhport == 0) + { + /* Then enable or disable VBUS power */ + + regval = HCOR->portsc[rhport]; + regval &= ~EHCI_PORTSC_PP; + if (enable) + { + regval |= EHCI_PORTSC_PP; + } + + HCOR->portsc[rhport] = regval; + } +} + +/**************************************************************************** + * Name: imxrt_setup_overcurrent + * + * Description: + * Setup to receive an interrupt-level callback if an overcurrent condition + * is detected. + * + * Input Parameters: + * handler - New overcurrent interrupt handler + * arg - The argument that will accompany the interrupt + * + * Returned Value: + * Zero (OK) returned on success; a negated errno value is returned on + * failure. + * + ****************************************************************************/ + +#if 0 /* Not ready yet */ +int imxrt_setup_overcurrent(xcpt_t handler, void *arg) +{ + irqstate_t flags; + + /* Disable interrupts until we are done. This guarantees that the + * following operations are atomic. + */ + + flags = enter_critical_section(); + + /* Configure the interrupt */ + +#warning Missing logic + + leave_critical_section(flags); + return OK; +} +#endif /* 0 */ + +#endif /* CONFIG_IMXRT_USBOTG || CONFIG_USBHOST */