From eadcf7530b66262c62cb8a3867ff582587ddfbb0 Mon Sep 17 00:00:00 2001 From: sakumisu <1203593632@qq.com> Date: Thu, 15 May 2025 16:08:25 +0800 Subject: refacor(port/hpmicro): move hpmicro glue into hpmicro directory Signed-off-by: sakumisu <1203593632@qq.com> --- CMakeLists.txt | 16 ++ SConscript | 6 +- cherryusb.cmake | 6 +- port/ehci/README.md | 8 +- port/ehci/usb_glue_hpm.c | 108 ------------- port/hpm/usb_dc_hpm.c | 377 ------------------------------------------- port/hpmicro/README.md | 5 + port/hpmicro/usb_dc_hpm.c | 381 ++++++++++++++++++++++++++++++++++++++++++++ port/hpmicro/usb_glue_hpm.c | 25 +++ port/hpmicro/usb_hc_hpm.c | 107 +++++++++++++ 10 files changed, 546 insertions(+), 493 deletions(-) delete mode 100644 port/ehci/usb_glue_hpm.c delete mode 100644 port/hpm/usb_dc_hpm.c create mode 100644 port/hpmicro/README.md create mode 100644 port/hpmicro/usb_dc_hpm.c create mode 100644 port/hpmicro/usb_glue_hpm.c create mode 100644 port/hpmicro/usb_hc_hpm.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bad52e6..a181def9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 3.15) if(CONFIG_CHERRYUSB) if(BL_SDK_BASE) + message(STATUS "enable cherryusb in bouffalo_sdk") + set(CONFIG_CHERRYUSB_DEVICE_CDC_ACM 1) set(CONFIG_CHERRYUSB_DEVICE_HID 1) set(CONFIG_CHERRYUSB_DEVICE_MSC 1) @@ -30,16 +32,22 @@ if(BL_SDK_BASE) set(CONFIG_CHERRYUSB_OSAL "freertos") include(${CMAKE_CURRENT_LIST_DIR}/cherryusb.cmake) + list(REMOVE_DUPLICATES cherryusb_srcs) + list(REMOVE_DUPLICATES cherryusb_incs) sdk_generate_library(cherryusb) sdk_add_include_directories(${cherryusb_incs}) sdk_library_add_sources(${cherryusb_srcs}) elseif(ESP_PLATFORM) + message(STATUS "enable cherryusb in esp-idf") + set(CONFIG_CHERRYUSB_DEVICE_DWC2_ESP 1) set(CONFIG_CHERRYUSB_HOST_DWC2_ESP 1) set(CONFIG_CHERRYUSB_OSAL "idf") include(${CMAKE_CURRENT_LIST_DIR}/cherryusb.cmake) + list(REMOVE_DUPLICATES cherryusb_srcs) + list(REMOVE_DUPLICATES cherryusb_incs) set(ldfragments "osal/idf/linker.lf") @@ -130,8 +138,12 @@ elseif(ESP_PLATFORM) set_source_files_properties("class/audio/usbd_audio.c" PROPERTIES COMPILE_FLAGS -Wno-maybe-uninitialized) endif() elseif(ZEPHYR_BASE) + message(STATUS "enable cherryusb in zephyr") + set(CONFIG_CHERRYUSB_OSAL "zephyr") include(${CMAKE_CURRENT_LIST_DIR}/cherryusb.cmake) + list(REMOVE_DUPLICATES cherryusb_srcs) + list(REMOVE_DUPLICATES cherryusb_incs) if (CONFIG_SHELL) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/platform/zephyr/usb_cmd.c) @@ -149,6 +161,8 @@ elseif(ZEPHYR_BASE) zephyr_linker_sources(SECTIONS zephyr/usbh_class_info.ld) endif() elseif(HPM_SDK_BASE) + message(STATUS "enable cherryusb in hpm_sdk") + set(CONFIG_CHERRYUSB_DEVICE_CDC_ACM 1) set(CONFIG_CHERRYUSB_DEVICE_HID 1) set(CONFIG_CHERRYUSB_DEVICE_MSC 1) @@ -177,6 +191,8 @@ elseif(HPM_SDK_BASE) set(CONFIG_CHERRYUSB_OSAL "freertos") include(${CMAKE_CURRENT_LIST_DIR}/cherryusb.cmake) + list(REMOVE_DUPLICATES cherryusb_srcs) + list(REMOVE_DUPLICATES cherryusb_incs) sdk_inc(${cherryusb_incs}) sdk_src(${cherryusb_srcs}) diff --git a/SConscript b/SConscript index 93730091..ff70d0e5 100644 --- a/SConscript +++ b/SConscript @@ -85,7 +85,8 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']): if GetDepend(['PKG_CHERRYUSB_DEVICE_BL']): src += Glob('port/bouffalolab/usb_dc_bl.c') if GetDepend(['PKG_CHERRYUSB_DEVICE_HPM']): - src += Glob('port/hpm/usb_dc_hpm.c') + src += Glob('port/hpmicro/usb_dc_hpm.c') + src += Glob('port/hpmicro/usb_glue_hpm.c') if GetDepend(['PKG_CHERRYUSB_DEVICE_AIC']): src += Glob('port/aic/usb_dc_aic.c') src += Glob('port/aic/usb_dc_aic_ll.c') @@ -169,7 +170,8 @@ if GetDepend(['PKG_CHERRYUSB_HOST']): src += Glob('port/ehci/usb_glue_bouffalo.c') if GetDepend(['PKG_CHERRYUSB_HOST_EHCI_HPM']): src += Glob('port/ehci/usb_hc_ehci.c') - src += Glob('port/ehci/usb_glue_hpm.c') + src += Glob('port/hpmicro/usb_hc_hpm.c') + src += Glob('port/hpmicro/usb_glue_hpm.c') if GetDepend(['PKG_CHERRYUSB_HOST_EHCI_AIC']): path += [cwd + '/port/ehci'] path += [cwd + '/port/ohci'] diff --git a/cherryusb.cmake b/cherryusb.cmake index 443aed95..bc4e96b0 100644 --- a/cherryusb.cmake +++ b/cherryusb.cmake @@ -131,7 +131,8 @@ if(CONFIG_CHERRYUSB_DEVICE) elseif(CONFIG_CHERRYUSB_DEVICE_CHIPIDEA_CUSTOM) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/chipidea/usb_dc_chipidea.c) elseif(CONFIG_CHERRYUSB_DEVICE_HPM) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/hpm/usb_dc_hpm.c) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/hpmicro/usb_dc_hpm.c) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/hpmicro/usb_glue_hpm.c) elseif(CONFIG_CHERRYUSB_DEVICE_BL) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/bouffalolab/usb_dc_bl.c) elseif(CONFIG_CHERRYUSB_DEVICE_AIC) @@ -264,7 +265,8 @@ if(CONFIG_CHERRYUSB_HOST) elseif(CONFIG_CHERRYUSB_HOST_EHCI_HPM) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci.c) # list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci_iso.c) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_glue_hpm.c) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/hpmicro/usb_hc_hpm.c) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/hpmicro/usb_glue_hpm.c) list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/port/ehci) elseif(CONFIG_CHERRYUSB_HOST_EHCI_AIC) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci.c) diff --git a/port/ehci/README.md b/port/ehci/README.md index ede4cab8..753fc446 100644 --- a/port/ehci/README.md +++ b/port/ehci/README.md @@ -4,11 +4,11 @@ ### BouffaloLab -- BouffaloLab BL616/BL808 +- BouffaloLab BL616/BL808 (bouffalolab + EHCI) ### HPMicro -- HPM all series +- HPM all series (hpmicro + EHCI) ### AllwinnerTech @@ -30,8 +30,8 @@ Modify USB_NOCACHE_RAM_SECTION #define USB_NOCACHE_RAM_SECTION __attribute__((section(".NonCacheable"))) ``` -- IMRT10XX/IMRT11XX -- MCXN9XX/MCXN236 +- IMRT10XX/IMRT11XX (chipidea + EHCI) +- MCXN9XX/MCXN236 (chipidea + EHCI) ### Intel diff --git a/port/ehci/usb_glue_hpm.c b/port/ehci/usb_glue_hpm.c deleted file mode 100644 index 40105a94..00000000 --- a/port/ehci/usb_glue_hpm.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2022-2024 HPMicro - * - * SPDX-License-Identifier: BSD-3-Clause - * - */ -#include "usbh_core.h" -#include "hpm_common.h" -#include "hpm_soc.h" -#include "hpm_usb_drv.h" - -#if !defined(CONFIG_USB_EHCI_HPMICRO) || !CONFIG_USB_EHCI_HPMICRO -#error "hpm ehci must set CONFIG_USB_EHCI_HPMICRO=1" -#endif - -#if !defined(CONFIG_USB_EHCI_HCCR_OFFSET) || CONFIG_USB_EHCI_HCCR_OFFSET != 0x100 -#error "hpm ehci must config CONFIG_USB_EHCI_HCCR_OFFSET to 0x100" -#endif - -static uint32_t _hcd_irqnum[CONFIG_USBHOST_MAX_BUS]; -static uint8_t _hcd_busid[CONFIG_USBHOST_MAX_BUS]; - -static void usb_host_mode_init(USB_Type *ptr) -{ - /* Set mode to host, must be set immediately after reset */ - ptr->USBMODE &= ~USB_USBMODE_CM_MASK; - ptr->USBMODE |= USB_USBMODE_CM_SET(3); - - /* Set the endian */ - ptr->USBMODE &= ~USB_USBMODE_ES_MASK; - - /* Set parallel interface signal */ - ptr->PORTSC1 &= ~USB_PORTSC1_STS_MASK; - - /* Set parallel transceiver width */ - ptr->PORTSC1 &= ~USB_PORTSC1_PTW_MASK; - -#ifdef CONFIG_USB_HOST_FORCE_FULL_SPEED - /* Set usb forced to full speed mode */ - ptr->PORTSC1 |= USB_PORTSC1_PFSC_MASK; -#endif - - /* Not use interrupt threshold. */ - ptr->USBCMD &= ~USB_USBCMD_ITC_MASK; -} - -void usb_hc_low_level_init(struct usbh_bus *bus) -{ - if (bus->hcd.reg_base == HPM_USB0_BASE) { - _hcd_irqnum[bus->hcd.hcd_id] = IRQn_USB0; - _hcd_busid[0] = bus->hcd.hcd_id; - } else { -#ifdef HPM_USB1_BASE - if (bus->hcd.reg_base == HPM_USB1_BASE) { - _hcd_irqnum[bus->hcd.hcd_id] = IRQn_USB1; - _hcd_busid[1] = bus->hcd.hcd_id; - } -#endif - } - - usb_phy_init((USB_Type *)(bus->hcd.reg_base), true); - intc_m_enable_irq(_hcd_irqnum[bus->hcd.hcd_id]); -} - -void usb_hc_low_level2_init(struct usbh_bus *bus) -{ - usb_host_mode_init((USB_Type *)(bus->hcd.reg_base)); -} - -uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port) -{ - (void)port; - uint8_t speed; - - speed = usb_get_port_speed((USB_Type *)(bus->hcd.reg_base)); - - if (speed == 0x00) { - return USB_SPEED_FULL; - } - if (speed == 0x01) { - return USB_SPEED_LOW; - } - if (speed == 0x02) { - return USB_SPEED_HIGH; - } - - return 0; -} - -#if !defined(USBH_USE_CUSTOM_ISR) || !USBH_USE_CUSTOM_ISR - -extern void USBH_IRQHandler(uint8_t busid); - -SDK_DECLARE_EXT_ISR_M(IRQn_USB0, isr_usbh0) -void isr_usbh0(void) -{ - USBH_IRQHandler(_hcd_busid[0]); -} - -#ifdef HPM_USB1_BASE -SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usbh1) -void isr_usbh1(void) -{ - USBH_IRQHandler(_hcd_busid[1]); -} -#endif - -#endif diff --git a/port/hpm/usb_dc_hpm.c b/port/hpm/usb_dc_hpm.c deleted file mode 100644 index 011e193c..00000000 --- a/port/hpm/usb_dc_hpm.c +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (c) 2022-2025 HPMicro - * - * SPDX-License-Identifier: BSD-3-Clause - * - */ -#include "usbd_core.h" -#include "hpm_usb_device.h" - -#ifndef USB_NUM_BIDIR_ENDPOINTS -#define USB_NUM_BIDIR_ENDPOINTS CONFIG_USBDEV_EP_NUM -#endif - -/* USBSTS, USBINTR */ -enum { - intr_usb = USB_USBINTR_UE_MASK, - intr_error = USB_USBINTR_UEE_MASK, - intr_port_change = USB_USBINTR_PCE_MASK, - intr_reset = USB_USBINTR_URE_MASK, - intr_sof = USB_USBINTR_SRE_MASK, - intr_suspend = USB_USBINTR_SLE_MASK, - intr_nak = USB_USBINTR_NAKE_MASK, -}; - -/* Endpoint state */ -struct hpm_ep_state { - uint16_t ep_mps; /* Endpoint max packet size */ - uint8_t ep_type; /* Endpoint type */ - uint8_t ep_stalled; /* Endpoint stall flag */ - uint8_t ep_enable; /* Endpoint enable */ - uint8_t *xfer_buf; - uint32_t xfer_len; - uint32_t actual_xfer_len; -}; - -/*---------------------------------------------------------------------* - * Variable Definitions - *---------------------------------------------------------------------*/ -/* Driver state */ -struct hpm_udc { - usb_device_handle_t *handle; - bool is_suspend; - struct hpm_ep_state in_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< IN endpoint parameters*/ - struct hpm_ep_state out_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< OUT endpoint parameters */ -} g_hpm_udc[CONFIG_USBDEV_MAX_BUS]; - -static USB_NOCACHE_RAM_SECTION ATTR_ALIGN(USB_SOC_DCD_DATA_RAM_ADDRESS_ALIGNMENT) - uint8_t _dcd_data[CONFIG_USBDEV_MAX_BUS][HPM_ALIGN_UP(sizeof(dcd_data_t), USB_SOC_DCD_DATA_RAM_ADDRESS_ALIGNMENT)]; -static USB_NOCACHE_RAM_SECTION usb_device_handle_t usb_device_handle[CONFIG_USBDEV_MAX_BUS]; -static uint32_t _dcd_irqnum[CONFIG_USBDEV_MAX_BUS]; -static uint8_t _dcd_busid[CONFIG_USBDEV_MAX_BUS]; - -/* Index to bit position in register */ -static inline uint8_t ep_idx2bit(uint8_t ep_idx) -{ - return ep_idx / 2 + ((ep_idx % 2) ? 16 : 0); -} - -void usbd_execute_test_mode(uint8_t busid, uint8_t test_mode) -{ - usb_set_port_test_mode(g_hpm_udc[busid].handle->regs, test_mode); -} - -int usb_dc_init(uint8_t busid) -{ - memset(&g_hpm_udc[busid], 0, sizeof(struct hpm_udc)); - g_hpm_udc[busid].handle = &usb_device_handle[busid]; - g_hpm_udc[busid].handle->regs = (USB_Type *)g_usbdev_bus[busid].reg_base; - g_hpm_udc[busid].handle->dcd_data = (dcd_data_t *)&_dcd_data[busid][0]; - - if (g_usbdev_bus[busid].reg_base == HPM_USB0_BASE) { - _dcd_irqnum[busid] = IRQn_USB0; - _dcd_busid[0] = busid; - } else { -#ifdef HPM_USB1_BASE - if (g_usbdev_bus[busid].reg_base == HPM_USB1_BASE) { - _dcd_irqnum[busid] = IRQn_USB1; - _dcd_busid[1] = busid; - } -#endif - } - - uint32_t int_mask; - int_mask = (intr_usb | intr_error |intr_port_change | intr_reset | intr_suspend); - -#ifdef CONFIG_USBDEV_SOF_ENABLE - int_mask |= intr_sof; -#endif - - usb_device_init(g_hpm_udc[busid].handle, int_mask); - - intc_m_enable_irq(_dcd_irqnum[busid]); - return 0; -} - -int usb_dc_deinit(uint8_t busid) -{ - intc_m_disable_irq(_dcd_irqnum[busid]); - - usb_device_deinit(g_hpm_udc[busid].handle); - - return 0; -} - -int usbd_set_address(uint8_t busid, const uint8_t addr) -{ - usb_device_handle_t *handle = g_hpm_udc[busid].handle; - usb_dcd_set_address(handle->regs, addr); - return 0; -} - -int usbd_set_remote_wakeup(uint8_t busid) -{ - USB_Type *ptr; - - ptr = g_hpm_udc[busid].handle->regs; - - if (!usb_get_suspend_status(ptr)) { - return -1; - } - - usb_force_port_resume(ptr); - - return 0; -} - -uint8_t usbd_get_port_speed(uint8_t busid) -{ - uint8_t speed; - - speed = usb_get_port_speed(g_hpm_udc[busid].handle->regs); - - if (speed == 0x00) { - return USB_SPEED_FULL; - } - if (speed == 0x01) { - return USB_SPEED_LOW; - } - if (speed == 0x02) { - return USB_SPEED_HIGH; - } - - return 0; -} - -int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) -{ - usb_endpoint_config_t tmp_ep_cfg; - usb_device_handle_t *handle = g_hpm_udc[busid].handle; - uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress); - - tmp_ep_cfg.xfer = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); - tmp_ep_cfg.ep_addr = ep->bEndpointAddress; - tmp_ep_cfg.max_packet_size = ep->wMaxPacketSize; - - usb_device_edpt_open(handle, &tmp_ep_cfg); - - if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) { - g_hpm_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); - g_hpm_udc[busid].out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); - g_hpm_udc[busid].out_ep[ep_idx].ep_enable = true; - } else { - g_hpm_udc[busid].in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); - g_hpm_udc[busid].in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); - g_hpm_udc[busid].in_ep[ep_idx].ep_enable = true; - } - - return 0; -} - -int usbd_ep_close(uint8_t busid, const uint8_t ep) -{ - usb_device_handle_t *handle = g_hpm_udc[busid].handle; - uint8_t ep_idx = USB_EP_GET_IDX(ep); - - if (USB_EP_DIR_IS_OUT(ep)) { - g_hpm_udc[busid].out_ep[ep_idx].ep_enable = false; - } else { - g_hpm_udc[busid].in_ep[ep_idx].ep_enable = false; - } - - usb_device_edpt_close(handle, ep); - - return 0; -} - -int usbd_ep_set_stall(uint8_t busid, const uint8_t ep) -{ - usb_device_handle_t *handle = g_hpm_udc[busid].handle; - - usb_device_edpt_stall(handle, ep); - return 0; -} - -int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep) -{ - usb_device_handle_t *handle = g_hpm_udc[busid].handle; - - usb_device_edpt_clear_stall(handle, ep); - return 0; -} - -int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled) -{ - usb_device_handle_t *handle = g_hpm_udc[busid].handle; - - *stalled = usb_device_edpt_check_stall(handle, ep); - return 0; -} - -int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len) -{ - uint8_t ep_idx = USB_EP_GET_IDX(ep); - usb_device_handle_t *handle = g_hpm_udc[busid].handle; - - if (!data && data_len) { - return -1; - } - if (!g_hpm_udc[busid].in_ep[ep_idx].ep_enable) { - return -2; - } - - g_hpm_udc[busid].in_ep[ep_idx].xfer_buf = (uint8_t *)data; - g_hpm_udc[busid].in_ep[ep_idx].xfer_len = data_len; - g_hpm_udc[busid].in_ep[ep_idx].actual_xfer_len = 0; - - usb_device_edpt_xfer(handle, ep, (uint8_t *)data, data_len); - - return 0; -} - -int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len) -{ - uint8_t ep_idx = USB_EP_GET_IDX(ep); - usb_device_handle_t *handle = g_hpm_udc[busid].handle; - - if (!data && data_len) { - return -1; - } - if (!g_hpm_udc[busid].out_ep[ep_idx].ep_enable) { - return -2; - } - - g_hpm_udc[busid].out_ep[ep_idx].xfer_buf = (uint8_t *)data; - g_hpm_udc[busid].out_ep[ep_idx].xfer_len = data_len; - g_hpm_udc[busid].out_ep[ep_idx].actual_xfer_len = 0; - - usb_device_edpt_xfer(handle, ep, data, data_len); - - return 0; -} - -void USBD_IRQHandler(uint8_t busid) -{ - uint32_t int_status; - usb_device_handle_t *handle = g_hpm_udc[busid].handle; - uint32_t transfer_len; - bool ep_cb_req; - - /* Acknowledge handled interrupt */ - int_status = usb_device_status_flags(handle); - int_status &= usb_device_interrupts(handle); - usb_device_clear_status_flags(handle, int_status); - - if (int_status & intr_error) { - USB_LOG_ERR("usbd intr error!\r\n"); - } - -#ifdef CONFIG_USBDEV_SOF_ENABLE - if (int_status & intr_sof) { - usbd_event_sof_handler(busid); - } -#endif - - if (int_status & intr_reset) { - g_hpm_udc[busid].is_suspend = false; - memset(g_hpm_udc[busid].in_ep, 0, sizeof(struct hpm_ep_state) * USB_NUM_BIDIR_ENDPOINTS); - memset(g_hpm_udc[busid].out_ep, 0, sizeof(struct hpm_ep_state) * USB_NUM_BIDIR_ENDPOINTS); - usbd_event_reset_handler(busid); - usb_device_bus_reset(handle, 64); - } - - if (int_status & intr_suspend) { - if (usb_device_get_suspend_status(handle)) { - /* Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. */ - if (usb_device_get_address(handle)) { - g_hpm_udc[busid].is_suspend = true; - usbd_event_suspend_handler(busid); - } - } else { - } - } - - if (int_status & intr_port_change) { - if (!usb_device_get_port_ccs(handle)) { - usbd_event_disconnect_handler(busid); - } else { - if (g_hpm_udc[busid].is_suspend) { - g_hpm_udc[busid].is_suspend = false; - usbd_event_resume_handler(busid); - } - usbd_event_connect_handler(busid); - } - } - - if (int_status & intr_usb) { - uint32_t const edpt_complete = usb_device_get_edpt_complete_status(handle); - uint32_t const edpt_setup_status = usb_device_get_setup_status(handle); - - if (edpt_complete) { - usb_device_clear_edpt_complete_status(handle, edpt_complete); - for (uint8_t ep_idx = 0; ep_idx < USB_SOS_DCD_MAX_QHD_COUNT; ep_idx++) { - if (edpt_complete & (1 << ep_idx2bit(ep_idx))) { - transfer_len = 0; - ep_cb_req = true; - - /* Failed QTD also get ENDPTCOMPLETE set */ - dcd_qhd_t *p_qhd = usb_device_qhd_get(handle, ep_idx); - dcd_qtd_t *p_qtd = p_qhd->attached_qtd; - while (1) { - if (p_qtd->halted || p_qtd->xact_err || p_qtd->buffer_err) { - USB_LOG_ERR("usbd transfer error!\r\n"); - ep_cb_req = false; - break; - } else if (p_qtd->active) { - ep_cb_req = false; - break; - } else { - transfer_len += p_qtd->expected_bytes - p_qtd->total_bytes; - p_qtd->in_use = false; - } - - if (p_qtd->next == USB_SOC_DCD_QTD_NEXT_INVALID) { - break; - } else { - p_qtd = (dcd_qtd_t *)p_qtd->next; - } - } - - if (ep_cb_req) { - uint8_t const ep_addr = (ep_idx / 2) | ((ep_idx & 0x01) ? 0x80 : 0); - if (ep_addr & 0x80) { - usbd_event_ep_in_complete_handler(busid, ep_addr, transfer_len); - } else { - usbd_event_ep_out_complete_handler(busid, ep_addr, transfer_len); - } - } - } - } - } - - if (edpt_setup_status) { - /*------------- Set up Received -------------*/ - usb_device_clear_setup_status(handle, edpt_setup_status); - dcd_qhd_t *qhd0 = usb_device_qhd_get(handle, 0); - usbd_event_ep0_setup_complete_handler(busid, (uint8_t *)&qhd0->setup_request); - } - } -} - -#if !defined(USBD_USE_CUSTOM_ISR) || !USBD_USE_CUSTOM_ISR - -SDK_DECLARE_EXT_ISR_M(IRQn_USB0, isr_usbd0) -void isr_usbd0(void) -{ - USBD_IRQHandler(_dcd_busid[0]); -} - -#ifdef HPM_USB1_BASE -SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usbd1) -void isr_usbd1(void) -{ - USBD_IRQHandler(_dcd_busid[1]); -} -#endif - -#endif diff --git a/port/hpmicro/README.md b/port/hpmicro/README.md new file mode 100644 index 00000000..ec159f2a --- /dev/null +++ b/port/hpmicro/README.md @@ -0,0 +1,5 @@ +# Note + +## Support Chip List + +- HPM all series (hpmicro + EHCI) diff --git a/port/hpmicro/usb_dc_hpm.c b/port/hpmicro/usb_dc_hpm.c new file mode 100644 index 00000000..0c6c143d --- /dev/null +++ b/port/hpmicro/usb_dc_hpm.c @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2022-2025 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ +#include "usbd_core.h" +#include "hpm_usb_device.h" + +#ifndef USB_NUM_BIDIR_ENDPOINTS +#define USB_NUM_BIDIR_ENDPOINTS CONFIG_USBDEV_EP_NUM +#endif + +/* USBSTS, USBINTR */ +enum { + intr_usb = USB_USBINTR_UE_MASK, + intr_error = USB_USBINTR_UEE_MASK, + intr_port_change = USB_USBINTR_PCE_MASK, + intr_reset = USB_USBINTR_URE_MASK, + intr_sof = USB_USBINTR_SRE_MASK, + intr_suspend = USB_USBINTR_SLE_MASK, + intr_nak = USB_USBINTR_NAKE_MASK, +}; + +/* Endpoint state */ +struct hpm_ep_state { + uint16_t ep_mps; /* Endpoint max packet size */ + uint8_t ep_type; /* Endpoint type */ + uint8_t ep_stalled; /* Endpoint stall flag */ + uint8_t ep_enable; /* Endpoint enable */ + uint8_t *xfer_buf; + uint32_t xfer_len; + uint32_t actual_xfer_len; +}; + +/*---------------------------------------------------------------------* + * Variable Definitions + *---------------------------------------------------------------------*/ +/* Driver state */ +struct hpm_udc { + usb_device_handle_t *handle; + bool is_suspend; + struct hpm_ep_state in_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< IN endpoint parameters*/ + struct hpm_ep_state out_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< OUT endpoint parameters */ +} g_hpm_udc[CONFIG_USBDEV_MAX_BUS]; + +static USB_NOCACHE_RAM_SECTION ATTR_ALIGN(USB_SOC_DCD_DATA_RAM_ADDRESS_ALIGNMENT) + uint8_t _dcd_data[CONFIG_USBDEV_MAX_BUS][HPM_ALIGN_UP(sizeof(dcd_data_t), USB_SOC_DCD_DATA_RAM_ADDRESS_ALIGNMENT)]; +static USB_NOCACHE_RAM_SECTION usb_device_handle_t usb_device_handle[CONFIG_USBDEV_MAX_BUS]; + +extern void (*g_usb_hpm_irq[2])(uint8_t busid); +extern uint8_t g_usb_hpm_busid[2]; + +/* Index to bit position in register */ +static inline uint8_t ep_idx2bit(uint8_t ep_idx) +{ + return ep_idx / 2 + ((ep_idx % 2) ? 16 : 0); +} + +void usbd_execute_test_mode(uint8_t busid, uint8_t test_mode) +{ + usb_set_port_test_mode(g_hpm_udc[busid].handle->regs, test_mode); +} + +void usb_dc_low_level_init(uint8_t busid) +{ + if (g_usbdev_bus[busid].reg_base == HPM_USB0_BASE) { + g_usb_hpm_busid[0] = busid; + g_usb_hpm_irq[0] = USBD_IRQHandler; + + intc_m_enable_irq(IRQn_USB0); + } else { +#ifdef HPM_USB1_BASE + g_usb_hpm_busid[1] = busid; + g_usb_hpm_irq[1] = USBD_IRQHandler; + + intc_m_enable_irq(IRQn_USB1); +#endif + } +} + +void usb_dc_low_level_deinit(uint8_t busid) +{ + if (g_usbdev_bus[busid].reg_base == HPM_USB0_BASE) { + intc_m_disable_irq(IRQn_USB0); + + g_usb_hpm_busid[0] = 0; + g_usb_hpm_irq[0] = NULL; + } else { +#ifdef HPM_USB1_BASE + intc_m_disable_irq(IRQn_USB1); + + g_usb_hpm_busid[1] = 0; + g_usb_hpm_irq[1] = NULL; +#endif + } +} + +int usb_dc_init(uint8_t busid) +{ + usb_dc_low_level_init(busid); + + memset(&g_hpm_udc[busid], 0, sizeof(struct hpm_udc)); + g_hpm_udc[busid].handle = &usb_device_handle[busid]; + g_hpm_udc[busid].handle->regs = (USB_Type *)g_usbdev_bus[busid].reg_base; + g_hpm_udc[busid].handle->dcd_data = (dcd_data_t *)&_dcd_data[busid][0]; + + uint32_t int_mask; + int_mask = (intr_usb | intr_error |intr_port_change | intr_reset | intr_suspend); + +#ifdef CONFIG_USBDEV_SOF_ENABLE + int_mask |= intr_sof; +#endif + + usb_device_init(g_hpm_udc[busid].handle, int_mask); + return 0; +} + +int usb_dc_deinit(uint8_t busid) +{ + usb_device_deinit(g_hpm_udc[busid].handle); + usb_dc_low_level_deinit(busid); + + return 0; +} + +int usbd_set_address(uint8_t busid, const uint8_t addr) +{ + usb_device_handle_t *handle = g_hpm_udc[busid].handle; + usb_dcd_set_address(handle->regs, addr); + return 0; +} + +int usbd_set_remote_wakeup(uint8_t busid) +{ + USB_Type *ptr; + + ptr = g_hpm_udc[busid].handle->regs; + + if (!usb_get_suspend_status(ptr)) { + return -1; + } + + usb_force_port_resume(ptr); + + return 0; +} + +uint8_t usbd_get_port_speed(uint8_t busid) +{ + uint8_t speed; + + speed = usb_get_port_speed(g_hpm_udc[busid].handle->regs); + + if (speed == 0x00) { + return USB_SPEED_FULL; + } + if (speed == 0x01) { + return USB_SPEED_LOW; + } + if (speed == 0x02) { + return USB_SPEED_HIGH; + } + + return 0; +} + +int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) +{ + usb_endpoint_config_t tmp_ep_cfg; + usb_device_handle_t *handle = g_hpm_udc[busid].handle; + uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress); + + tmp_ep_cfg.xfer = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); + tmp_ep_cfg.ep_addr = ep->bEndpointAddress; + tmp_ep_cfg.max_packet_size = ep->wMaxPacketSize; + + usb_device_edpt_open(handle, &tmp_ep_cfg); + + if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) { + g_hpm_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); + g_hpm_udc[busid].out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); + g_hpm_udc[busid].out_ep[ep_idx].ep_enable = true; + } else { + g_hpm_udc[busid].in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); + g_hpm_udc[busid].in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); + g_hpm_udc[busid].in_ep[ep_idx].ep_enable = true; + } + + return 0; +} + +int usbd_ep_close(uint8_t busid, const uint8_t ep) +{ + usb_device_handle_t *handle = g_hpm_udc[busid].handle; + uint8_t ep_idx = USB_EP_GET_IDX(ep); + + if (USB_EP_DIR_IS_OUT(ep)) { + g_hpm_udc[busid].out_ep[ep_idx].ep_enable = false; + } else { + g_hpm_udc[busid].in_ep[ep_idx].ep_enable = false; + } + + usb_device_edpt_close(handle, ep); + + return 0; +} + +int usbd_ep_set_stall(uint8_t busid, const uint8_t ep) +{ + usb_device_handle_t *handle = g_hpm_udc[busid].handle; + + usb_device_edpt_stall(handle, ep); + return 0; +} + +int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep) +{ + usb_device_handle_t *handle = g_hpm_udc[busid].handle; + + usb_device_edpt_clear_stall(handle, ep); + return 0; +} + +int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled) +{ + usb_device_handle_t *handle = g_hpm_udc[busid].handle; + + *stalled = usb_device_edpt_check_stall(handle, ep); + return 0; +} + +int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len) +{ + uint8_t ep_idx = USB_EP_GET_IDX(ep); + usb_device_handle_t *handle = g_hpm_udc[busid].handle; + + if (!data && data_len) { + return -1; + } + if (!g_hpm_udc[busid].in_ep[ep_idx].ep_enable) { + return -2; + } + + g_hpm_udc[busid].in_ep[ep_idx].xfer_buf = (uint8_t *)data; + g_hpm_udc[busid].in_ep[ep_idx].xfer_len = data_len; + g_hpm_udc[busid].in_ep[ep_idx].actual_xfer_len = 0; + + usb_device_edpt_xfer(handle, ep, (uint8_t *)data, data_len); + + return 0; +} + +int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len) +{ + uint8_t ep_idx = USB_EP_GET_IDX(ep); + usb_device_handle_t *handle = g_hpm_udc[busid].handle; + + if (!data && data_len) { + return -1; + } + if (!g_hpm_udc[busid].out_ep[ep_idx].ep_enable) { + return -2; + } + + g_hpm_udc[busid].out_ep[ep_idx].xfer_buf = (uint8_t *)data; + g_hpm_udc[busid].out_ep[ep_idx].xfer_len = data_len; + g_hpm_udc[busid].out_ep[ep_idx].actual_xfer_len = 0; + + usb_device_edpt_xfer(handle, ep, data, data_len); + + return 0; +} + +void USBD_IRQHandler(uint8_t busid) +{ + uint32_t int_status; + usb_device_handle_t *handle = g_hpm_udc[busid].handle; + uint32_t transfer_len; + bool ep_cb_req; + + /* Acknowledge handled interrupt */ + int_status = usb_device_status_flags(handle); + int_status &= usb_device_interrupts(handle); + usb_device_clear_status_flags(handle, int_status); + + if (int_status & intr_error) { + USB_LOG_ERR("usbd intr error!\r\n"); + } + +#ifdef CONFIG_USBDEV_SOF_ENABLE + if (int_status & intr_sof) { + usbd_event_sof_handler(busid); + } +#endif + + if (int_status & intr_reset) { + g_hpm_udc[busid].is_suspend = false; + memset(g_hpm_udc[busid].in_ep, 0, sizeof(struct hpm_ep_state) * USB_NUM_BIDIR_ENDPOINTS); + memset(g_hpm_udc[busid].out_ep, 0, sizeof(struct hpm_ep_state) * USB_NUM_BIDIR_ENDPOINTS); + usbd_event_reset_handler(busid); + usb_device_bus_reset(handle, 64); + } + + if (int_status & intr_suspend) { + if (usb_device_get_suspend_status(handle)) { + /* Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. */ + if (usb_device_get_address(handle)) { + g_hpm_udc[busid].is_suspend = true; + usbd_event_suspend_handler(busid); + } + } else { + } + } + + if (int_status & intr_port_change) { + if (!usb_device_get_port_ccs(handle)) { + usbd_event_disconnect_handler(busid); + } else { + if (g_hpm_udc[busid].is_suspend) { + g_hpm_udc[busid].is_suspend = false; + usbd_event_resume_handler(busid); + } + usbd_event_connect_handler(busid); + } + } + + if (int_status & intr_usb) { + uint32_t const edpt_complete = usb_device_get_edpt_complete_status(handle); + uint32_t const edpt_setup_status = usb_device_get_setup_status(handle); + + if (edpt_complete) { + usb_device_clear_edpt_complete_status(handle, edpt_complete); + for (uint8_t ep_idx = 0; ep_idx < USB_SOS_DCD_MAX_QHD_COUNT; ep_idx++) { + if (edpt_complete & (1 << ep_idx2bit(ep_idx))) { + transfer_len = 0; + ep_cb_req = true; + + /* Failed QTD also get ENDPTCOMPLETE set */ + dcd_qhd_t *p_qhd = usb_device_qhd_get(handle, ep_idx); + dcd_qtd_t *p_qtd = p_qhd->attached_qtd; + while (1) { + if (p_qtd->halted || p_qtd->xact_err || p_qtd->buffer_err) { + USB_LOG_ERR("usbd transfer error!\r\n"); + ep_cb_req = false; + break; + } else if (p_qtd->active) { + ep_cb_req = false; + break; + } else { + transfer_len += p_qtd->expected_bytes - p_qtd->total_bytes; + p_qtd->in_use = false; + } + + if (p_qtd->next == USB_SOC_DCD_QTD_NEXT_INVALID) { + break; + } else { + p_qtd = (dcd_qtd_t *)p_qtd->next; + } + } + + if (ep_cb_req) { + uint8_t const ep_addr = (ep_idx / 2) | ((ep_idx & 0x01) ? 0x80 : 0); + if (ep_addr & 0x80) { + usbd_event_ep_in_complete_handler(busid, ep_addr, transfer_len); + } else { + usbd_event_ep_out_complete_handler(busid, ep_addr, transfer_len); + } + } + } + } + } + + if (edpt_setup_status) { + /*------------- Set up Received -------------*/ + usb_device_clear_setup_status(handle, edpt_setup_status); + dcd_qhd_t *qhd0 = usb_device_qhd_get(handle, 0); + usbd_event_ep0_setup_complete_handler(busid, (uint8_t *)&qhd0->setup_request); + } + } +} \ No newline at end of file diff --git a/port/hpmicro/usb_glue_hpm.c b/port/hpmicro/usb_glue_hpm.c new file mode 100644 index 00000000..5605eb13 --- /dev/null +++ b/port/hpmicro/usb_glue_hpm.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022-2025 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ +#include "hpm_common.h" +#include "hpm_soc.h" + +void (*g_usb_hpm_irq[2])(uint8_t busid); +uint8_t g_usb_hpm_busid[2] = { 0, 0 }; + +SDK_DECLARE_EXT_ISR_M(IRQn_USB0, isr_usbh0) +void isr_usbh0(void) +{ + g_usb_hpm_irq[0](g_usb_hpm_busid[0]); +} + +#ifdef HPM_USB1_BASE +SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usbh1) +void isr_usbh1(void) +{ + g_usb_hpm_irq[1](g_usb_hpm_busid[1]); +} +#endif \ No newline at end of file diff --git a/port/hpmicro/usb_hc_hpm.c b/port/hpmicro/usb_hc_hpm.c new file mode 100644 index 00000000..94515fb7 --- /dev/null +++ b/port/hpmicro/usb_hc_hpm.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2022-2025 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ +#include "usbh_core.h" +#include "hpm_common.h" +#include "hpm_soc.h" +#include "hpm_usb_drv.h" + +#if !defined(CONFIG_USB_EHCI_HPMICRO) || !CONFIG_USB_EHCI_HPMICRO +#error "hpm ehci must set CONFIG_USB_EHCI_HPMICRO=1" +#endif + +#if !defined(CONFIG_USB_EHCI_HCCR_OFFSET) || CONFIG_USB_EHCI_HCCR_OFFSET != 0x100 +#error "hpm ehci must config CONFIG_USB_EHCI_HCCR_OFFSET to 0x100" +#endif + +extern void (*g_usb_hpm_irq[2])(uint8_t busid); +extern uint8_t g_usb_hpm_busid[2]; + +static void usb_host_mode_init(USB_Type *ptr) +{ + /* Set mode to host, must be set immediately after reset */ + ptr->USBMODE &= ~USB_USBMODE_CM_MASK; + ptr->USBMODE |= USB_USBMODE_CM_SET(3); + + /* Set the endian */ + ptr->USBMODE &= ~USB_USBMODE_ES_MASK; + + /* Set parallel interface signal */ + ptr->PORTSC1 &= ~USB_PORTSC1_STS_MASK; + + /* Set parallel transceiver width */ + ptr->PORTSC1 &= ~USB_PORTSC1_PTW_MASK; + +#ifdef CONFIG_USB_HOST_FORCE_FULL_SPEED + /* Set usb forced to full speed mode */ + ptr->PORTSC1 |= USB_PORTSC1_PFSC_MASK; +#endif + + /* Not use interrupt threshold. */ + ptr->USBCMD &= ~USB_USBCMD_ITC_MASK; +} + +void usb_hc_low_level_init(struct usbh_bus *bus) +{ + if (bus->hcd.reg_base == HPM_USB0_BASE) { + g_usb_hpm_busid[0] = bus->hcd.hcd_id; + g_usb_hpm_irq[0] = USBH_IRQHandler; + + intc_m_enable_irq(IRQn_USB0); + } else { +#ifdef HPM_USB1_BASE + g_usb_hpm_busid[1] = bus->hcd.hcd_id; + g_usb_hpm_irq[1] = USBH_IRQHandler; + + intc_m_enable_irq(IRQn_USB1); +#endif + } + usb_phy_init((USB_Type *)(bus->hcd.reg_base), true); +} + +void usb_hc_low_level2_init(struct usbh_bus *bus) +{ + usb_host_mode_init((USB_Type *)(bus->hcd.reg_base)); +} + +void usb_hc_low_level_deinit(struct usbh_bus *bus) +{ + usb_phy_deinit((USB_Type *)(bus->hcd.reg_base)); + + if (bus->hcd.reg_base == HPM_USB0_BASE) { + intc_m_disable_irq(IRQn_USB0); + + g_usb_hpm_busid[0] = 0; + g_usb_hpm_irq[0] = NULL; + } else { +#ifdef HPM_USB1_BASE + intc_m_disable_irq(IRQn_USB1); + + g_usb_hpm_busid[1] = 0; + g_usb_hpm_irq[1] = NULL; +#endif + } +} + +uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port) +{ + (void)port; + uint8_t speed; + + speed = usb_get_port_speed((USB_Type *)(bus->hcd.reg_base)); + + if (speed == 0x00) { + return USB_SPEED_FULL; + } + if (speed == 0x01) { + return USB_SPEED_LOW; + } + if (speed == 0x02) { + return USB_SPEED_HIGH; + } + + return 0; +} \ No newline at end of file -- cgit v1.3.1