From eb3791487672deb1cde168fd27565771ffb896cc Mon Sep 17 00:00:00 2001
From: Victor Mateus Oliveira <rhapsodyv@gmail.com>
Date: Sat, 3 Oct 2020 21:57:50 -0300
Subject: [PATCH 1/8] first working version of usb host + msc

---
 .../arduino/stm32/usb_host/msc/usb_host_msc.c |   5 +
 .../stm32/usb_host/msc/usb_host_msc_bot.c     |   5 +
 .../stm32/usb_host/msc/usb_host_msc_scsi.c    |   5 +
 cores/arduino/stm32/usb_host/usb_host_core.c  |   5 +
 .../arduino/stm32/usb_host/usb_host_ctlreq.c  |   5 +
 cores/arduino/stm32/usb_host/usb_host_ioreq.c |   5 +
 cores/arduino/stm32/usb_host/usb_host_pipes.c |   5 +
 cores/arduino/stm32/usb_host/usbh_conf.c      | 585 ++++++++++++++++++
 cores/arduino/stm32/usb_host/usbh_conf.h      | 218 +++++++
 tools/platformio-build.py                     |  39 ++
 10 files changed, 877 insertions(+)
 create mode 100644 cores/arduino/stm32/usb_host/msc/usb_host_msc.c
 create mode 100644 cores/arduino/stm32/usb_host/msc/usb_host_msc_bot.c
 create mode 100644 cores/arduino/stm32/usb_host/msc/usb_host_msc_scsi.c
 create mode 100644 cores/arduino/stm32/usb_host/usb_host_core.c
 create mode 100644 cores/arduino/stm32/usb_host/usb_host_ctlreq.c
 create mode 100644 cores/arduino/stm32/usb_host/usb_host_ioreq.c
 create mode 100644 cores/arduino/stm32/usb_host/usb_host_pipes.c
 create mode 100644 cores/arduino/stm32/usb_host/usbh_conf.c
 create mode 100644 cores/arduino/stm32/usb_host/usbh_conf.h

