/**************************************************************************** * boards/arm/stm32h7/openh743i/src/stm32_usb.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 #include #include #include #include #include #include #include #include "stm32_gpio.h" #include "stm32_otg.h" #include "openh743i.h" /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ #if defined(CONFIG_STM32H7_OTGFS_HOST) && defined(CONFIG_STM32H7_OTGHS_USBDEV) # ifndef CONFIG_OPENH743I_DISABLE_OTGFS_PWRON # error PWRON must be disabled for this configuration # endif #endif #define USBHOST_PRIO (100) #define USBHOST_STACKSIZE (1024) /**************************************************************************** * Private Data ****************************************************************************/ #ifdef CONFIG_USBHOST static struct usbhost_connection_s *g_usbconn; #endif /**************************************************************************** * Private Functions ****************************************************************************/ /**************************************************************************** * Name: usbhost_waiter * * Description: * Wait for USB devices to be connected. * ****************************************************************************/ #ifdef CONFIG_USBHOST static int usbhost_waiter(int argc, char *argv[]) { struct usbhost_hubport_s *hport; uinfo("Running\n"); for (; ; ) { /* Wait for the device to change state */ DEBUGVERIFY(CONN_WAIT(g_usbconn, &hport)); uinfo("%s\n", hport->connected ? "connected" : "disconnected"); /* Did we just become connected? */ if (hport->connected) { /* Yes.. enumerate the newly connected device */ CONN_ENUMERATE(g_usbconn, hport); } } /* Keep the compiler from complaining */ return 0; } #endif /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: stm32_usbinitialize * * Description: * Called from stm32_usbinitialize very early in inialization to setup * USB-related GPIO pins for the board. * ****************************************************************************/ void stm32_usbinitialize(void) { /* Configure the OTG FS VBUS sensing GPIO, * Power On, and Overcurrent GPIOs */ #ifdef CONFIG_STM32H7_OTGFS stm32_configgpio(GPIO_OTGFS_VBUS); stm32_configgpio(GPIO_OTGFS_PWRON); stm32_configgpio(GPIO_OTGFS_OVER); #endif } /**************************************************************************** * Name: stm32_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. * ****************************************************************************/ #ifdef CONFIG_USBHOST int stm32_usbhost_initialize(void) { int ret; /* First, register all of the class drivers needed to support the drivers * that we care about: */ uinfo("Register class drivers\n"); #ifdef CONFIG_USBHOST_HUB /* Initialize USB hub class support */ ret = usbhost_hub_initialize(); if (ret < 0) { uerr("ERROR: usbhost_hub_initialize failed: %d\n", ret); } #endif #ifdef CONFIG_USBHOST_MSC /* Register the USB mass storage class class */ ret = usbhost_msc_initialize(); if (ret != OK) { uerr("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: %d\n", ret); } #endif #ifdef CONFIG_USBHOST_HIDKBD /* Initialize the HID keyboard class */ ret = usbhost_kbdinit(); if (ret != OK) { uerr("ERROR: Failed to register the HID keyboard class\n"); } #endif #ifdef CONFIG_USBHOST_HIDMOUSE /* Initialize the HID mouse class */ ret = usbhost_mouse_init(); if (ret != OK) { uerr("ERROR: Failed to register the HID mouse class\n"); } #endif /* Then get an instance of the USB host interface */ uinfo("Initialize USB host\n"); g_usbconn = stm32_otgfshost_initialize(0); if (g_usbconn) { /* Start a thread to handle device connection. */ uinfo("Start usbhost_waiter\n"); ret = kthread_create("usbhost", USBHOST_PRIO, USBHOST_STACKSIZE, usbhost_waiter, NULL); return ret < 0 ? -ENOEXEC : OK; } return -ENODEV; } #endif /**************************************************************************** * Name: stm32_usbhost_vbusdrive * * Description: * Enable/disable driving of VBUS 5V output. This function must be * provided be each platform that implements the STM32 OTG FS host * interface * * "On-chip 5 V VBUS generation is not supported. For this reason, a * charge pump or, if 5 V are available on the application board, a * basic power switch, must be added externally to drive the 5 V VBUS * line. The external charge pump can be driven by any GPIO output. * When the application decides to power on VBUS using the chosen GPIO, * it must also set the port power bit in the host port control and status * register (PPWR bit in OTG_FS_HPRT). * * "The application uses this field to control power to this port, and * the core clears this bit on an overcurrent condition." * * Input Parameters: * iface - For future growth to handle multiple USB host interface. * Should be zero. * enable - true: enable VBUS power; false: disable VBUS power * * Returned Value: * None * ****************************************************************************/ #ifdef CONFIG_USBHOST void stm32_usbhost_vbusdrive(int iface, bool enable) { DEBUGASSERT(iface == 0); /* Set the Power Switch by driving the active high enable pin. * * NOTE: Setting PWRON in high state somehow breaks USBDEV on OTGHS. * If both OTG peripherals are used and OTGFS is used as HOST, * then the power switch enable pin must be set directly from * 3.3V bus. */ #ifdef CONFIG_OPENH743I_DISABLE_OTGFS_PWRON stm32_gpiowrite(GPIO_OTGFS_PWRON, enable); #endif } #endif /**************************************************************************** * Name: stm32_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 provided for the interrupt handler * * Returned Value: * Zero (OK) is returned on success. Otherwise, a negated errno value * is returned to indicate the nature of the failure. * ****************************************************************************/ #ifdef CONFIG_USBHOST int stm32_setup_overcurrent(xcpt_t handler, void *arg) { return stm32_gpiosetevent(GPIO_OTGFS_OVER, true, true, true, handler, arg); } #endif /**************************************************************************** * Name: stm32_usbsuspend * * Description: * Board logic must provide the stm32_usbsuspend logic if the USBDEV * driver is used. This function is called whenever the USB enters or * leaves suspend mode. This is an opportunity for the board logic to * shutdown clocks, power, etc. while the USB is suspended. * ****************************************************************************/ void stm32_usbsuspend(struct usbdev_s *dev, bool resume) { uinfo("resume: %d\n", resume); } #ifdef CONFIG_STM32H7_OTGHS_EXTERNAL_ULPI /**************************************************************************** * Name: stm32_usbulpireset * * Description: * Reset external ULPI. * ****************************************************************************/ void stm32_usbulpireset(struct usbdev_s *dev) { stm32_configgpio(GPIO_ULPI_RESET); up_mdelay(5); stm32_gpiowrite(GPIO_ULPI_RESET, true); up_mdelay(10); stm32_gpiowrite(GPIO_ULPI_RESET, false); up_mdelay(10); } #endif