diff --git a/cores/arduino/stm32/usb_host/msc/usb_host_msc.c b/cores/arduino/stm32/usb_host/msc/usb_host_msc.c
new file mode 100644
index 0000000000..bb0ce9bb74
--- /dev/null
+++ b/cores/arduino/stm32/usb_host/msc/usb_host_msc.c
@@ -0,0 +1,5 @@
+#ifdef USBHOST
+
+#include "usbh_msc.c"
+
+#endif /* USBHOST */
diff --git a/cores/arduino/stm32/usb_host/msc/usb_host_msc_bot.c b/cores/arduino/stm32/usb_host/msc/usb_host_msc_bot.c
new file mode 100644
index 0000000000..8f0eccd59a
--- /dev/null
+++ b/cores/arduino/stm32/usb_host/msc/usb_host_msc_bot.c
@@ -0,0 +1,5 @@
+#ifdef USBHOST
+
+#include "usbh_msc_bot.c"
+
+#endif /* USBHOST */
diff --git a/cores/arduino/stm32/usb_host/msc/usb_host_msc_scsi.c b/cores/arduino/stm32/usb_host/msc/usb_host_msc_scsi.c
new file mode 100644
index 0000000000..ec810c1528
--- /dev/null
+++ b/cores/arduino/stm32/usb_host/msc/usb_host_msc_scsi.c
@@ -0,0 +1,5 @@
+#ifdef USBHOST
+
+#include "usbh_msc_scsi.c"
+
+#endif /* USBHOST */
diff --git a/cores/arduino/stm32/usb_host/usb_host_core.c b/cores/arduino/stm32/usb_host/usb_host_core.c
new file mode 100644
index 0000000000..279333e3a8
--- /dev/null
+++ b/cores/arduino/stm32/usb_host/usb_host_core.c
@@ -0,0 +1,5 @@
+#ifdef USBHOST
+
+#include "usbh_core.c"
+
+#endif /* USBHOST */
diff --git a/cores/arduino/stm32/usb_host/usb_host_ctlreq.c b/cores/arduino/stm32/usb_host/usb_host_ctlreq.c
new file mode 100644
index 0000000000..88af2efad5
--- /dev/null
+++ b/cores/arduino/stm32/usb_host/usb_host_ctlreq.c
@@ -0,0 +1,5 @@
+#ifdef USBHOST
+
+#include "usbh_ctlreq.c"
+
+#endif /* USBHOST */
diff --git a/cores/arduino/stm32/usb_host/usb_host_ioreq.c b/cores/arduino/stm32/usb_host/usb_host_ioreq.c
new file mode 100644
index 0000000000..f1b2c54042
--- /dev/null
+++ b/cores/arduino/stm32/usb_host/usb_host_ioreq.c
@@ -0,0 +1,5 @@
+#ifdef USBHOST
+
+#include "usbh_ioreq.c"
+
+#endif /* USBHOST */
diff --git a/cores/arduino/stm32/usb_host/usb_host_pipes.c b/cores/arduino/stm32/usb_host/usb_host_pipes.c
new file mode 100644
index 0000000000..45052806ff
--- /dev/null
+++ b/cores/arduino/stm32/usb_host/usb_host_pipes.c
@@ -0,0 +1,5 @@
+#ifdef USBHOST
+
+#include "usbh_pipes.c"
+
+#endif /* USBHOST */
diff --git a/cores/arduino/stm32/usb_host/usbh_conf.c b/cores/arduino/stm32/usb_host/usbh_conf.c
new file mode 100644
index 0000000000..f62b072272
--- /dev/null
+++ b/cores/arduino/stm32/usb_host/usbh_conf.c
@@ -0,0 +1,585 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file           : Target/usbh_conf.c
+  * @version        : v1.0_Cube
+  * @brief          : This file implements the board support package for the USB host library
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under Ultimate Liberty license
+  * SLA0044, the "License"; You may not use this file except in compliance with
+  * the License. You may obtain a copy of the License at:
+  *                             www.st.com/SLA0044
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_core.h"
+#include "Arduino.h"
+
+#include "stm32f4xx_hal_hcd.h"
+
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+
+/* USER CODE BEGIN PV */
+/* Private variables ---------------------------------------------------------*/
+
+/* USER CODE END PV */
+
+HCD_HandleTypeDef hhcd_USB_OTG_FS;
+
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/* USER CODE BEGIN PFP */
+/* Private function prototypes -----------------------------------------------*/
+USBH_StatusTypeDef USBH_Get_USB_Status(HAL_StatusTypeDef hal_status);
+
+/* USER CODE END PFP */
+
+/* Private functions ---------------------------------------------------------*/
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */
+
+/*******************************************************************************
+                       LL Driver Callbacks (HCD -> USB Host Library)
+*******************************************************************************/
+/* MSP Init */
+
+void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd)
+{
+  const PinMap *map = NULL;
+#if defined (USB_OTG_FS)
+  if(hhcd->Instance==USB_OTG_FS)
+  {
+  /* Configure USB FS GPIOs */
+    map = PinMap_USB_OTG_FS;
+    while (map->pin != NC) {
+      pin_function(map->pin, map->function);
+      map++;
+    }
+
+    /* Peripheral clock enable */
+    __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
+
+    /* Set USB FS Interrupt priority */
+    HAL_NVIC_SetPriority(OTG_FS_IRQn, USBH_IRQ_PRIO, USBH_IRQ_SUBPRIO);
+
+    /* Enable USB FS Interrupt */
+    HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
+
+    if (hhcd->Init.low_power_enable == 1) {
+      /* Enable EXTI Line 18 for USB wakeup */
+#ifdef __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG
+      __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG();
+#endif
+#ifdef __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE
+      __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE();
+#endif
+      __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT();
+#if !defined(STM32L4xx)
+      /* Set EXTI Wakeup Interrupt priority */
+      HAL_NVIC_SetPriority(OTG_FS_WKUP_IRQn, USBH_IRQ_PRIO, USBH_IRQ_SUBPRIO);
+
+      /* Enable EXTI Interrupt */
+      HAL_NVIC_EnableIRQ(OTG_FS_WKUP_IRQn);
+#endif
+    }
+  }
+#endif
+}
+
+void HAL_HCD_MspDeInit(HCD_HandleTypeDef* hhcd)
+{
+#if defined (USB_OTG_FS)
+  if (hhcd->Instance == USB_OTG_FS) {
+    /* Disable USB FS Clock */
+    __HAL_RCC_USB_OTG_FS_CLK_DISABLE();
+  }
+#endif
+#if defined (USB_OTG_HS)
+  if (hhcd->Instance == USB_OTG_HS) {
+    /* Disable USB HS Clocks */
+    __HAL_RCC_USB_OTG_HS_CLK_DISABLE();
+  }
+#endif /* USB_OTG_HS */
+}
+
+/**
+  * @brief  SOF callback.
+  * @param  hhcd: HCD handle
+  * @retval None
+  */
+void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
+{
+  USBH_LL_IncTimer(hhcd->pData);
+}
+
+/**
+  * @brief  SOF callback.
+  * @param  hhcd: HCD handle
+  * @retval None
+  */
+void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
+{
+  USBH_LL_Connect(hhcd->pData);
+}
+
+/**
+  * @brief  SOF callback.
+  * @param  hhcd: HCD handle
+  * @retval None
+  */
+void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
+{
+  USBH_LL_Disconnect(hhcd->pData);
+}
+
+/**
+  * @brief  Notify URB state change callback.
+  * @param  hhcd: HCD handle
+  * @param  chnum: channel number
+  * @param  urb_state: state
+  * @retval None
+  */
+void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
+{
+  /* To be used with OS to sync URB state with the global state machine */
+#if (USBH_USE_OS == 1)
+  USBH_LL_NotifyURBChange(hhcd->pData);
+#endif
+}
+/**
+* @brief  Port Port Enabled callback.
+  * @param  hhcd: HCD handle
+  * @retval None
+  */
+void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd)
+{
+  USBH_LL_PortEnabled(hhcd->pData);
+}
+
+/**
+  * @brief  Port Port Disabled callback.
+  * @param  hhcd: HCD handle
+  * @retval None
+  */
+void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd)
+{
+  USBH_LL_PortDisabled(hhcd->pData);
+}
+
+/*******************************************************************************
+                       LL Driver Interface (USB Host Library --> HCD)
+*******************************************************************************/
+
+/**
+  * @brief  Initialize the low level portion of the host driver.
+  * @param  phost: Host handle
+  * @retval USBH status
+  */
+USBH_StatusTypeDef USBH_LL_Init(USBH_HandleTypeDef *phost)
+{
+  /* Init USB_IP */
+  if (phost->id == HOST_FS) {
+  /* Link the driver to the stack. */
+  hhcd_USB_OTG_FS.pData = phost;
+  phost->pData = &hhcd_USB_OTG_FS;
+
+  hhcd_USB_OTG_FS.Instance = USB_OTG_FS;
+  hhcd_USB_OTG_FS.Init.Host_channels = 8;
+  hhcd_USB_OTG_FS.Init.speed = HCD_SPEED_FULL;
+  hhcd_USB_OTG_FS.Init.dma_enable = DISABLE;
+  hhcd_USB_OTG_FS.Init.phy_itface = HCD_PHY_EMBEDDED;
+  hhcd_USB_OTG_FS.Init.Sof_enable = DISABLE;
+  if (HAL_HCD_Init(&hhcd_USB_OTG_FS) != HAL_OK)
+  {
+    // Error_Handler( );
+    return USBH_FAIL;
+  }
+
+  USBH_LL_SetTimer(phost, HAL_HCD_GetCurrentFrame(&hhcd_USB_OTG_FS));
+  }
+  return USBH_OK;
+}
+
+/**
+  * @brief  De-Initialize the low level portion of the host driver.
+  * @param  phost: Host handle
+  * @retval USBH status
+  */
+USBH_StatusTypeDef USBH_LL_DeInit(USBH_HandleTypeDef *phost)
+{
+  HAL_StatusTypeDef hal_status = HAL_OK;
+  USBH_StatusTypeDef usb_status = USBH_OK;
+
+  hal_status = HAL_HCD_DeInit(phost->pData);
+
+  usb_status = USBH_Get_USB_Status(hal_status);
+
+  return usb_status;
+}
+
+/**
+  * @brief  Start the low level portion of the host driver.
+  * @param  phost: Host handle
+  * @retval USBH status
+  */
+USBH_StatusTypeDef USBH_LL_Start(USBH_HandleTypeDef *phost)
+{
+  HAL_StatusTypeDef hal_status = HAL_OK;
+  USBH_StatusTypeDef usb_status = USBH_OK;
+
+  hal_status = HAL_HCD_Start(phost->pData);
+
+  usb_status = USBH_Get_USB_Status(hal_status);
+
+  return usb_status;
+}
+
+/**
+  * @brief  Stop the low level portion of the host driver.
+  * @param  phost: Host handle
+  * @retval USBH status
+  */
+USBH_StatusTypeDef USBH_LL_Stop(USBH_HandleTypeDef *phost)
+{
+  HAL_StatusTypeDef hal_status = HAL_OK;
+  USBH_StatusTypeDef usb_status = USBH_OK;
+
+  hal_status = HAL_HCD_Stop(phost->pData);
+
+  usb_status = USBH_Get_USB_Status(hal_status);
+
+  return usb_status;
+}
+
+/**
+  * @brief  Return the USB host speed from the low level driver.
+  * @param  phost: Host handle
+  * @retval USBH speeds
+  */
+USBH_SpeedTypeDef USBH_LL_GetSpeed(USBH_HandleTypeDef *phost)
+{
+  USBH_SpeedTypeDef speed = USBH_SPEED_FULL;
+
+  switch (HAL_HCD_GetCurrentSpeed(phost->pData))
+  {
+  case 0 :
+    speed = USBH_SPEED_HIGH;
+    break;
+
+  case 1 :
+    speed = USBH_SPEED_FULL;
+    break;
+
+  case 2 :
+    speed = USBH_SPEED_LOW;
+    break;
+
+  default:
+   speed = USBH_SPEED_FULL;
+    break;
+  }
+  return  speed;
+}
+
+/**
+  * @brief  Reset the Host port of the low level driver.
+  * @param  phost: Host handle
+  * @retval USBH status
+  */
+USBH_StatusTypeDef USBH_LL_ResetPort(USBH_HandleTypeDef *phost)
+{
+  HAL_StatusTypeDef hal_status = HAL_OK;
+  USBH_StatusTypeDef usb_status = USBH_OK;
+
+  hal_status = HAL_HCD_ResetPort(phost->pData);
+
+  usb_status = USBH_Get_USB_Status(hal_status);
+
+  return usb_status;
+}
+
+/**
+  * @brief  Return the last transfered packet size.
+  * @param  phost: Host handle
+  * @param  pipe: Pipe index
+  * @retval Packet size
+  */
+uint32_t USBH_LL_GetLastXferSize(USBH_HandleTypeDef *phost, uint8_t pipe)
+{
+  return HAL_HCD_HC_GetXferCount(phost->pData, pipe);
+}
+
+/**
+  * @brief  Open a pipe of the low level driver.
+  * @param  phost: Host handle
+  * @param  pipe_num: Pipe index
+  * @param  epnum: Endpoint number
+  * @param  dev_address: Device USB address
+  * @param  speed: Device Speed
+  * @param  ep_type: Endpoint type
+  * @param  mps: Endpoint max packet size
+  * @retval USBH status
+  */
+USBH_StatusTypeDef USBH_LL_OpenPipe(USBH_HandleTypeDef *phost, uint8_t pipe_num, uint8_t epnum,
+                                    uint8_t dev_address, uint8_t speed, uint8_t ep_type, uint16_t mps)
+{
+  HAL_StatusTypeDef hal_status = HAL_OK;
+  USBH_StatusTypeDef usb_status = USBH_OK;
+
+  hal_status = HAL_HCD_HC_Init(phost->pData, pipe_num, epnum,
+                               dev_address, speed, ep_type, mps);
+
+  usb_status = USBH_Get_USB_Status(hal_status);
+
+  return usb_status;
+}
+
+/**
+  * @brief  Close a pipe of the low level driver.
+  * @param  phost: Host handle
+  * @param  pipe: Pipe index
+  * @retval USBH status
+  */
+USBH_StatusTypeDef USBH_LL_ClosePipe(USBH_HandleTypeDef *phost, uint8_t pipe)
+{
+  HAL_StatusTypeDef hal_status = HAL_OK;
+  USBH_StatusTypeDef usb_status = USBH_OK;
+
+  hal_status = HAL_HCD_HC_Halt(phost->pData, pipe);
+
+  usb_status = USBH_Get_USB_Status(hal_status);
+
+  return usb_status;
+}
+
+/**
+  * @brief  Submit a new URB to the low level driver.
+  * @param  phost: Host handle
+  * @param  pipe: Pipe index
+  *         This parameter can be a value from 1 to 15
+  * @param  direction : Channel number
+  *          This parameter can be one of the these values:
+  *           0 : Output
+  *           1 : Input
+  * @param  ep_type : Endpoint Type
+  *          This parameter can be one of the these values:
+  *            @arg EP_TYPE_CTRL: Control type
+  *            @arg EP_TYPE_ISOC: Isochrounous type
+  *            @arg EP_TYPE_BULK: Bulk type
+  *            @arg EP_TYPE_INTR: Interrupt type
+  * @param  token : Endpoint Type
+  *          This parameter can be one of the these values:
+  *            @arg 0: PID_SETUP
+  *            @arg 1: PID_DATA
+  * @param  pbuff : pointer to URB data
+  * @param  length : Length of URB data
+  * @param  do_ping : activate do ping protocol (for high speed only)
+  *          This parameter can be one of the these values:
+  *           0 : do ping inactive
+  *           1 : do ping active
+  * @retval Status
+  */
+USBH_StatusTypeDef USBH_LL_SubmitURB(USBH_HandleTypeDef *phost, uint8_t pipe, uint8_t direction,
+                                     uint8_t ep_type, uint8_t token, uint8_t *pbuff, uint16_t length,
+                                     uint8_t do_ping)
+{
+  HAL_StatusTypeDef hal_status = HAL_OK;
+  USBH_StatusTypeDef usb_status = USBH_OK;
+
+  hal_status = HAL_HCD_HC_SubmitRequest(phost->pData, pipe, direction ,
+                                        ep_type, token, pbuff, length,
+                                        do_ping);
+  usb_status =  USBH_Get_USB_Status(hal_status);
+
+  return usb_status;
+}
+
+/**
+  * @brief  Get a URB state from the low level driver.
+  * @param  phost: Host handle
+  * @param  pipe: Pipe index
+  *         This parameter can be a value from 1 to 15
+  * @retval URB state
+  *          This parameter can be one of the these values:
+  *            @arg URB_IDLE
+  *            @arg URB_DONE
+  *            @arg URB_NOTREADY
+  *            @arg URB_NYET
+  *            @arg URB_ERROR
+  *            @arg URB_STALL
+  */
+USBH_URBStateTypeDef USBH_LL_GetURBState(USBH_HandleTypeDef *phost, uint8_t pipe)
+{
+  return (USBH_URBStateTypeDef)HAL_HCD_HC_GetURBState (phost->pData, pipe);
+}
+
+/**
+  * @brief  Drive VBUS.
+  * @param  phost: Host handle
+  * @param  state : VBUS state
+  *          This parameter can be one of the these values:
+  *           0 : VBUS Inactive
+  *           1 : VBUS Active
+  * @retval Status
+  */
+USBH_StatusTypeDef USBH_LL_DriverVBUS(USBH_HandleTypeDef *phost, uint8_t state)
+{
+
+  /* USER CODE BEGIN 0 */
+
+  /* USER CODE END 0*/
+
+  if (phost->id == HOST_FS)
+  {
+    if (state == 0)
+    {
+      /* Drive high Charge pump */
+      /* ToDo: Add IOE driver control */
+      /* USER CODE BEGIN DRIVE_HIGH_CHARGE_FOR_FS */
+
+      /* USER CODE END DRIVE_HIGH_CHARGE_FOR_FS */
+    }
+    else
+    {
+      /* Drive low Charge pump */
+      /* ToDo: Add IOE driver control */
+      /* USER CODE BEGIN DRIVE_LOW_CHARGE_FOR_FS */
+
+      /* USER CODE END DRIVE_LOW_CHARGE_FOR_FS */
+    }
+  }
+  HAL_Delay(200);
+  return USBH_OK;
+}
+
+/**
+  * @brief  Set toggle for a pipe.
+  * @param  phost: Host handle
+  * @param  pipe: Pipe index
+  * @param  toggle: toggle (0/1)
+  * @retval Status
+  */
+USBH_StatusTypeDef USBH_LL_SetToggle(USBH_HandleTypeDef *phost, uint8_t pipe, uint8_t toggle)
+{
+  HCD_HandleTypeDef *pHandle;
+  pHandle = phost->pData;
+
+  if(pHandle->hc[pipe].ep_is_in)
+  {
+    pHandle->hc[pipe].toggle_in = toggle;
+  }
+  else
+  {
+    pHandle->hc[pipe].toggle_out = toggle;
+  }
+
+  return USBH_OK;
+}
+
+/**
+  * @brief  Return the current toggle of a pipe.
+  * @param  phost: Host handle
+  * @param  pipe: Pipe index
+  * @retval toggle (0/1)
+  */
+uint8_t USBH_LL_GetToggle(USBH_HandleTypeDef *phost, uint8_t pipe)
+{
+  uint8_t toggle = 0;
+  HCD_HandleTypeDef *pHandle;
+  pHandle = phost->pData;
+
+  if(pHandle->hc[pipe].ep_is_in)
+  {
+    toggle = pHandle->hc[pipe].toggle_in;
+  }
+  else
+  {
+    toggle = pHandle->hc[pipe].toggle_out;
+  }
+  return toggle;
+}
+
+/**
+  * @brief  Delay routine for the USB Host Library
+  * @param  Delay: Delay in ms
+  * @retval None
+  */
+void USBH_Delay(uint32_t Delay)
+{
+  HAL_Delay(Delay);
+}
+
+/**
+  * @brief  Retuns the USB status depending on the HAL status:
+  * @param  hal_status: HAL status
+  * @retval USB status
+  */
+USBH_StatusTypeDef USBH_Get_USB_Status(HAL_StatusTypeDef hal_status)
+{
+  USBH_StatusTypeDef usb_status = USBH_OK;
+
+  switch (hal_status)
+  {
+    case HAL_OK :
+      usb_status = USBH_OK;
+    break;
+    case HAL_ERROR :
+      usb_status = USBH_FAIL;
+    break;
+    case HAL_BUSY :
+      usb_status = USBH_BUSY;
+    break;
+    case HAL_TIMEOUT :
+      usb_status = USBH_FAIL;
+    break;
+    default :
+      usb_status = USBH_FAIL;
+    break;
+  }
+  return usb_status;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
+//#include "stm32f4xx_hal_hcd.c"
+
+#if !defined(USBCON)
+
+// extern HCD_HandleTypeDef hhcd_USB_OTG_FS;
+
+/**
+  * @brief  This function handles USB-On-The-Go FS/HS global interrupt request.
+  * @param  None
+  * @retval None
+  */
+#ifdef USE_USB_HS
+  void OTG_HS_IRQHandler(void)
+#elif defined(USB_OTG_FS)
+  void OTG_FS_IRQHandler(void)
+#else /* USB */
+  void USB_IRQHandler(void)
+#endif
+{
+  HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS);
+}
+
+#endif // !defined(USBCON)
diff --git a/cores/arduino/stm32/usb_host/usbh_conf.h b/cores/arduino/stm32/usb_host/usbh_conf.h
new file mode 100644
index 0000000000..ae92469d72
--- /dev/null
+++ b/cores/arduino/stm32/usb_host/usbh_conf.h
@@ -0,0 +1,218 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file           : Target/usbh_conf.h
+  * @version        : v1.0_Cube
+  * @brief          : Header for usbh_conf.c file.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under Ultimate Liberty license
+  * SLA0044, the "License"; You may not use this file except in compliance with
+  * the License. You may obtain a copy of the License at:
+  *                             www.st.com/SLA0044
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBH_CONF__H__
+#define __USBH_CONF__H__
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+// #define USBHOST
+
+#ifdef USBHOST
+/* Includes ------------------------------------------------------------------*/
+#include "stm32_def.h"
+
+/* Includes ------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+// #include "main.h"
+
+// #include "stm32f4xx.h"
+// #include "stm32f4xx_hal.h"
+
+/* USER CODE BEGIN INCLUDE */
+
+/* USER CODE END INCLUDE */
+
+/** @addtogroup STM32_USB_HOST_LIBRARY
+  * @{
+  */
+
+/** @defgroup USBH_CONF
+  * @brief usb host low level driver configuration file
+  * @{
+  */
+
+/** @defgroup USBH_CONF_Exported_Variables USBH_CONF_Exported_Variables
+  * @brief Public variables.
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBH_CONF_Exported_Defines USBH_CONF_Exported_Defines
+  * @brief Defines for configuration of the Usb host.
+  * @{
+  */
+
+/*----------   -----------*/
+#define USBH_MAX_NUM_ENDPOINTS      2U
+
+/*----------   -----------*/
+#define USBH_MAX_NUM_INTERFACES      2U
+
+/*----------   -----------*/
+#define USBH_MAX_NUM_CONFIGURATION      2U
+
+/*----------   -----------*/
+#define USBH_KEEP_CFG_DESCRIPTOR      2U
+
+/*----------   -----------*/
+#define USBH_MAX_NUM_SUPPORTED_CLASS      2U
+
+/*----------   -----------*/
+#define USBH_MAX_SIZE_CONFIGURATION      256U
+
+/*----------   -----------*/
+#define USBH_MAX_DATA_BUFFER      512U
+
+/*----------   -----------*/
+#define USBH_DEBUG_LEVEL      0U
+
+/*----------   -----------*/
+#define USBH_USE_OS      0U
+
+/****************************************/
+/* #define for FS and HS identification */
+#define HOST_HS 		0
+#define HOST_FS 		1
+
+/* Interrupt priority */
+#ifndef USBH_IRQ_PRIO
+#define USBH_IRQ_PRIO                       0
+#endif /* USBH_IRQ_PRIO */
+#ifndef USBH_IRQ_SUBPRIO
+#define USBH_IRQ_SUBPRIO                    0
+#endif /* USBH_IRQ_SUBPRIO */
+
+#if (USBH_USE_OS == 1)
+  #include "cmsis_os.h"
+  #define USBH_PROCESS_PRIO          osPriorityNormal
+  #define USBH_PROCESS_STACK_SIZE    ((uint16_t)0)
+#endif /* (USBH_USE_OS == 1) */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBH_CONF_Exported_Macros USBH_CONF_Exported_Macros
+  * @brief Aliases.
+  * @{
+  */
+
+/* Memory management macros */
+
+/** Alias for memory allocation. */
+#define USBH_malloc         malloc
+
+/** Alias for memory release. */
+#define USBH_free           free
+
+/** Alias for memory set. */
+#define USBH_memset         memset
+
+/** Alias for memory copy. */
+#define USBH_memcpy         memcpy
+
+/* DEBUG macros */
+
+extern void spi_debug(const char *msg, ...);
+
+#if (USBH_DEBUG_LEVEL > 0U)
+#define  USBH_UsrLog(...)   do { \
+                            printf(__VA_ARGS__); \
+                            printf("\n"); \
+} while (0)
+#else
+#define USBH_UsrLog(MSG, ...) spi_debug(MSG __VA_OPT__(,) __VA_ARGS__);
+//do {} while (0)
+#endif
+
+#if (USBH_DEBUG_LEVEL > 1U)
+
+#define  USBH_ErrLog(...) do { \
+                            printf("ERROR: ") ; \
+                            printf(__VA_ARGS__); \
+                            printf("\n"); \
+} while (0)
+#else
+#define USBH_ErrLog(MSG, ...) spi_debug(MSG __VA_OPT__(,) __VA_ARGS__);
+//do {} while (0)
+#endif
+
+#if (USBH_DEBUG_LEVEL > 2U)
+#define  USBH_DbgLog(...)   do { \
+                            printf("DEBUG : ") ; \
+                            printf(__VA_ARGS__); \
+                            printf("\n"); \
+} while (0)
+#else
+#define USBH_DbgLog(MSG, ...) spi_debug(MSG __VA_OPT__(,) __VA_ARGS__);
+//do {} while (0)
+#endif
+
+/**
+  * @}
+  */
+
+/** @defgroup USBH_CONF_Exported_Types USBH_CONF_Exported_Types
+  * @brief Types.
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBH_CONF_Exported_FunctionsPrototype USBH_CONF_Exported_FunctionsPrototype
+  * @brief Declaration of public functions for Usb host.
+  * @{
+  */
+
+/* Exported functions -------------------------------------------------------*/
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+ #endif /* USBHOST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBH_CONF__H__ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/tools/platformio-build.py b/tools/platformio-build.py
index c9102f2290..6bca65ced5 100644
--- a/tools/platformio-build.py
+++ b/tools/platformio-build.py
@@ -187,6 +187,7 @@ def configure_application_offset(mcu, upload_protocol):
         join(FRAMEWORK_DIR, "cores", "arduino", "stm32", "OpenAMP"),
         join(FRAMEWORK_DIR, "cores", "arduino", "stm32", "usb", "hid"),
         join(FRAMEWORK_DIR, "cores", "arduino", "stm32", "usb", "cdc"),
+        join(FRAMEWORK_DIR, "cores", "arduino", "stm32", "usb_host"),
         join(FRAMEWORK_DIR, "system", "Drivers", series + "_HAL_Driver", "Inc"),
         join(FRAMEWORK_DIR, "system", "Drivers", series + "_HAL_Driver", "Src"),
         join(FRAMEWORK_DIR, "system", series),
@@ -208,6 +209,44 @@ def configure_application_offset(mcu, upload_protocol):
             "Core",
             "Src",
         ),
+        join(
+            FRAMEWORK_DIR,
+            "system",
+            "Middlewares",
+            "ST",
+            "STM32_USB_Host_Library",
+            "Core",
+            "Inc",
+        ),
+        join(
+            FRAMEWORK_DIR,
+            "system",
+            "Middlewares",
+            "ST",
+            "STM32_USB_Host_Library",
+            "Core",
+            "Src",
+        ),
+        join(
+            FRAMEWORK_DIR,
+            "system",
+            "Middlewares",
+            "ST",
+            "STM32_USB_Host_Library",
+            "Class",
+            "MSC",
+            "Inc",
+        ),
+        join(
+            FRAMEWORK_DIR,
+            "system",
+            "Middlewares",
+            "ST",
+            "STM32_USB_Host_Library",
+            "Class",
+            "MSC",
+            "Src",
+        ),
         join(
             FRAMEWORK_DIR,
             "system",

From 2a59eb5ac7a21e438a1597b733cb8c81ac747f20 Mon Sep 17 00:00:00 2001
From: Victor Mateus Oliveira <rhapsodyv@gmail.com>
Date: Sat, 3 Oct 2020 22:21:49 -0300
Subject: [PATCH 2/8] astyle

---
 cores/arduino/stm32/usb_host/usbh_conf.c | 108 ++++++++++-------------
 cores/arduino/stm32/usb_host/usbh_conf.h |  14 +--
 2 files changed, 54 insertions(+), 68 deletions(-)

diff --git a/cores/arduino/stm32/usb_host/usbh_conf.c b/cores/arduino/stm32/usb_host/usbh_conf.c
index f62b072272..59092db816 100644
--- a/cores/arduino/stm32/usb_host/usbh_conf.c
+++ b/cores/arduino/stm32/usb_host/usbh_conf.c
@@ -61,13 +61,12 @@ USBH_StatusTypeDef USBH_Get_USB_Status(HAL_StatusTypeDef hal_status);
 *******************************************************************************/
 /* MSP Init */
 
-void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd)
+void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
 {
   const PinMap *map = NULL;
 #if defined (USB_OTG_FS)
-  if(hhcd->Instance==USB_OTG_FS)
-  {
-  /* Configure USB FS GPIOs */
+  if (hhcd->Instance == USB_OTG_FS) {
+    /* Configure USB FS GPIOs */
     map = PinMap_USB_OTG_FS;
     while (map->pin != NC) {
       pin_function(map->pin, map->function);
@@ -104,7 +103,7 @@ void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd)
 #endif
 }
 
-void HAL_HCD_MspDeInit(HCD_HandleTypeDef* hhcd)
+void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
 {
 #if defined (USB_OTG_FS)
   if (hhcd->Instance == USB_OTG_FS) {
@@ -197,23 +196,22 @@ USBH_StatusTypeDef USBH_LL_Init(USBH_HandleTypeDef *phost)
 {
   /* Init USB_IP */
   if (phost->id == HOST_FS) {
-  /* Link the driver to the stack. */
-  hhcd_USB_OTG_FS.pData = phost;
-  phost->pData = &hhcd_USB_OTG_FS;
-
-  hhcd_USB_OTG_FS.Instance = USB_OTG_FS;
-  hhcd_USB_OTG_FS.Init.Host_channels = 8;
-  hhcd_USB_OTG_FS.Init.speed = HCD_SPEED_FULL;
-  hhcd_USB_OTG_FS.Init.dma_enable = DISABLE;
-  hhcd_USB_OTG_FS.Init.phy_itface = HCD_PHY_EMBEDDED;
-  hhcd_USB_OTG_FS.Init.Sof_enable = DISABLE;
-  if (HAL_HCD_Init(&hhcd_USB_OTG_FS) != HAL_OK)
-  {
-    // Error_Handler( );
-    return USBH_FAIL;
-  }
+    /* Link the driver to the stack. */
+    hhcd_USB_OTG_FS.pData = phost;
+    phost->pData = &hhcd_USB_OTG_FS;
+
+    hhcd_USB_OTG_FS.Instance = USB_OTG_FS;
+    hhcd_USB_OTG_FS.Init.Host_channels = 8;
+    hhcd_USB_OTG_FS.Init.speed = HCD_SPEED_FULL;
+    hhcd_USB_OTG_FS.Init.dma_enable = DISABLE;
+    hhcd_USB_OTG_FS.Init.phy_itface = HCD_PHY_EMBEDDED;
+    hhcd_USB_OTG_FS.Init.Sof_enable = DISABLE;
+    if (HAL_HCD_Init(&hhcd_USB_OTG_FS) != HAL_OK) {
+      // Error_Handler( );
+      return USBH_FAIL;
+    }
 
-  USBH_LL_SetTimer(phost, HAL_HCD_GetCurrentFrame(&hhcd_USB_OTG_FS));
+    USBH_LL_SetTimer(phost, HAL_HCD_GetCurrentFrame(&hhcd_USB_OTG_FS));
   }
   return USBH_OK;
 }
@@ -278,23 +276,22 @@ USBH_SpeedTypeDef USBH_LL_GetSpeed(USBH_HandleTypeDef *phost)
 {
   USBH_SpeedTypeDef speed = USBH_SPEED_FULL;
 
-  switch (HAL_HCD_GetCurrentSpeed(phost->pData))
-  {
-  case 0 :
-    speed = USBH_SPEED_HIGH;
-    break;
+  switch (HAL_HCD_GetCurrentSpeed(phost->pData)) {
+    case 0 :
+      speed = USBH_SPEED_HIGH;
+      break;
 
-  case 1 :
-    speed = USBH_SPEED_FULL;
-    break;
+    case 1 :
+      speed = USBH_SPEED_FULL;
+      break;
 
-  case 2 :
-    speed = USBH_SPEED_LOW;
-    break;
+    case 2 :
+      speed = USBH_SPEED_LOW;
+      break;
 
-  default:
-   speed = USBH_SPEED_FULL;
-    break;
+    default:
+      speed = USBH_SPEED_FULL;
+      break;
   }
   return  speed;
 }
@@ -404,7 +401,7 @@ USBH_StatusTypeDef USBH_LL_SubmitURB(USBH_HandleTypeDef *phost, uint8_t pipe, ui
   HAL_StatusTypeDef hal_status = HAL_OK;
   USBH_StatusTypeDef usb_status = USBH_OK;
 
-  hal_status = HAL_HCD_HC_SubmitRequest(phost->pData, pipe, direction ,
+  hal_status = HAL_HCD_HC_SubmitRequest(phost->pData, pipe, direction,
                                         ep_type, token, pbuff, length,
                                         do_ping);
   usb_status =  USBH_Get_USB_Status(hal_status);
@@ -428,7 +425,7 @@ USBH_StatusTypeDef USBH_LL_SubmitURB(USBH_HandleTypeDef *phost, uint8_t pipe, ui
   */
 USBH_URBStateTypeDef USBH_LL_GetURBState(USBH_HandleTypeDef *phost, uint8_t pipe)
 {
-  return (USBH_URBStateTypeDef)HAL_HCD_HC_GetURBState (phost->pData, pipe);
+  return (USBH_URBStateTypeDef)HAL_HCD_HC_GetURBState(phost->pData, pipe);
 }
 
 /**
@@ -447,18 +444,14 @@ USBH_StatusTypeDef USBH_LL_DriverVBUS(USBH_HandleTypeDef *phost, uint8_t state)
 
   /* USER CODE END 0*/
 
-  if (phost->id == HOST_FS)
-  {
-    if (state == 0)
-    {
+  if (phost->id == HOST_FS) {
+    if (state == 0) {
       /* Drive high Charge pump */
       /* ToDo: Add IOE driver control */
       /* USER CODE BEGIN DRIVE_HIGH_CHARGE_FOR_FS */
 
       /* USER CODE END DRIVE_HIGH_CHARGE_FOR_FS */
-    }
-    else
-    {
+    } else {
       /* Drive low Charge pump */
       /* ToDo: Add IOE driver control */
       /* USER CODE BEGIN DRIVE_LOW_CHARGE_FOR_FS */
@@ -482,12 +475,9 @@ USBH_StatusTypeDef USBH_LL_SetToggle(USBH_HandleTypeDef *phost, uint8_t pipe, ui
   HCD_HandleTypeDef *pHandle;
   pHandle = phost->pData;
 
-  if(pHandle->hc[pipe].ep_is_in)
-  {
+  if (pHandle->hc[pipe].ep_is_in) {
     pHandle->hc[pipe].toggle_in = toggle;
-  }
-  else
-  {
+  } else {
     pHandle->hc[pipe].toggle_out = toggle;
   }
 
@@ -506,12 +496,9 @@ uint8_t USBH_LL_GetToggle(USBH_HandleTypeDef *phost, uint8_t pipe)
   HCD_HandleTypeDef *pHandle;
   pHandle = phost->pData;
 
-  if(pHandle->hc[pipe].ep_is_in)
-  {
+  if (pHandle->hc[pipe].ep_is_in) {
     toggle = pHandle->hc[pipe].toggle_in;
-  }
-  else
-  {
+  } else {
     toggle = pHandle->hc[pipe].toggle_out;
   }
   return toggle;
@@ -536,23 +523,22 @@ USBH_StatusTypeDef USBH_Get_USB_Status(HAL_StatusTypeDef hal_status)
 {
   USBH_StatusTypeDef usb_status = USBH_OK;
 
-  switch (hal_status)
-  {
+  switch (hal_status) {
     case HAL_OK :
       usb_status = USBH_OK;
-    break;
+      break;
     case HAL_ERROR :
       usb_status = USBH_FAIL;
-    break;
+      break;
     case HAL_BUSY :
       usb_status = USBH_BUSY;
-    break;
+      break;
     case HAL_TIMEOUT :
       usb_status = USBH_FAIL;
-    break;
+      break;
     default :
       usb_status = USBH_FAIL;
-    break;
+      break;
   }
   return usb_status;
 }
diff --git a/cores/arduino/stm32/usb_host/usbh_conf.h b/cores/arduino/stm32/usb_host/usbh_conf.h
index ae92469d72..07f3b53a29 100644
--- a/cores/arduino/stm32/usb_host/usbh_conf.h
+++ b/cores/arduino/stm32/usb_host/usbh_conf.h
@@ -23,7 +23,7 @@
 #ifndef __USBH_CONF__H__
 #define __USBH_CONF__H__
 #ifdef __cplusplus
- extern "C" {
+extern "C" {
 #endif
 
 // #define USBHOST
@@ -98,8 +98,8 @@
 
 /****************************************/
 /* #define for FS and HS identification */
-#define HOST_HS 		0
-#define HOST_FS 		1
+#define HOST_HS     0
+#define HOST_FS     1
 
 /* Interrupt priority */
 #ifndef USBH_IRQ_PRIO
@@ -110,9 +110,9 @@
 #endif /* USBH_IRQ_SUBPRIO */
 
 #if (USBH_USE_OS == 1)
-  #include "cmsis_os.h"
-  #define USBH_PROCESS_PRIO          osPriorityNormal
-  #define USBH_PROCESS_STACK_SIZE    ((uint16_t)0)
+#include "cmsis_os.h"
+#define USBH_PROCESS_PRIO          osPriorityNormal
+#define USBH_PROCESS_STACK_SIZE    ((uint16_t)0)
 #endif /* (USBH_USE_OS == 1) */
 
 /**
@@ -207,7 +207,7 @@ extern void spi_debug(const char *msg, ...);
   * @}
   */
 
- #endif /* USBHOST */
+#endif /* USBHOST */
 
 #ifdef __cplusplus
 }

From 95df0144e2f4b64cdfc9452424cadd4257e7b7eb Mon Sep 17 00:00:00 2001
From: Victor Mateus Oliveira <rhapsodyv@gmail.com>
Date: Sat, 3 Oct 2020 23:53:34 -0300
Subject: [PATCH 3/8] fix include

---
 cores/arduino/stm32/usb_host/usbh_conf.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/cores/arduino/stm32/usb_host/usbh_conf.c b/cores/arduino/stm32/usb_host/usbh_conf.c
index 59092db816..b67d2d588d 100644
--- a/cores/arduino/stm32/usb_host/usbh_conf.c
+++ b/cores/arduino/stm32/usb_host/usbh_conf.c
@@ -17,13 +17,16 @@
   *
   ******************************************************************************
   */
+#ifdef USBHOST
 /* USER CODE END Header */
 
 /* Includes ------------------------------------------------------------------*/
 #include "usbh_core.h"
 #include "Arduino.h"
 
-#include "stm32f4xx_hal_hcd.h"
+#ifndef HAL_HCD_MODULE_ENABLED
+  #error "HAL_HCD_MODULE_ENABLED is required"
+#endif
 
 /* USER CODE BEGIN Includes */
 
@@ -569,3 +572,5 @@ USBH_StatusTypeDef USBH_Get_USB_Status(HAL_StatusTypeDef hal_status)
 }
 
 #endif // !defined(USBCON)
+
+#endif /* USBHOST */

From a0c46a2962e632fa29a726c3e0ce5990da00cd46 Mon Sep 17 00:00:00 2001
From: Victor Mateus Oliveira <rhapsodyv@gmail.com>
Date: Sun, 4 Oct 2020 00:11:07 -0300
Subject: [PATCH 4/8] remove debug code

---
 cores/arduino/stm32/usb_host/usbh_conf.h | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/cores/arduino/stm32/usb_host/usbh_conf.h b/cores/arduino/stm32/usb_host/usbh_conf.h
index 07f3b53a29..af1c1c5a2a 100644
--- a/cores/arduino/stm32/usb_host/usbh_conf.h
+++ b/cores/arduino/stm32/usb_host/usbh_conf.h
@@ -140,16 +140,13 @@ extern "C" {
 
 /* DEBUG macros */
 
-extern void spi_debug(const char *msg, ...);
-
 #if (USBH_DEBUG_LEVEL > 0U)
 #define  USBH_UsrLog(...)   do { \
                             printf(__VA_ARGS__); \
                             printf("\n"); \
 } while (0)
 #else
-#define USBH_UsrLog(MSG, ...) spi_debug(MSG __VA_OPT__(,) __VA_ARGS__);
-//do {} while (0)
+#define USBH_UsrLog(MSG, ...) do {} while (0)
 #endif
 
 #if (USBH_DEBUG_LEVEL > 1U)
@@ -160,8 +157,7 @@ extern void spi_debug(const char *msg, ...);
                             printf("\n"); \
 } while (0)
 #else
-#define USBH_ErrLog(MSG, ...) spi_debug(MSG __VA_OPT__(,) __VA_ARGS__);
-//do {} while (0)
+#define USBH_ErrLog(MSG, ...) do {} while (0)
 #endif
 
 #if (USBH_DEBUG_LEVEL > 2U)
@@ -171,8 +167,7 @@ extern void spi_debug(const char *msg, ...);
                             printf("\n"); \
 } while (0)
 #else
-#define USBH_DbgLog(MSG, ...) spi_debug(MSG __VA_OPT__(,) __VA_ARGS__);
-//do {} while (0)
+#define USBH_DbgLog(MSG, ...) do {} while (0)
 #endif
 
 /**

From 9691c9fe954e4e3fb7fc0a2c8b7a00f4539e5d9b Mon Sep 17 00:00:00 2001
From: Victor Mateus Oliveira <rhapsodyv@gmail.com>
Date: Thu, 10 Dec 2020 01:41:53 -0300
Subject: [PATCH 5/8] support for OTG HS on HCD

---
 cores/arduino/stm32/usb_host/usbh_conf.c | 130 ++++++++++++++++++-----
 1 file changed, 106 insertions(+), 24 deletions(-)

diff --git a/cores/arduino/stm32/usb_host/usbh_conf.c b/cores/arduino/stm32/usb_host/usbh_conf.c
index b67d2d588d..f0b6287854 100644
--- a/cores/arduino/stm32/usb_host/usbh_conf.c
+++ b/cores/arduino/stm32/usb_host/usbh_conf.c
@@ -41,7 +41,7 @@
 
 /* USER CODE END PV */
 
-HCD_HandleTypeDef hhcd_USB_OTG_FS;
+HCD_HandleTypeDef g_hhcd;
 
 /* USER CODE BEGIN 0 */
 
@@ -104,6 +104,43 @@ void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
     }
   }
 #endif
+#if defined(USB_OTG_HS)
+  if (hhcd->Instance == USB_OTG_HS) {
+    __HAL_RCC_GPIOB_CLK_ENABLE();
+    map = PinMap_USB_OTG_HS;
+    while (map->pin != NC) {
+      pin_function(map->pin, map->function);
+      map++;
+    }
+
+    /* Peripheral clock enable */
+    __HAL_RCC_USB_OTG_HS_CLK_ENABLE();
+
+    /* Set USB HS Interrupt priority */
+    HAL_NVIC_SetPriority(OTG_HS_IRQn, USBH_IRQ_PRIO, USBH_IRQ_SUBPRIO);
+
+    /* Enable USB HS Interrupt */
+    HAL_NVIC_EnableIRQ(OTG_HS_IRQn);
+
+    if (hhcd->Init.low_power_enable == 1) {
+      /* Enable EXTI Line 18 for USB wakeup */
+#ifdef __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG
+      __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG();
+#endif
+#ifdef __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_EDGE
+      __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_EDGE();
+#endif
+      __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_IT();
+#if !defined(STM32L4xx)
+      /* Set EXTI Wakeup Interrupt priority */
+      HAL_NVIC_SetPriority(OTG_HS_WKUP_IRQn, USBH_IRQ_PRIO, USBH_IRQ_SUBPRIO);
+
+      /* Enable EXTI Interrupt */
+      HAL_NVIC_EnableIRQ(OTG_HS_WKUP_IRQn);
+#endif
+    }
+  }
+#endif
 }
 
 void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
@@ -200,21 +237,45 @@ USBH_StatusTypeDef USBH_LL_Init(USBH_HandleTypeDef *phost)
   /* Init USB_IP */
   if (phost->id == HOST_FS) {
     /* Link the driver to the stack. */
-    hhcd_USB_OTG_FS.pData = phost;
-    phost->pData = &hhcd_USB_OTG_FS;
-
-    hhcd_USB_OTG_FS.Instance = USB_OTG_FS;
-    hhcd_USB_OTG_FS.Init.Host_channels = 8;
-    hhcd_USB_OTG_FS.Init.speed = HCD_SPEED_FULL;
-    hhcd_USB_OTG_FS.Init.dma_enable = DISABLE;
-    hhcd_USB_OTG_FS.Init.phy_itface = HCD_PHY_EMBEDDED;
-    hhcd_USB_OTG_FS.Init.Sof_enable = DISABLE;
-    if (HAL_HCD_Init(&hhcd_USB_OTG_FS) != HAL_OK) {
+    g_hhcd.pData = phost;
+    phost->pData = &g_hhcd;
+
+    g_hhcd.Instance = USB_OTG_FS;
+    g_hhcd.Init.Host_channels = 8;
+    g_hhcd.Init.speed = HCD_SPEED_FULL;
+    g_hhcd.Init.dma_enable = DISABLE;
+    g_hhcd.Init.phy_itface = HCD_PHY_EMBEDDED;
+    g_hhcd.Init.Sof_enable = DISABLE;
+    if (HAL_HCD_Init(&g_hhcd) != HAL_OK) {
       // Error_Handler( );
       return USBH_FAIL;
     }
 
-    USBH_LL_SetTimer(phost, HAL_HCD_GetCurrentFrame(&hhcd_USB_OTG_FS));
+    USBH_LL_SetTimer(phost, HAL_HCD_GetCurrentFrame(&g_hhcd));
+  } else if (phost->id == HOST_HS) {
+    /* Link the driver to the stack. */
+    g_hhcd.pData = phost;
+    phost->pData = &g_hhcd;
+
+    g_hhcd.Instance = USB_OTG_HS;
+    g_hhcd.Init.Host_channels = 12;
+    g_hhcd.Init.speed = HCD_SPEED_FULL;
+    g_hhcd.Init.dma_enable = DISABLE;
+#ifdef USE_USB_HS_IN_FS
+    g_hhcd.Init.phy_itface = USB_OTG_EMBEDDED_PHY;
+#else
+    g_hhcd.Init.phy_itface = USB_OTG_ULPI_PHY;
+#endif
+    g_hhcd.Init.Sof_enable = DISABLE;
+    g_hhcd.Init.low_power_enable = DISABLE;
+    g_hhcd.Init.vbus_sensing_enable = DISABLE;
+    g_hhcd.Init.use_external_vbus = DISABLE;
+
+    if (HAL_HCD_Init(&g_hhcd) != HAL_OK) {
+      Error_Handler();
+    }
+
+    USBH_LL_SetTimer(phost, HAL_HCD_GetCurrentFrame(&g_hhcd));
   }
   return USBH_OK;
 }
@@ -245,11 +306,8 @@ USBH_StatusTypeDef USBH_LL_Start(USBH_HandleTypeDef *phost)
 {
   HAL_StatusTypeDef hal_status = HAL_OK;
   USBH_StatusTypeDef usb_status = USBH_OK;
-
   hal_status = HAL_HCD_Start(phost->pData);
-
   usb_status = USBH_Get_USB_Status(hal_status);
-
   return usb_status;
 }
 
@@ -549,18 +607,12 @@ USBH_StatusTypeDef USBH_Get_USB_Status(HAL_StatusTypeDef hal_status)
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
 
 
-//#include "stm32f4xx_hal_hcd.c"
-
-#if !defined(USBCON)
-
-// extern HCD_HandleTypeDef hhcd_USB_OTG_FS;
-
 /**
   * @brief  This function handles USB-On-The-Go FS/HS global interrupt request.
   * @param  None
   * @retval None
   */
-#ifdef USE_USB_HS
+#ifdef USE_USBHOST_HS
   void OTG_HS_IRQHandler(void)
 #elif defined(USB_OTG_FS)
   void OTG_FS_IRQHandler(void)
@@ -568,9 +620,39 @@ USBH_StatusTypeDef USBH_Get_USB_Status(HAL_StatusTypeDef hal_status)
   void USB_IRQHandler(void)
 #endif
 {
-  HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS);
+  HAL_HCD_IRQHandler(&g_hhcd);
 }
 
-#endif // !defined(USBCON)
+/**
+  * @brief  This function handles USB OTG HCD Wakeup IRQ Handler.
+  * @param  None
+  * @retval None
+  */
+#ifdef USE_USBHOST_HS
+  void OTG_HS_WKUP_IRQHandler(void)
+#elif defined(USB_OTG_FS)
+  void OTG_FS_WKUP_IRQHandler(void)
+#else
+  void USBWakeUp_IRQHandler(void)
+#endif
+{
+  if ((&g_hhcd)->Init.low_power_enable) {
+    /* Reset SLEEPDEEP bit of Cortex System Control Register */
+    SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
+
+    /* Configures system clock after wake-up from STOP: enable HSE, PLL and select
+    PLL as system clock source (HSE and PLL are disabled in STOP mode) */
+    SystemClock_Config();
+  }
+#if defined(USE_USBHOST_HS) && defined(__HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG)
+  /* Clear EXTI pending Bit*/
+  __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG();
+#elif defined(USB_OTG_FS) && defined(__HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG)
+  /* Clear EXTI pending Bit*/
+  __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG();
+#elif defined(__HAL_USB_WAKEUP_EXTI_CLEAR_FLAG)
+  __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG();
+#endif
+}
 
 #endif /* USBHOST */

From 6f5617873a88186c43ec7477aa5062997fc385ce Mon Sep 17 00:00:00 2001
From: Victor Mateus Oliveira <rhapsodyv@gmail.com>
Date: Sat, 26 Dec 2020 19:39:05 -0300
Subject: [PATCH 6/8] hid for usb host

---
 cores/arduino/stm32/usb_host/hid/usb_host_hid.c        | 5 +++++
 cores/arduino/stm32/usb_host/hid/usb_host_hid_keybd.c  | 5 +++++
 cores/arduino/stm32/usb_host/hid/usb_host_hid_mouse.c  | 5 +++++
 cores/arduino/stm32/usb_host/hid/usb_host_hid_parser.c | 5 +++++
 4 files changed, 20 insertions(+)
 create mode 100644 cores/arduino/stm32/usb_host/hid/usb_host_hid.c
 create mode 100644 cores/arduino/stm32/usb_host/hid/usb_host_hid_keybd.c
 create mode 100644 cores/arduino/stm32/usb_host/hid/usb_host_hid_mouse.c
 create mode 100644 cores/arduino/stm32/usb_host/hid/usb_host_hid_parser.c

diff --git a/cores/arduino/stm32/usb_host/hid/usb_host_hid.c b/cores/arduino/stm32/usb_host/hid/usb_host_hid.c
new file mode 100644
index 0000000000..b7f96c169b
--- /dev/null
+++ b/cores/arduino/stm32/usb_host/hid/usb_host_hid.c
@@ -0,0 +1,5 @@
+#ifdef USBHOST
+
+#include "usbh_hid.c"
+
+#endif /* USBHOST */
diff --git a/cores/arduino/stm32/usb_host/hid/usb_host_hid_keybd.c b/cores/arduino/stm32/usb_host/hid/usb_host_hid_keybd.c
new file mode 100644
index 0000000000..f849d98b4b
--- /dev/null
+++ b/cores/arduino/stm32/usb_host/hid/usb_host_hid_keybd.c
@@ -0,0 +1,5 @@
+#ifdef USBHOST
+
+#include "usbh_hid_keybd.c"
+
+#endif /* USBHOST */
diff --git a/cores/arduino/stm32/usb_host/hid/usb_host_hid_mouse.c b/cores/arduino/stm32/usb_host/hid/usb_host_hid_mouse.c
new file mode 100644
index 0000000000..aeced61c8e
--- /dev/null
+++ b/cores/arduino/stm32/usb_host/hid/usb_host_hid_mouse.c
@@ -0,0 +1,5 @@
+#ifdef USBHOST
+
+#include "usbh_hid_mouse.c"
+
+#endif /* USBHOST */
diff --git a/cores/arduino/stm32/usb_host/hid/usb_host_hid_parser.c b/cores/arduino/stm32/usb_host/hid/usb_host_hid_parser.c
new file mode 100644
index 0000000000..d6c261ec10
--- /dev/null
+++ b/cores/arduino/stm32/usb_host/hid/usb_host_hid_parser.c
@@ -0,0 +1,5 @@
+#ifdef USBHOST
+
+#include "usbh_hid_parser.c"
+
+#endif /* USBHOST */

From a9059d5ba2567da2c51bead7e3348cd00c7046bd Mon Sep 17 00:00:00 2001
From: Victor Mateus Oliveira <rhapsodyv@gmail.com>
Date: Sat, 26 Dec 2020 19:39:35 -0300
Subject: [PATCH 7/8] stop otg irqs

---
 cores/arduino/stm32/usb_host/usbh_conf.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/cores/arduino/stm32/usb_host/usbh_conf.c b/cores/arduino/stm32/usb_host/usbh_conf.c
index f0b6287854..0681ded4d1 100644
--- a/cores/arduino/stm32/usb_host/usbh_conf.c
+++ b/cores/arduino/stm32/usb_host/usbh_conf.c
@@ -149,12 +149,14 @@ void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
   if (hhcd->Instance == USB_OTG_FS) {
     /* Disable USB FS Clock */
     __HAL_RCC_USB_OTG_FS_CLK_DISABLE();
+    HAL_NVIC_DisableIRQ(OTG_FS_IRQn);
   }
 #endif
 #if defined (USB_OTG_HS)
   if (hhcd->Instance == USB_OTG_HS) {
     /* Disable USB HS Clocks */
     __HAL_RCC_USB_OTG_HS_CLK_DISABLE();
+    HAL_NVIC_DisableIRQ(OTG_HS_IRQn);
   }
 #endif /* USB_OTG_HS */
 }
@@ -289,11 +291,8 @@ USBH_StatusTypeDef USBH_LL_DeInit(USBH_HandleTypeDef *phost)
 {
   HAL_StatusTypeDef hal_status = HAL_OK;
   USBH_StatusTypeDef usb_status = USBH_OK;
-
   hal_status = HAL_HCD_DeInit(phost->pData);
-
   usb_status = USBH_Get_USB_Status(hal_status);
-
   return usb_status;
 }
 
@@ -320,11 +319,8 @@ USBH_StatusTypeDef USBH_LL_Stop(USBH_HandleTypeDef *phost)
 {
   HAL_StatusTypeDef hal_status = HAL_OK;
   USBH_StatusTypeDef usb_status = USBH_OK;
-
   hal_status = HAL_HCD_Stop(phost->pData);
-
   usb_status = USBH_Get_USB_Status(hal_status);
-
   return usb_status;
 }
 
@@ -366,11 +362,8 @@ USBH_StatusTypeDef USBH_LL_ResetPort(USBH_HandleTypeDef *phost)
 {
   HAL_StatusTypeDef hal_status = HAL_OK;
   USBH_StatusTypeDef usb_status = USBH_OK;
-
   hal_status = HAL_HCD_ResetPort(phost->pData);
-
   usb_status = USBH_Get_USB_Status(hal_status);
-
   return usb_status;
 }
 

From 4bfaf3d76940263d828ff639755bba3ea49bd31d Mon Sep 17 00:00:00 2001
From: Victor Mateus Oliveira <rhapsodyv@gmail.com>
Date: Mon, 28 Dec 2020 23:47:39 -0300
Subject: [PATCH 8/8] add HID to the build

---
 tools/platformio-build.py | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/tools/platformio-build.py b/tools/platformio-build.py
index 6bca65ced5..fecdac1fc2 100644
--- a/tools/platformio-build.py
+++ b/tools/platformio-build.py
@@ -247,6 +247,26 @@ def configure_application_offset(mcu, upload_protocol):
             "MSC",
             "Src",
         ),
+        join(
+            FRAMEWORK_DIR,
+            "system",
+            "Middlewares",
+            "ST",
+            "STM32_USB_Host_Library",
+            "Class",
+            "HID",
+            "Inc",
+        ),
+        join(
+            FRAMEWORK_DIR,
+            "system",
+            "Middlewares",
+            "ST",
+            "STM32_USB_Host_Library",
+            "Class",
+            "HID",
+            "Src",
+        ),
         join(
             FRAMEWORK_DIR,
             "system",