From 132bcd0b5e808837113206743035f0e85dd1dc9c Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 10 Dec 2025 21:37:00 +0100 Subject: hcd: add NXP IP3516 Signed-off-by: HiFiPhile --- src/common/tusb_mcu.h | 2 + src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c | 787 +++++++++++++++++++++++++++ src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.h | 188 +++++++ 3 files changed, 977 insertions(+) create mode 100644 src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c create mode 100644 src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.h (limited to 'src') diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 1e773bf96..c4b1155f3 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -73,11 +73,13 @@ #elif TU_CHECK_MCU(OPT_MCU_LPC54) // TODO USB0 has 5, USB1 has 6 #define TUP_USBIP_IP3511 + #define TUP_USBIP_IP3516 #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_LPC55) // TODO USB0 has 5, USB1 has 6 #define TUP_USBIP_IP3511 + #define TUP_USBIP_IP3516 #define TUP_USBIP_OHCI #define TUP_USBIP_OHCI_NXP #define TUP_OHCI_RHPORTS 1 // 1 downstream port diff --git a/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c b/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c new file mode 100644 index 000000000..16936e2c1 --- /dev/null +++ b/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c @@ -0,0 +1,787 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2025 HiFiPhile (Zixun LI) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED && defined(TUP_USBIP_IP3516) + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "common/tusb_common.h" +#include "host/hcd.h" +#include "host/usbh.h" +#include "hcd_lpc_ip3516.h" + +#if CFG_TUSB_MCU == OPT_MCU_LPC55 + #include "fsl_device_registers.h" +#else + #error "Unsupported MCUs" +#endif + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +#define USBHSH_PORTSC1_W1C_MASK (USBHSH_PORTSC1_CSC_MASK | USBHSH_PORTSC1_PEDC_MASK | USBHSH_PORTSC1_OCC_MASK) + +//--------------------------------------------------------------------+ +// Proprietary Transfer Descriptor +//--------------------------------------------------------------------+ + +CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(1024) static ip3516_ptd_t _ptd; + +static struct { + uint32_t uframe_number; + uint32_t uframe_length; + bool attached; // Track attachment state to avoid duplicate events, sometimes high-speed disconnection detector is not reliable +} _hcd_data; + +//--------------------------------------------------------------------+ +// Helper Functions +//--------------------------------------------------------------------+ + +static inline bool is_ptd_free(const ptd_ctrl1_t ctrl1) { + return ctrl1.mps == 0; +} + +static inline bool is_xfer_asyc(tusb_xfer_type_t xfer_type) { + return (xfer_type == TUSB_XFER_CONTROL || xfer_type == TUSB_XFER_BULK); +} + +static inline void ptd_clear_state(ptd_state_t *state) { + ptd_state_t local = {.value = 0}; + local.ep_type = state->ep_type; // preserve ep_type + local.token = state->token; // preserve token + local.data_toggle = state->data_toggle; // preserve data_toggle + *state = local; +} + +static inline uint8_t ptd_find_free(tusb_xfer_type_t xfer_type) { + uint8_t max_count; + intptr_t ptd_array; + + switch (xfer_type) { + case TUSB_XFER_CONTROL: + case TUSB_XFER_BULK: + max_count = IP3516_ATL_NUM; + ptd_array = (intptr_t)&_ptd.atl; + break; + + case TUSB_XFER_INTERRUPT: + max_count = IP3516_PTL_NUM; + ptd_array = (intptr_t)&_ptd.intr; + break; + + case TUSB_XFER_ISOCHRONOUS: + max_count = IP3516_PTL_NUM; + ptd_array = (intptr_t)&_ptd.iso; + break; + + default: + return TUSB_INDEX_INVALID_8; + } + + for (uint8_t i = 0; i < max_count; i++) { + // For ATL: stride is sizeof(ip3516_atl_t) = 16 bytes = 4 words + // For PTL: stride is sizeof(ip3516_ptl_t) = 32 bytes = 8 words + uint8_t stride = is_xfer_asyc(xfer_type) ? sizeof(ip3516_atl_t) : sizeof(ip3516_ptl_t); + ptd_ctrl1_t *ctrl1 = (ptd_ctrl1_t *)(ptd_array + i * stride); + + if (is_ptd_free(*ctrl1)) { + return i; + } + } + + return TUSB_INDEX_INVALID_8; // No free PTD found +} + +// Close all PTDs associated with a specific device address +static void close_ptds_by_device(uint8_t dev_addr, intptr_t ptd_array, uint8_t max_count, uint8_t stride, + volatile uint32_t *skip_reg) { + + uint32_t skip_mask = 0; + + for (uint8_t i = 0; i < max_count; i++) { + intptr_t ptd_ptr = ptd_array + i * stride; + ptd_ctrl1_t *ptd_ctrl1 = (ptd_ctrl1_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl1)); + ptd_ctrl2_t *ptd_ctrl2 = (ptd_ctrl2_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl2)); + + if (!is_ptd_free(*ptd_ctrl1) && ptd_ctrl2->dev_addr == dev_addr) { + *skip_reg |= (1 << i); + skip_mask |= (1 << i); + } + } + + if (skip_mask) { + // Wait 1 uframe for PTDs to be inactive + uint32_t start_uframe = + (USBHSH->FLADJ_FRINDEX & USBHSH_FLADJ_FRINDEX_FRINDEX_MASK) >> USBHSH_FLADJ_FRINDEX_FRINDEX_SHIFT; + while (((USBHSH->FLADJ_FRINDEX & USBHSH_FLADJ_FRINDEX_FRINDEX_MASK) >> USBHSH_FLADJ_FRINDEX_FRINDEX_SHIFT) == + start_uframe) {} + + // Clear PTDs + for (uint8_t i = 0; i < max_count; i++) { + if (skip_mask & (1 << i)) { + intptr_t ptd_ptr = ptd_array + i * stride; + tu_memclr((void *)ptd_ptr, stride); + } + } + + // Clear skip bits + *skip_reg &= ~skip_mask; + } +} + +// Check if a PTD matches the given endpoint criteria +static bool ptd_matches(intptr_t ptd_ptr, uint8_t dev_addr, uint8_t ep_num, uint8_t ep_dir) { + ptd_ctrl1_t *ptd_ctrl1 = (ptd_ctrl1_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl1)); + if (is_ptd_free(*ptd_ctrl1)) { + return false; + } + + ptd_ctrl2_t *ptd_ctrl2 = (ptd_ctrl2_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl2)); + if (ptd_ctrl2->dev_addr != dev_addr || ptd_ctrl2->ep_num != ep_num) { + return false; + } + + ptd_state_t *ptd_state = (ptd_state_t *)(ptd_ptr + offsetof(ip3516_atl_t, state)); + bool is_control = (ptd_state->ep_type == TUSB_XFER_CONTROL); + + // For control endpoint, match both IN and OUT directions + if (is_control) { + return true; + } + + if (ep_dir == TUSB_DIR_IN && ptd_state->token == IP3516_PTD_TOKEN_IN) { + return true; + } + + if (ep_dir == TUSB_DIR_OUT && ptd_state->token == IP3516_PTD_TOKEN_OUT) { + return true; + } + + return false; +} + +// Find and close a specific PTD +static bool find_and_close_ptd(uint8_t dev_addr, uint8_t ep_num, uint8_t ep_dir, intptr_t ptd_array, uint8_t max_count, + uint8_t stride, volatile uint32_t *skip_reg) { + for (uint8_t i = 0; i < max_count; i++) { + intptr_t ptd_ptr = ptd_array + i * stride; + if (ptd_matches(ptd_ptr, dev_addr, ep_num, ep_dir)) { + if (skip_reg) { + *skip_reg |= (1 << i); + + // Wait 1 uframe for PTD to be inactive + uint32_t start_uframe = + (USBHSH->FLADJ_FRINDEX & USBHSH_FLADJ_FRINDEX_FRINDEX_MASK) >> USBHSH_FLADJ_FRINDEX_FRINDEX_SHIFT; + while (((USBHSH->FLADJ_FRINDEX & USBHSH_FLADJ_FRINDEX_FRINDEX_MASK) >> USBHSH_FLADJ_FRINDEX_FRINDEX_SHIFT) == + start_uframe) {} + + // Just clear state + ptd_ctrl1_t *ptd_ctrl1 = (ptd_ctrl1_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl1)); + ptd_state_t *ptd_state = (ptd_state_t *)(ptd_ptr + offsetof(ip3516_atl_t, state)); + ptd_clear_state(ptd_state); + ptd_ctrl1->valid = 0; + + *skip_reg &= ~(1 << i); + } else { + // Clear PTD + tu_memclr((void *)ptd_ptr, stride); + } + return true; + } + } + return false; +} + +// Find an opened PTD +static intptr_t find_opened_ptd(uint8_t dev_addr, uint8_t ep_addr) { + const uint8_t ep_num = tu_edpt_number(ep_addr); + const uint8_t ep_dir = tu_edpt_dir(ep_addr); + + // Search in ATL + for (uint8_t i = 0; i < IP3516_ATL_NUM; i++) { + intptr_t ptd_ptr = (intptr_t)&_ptd.atl[i]; + if (ptd_matches(ptd_ptr, dev_addr, ep_num, ep_dir)) { + return ptd_ptr; + } + } + + // Search in INT + for (uint8_t i = 0; i < IP3516_PTL_NUM; i++) { + intptr_t ptd_ptr = (intptr_t)&_ptd.intr[i]; + if (ptd_matches(ptd_ptr, dev_addr, ep_num, ep_dir)) { + return ptd_ptr; + } + } + + // Search in ISO + for (uint8_t i = 0; i < IP3516_PTL_NUM; i++) { + intptr_t ptd_ptr = (intptr_t)&_ptd.iso[i]; + if (ptd_matches(ptd_ptr, dev_addr, ep_num, ep_dir)) { + return ptd_ptr; + } + } + + return TUSB_INDEX_INVALID_8; +} + +static bool edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen, bool is_setup) { + const uint8_t ep_num = tu_edpt_number(ep_addr); + const uint8_t ep_dir = tu_edpt_dir(ep_addr); + + intptr_t ptd_ptr = find_opened_ptd(dev_addr, ep_addr); + TU_ASSERT(ptd_ptr != TUSB_INDEX_INVALID_8); + + ptd_ctrl1_t *ptd_ctrl1 = (ptd_ctrl1_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl1)); + ptd_ctrl2_t *ptd_ctrl2 = (ptd_ctrl2_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl2)); + ptd_data_t *ptd_data = (ptd_data_t *)(ptd_ptr + offsetof(ip3516_atl_t, data)); + ptd_state_t *ptd_state = (ptd_state_t *)(ptd_ptr + offsetof(ip3516_atl_t, state)); + + // Setup data buffer and length + ptd_data->data_addr = (uint32_t)(uintptr_t)buffer & IP3516_PTD_DATA_ADDR_MASK; + ptd_data->xfer_len = buflen; + + // Clear previous state + ptd_clear_state(ptd_state); + + // Set token for EP0 + if (ep_num == 0) { + if (is_setup) { + ptd_state->token = IP3516_PTD_TOKEN_SETUP; + ptd_state->data_toggle = 0; + } else { + ptd_state->token = (ep_dir == TUSB_DIR_IN) ? IP3516_PTD_TOKEN_IN : IP3516_PTD_TOKEN_OUT; + ptd_state->data_toggle = 1; + } + } + + // Interrupt split transfer needs to be relauched manually if NAKed + if (ptd_ctrl2->split && ptd_state->ep_type == TUSB_XFER_INTERRUPT) { + ptd_ctrl2->reload = 0x0f; + ptd_state->nak_cnt = 0x0f; + } + + // Activate PTD + ptd_ctrl1->valid = 1; + ptd_state->active = 1; + + return true; +} + +//--------------------------------------------------------------------+ +// Controller API +//--------------------------------------------------------------------+ + +// Initialize controller to host mode +bool hcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { + (void)rh_init; + (void)rhport; + + // Reset controller + USBHSH->USBCMD |= USBHSH_USBCMD_HCRESET_MASK; + while (USBHSH->USBCMD & USBHSH_USBCMD_HCRESET_MASK) {} + + USBHSH->PORTMODE = USBHSH_PORTMODE_SW_CTRL_PDCOM_MASK; + + tu_memclr(&_ptd, sizeof(_ptd)); + tu_varclr(&_hcd_data); + + // Set base addresses + USBHSH->ATLPTD = (uint32_t)&_ptd.atl & USBHSH_ATLPTD_ATL_BASE_MASK; + USBHSH->INTPTD = (uint32_t)&_ptd.intr & USBHSH_INTPTD_INT_BASE_MASK; + USBHSH->ISOPTD = (uint32_t)&_ptd.iso & USBHSH_ISOPTD_ISO_BASE_MASK; + USBHSH->DATAPAYLOAD = (uint32_t)&_ptd & USBHSH_DATAPAYLOAD_DAT_BASE_MASK; + + // Turn on power switch + if (USBHSH->HCSPARAMS & USBHSH_HCSPARAMS_PPC_MASK) { + USBHSH->PORTSC1 |= USBHSH_PORTSC1_PP_MASK; + } + + // Get frame list size + uint32_t fls = (USBHSH->USBCMD & USBHSH_USBCMD_FLS_MASK) >> USBHSH_USBCMD_FLS_SHIFT; + _hcd_data.uframe_length = 8192 >> fls; + + // Clear pending interrupts + USBHSH->USBSTS = 0xFFFFFFFF; + + // Enable interrupts + USBHSH->USBINTR = USBHSH_USBINTR_ATL_IRQ_E_MASK | USBHSH_USBINTR_INT_IRQ_E_MASK | USBHSH_USBINTR_ISO_IRQ_E_MASK | + USBHSH_USBINTR_PCDE_MASK | USBHSH_USBINTR_FLRE_MASK; + + + // Enable all PTDs + USBHSH->LASTPTD = USBHSH_LASTPTD_ATL_LAST(IP3516_ATL_NUM - 1) | USBHSH_LASTPTD_INT_LAST(IP3516_PTL_NUM - 1) | + USBHSH_LASTPTD_ISO_LAST(IP3516_PTL_NUM - 1); + + // Enable controller + USBHSH->USBCMD = USBHSH_USBCMD_ATL_EN_MASK | USBHSH_USBCMD_INT_EN_MASK | USBHSH_USBCMD_ISO_EN_MASK | USBHSH_USBCMD_RS_MASK; + + return true; +} + +// Enable USB interrupt +void hcd_int_enable(uint8_t rhport) { + (void)rhport; + NVIC_EnableIRQ(USB1_IRQn); +} + +// Disable USB interrupt +void hcd_int_disable(uint8_t rhport) { + (void)rhport; + NVIC_DisableIRQ(USB1_IRQn); +} + +bool hcd_deinit(uint8_t rhport) { + (void)rhport; + + // Disable interrupts + USBHSH->USBINTR = 0; + USBHSH->USBSTS = 0xFFFFFFFF; + + // Disable controller + USBHSH->USBCMD &= ~(USBHSH_USBCMD_ATL_EN_MASK | USBHSH_USBCMD_INT_EN_MASK | USBHSH_USBCMD_ISO_EN_MASK | USBHSH_USBCMD_RS_MASK); + + // Turn off power switch + if (USBHSH->HCSPARAMS & USBHSH_HCSPARAMS_PPC_MASK) { + USBHSH->PORTSC1 &= ~USBHSH_PORTSC1_PP_MASK; + } + + // Connect PHY to device mode + USBHSH->PORTMODE = USBHSH_PORTMODE_SW_CTRL_PDCOM_MASK | USBHSH_PORTMODE_DEV_ENABLE_MASK; + + return true; +} + +//--------------------------------------------------------------------+ +// Port API +//--------------------------------------------------------------------+ + +// Reset USB bus on the port. Return immediately, bus reset sequence may not be complete. +// Some port would require hcd_port_reset_end() to be invoked after 10ms to complete the reset sequence. +void hcd_port_reset(uint8_t rhport) { + (void)rhport; + uint32_t status = USBHSH->PORTSC1 & ~USBHSH_PORTSC1_W1C_MASK; + USBHSH->PORTSC1 = status | USBHSH_PORTSC1_PR_MASK; +} + +// Complete bus reset sequence, may be required by some controllers +void hcd_port_reset_end(uint8_t rhport) { + (void)rhport; + uint32_t status = USBHSH->PORTSC1 & ~USBHSH_PORTSC1_W1C_MASK; + USBHSH->PORTSC1 = status & ~USBHSH_PORTSC1_PR_MASK; + while (USBHSH->PORTSC1 & USBHSH_PORTSC1_PR_MASK) {} +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) + uint32_t pspd = (USBHSH->PORTSC1 & USBHSH_PORTSC1_PSPD_MASK) >> USBHSH_PORTSC1_PSPD_SHIFT; + if (pspd == 2) { + // enable phy disconnection for high speed + USBPHY->CTRL |= USBPHY_CTRL_ENHOSTDISCONDETECT_MASK; + } +#endif +} + +// Get the current connect status of roothub port +bool hcd_port_connect_status(uint8_t rhport) { + (void)rhport; + return (USBHSH->PORTSC1 & USBHSH_PORTSC1_CCS_MASK) ? true : false; +} + +// Get port link speed +tusb_speed_t hcd_port_speed_get(uint8_t rhport) { + (void)rhport; + uint32_t pspd = (USBHSH->PORTSC1 & USBHSH_PORTSC1_PSPD_MASK) >> USBHSH_PORTSC1_PSPD_SHIFT; + switch (pspd) { + case 0: + return TUSB_SPEED_LOW; + case 1: + return TUSB_SPEED_FULL; + case 2: + return TUSB_SPEED_HIGH; + default: + return TUSB_SPEED_INVALID; + } +} + +// Get frame number (1ms) +uint32_t hcd_frame_number(uint8_t rhport) { + (void)rhport; + uint32_t uframe = (USBHSH->FLADJ_FRINDEX & USBHSH_FLADJ_FRINDEX_FRINDEX_MASK) >> USBHSH_FLADJ_FRINDEX_FRINDEX_SHIFT; + uframe &= (_hcd_data.uframe_length - 1); + return (uframe + _hcd_data.uframe_number) >> 3; +} + +// HCD closes all opened endpoints belong to this device +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { + (void)rhport; + + close_ptds_by_device(dev_addr, (intptr_t)&_ptd.atl, IP3516_ATL_NUM, sizeof(ip3516_atl_t), &USBHSH->ATLPTDS); + close_ptds_by_device(dev_addr, (intptr_t)&_ptd.intr, IP3516_PTL_NUM, sizeof(ip3516_ptl_t), &USBHSH->INTPTDS); + close_ptds_by_device(dev_addr, (intptr_t)&_ptd.iso, IP3516_PTL_NUM, sizeof(ip3516_ptl_t), &USBHSH->ISOPTDS); +} + +//--------------------------------------------------------------------+ +// Endpoints API +//--------------------------------------------------------------------+ + +static inline intptr_t get_ptd_from_index(tusb_xfer_type_t xfer_type, uint8_t ptd_index) { + if (is_xfer_asyc(xfer_type)) { + return (intptr_t)&_ptd.atl[ptd_index]; + } else { + if (xfer_type == TUSB_XFER_INTERRUPT) { + return (intptr_t)&_ptd.intr[ptd_index]; + } else { + return (intptr_t)&_ptd.iso[ptd_index]; + } + } +} + + +// Open an endpoint +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_endpoint_t *ep_desc) { + (void)rhport; + + const uint8_t ep_num = tu_edpt_number(ep_desc->bEndpointAddress); + const tusb_xfer_type_t xfer_type = (tusb_xfer_type_t)ep_desc->bmAttributes.xfer; + + tuh_bus_info_t bus_info; + tuh_bus_info_get(dev_addr, &bus_info); + + // Find a free PTD + uint8_t ptd_index = ptd_find_free(xfer_type); + TU_ASSERT(ptd_index != TUSB_INDEX_INVALID_8); + + // Configure PTD + intptr_t ptd_ptr = get_ptd_from_index(xfer_type, ptd_index); + volatile ptd_ctrl1_t *ctrl1 = (volatile ptd_ctrl1_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl1)); + volatile ptd_ctrl2_t *ctrl2 = (volatile ptd_ctrl2_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl2)); + volatile ptd_data_t *data = (volatile ptd_data_t *)(ptd_ptr + offsetof(ip3516_atl_t, data)); + volatile ptd_state_t *state = (volatile ptd_state_t *)(ptd_ptr + offsetof(ip3516_atl_t, state)); + + // Initialize PTD fields + ctrl1->mps = ep_desc->wMaxPacketSize; + ctrl1->mult = 1; + + ctrl2->dev_addr = dev_addr; + ctrl2->ep_num = ep_num; + ctrl2->speed = bus_info.speed == TUSB_SPEED_LOW ? 2 : 0; + ctrl2->hub_addr = bus_info.hub_addr; + ctrl2->hub_port = bus_info.hub_port; + ctrl2->split = (hcd_port_speed_get(rhport) == TUSB_SPEED_HIGH) && (bus_info.speed != TUSB_SPEED_HIGH) ? 1 : 0; + + data->intr = 1; + + state->ep_type = (uint32_t)xfer_type; + state->token = tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN ? IP3516_PTD_TOKEN_IN : IP3516_PTD_TOKEN_OUT; + + if (!is_xfer_asyc(xfer_type)) { + ip3516_ptl_t *ptd = (ip3516_ptl_t *)ptd_ptr; + + uint32_t uframe_interval; + if (bus_info.speed == TUSB_SPEED_HIGH) { + uframe_interval = 1 << (ep_desc->bInterval - 1); + } else { + uframe_interval = ep_desc->bInterval << 3; + // round down to nearest power of 2 + uframe_interval = 1 << tu_log2(uframe_interval); + } + uframe_interval = tu_min32(uframe_interval, IP3516_MAX_UFRAME); + + // uframe_active is an 8-bit mask, where each bit corresponds to a micro-frame within a 1ms frame. + // A '1' indicates the endpoint should be polled in that micro-frame. + // For example: + // Interval 1 (poll every u-frame) -> mask is 0b11111111 (0xFF) + // Interval 2 (poll every 2nd u-frame, e.g., 0, 2, 4, 6) -> mask is 0b10101010 (0xAA) + // Interval 4 (poll every 4th u-frame, e.g., 0, 4) -> mask is 0b10001000 (0x88) + // Interval 8 (poll every 8th u-frame, e.g., 0) -> mask is 0b10000000 (0x80) + switch (uframe_interval) { + case 1: + ptd->status.uframe_active = 0xFF; + break; + case 2: + ptd->status.uframe_active = 0xAA; + break; + case 4: + ptd->status.uframe_active = 0x11; + break; + case 8: + ptd->status.uframe_active = 0x01; + break; + default: + // For intervals > 8, we poll once per frame (every 8 u-frames) and use ctrl1.uframe to skip frames. + ptd->status.uframe_active = 0x01; + if (uframe_interval >= 16) { + ctrl1->uframe = tu_log2(uframe_interval) - 3; + } + break; + } + + if (ctrl2->split) { + // 11.18.1 Best Case Full-Speed Budget + // + // A microframe of time allows at most 187.5 raw bytes of signaling on a full-speed bus. + // The best case full-speed budget assumes that 188 full-speed bytes occur in each microframe. + // + // A 1 ms frame subdivided into microframes of budget time: + // + // Microframes Y_0 Y_1 Y_2 Y_3 Y_4 Y_5 Y_6 Y_7 + // Max wire time 187.5 187.5 187.5 187.5 187.5 187.5 32 + // Best case wire budget 188 188 188 188 188 188 29 + // + // 11.18.4 Host Split Transaction Scheduling Requirements + // + // 1. The host must never schedule a start-split in microframe Y_6. + // 2. For isochronous OUT full-speed transactions, for each microframe in which the transaction is + // budgeted, the host must schedule a 188 (or the remaining data size) data byte start-split transaction. + // For isochronous IN and interrupt IN/OUT full-/low-speed transactions, a single start-split must be + // scheduled in the microframe before the transaction is budgeted to start on the full-/low-speed bus. + // 3. For isochronous OUT full-speed transactions, the host must never schedule a complete-split. The + // TT response to a complete-split for an isochronous OUT is undefined. + // For interrupt IN/OUT full-/low-speed transactions, the host must schedule a complete-split + // transaction in each of the two microframes following the first microframe in which the full-/low- + // speed transaction is budgeted. An additional complete-split must also be scheduled in the third + // following microframe unless the full-/low-speed transaction was budgeted to start in microframe Y_6 + // For isochronous IN full-speed transactions, for each microframe in which the full-speed transaction + // is budgeted, a complete-split must be scheduled for each following microframe. + // Also, determine the last microframe in which a complete-split is scheduled, call it L. + // If L is less than Y_6, schedule additional complete-splits in microframe L+1 and L+2. + // If L is equal to Y_6, schedule one complete-split in microframe Y_7. + // + // TODO: Implement budget check scheduling + // Otherwise, it may cause bus contention with other split transfers + // Here we simply start interrupt transfers for Y_0 and Y1 and isochronous transfers for Y_2 + if (xfer_type == TUSB_XFER_ISOCHRONOUS) { + const uint8_t ss_slot = 2; // Start-split slot + const uint8_t slots = (ep_desc->wMaxPacketSize + 187) / 188; + const tusb_dir_t ep_dir = tu_edpt_dir(ep_desc->bEndpointAddress); + if (ep_dir == TUSB_DIR_IN) { + if (ep_desc->wMaxPacketSize > 192) { + ctrl1->mps = 192; + } + ptd->status.uframe_active = 1 << ss_slot; + for (uint8_t i = 0; i < slots; i++) { + ptd->iso_in_0.uframe_complete |= 1 << (2 + ss_slot + i); + } + // Schedule additional complete-splits if needed + uint8_t last_complete = ss_slot + slots + 1; + if (last_complete < 6) { + ptd->iso_in_0.uframe_complete |= 1 << (ss_slot + last_complete + 1); + ptd->iso_in_0.uframe_complete |= 1 << (ss_slot + last_complete + 2); + } else if (last_complete == 6) { + ptd->iso_in_0.uframe_complete |= 1 << 7; + } + } else { + if (ep_desc->wMaxPacketSize > 188) { + ctrl1->mps = 188; + } + for (uint8_t i = 0; i < slots; i++) { + ptd->status.uframe_active |= 1 << (ss_slot + i); + } + } + } else { + // Start-split slot, jigging to avoid bus contention: EP odd -> Y_1, EP even -> Y_0 + const uint8_t ss_slot = ep_num & 0x01; + ptd->status.uframe_active = 1 << ss_slot; + // Complete-split slots: next 3 u-frames + ptd->iso_in_0.uframe_complete = 0x1c << ss_slot; + } + } + } + + return true; +} + +// Close an opened endpoint +bool hcd_edpt_close(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { + (void)rhport; + const uint8_t ep_num = tu_edpt_number(ep_addr); + const uint8_t ep_dir = tu_edpt_dir(ep_addr); + + // Search in ATL + if (find_and_close_ptd(dev_addr, ep_num, ep_dir, (intptr_t)&_ptd.atl, IP3516_ATL_NUM, sizeof(ip3516_atl_t), NULL)) { + return true; + } + + // Search in INT + if (find_and_close_ptd(dev_addr, ep_num, ep_dir, (intptr_t)&_ptd.intr, IP3516_PTL_NUM, sizeof(ip3516_ptl_t), NULL)) { + return true; + } + + // Search in ISO + if (find_and_close_ptd(dev_addr, ep_num, ep_dir, (intptr_t)&_ptd.iso, IP3516_PTL_NUM, sizeof(ip3516_ptl_t), NULL)) { + return true; + } + + return false; +} + +// Submit a transfer on an endpoint +bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) { + (void)rhport; + + return edpt_xfer(dev_addr, ep_addr, buffer, buflen, false); +} + +// Abort a queued transfer. Note: it can only abort transfer that has not been started +// Return true if a queued transfer is aborted, false if there is no transfer to abort +bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { + (void)rhport; + + const uint8_t ep_num = tu_edpt_number(ep_addr); + const uint8_t ep_dir = tu_edpt_dir(ep_addr); + + // Search in ATL + if (find_and_close_ptd(dev_addr, ep_num, ep_dir, (intptr_t)&_ptd.atl, IP3516_ATL_NUM, sizeof(ip3516_atl_t), + &USBHSH->ATLPTDS)) { + return true; + } + + // Search in INT + if (find_and_close_ptd(dev_addr, ep_num, ep_dir, (intptr_t)&_ptd.intr, IP3516_PTL_NUM, sizeof(ip3516_ptl_t), + &USBHSH->INTPTDS)) { + return true; + } + + // Search in ISO + if (find_and_close_ptd(dev_addr, ep_num, ep_dir, (intptr_t)&_ptd.iso, IP3516_PTL_NUM, sizeof(ip3516_ptl_t), + &USBHSH->ISOPTDS)) { + return true; + } + + return false; +} + +bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, const uint8_t setup_packet[8]) { + (void)rhport; + + return edpt_xfer(dev_addr, 0x00, (uint8_t *)(uintptr_t)setup_packet, 8, true); +} + +bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { + (void)rhport; + + intptr_t ptd_ptr = find_opened_ptd(dev_addr, ep_addr); + TU_ASSERT(ptd_ptr != TUSB_INDEX_INVALID_8); + + ptd_state_t *ptd_state = (ptd_state_t *)(ptd_ptr + offsetof(ip3516_atl_t, state)); + ptd_clear_state(ptd_state); + ptd_state->data_toggle = 0; // reset data toggle to DATA0 + + return true; +} + +//--------------------------------------------------------------------+ +// Interrupt Handler +//--------------------------------------------------------------------+ + +// Handle port status change event +static inline void handle_port_status_change(uint8_t rhport) { + const uint32_t status = USBHSH->PORTSC1; + + if (status & USBHSH_PORTSC1_CSC_MASK) { + if (status & USBHSH_PORTSC1_CCS_MASK && !_hcd_data.attached) { + _hcd_data.attached = true; + hcd_event_device_attach(rhport, true); + } else { + _hcd_data.attached = false; + hcd_event_device_remove(rhport, true); + #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) + // disable phy disconnection for high speed + USBPHY->CTRL &= ~USBPHY_CTRL_ENHOSTDISCONDETECT_MASK; + #endif + } + } + + USBHSH->PORTSC1 |= status & USBHSH_PORTSC1_W1C_MASK; +} + +// Handle PTD done interrupt +static inline void handle_ptd_done(uint32_t done_status, intptr_t ptd_array, bool is_async) { + uint8_t max_count = is_async ? IP3516_ATL_NUM : IP3516_PTL_NUM; + uint8_t stride = is_async ? sizeof(ip3516_atl_t) : sizeof(ip3516_ptl_t); + + for (uint8_t i = 0; i < max_count; i++) { + if (done_status & (1 << i)) { + intptr_t ptd_ptr = ptd_array + i * stride; + ptd_ctrl2_t *ptd_ctrl2 = (ptd_ctrl2_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl2)); + ptd_state_t *ptd_state = (ptd_state_t *)(ptd_ptr + offsetof(ip3516_atl_t, state)); + + xfer_result_t result; + if (ptd_state->halt) { + result = XFER_RESULT_STALLED; + } else if (ptd_state->error || ptd_state->babble) { + result = XFER_RESULT_FAILED; + } else { + result = XFER_RESULT_SUCCESS; + } + + uint8_t ep_addr = ptd_ctrl2->ep_num | (ptd_state->token == IP3516_PTD_TOKEN_IN ? 0x80 : 0x00); + + hcd_event_xfer_complete(ptd_ctrl2->dev_addr, ep_addr, ptd_state->xferred_len, result, true); + } + } +} + +void hcd_int_handler(uint8_t rhport, bool in_isr) { + (void)in_isr; + + uint32_t int_status = USBHSH->USBSTS; + USBHSH->USBSTS = int_status; // clear interrupt status + + // Port Change Detect + if (int_status & USBHSH_USBSTS_PCD_MASK) { + handle_port_status_change(rhport); + } + + // Frame List Rollover + if (int_status & USBHSH_USBSTS_FLR_MASK) { + _hcd_data.uframe_number += _hcd_data.uframe_length; + } + + // ATL done + if (int_status & USBHSH_USBSTS_ATL_IRQ_MASK) { + uint32_t done_status = USBHSH->ATLPTDD; + handle_ptd_done(done_status, (intptr_t)&_ptd.atl, true); + USBHSH->ATLPTDD = done_status; + } + + // INT done + if (int_status & USBHSH_USBSTS_INT_IRQ_MASK) { + uint32_t done_status = USBHSH->INTPTDD; + handle_ptd_done(done_status, (intptr_t)&_ptd.intr, false); + USBHSH->INTPTDD = done_status; + } + + // ISO done + if (int_status & USBHSH_USBSTS_ISO_IRQ_MASK) { + uint32_t done_status = USBHSH->ISOPTDD; + handle_ptd_done(done_status, (intptr_t)&_ptd.iso, false); + USBHSH->ISOPTDD = done_status; + } +} + +#endif diff --git a/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.h b/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.h new file mode 100644 index 000000000..38c3a3224 --- /dev/null +++ b/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.h @@ -0,0 +1,188 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2025 HiFiPhile (Zixun LI) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef TUSB_HCD_IP3516_H_ +#define TUSB_HCD_IP3516_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// IP3516 CONFIGURATION & CONSTANTS +//--------------------------------------------------------------------+ + +#define IP3516_ATL_NUM 32 +#define IP3516_PTL_NUM 32 + +#define IP3516_PTD_TOKEN_OUT 0x00U +#define IP3516_PTD_TOKEN_IN 0x01U +#define IP3516_PTD_TOKEN_SETUP 0x02U + +#define IP3516_PTD_EPTYPE_OUT 0x00U +#define IP3516_PTD_EPTYPE_IN 0x01U +#define IP3516_PTD_EPTYPE_SETUP 0x02U + +#define IP3516_PTD_MAX_TRANSFER_LENGTH 0x7FFFU + +#define IP3516_PTD_DATA_ADDR_MASK 0xFFFFU + +#define IP3516_MAX_UFRAME (1UL << 8) + +#define IP3516_PERIODIC_TRANSFER_GAP (3U) +#define IP3516_ISO_MULTIPLE_TRANSFER (8U) + + +//--------------------------------------------------------------------+ +// OHCI Data Structure +//--------------------------------------------------------------------+ + +// Control Word 1 +typedef union { + uint32_t value; + struct { + uint32_t valid : 1; + uint32_t next_ptd : 5; + uint32_t : 1; + uint32_t jump : 1; + uint32_t uframe : 8; + uint32_t mps : 11; + uint32_t : 1; + uint32_t mult : 2; + uint32_t : 2; + }; +} ptd_ctrl1_t; + +TU_VERIFY_STATIC(sizeof(ptd_ctrl1_t) == 4, "size is not correct"); + +// Control Word 2 +typedef union { + uint32_t value; + struct { + uint32_t ep_num : 4; + uint32_t dev_addr : 7; + uint32_t split : 1; + uint32_t reload : 4; + uint32_t speed : 2; + uint32_t hub_port : 7; + uint32_t hub_addr : 7; + }; +} ptd_ctrl2_t; + +TU_VERIFY_STATIC(sizeof(ptd_ctrl2_t) == 4, "size is not correct"); + +// Data Word +typedef union { + uint32_t value; + struct { + uint32_t xfer_len : 15; + uint32_t intr : 1; + uint32_t data_addr : 16; + }; +} ptd_data_t; + +TU_VERIFY_STATIC(sizeof(ptd_data_t) == 4, "size is not correct"); + +// State Word +typedef union { + uint32_t value; + struct { + uint32_t xferred_len : 15; + uint32_t token : 2; + uint32_t ep_type : 2; + uint32_t nak_cnt : 4; + uint32_t err_cnt : 2; + uint32_t data_toggle : 1; + uint32_t ping : 1; + uint32_t start_complete : 1; + uint32_t error : 1; + uint32_t babble : 1; + uint32_t halt : 1; + uint32_t active : 1; + }; +} ptd_state_t; + +TU_VERIFY_STATIC(sizeof(ptd_state_t) == 4, "size is not correct"); + +// Status Word +typedef union { + uint32_t value; + struct { + uint32_t uframe_active : 8; + uint32_t iso_status0 : 3; + uint32_t iso_status1 : 3; + uint32_t iso_status2 : 3; + uint32_t iso_status3 : 3; + uint32_t iso_status4 : 3; + uint32_t iso_status5 : 3; + uint32_t iso_status6 : 3; + uint32_t iso_status7 : 3; + }; +} ptd_status_t; + +TU_VERIFY_STATIC(sizeof(ptd_status_t) == 4, "size is not correct"); + +// ATL (Asynchronous Transfer List) structure +typedef volatile struct { + ptd_ctrl1_t ctrl1; + ptd_ctrl2_t ctrl2; + ptd_data_t data; + ptd_state_t state; +} ip3516_atl_t; + +TU_VERIFY_STATIC(sizeof(ip3516_atl_t) == 16, "size is not correct"); + +// PTL (Periodic Transfer List) structure +typedef volatile struct { + ptd_ctrl1_t ctrl1; + ptd_ctrl2_t ctrl2; + ptd_data_t data; + ptd_state_t state; + ptd_status_t status; + union { + uint32_t value; + struct { + uint32_t uframe_complete : 8; + uint32_t spl_iso_in_0 : 24; + }; + } iso_in_0; + uint32_t iso_in_1; + uint32_t iso_in_2; +} ip3516_ptl_t; + +TU_VERIFY_STATIC(sizeof(ip3516_ptl_t) == 32, "size is not correct"); + +// Proprietary Transfer Descriptor +typedef struct { + ip3516_ptl_t intr[IP3516_PTL_NUM]; + ip3516_ptl_t iso[IP3516_PTL_NUM]; + ip3516_atl_t atl[IP3516_ATL_NUM]; +} ip3516_ptd_t; + +#ifdef __cplusplus +} +#endif +#endif /* TUSB_HCD_IP3516_H_ */ -- cgit v1.3.1 From 32dafcccc79cb96df7e91a5cf600f14562f779c3 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 10 Dec 2025 21:39:48 +0100 Subject: hcd/ohci: fix warnings Signed-off-by: HiFiPhile --- src/portable/ohci/ohci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index 5ca093506..4b248d9e6 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -243,7 +243,7 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { OHCI_CONTROL_LIST_BULK_ENABLE_MASK | OHCI_CONTROL_LIST_PERIODIC_ENABLE_MASK; // TODO Isochronous OHCI_REG->frame_interval = (OHCI_FMINTERVAL_FSMPS << 16) | OHCI_FMINTERVAL_FI; - OHCI_REG->frame_interval ^= (1 << 31); //Must toggle when frame_interval is updated. + OHCI_REG->frame_interval ^= (1ul << 31); //Must toggle when frame_interval is updated. OHCI_REG->periodic_start = (OHCI_FMINTERVAL_FI * 9) / 10; // Periodic start is 90% of frame interval OHCI_REG->control_bit.hc_functional_state = OHCI_CONTROL_FUNCSTATE_OPERATIONAL; // make HC's state to operational state TODO use this to suspend (save power) @@ -557,6 +557,7 @@ bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; ohci_ed_t * const p_ed = ed_from_addr(dev_addr, ep_addr); + TU_ASSERT(p_ed); ohci_ed_word2_t td_head = p_ed->td_head; td_head.toggle = 0; // reset data toggle -- cgit v1.3.1 From ba9bc1a79d2c00290e64a93907f37cd3db7140f8 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 12 Dec 2025 12:30:36 +0100 Subject: update LPC54 Signed-off-by: HiFiPhile --- README.rst | 4 +- examples/host/bare_api/only.txt | 1 + examples/host/cdc_msc_hid/only.txt | 1 + examples/host/cdc_msc_hid_freertos/only.txt | 1 + examples/host/device_info/only.txt | 1 + examples/host/hid_controller/only.txt | 1 + examples/host/midi_rx/only.txt | 1 + examples/host/msc_file_explorer/only.txt | 1 + hw/bsp/lpc54/boards/lpcxpresso54114/board.h | 12 + hw/bsp/lpc54/boards/lpcxpresso54608/board.h | 21 + hw/bsp/lpc54/boards/lpcxpresso54628/board.h | 12 + hw/bsp/lpc54/family.c | 78 ++-- hw/bsp/lpc54/family.cmake | 72 ++- hw/bsp/lpc54/iar/LPC54608_flash.icf | 85 ++++ hw/bsp/lpc54/iar/LPC54628_flash.icf | 83 ++++ hw/bsp/lpc54/iar/startup_LPC54608.s | 654 +++++++++++++++++++++++++++ hw/bsp/lpc54/iar/startup_LPC54628.s | 654 +++++++++++++++++++++++++++ src/common/tusb_mcu.h | 4 + src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c | 26 +- 19 files changed, 1665 insertions(+), 47 deletions(-) create mode 100644 hw/bsp/lpc54/iar/LPC54608_flash.icf create mode 100644 hw/bsp/lpc54/iar/LPC54628_flash.icf create mode 100644 hw/bsp/lpc54/iar/startup_LPC54608.s create mode 100644 hw/bsp/lpc54/iar/startup_LPC54628.s (limited to 'src') diff --git a/README.rst b/README.rst index 6a6f07825..64583f2cc 100644 --- a/README.rst +++ b/README.rst @@ -203,7 +203,9 @@ Supported CPUs | | +-------------------+--------+------+-----------+------------------------+-------------------+ | | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | | | | +-------------------+--------+------+-----------+------------------------+-------------------+ -| | | 54, 55 | ✔ | | ✔ | lpc_ip3511 | | +| | | 54 | ⚠ | ⚠ | ✔ | lpc_ip3511, lpc_ip3516 | NRND, read errata | +| | +-------------------+--------+------+-----------+------------------------+-------------------+ +| | | 55 | ✔ | ✔ | ✔ | lpc_ip3511, lpc_ip3516 | | | +---------+-------------------+--------+------+-----------+------------------------+-------------------+ | | MCX | N9 | ✔ | | ✔ | ci_fs, ci_hs, ehci | | | | +-------------------+--------+------+-----------+------------------------+-------------------+ diff --git a/examples/host/bare_api/only.txt b/examples/host/bare_api/only.txt index b39a23e40..31b35f7b9 100644 --- a/examples/host/bare_api/only.txt +++ b/examples/host/bare_api/only.txt @@ -5,6 +5,7 @@ mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX +mcu:LPC54 mcu:LPC55 mcu:MIMXRT1XXX mcu:MIMXRT10XX diff --git a/examples/host/cdc_msc_hid/only.txt b/examples/host/cdc_msc_hid/only.txt index b39a23e40..31b35f7b9 100644 --- a/examples/host/cdc_msc_hid/only.txt +++ b/examples/host/cdc_msc_hid/only.txt @@ -5,6 +5,7 @@ mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX +mcu:LPC54 mcu:LPC55 mcu:MIMXRT1XXX mcu:MIMXRT10XX diff --git a/examples/host/cdc_msc_hid_freertos/only.txt b/examples/host/cdc_msc_hid_freertos/only.txt index b755df825..54a9fee51 100644 --- a/examples/host/cdc_msc_hid_freertos/only.txt +++ b/examples/host/cdc_msc_hid_freertos/only.txt @@ -3,6 +3,7 @@ mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX +mcu:LPC54 mcu:LPC55 mcu:MIMXRT1XXX mcu:MIMXRT10XX diff --git a/examples/host/device_info/only.txt b/examples/host/device_info/only.txt index 2a3c5c583..36be2124d 100644 --- a/examples/host/device_info/only.txt +++ b/examples/host/device_info/only.txt @@ -5,6 +5,7 @@ mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX +mcu:LPC54 mcu:LPC55 mcu:MAX3421 mcu:MIMXRT1XXX diff --git a/examples/host/hid_controller/only.txt b/examples/host/hid_controller/only.txt index b39a23e40..31b35f7b9 100644 --- a/examples/host/hid_controller/only.txt +++ b/examples/host/hid_controller/only.txt @@ -5,6 +5,7 @@ mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX +mcu:LPC54 mcu:LPC55 mcu:MIMXRT1XXX mcu:MIMXRT10XX diff --git a/examples/host/midi_rx/only.txt b/examples/host/midi_rx/only.txt index b0afa4fc3..9c4771de0 100644 --- a/examples/host/midi_rx/only.txt +++ b/examples/host/midi_rx/only.txt @@ -8,6 +8,7 @@ mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX +mcu:LPC54 mcu:LPC55 mcu:MAX3421 mcu:MIMXRT1XXX diff --git a/examples/host/msc_file_explorer/only.txt b/examples/host/msc_file_explorer/only.txt index b39a23e40..31b35f7b9 100644 --- a/examples/host/msc_file_explorer/only.txt +++ b/examples/host/msc_file_explorer/only.txt @@ -5,6 +5,7 @@ mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX +mcu:LPC54 mcu:LPC55 mcu:MIMXRT1XXX mcu:MIMXRT10XX diff --git a/hw/bsp/lpc54/boards/lpcxpresso54114/board.h b/hw/bsp/lpc54/boards/lpcxpresso54114/board.h index c43ca9d7d..1158d0675 100644 --- a/hw/bsp/lpc54/boards/lpcxpresso54114/board.h +++ b/hw/bsp/lpc54/boards/lpcxpresso54114/board.h @@ -36,6 +36,18 @@ extern "C" { #endif +// IOCON pin mux +#define IOCON_PIO_DIGITAL_EN 0x80u // Enables digital function +#define IOCON_PIO_FUNC0 0x00u +#define IOCON_PIO_FUNC1 0x01u // Selects pin function 1 +#define IOCON_PIO_FUNC7 0x07u // Selects pin function 7 +#define IOCON_PIO_INPFILT_OFF 0x0100u // Input filter disabled +#define IOCON_PIO_INV_DI 0x00u // Input function is not inverted +#define IOCON_PIO_MODE_INACT 0x00u // No addition pin function +#define IOCON_PIO_MODE_PULLUP 0x10u +#define IOCON_PIO_OPENDRAIN_DI 0x00u // Open drain is disabled +#define IOCON_PIO_SLEW_STANDARD 0x00u // Standard mode, output slew rate control is enabled + // LED #define LED_PORT 0 #define LED_PIN 29 diff --git a/hw/bsp/lpc54/boards/lpcxpresso54608/board.h b/hw/bsp/lpc54/boards/lpcxpresso54608/board.h index e985e97e0..7a5cbea87 100644 --- a/hw/bsp/lpc54/boards/lpcxpresso54608/board.h +++ b/hw/bsp/lpc54/boards/lpcxpresso54608/board.h @@ -36,6 +36,18 @@ extern "C" { #endif +// IOCON pin mux +#define IOCON_PIO_DIGITAL_EN 0x0100u // Enables digital function +#define IOCON_PIO_FUNC0 0x00u +#define IOCON_PIO_FUNC1 0x01u // Selects pin function 1 +#define IOCON_PIO_FUNC7 0x07u // Selects pin function 7 +#define IOCON_PIO_INPFILT_OFF 0x0200u // Input filter disabled +#define IOCON_PIO_INV_DI 0x00u // Input function is not inverted +#define IOCON_PIO_MODE_INACT 0x00u // No addition pin function +#define IOCON_PIO_MODE_PULLUP 0x10u +#define IOCON_PIO_OPENDRAIN_DI 0x00u // Open drain is disabled +#define IOCON_PIO_SLEW_STANDARD 0x00u // Standard mode, output slew rate control is enabled + // LED #define LED_PORT 2 #define LED_PIN 2 @@ -54,6 +66,15 @@ // USB0 VBUS #define USB0_VBUS_PINMUX 0, 22, IOCON_PIO_DIG_FUNC7_EN +// Power switch +#define USBFS_POWER_PORT 4 +#define USBFS_POWER_PIN 7 +#define USBFS_POWER_STATE_ON 0 + +#define USBHS_POWER_PORT 4 +#define USBHS_POWER_PIN 9 +#define USBHS_POWER_STATE_ON 0 + // XTAL //#define XTAL0_CLK_HZ (16 * 1000 * 1000U) diff --git a/hw/bsp/lpc54/boards/lpcxpresso54628/board.h b/hw/bsp/lpc54/boards/lpcxpresso54628/board.h index 837d26aef..5c858ed99 100644 --- a/hw/bsp/lpc54/boards/lpcxpresso54628/board.h +++ b/hw/bsp/lpc54/boards/lpcxpresso54628/board.h @@ -36,6 +36,18 @@ extern "C" { #endif +// IOCON pin mux +#define IOCON_PIO_DIGITAL_EN 0x0100u // Enables digital function +#define IOCON_PIO_FUNC0 0x00u +#define IOCON_PIO_FUNC1 0x01u // Selects pin function 1 +#define IOCON_PIO_FUNC7 0x07u // Selects pin function 7 +#define IOCON_PIO_INPFILT_OFF 0x0200u // Input filter disabled +#define IOCON_PIO_INV_DI 0x00u // Input function is not inverted +#define IOCON_PIO_MODE_INACT 0x00u // No addition pin function +#define IOCON_PIO_MODE_PULLUP 0x10u +#define IOCON_PIO_OPENDRAIN_DI 0x00u // Open drain is disabled +#define IOCON_PIO_SLEW_STANDARD 0x00u // Standard mode, output slew rate control is enabled + // LED #define LED_PORT 2 #define LED_PIN 2 diff --git a/hw/bsp/lpc54/family.c b/hw/bsp/lpc54/family.c index 7bb73afbc..3d5bb8d5a 100644 --- a/hw/bsp/lpc54/family.c +++ b/hw/bsp/lpc54/family.c @@ -41,18 +41,6 @@ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ -// IOCON pin mux -#define IOCON_PIO_DIGITAL_EN 0x80u // Enables digital function -#define IOCON_PIO_FUNC0 0x00u -#define IOCON_PIO_FUNC1 0x01u // Selects pin function 1 -#define IOCON_PIO_FUNC7 0x07u // Selects pin function 7 -#define IOCON_PIO_INPFILT_OFF 0x0100u // Input filter disabled -#define IOCON_PIO_INV_DI 0x00u // Input function is not inverted -#define IOCON_PIO_MODE_INACT 0x00u // No addition pin function -#define IOCON_PIO_MODE_PULLUP 0x10u -#define IOCON_PIO_OPENDRAIN_DI 0x00u // Open drain is disabled -#define IOCON_PIO_SLEW_STANDARD 0x00u // Standard mode, output slew rate control is enabled - // Digital pin function n enabled #define IOCON_PIO_DIG_FUNC0_EN (IOCON_PIO_DIGITAL_EN | IOCON_PIO_INPFILT_OFF | IOCON_PIO_FUNC0) #define IOCON_PIO_DIG_FUNC1_EN (IOCON_PIO_DIGITAL_EN | IOCON_PIO_INPFILT_OFF | IOCON_PIO_FUNC1) @@ -149,37 +137,71 @@ void board_init(void) { USART_Init(UART_DEV, &uart_config, 12000000); #endif - // USB - IOCON_PinMuxSet(IOCON, USB0_VBUS_PINMUX); - #if defined(FSL_FEATURE_SOC_USBHSD_COUNT) && FSL_FEATURE_SOC_USBHSD_COUNT // LPC546xx and LPC540xx has OTG 1 FS + 1 HS rhports - #if defined(BOARD_TUD_RHPORT) && BOARD_TUD_RHPORT == 0 + #if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 0) || (CFG_TUH_ENABLED && BOARD_TUH_RHPORT == 0) + /* PORT0 PIN22 configured as USB0_VBUS */ + IOCON_PinMuxSet(IOCON, USB0_VBUS_PINMUX); + // Port0 is Full Speed POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); /*< Turn on USB Phy */ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false); CLOCK_AttachClk(kFRO_HF_to_USB0_CLK); - /*According to reference manual, device mode setting has to be set by access usb host register */ - CLOCK_EnableClock(kCLOCK_Usbhsl0); /* enable usb0 host clock */ - USBFSH->PORTMODE |= USBFSH_PORTMODE_DEV_ENABLE_MASK; - CLOCK_DisableClock(kCLOCK_Usbhsl0); /* disable usb0 host clock */ - - CLOCK_EnableUsbfs0DeviceClock(kCLOCK_UsbSrcFro, CLOCK_GetFroHfFreq()); + if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 0) { + /*According to reference manual, device mode setting has to be set by access usb host register */ + CLOCK_EnableClock(kCLOCK_Usbhsl0); /* enable usb0 host clock */ + USBFSH->PORTMODE |= USBFSH_PORTMODE_DEV_ENABLE_MASK; + CLOCK_DisableClock(kCLOCK_Usbhsl0); /* disable usb0 host clock */ + + CLOCK_EnableUsbfs0DeviceClock(kCLOCK_UsbSrcFro, CLOCK_GetFroHfFreq()); + } else { + #ifdef USBFS_POWER_PORT + /* Configure USB0 Power Switch Pin */ + IOCON_PinMuxSet(IOCON, USBFS_POWER_PORT, USBFS_POWER_PIN, IOCON_PIO_DIG_FUNC0_EN); + + gpio_pin_config_t const power_pin_config = {kGPIO_DigitalOutput, USBFS_POWER_STATE_ON}; + GPIO_PinInit(GPIO, USBFS_POWER_PORT, USBFS_POWER_PIN, &power_pin_config); + #endif + CLOCK_EnableUsbfs0HostClock(kCLOCK_UsbSrcFro, CLOCK_GetFroHfFreq()); + USBFSH->PORTMODE &= ~USBFSH_PORTMODE_DEV_ENABLE_MASK; + } #endif - #if defined(BOARD_TUD_RHPORT) && BOARD_TUD_RHPORT == 1 - // Port1 is High Speed - POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); + #if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 1) || (CFG_TUH_ENABLED && BOARD_TUH_RHPORT == 1) + // Port1 is High Speed + + /* Turn on USB1 Phy */ + POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); - /*According to reference manual, device mode setting has to be set by access usb host register */ - CLOCK_EnableClock(kCLOCK_Usbh1); /* enable usb1 host clock */ + /* reset the IP to make sure it's in reset state. */ + RESET_PeripheralReset(kUSB1H_RST_SHIFT_RSTn); + RESET_PeripheralReset(kUSB1D_RST_SHIFT_RSTn); + RESET_PeripheralReset(kUSB1RAM_RST_SHIFT_RSTn); + + if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 1) { + /* According to reference manual, device mode setting has to be set by access usb host register */ + CLOCK_EnableClock(kCLOCK_Usbh1); // enable usb0 host clock + + USBHSH->PORTMODE = USBHSH_PORTMODE_SW_PDCOM_MASK; // Put PHY powerdown under software control USBHSH->PORTMODE |= USBHSH_PORTMODE_DEV_ENABLE_MASK; - CLOCK_DisableClock(kCLOCK_Usbh1); /* enable usb1 host clock */ + CLOCK_DisableClock(kCLOCK_Usbh1); // disable usb0 host clock + /* enable USB Device clock */ CLOCK_EnableUsbhs0DeviceClock(kCLOCK_UsbSrcUsbPll, 0U); + } else { + #ifdef USBHS_POWER_PORT + /* Configure USB1 Power Switch Pin */ + IOCON_PinMuxSet(IOCON, USBHS_POWER_PORT, USBHS_POWER_PIN, IOCON_PIO_DIG_FUNC0_EN); + + gpio_pin_config_t const power_pin_config = {kGPIO_DigitalOutput, USBHS_POWER_STATE_ON}; + GPIO_PinInit(GPIO, USBHS_POWER_PORT, USBHS_POWER_PIN, &power_pin_config); + #endif + CLOCK_EnableUsbhs0HostClock(kCLOCK_UsbSrcUsbPll, 0U); + } #endif #else + IOCON_PinMuxSet(IOCON, USB0_VBUS_PINMUX); // LPC5411x series only has full speed device POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); // Turn on USB Phy CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcFro, CLOCK_GetFreq(kCLOCK_FroHf)); /* enable USB IP clock */ diff --git a/hw/bsp/lpc54/family.cmake b/hw/bsp/lpc54/family.cmake index c6145bd41..ebc0689fd 100644 --- a/hw/bsp/lpc54/family.cmake +++ b/hw/bsp/lpc54/family.cmake @@ -12,13 +12,29 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOL set(FAMILY_MCUS LPC54 CACHE INTERNAL "") -if (NOT DEFINED PORT) - set(PORT 0) -endif() +# ---------------------- +# Port & Speed Selection +# ---------------------- -# Host port will be the other port if available -set(HOST_PORT $) +# default device port to USB1 highspeed, host to USB0 fullspeed +if (NOT DEFINED RHPORT_DEVICE) + set(RHPORT_DEVICE 1) +endif () +if (NOT DEFINED RHPORT_HOST) + set(RHPORT_HOST 1) +endif () + +# port 0 is fullspeed, port 1 is highspeed +set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED) + +if (NOT DEFINED RHPORT_DEVICE_SPEED) + list(GET RHPORT_SPEED ${RHPORT_DEVICE} RHPORT_DEVICE_SPEED) +endif () +if (NOT DEFINED RHPORT_HOST_SPEED) + list(GET RHPORT_SPEED ${RHPORT_HOST} RHPORT_HOST_SPEED) +endif () +cmake_print_variables(RHPORT_DEVICE RHPORT_DEVICE_SPEED RHPORT_HOST RHPORT_HOST_SPEED) #------------------------------------ # Startup & Linker script #------------------------------------ @@ -26,11 +42,20 @@ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) + if (NOT DEFINED STARTUP_FILE_GNU) set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) +if (NOT DEFINED LD_FILE_IAR) + set(LD_FILE_IAR ${CMAKE_CURRENT_LIST_DIR}/iar/${MCU_CORE}_flash.icf) +endif () + +if (NOT DEFINED STARTUP_FILE_IAR) + set(STARTUP_FILE_IAR ${CMAKE_CURRENT_LIST_DIR}/iar/startup_${MCU_CORE}.s) +endif () + #------------------------------------ # Board Target #------------------------------------ @@ -64,24 +89,23 @@ function(family_add_board BOARD_TARGET) ) target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\) - BOARD_TUD_RHPORT=${PORT} - BOARD_TUH_RHPORT=${HOST_PORT} + BOARD_TUD_RHPORT=${RHPORT_DEVICE} + BOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} + BOARD_TUH_RHPORT=${RHPORT_HOST} + BOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} __STARTUP_CLEAR_BSS ) - # Port 0 is Fullspeed, Port 1 is Highspeed. Port1 controller can only access USB_SRAM - if (PORT EQUAL 1) + # Port 0 is Fullspeed, Port 1 is Highspeed. Port1 controller can only access USB_SRAM + if (RHPORT_DEVICE EQUAL 1) target_compile_definitions(${BOARD_TARGET} PUBLIC - BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED - BOARD_TUH_MAX_SPEED=OPT_MODE_FULL_SPEED - CFG_TUD_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\) + [=[CFG_TUD_MEM_SECTION=__attribute__((section("m_usb_global")))]=] ) - else () + endif () + if (RHPORT_HOST EQUAL 1) target_compile_definitions(${BOARD_TARGET} PUBLIC - BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED - BOARD_TUH_MAX_SPEED=OPT_MODE_HIGH_SPEED - CFG_TUH_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\) - #CFG_TUD_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\) + [=[CFG_TUH_MEM_SECTION=__attribute__((section("m_usb_global")))]=] + CFG_TUH_USBIP_IP3516=1 ) endif () @@ -107,11 +131,23 @@ function(family_configure_example TARGET RTOS) ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) + if (RHPORT_HOST EQUAL 0) + target_sources(${TARGET} PUBLIC + ${TOP}/src/portable/ohci/ohci.c + ) + elseif (RHPORT_HOST EQUAL 1) + target_sources(${TARGET} PUBLIC + ${TOP}/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c + ) + endif () + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs -nostartfiles + "LINKER:--defsym=__stack_size__=0x1000" + "LINKER:--defsym=__heap_size__=0" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC @@ -120,6 +156,8 @@ function(family_configure_example TARGET RTOS) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" + "LINKER:--config_def=__stack_size__=0x1000" + "LINKER:--config_def=__heap_size__=0" ) endif () diff --git a/hw/bsp/lpc54/iar/LPC54608_flash.icf b/hw/bsp/lpc54/iar/LPC54608_flash.icf new file mode 100644 index 000000000..2a7885541 --- /dev/null +++ b/hw/bsp/lpc54/iar/LPC54608_flash.icf @@ -0,0 +1,85 @@ +/* +** ################################################################### +** Processors: LPC54608J512BD208 +** LPC54608J512ET180 +** +** Compiler: IAR ANSI C/C++ Compiler for ARM +** Reference manual: LPC546xx User manual Rev.1.9 5 June 2017 +** Version: rev. 1.2, 2017-06-08 +** Build: b241125 +** +** Abstract: +** Linker file for the IAR ANSI C/C++ Compiler for ARM +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2024 NXP +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** ################################################################### +*/ + +define symbol m_interrupts_start = 0x00000000; +define symbol m_interrupts_end = 0x000003FF; + +define symbol m_text_start = 0x00000400; +define symbol m_text_end = 0x0007FFFF; + +define symbol m_data_start = 0x20000000; +define symbol m_data_end = 0x20027FFF; + +define symbol m_usb_sram_start = 0x40100000; +define symbol m_usb_sram_end = 0x40101FFF; + +/* USB BDT size */ +define symbol usb_bdt_size = 0x0; +/* Sizes */ +if (isdefinedsymbol(__stack_size__)) { + define symbol __size_cstack__ = __stack_size__; +} else { + define symbol __size_cstack__ = 0x0400; +} + +if (isdefinedsymbol(__heap_size__)) { + define symbol __size_heap__ = __heap_size__; +} else { + define symbol __size_heap__ = 0x0400; +} + + +define memory mem with size = 4G; +define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end] + | mem:[from m_text_start to m_text_end]; +define region DATA_region = mem:[from m_data_start to m_data_end-__size_cstack__]; +define region CSTACK_region = mem:[from m_data_end-__size_cstack__+1 to m_data_end]; + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; +define block RW { readwrite }; +define block ZI { zi }; + +/* regions for USB */ +define region USB_BDT_region = mem:[from m_usb_sram_start to m_usb_sram_start + usb_bdt_size - 1]; +define region USB_SRAM_region = mem:[from m_usb_sram_start + usb_bdt_size to m_usb_sram_end]; +place in USB_BDT_region { section m_usb_bdt }; +place in USB_SRAM_region { section m_usb_global }; + +initialize by copy { readwrite, section .textrw }; + +if (isdefinedsymbol(__USE_DLIB_PERTHREAD)) +{ + /* Required in a multi-threaded application */ + initialize by copy with packing = none { section __DLIB_PERTHREAD }; +} + +do not initialize { section .noinit, section m_usb_bdt, section m_usb_global }; + +place at address mem: m_interrupts_start { readonly section .intvec }; +place in TEXT_region { readonly }; +place in DATA_region { block RW }; +place in DATA_region { block ZI }; +place in DATA_region { last block HEAP }; +place in CSTACK_region { block CSTACK }; + diff --git a/hw/bsp/lpc54/iar/LPC54628_flash.icf b/hw/bsp/lpc54/iar/LPC54628_flash.icf new file mode 100644 index 000000000..7cca18159 --- /dev/null +++ b/hw/bsp/lpc54/iar/LPC54628_flash.icf @@ -0,0 +1,83 @@ +/* +** ################################################################### +** Processor: LPC54628J512ET180 +** Compiler: IAR ANSI C/C++ Compiler for ARM +** Reference manual: LPC546xx User manual Rev.1.9 5 June 2017 +** Version: rev. 1.2, 2017-06-08 +** Build: b241125 +** +** Abstract: +** Linker file for the IAR ANSI C/C++ Compiler for ARM +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2024 NXP +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** ################################################################### +*/ + +define symbol m_interrupts_start = 0x00000000; +define symbol m_interrupts_end = 0x000003FF; + +define symbol m_text_start = 0x00000400; +define symbol m_text_end = 0x0007FFFF; + +define symbol m_data_start = 0x20000000; +define symbol m_data_end = 0x20027FFF; + +define symbol m_usb_sram_start = 0x40100000; +define symbol m_usb_sram_end = 0x40101FFF; + +/* USB BDT size */ +define symbol usb_bdt_size = 0x0; +/* Sizes */ +if (isdefinedsymbol(__stack_size__)) { + define symbol __size_cstack__ = __stack_size__; +} else { + define symbol __size_cstack__ = 0x0400; +} + +if (isdefinedsymbol(__heap_size__)) { + define symbol __size_heap__ = __heap_size__; +} else { + define symbol __size_heap__ = 0x0400; +} + + +define memory mem with size = 4G; +define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end] + | mem:[from m_text_start to m_text_end]; +define region DATA_region = mem:[from m_data_start to m_data_end-__size_cstack__]; +define region CSTACK_region = mem:[from m_data_end-__size_cstack__+1 to m_data_end]; + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; +define block RW { readwrite }; +define block ZI { zi }; + +/* regions for USB */ +define region USB_BDT_region = mem:[from m_usb_sram_start to m_usb_sram_start + usb_bdt_size - 1]; +define region USB_SRAM_region = mem:[from m_usb_sram_start + usb_bdt_size to m_usb_sram_end]; +place in USB_BDT_region { section m_usb_bdt }; +place in USB_SRAM_region { section m_usb_global }; + +initialize by copy { readwrite, section .textrw }; + +if (isdefinedsymbol(__USE_DLIB_PERTHREAD)) +{ + /* Required in a multi-threaded application */ + initialize by copy with packing = none { section __DLIB_PERTHREAD }; +} + +do not initialize { section .noinit, section m_usb_bdt, section m_usb_global }; + +place at address mem: m_interrupts_start { readonly section .intvec }; +place in TEXT_region { readonly }; +place in DATA_region { block RW }; +place in DATA_region { block ZI }; +place in DATA_region { last block HEAP }; +place in CSTACK_region { block CSTACK }; + diff --git a/hw/bsp/lpc54/iar/startup_LPC54608.s b/hw/bsp/lpc54/iar/startup_LPC54608.s new file mode 100644 index 000000000..05c4350e5 --- /dev/null +++ b/hw/bsp/lpc54/iar/startup_LPC54608.s @@ -0,0 +1,654 @@ +; ------------------------------------------------------------------------- +; @file: startup_LPC54608.s +; @purpose: CMSIS Cortex-M4 Core Device Startup File +; LPC54608 +; @version: 2.0 +; @date: 2024-10-29 +; @build: b250521 +; ------------------------------------------------------------------------- +; +; Copyright 1997-2016 Freescale Semiconductor, Inc. +; Copyright 2016-2025 NXP +; SPDX-License-Identifier: BSD-3-Clause +; +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. +; +; Cortex-M version +; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + PUBLIC __vector_table_0x1c + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA + +__iar_init$$done: ; The vector table is not needed + ; until after copy initialization is done + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler + + DCD NMI_Handler ;NMI Handler + DCD HardFault_Handler ;Hard Fault Handler + DCD MemManage_Handler ;MPU Fault Handler + DCD BusFault_Handler ;Bus Fault Handler + DCD UsageFault_Handler ;Usage Fault Handler +__vector_table_0x1c + DCD 0 ;Reserved + DCD 0xFFFFFFFF ;ECRP + DCD 0 ;Reserved + DCD 0 ;Reserved + DCD SVC_Handler ;SVCall Handler + DCD DebugMon_Handler ;Debug Monitor Handler + DCD 0 ;Reserved + DCD PendSV_Handler ;PendSV Handler + DCD SysTick_Handler ;SysTick Handler + + ;External Interrupts + DCD WDT_BOD_IRQHandler ;Windowed watchdog timer, Brownout detect + DCD DMA0_IRQHandler ;DMA controller + DCD GINT0_IRQHandler ;GPIO group 0 + DCD GINT1_IRQHandler ;GPIO group 1 + DCD PIN_INT0_IRQHandler ;Pin interrupt 0 or pattern match engine slice 0 + DCD PIN_INT1_IRQHandler ;Pin interrupt 1or pattern match engine slice 1 + DCD PIN_INT2_IRQHandler ;Pin interrupt 2 or pattern match engine slice 2 + DCD PIN_INT3_IRQHandler ;Pin interrupt 3 or pattern match engine slice 3 + DCD UTICK0_IRQHandler ;Micro-tick Timer + DCD MRT0_IRQHandler ;Multi-rate timer + DCD CTIMER0_IRQHandler ;Standard counter/timer CTIMER0 + DCD CTIMER1_IRQHandler ;Standard counter/timer CTIMER1 + DCD SCT0_IRQHandler ;SCTimer/PWM + DCD CTIMER3_IRQHandler ;Standard counter/timer CTIMER3 + DCD FLEXCOMM0_IRQHandler ;Flexcomm Interface 0 (USART, SPI, I2C, FLEXCOMM) + DCD FLEXCOMM1_IRQHandler ;Flexcomm Interface 1 (USART, SPI, I2C, FLEXCOMM) + DCD FLEXCOMM2_IRQHandler ;Flexcomm Interface 2 (USART, SPI, I2C, FLEXCOMM) + DCD FLEXCOMM3_IRQHandler ;Flexcomm Interface 3 (USART, SPI, I2C, FLEXCOMM) + DCD FLEXCOMM4_IRQHandler ;Flexcomm Interface 4 (USART, SPI, I2C, FLEXCOMM) + DCD FLEXCOMM5_IRQHandler ;Flexcomm Interface 5 (USART, SPI, I2C,, FLEXCOMM) + DCD FLEXCOMM6_IRQHandler ;Flexcomm Interface 6 (USART, SPI, I2C, I2S,, FLEXCOMM) + DCD FLEXCOMM7_IRQHandler ;Flexcomm Interface 7 (USART, SPI, I2C, I2S,, FLEXCOMM) + DCD ADC0_SEQA_IRQHandler ;ADC0 sequence A completion. + DCD ADC0_SEQB_IRQHandler ;ADC0 sequence B completion. + DCD ADC0_THCMP_IRQHandler ;ADC0 threshold compare and error. + DCD DMIC0_IRQHandler ;Digital microphone and DMIC subsystem + DCD HWVAD0_IRQHandler ;Hardware Voice Activity Detector + DCD USB0_NEEDCLK_IRQHandler ;USB Activity Wake-up Interrupt + DCD USB0_IRQHandler ;USB device + DCD RTC_IRQHandler ;RTC alarm and wake-up interrupts + DCD Reserved46_IRQHandler ;Reserved interrupt + DCD Reserved47_IRQHandler ;Reserved interrupt + DCD PIN_INT4_IRQHandler ;Pin interrupt 4 or pattern match engine slice 4 int + DCD PIN_INT5_IRQHandler ;Pin interrupt 5 or pattern match engine slice 5 int + DCD PIN_INT6_IRQHandler ;Pin interrupt 6 or pattern match engine slice 6 int + DCD PIN_INT7_IRQHandler ;Pin interrupt 7 or pattern match engine slice 7 int + DCD CTIMER2_IRQHandler ;Standard counter/timer CTIMER2 + DCD CTIMER4_IRQHandler ;Standard counter/timer CTIMER4 + DCD RIT_IRQHandler ;Repetitive Interrupt Timer + DCD SPIFI0_IRQHandler ;SPI flash interface + DCD FLEXCOMM8_IRQHandler ;Flexcomm Interface 8 (USART, SPI, I2C, FLEXCOMM) + DCD FLEXCOMM9_IRQHandler ;Flexcomm Interface 9 (USART, SPI, I2C, FLEXCOMM) + DCD SDIO_IRQHandler ;SD/MMC + DCD CAN0_IRQ0_IRQHandler ;CAN0 interrupt0 + DCD CAN0_IRQ1_IRQHandler ;CAN0 interrupt1 + DCD CAN1_IRQ0_IRQHandler ;CAN1 interrupt0 + DCD CAN1_IRQ1_IRQHandler ;CAN1 interrupt1 + DCD USB1_IRQHandler ;USB1 interrupt + DCD USB1_NEEDCLK_IRQHandler ;USB1 activity + DCD ETHERNET_IRQHandler ;Ethernet + DCD ETHERNET_PMT_IRQHandler ;Ethernet power management interrupt + DCD ETHERNET_MACLP_IRQHandler ;Ethernet MAC interrupt + DCD EEPROM_IRQHandler ;EEPROM interrupt + DCD LCD_IRQHandler ;LCD interrupt + DCD SHA_IRQHandler ;SHA interrupt + DCD SMARTCARD0_IRQHandler ;Smart card 0 interrupt + DCD SMARTCARD1_IRQHandler ;Smart card 1 interrupt +__Vectors_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Reset_Handler + MOVS r0,#56 + LDR r1, =0x40000220 + STR r0, [r1] ;Enable SRAM clock used by Stack + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B . + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B . + + PUBWEAK MemManage_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +MemManage_Handler + B . + + PUBWEAK BusFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +BusFault_Handler + B . + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +UsageFault_Handler + B . + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B . + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +DebugMon_Handler + B . + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B . + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B . + + PUBWEAK WDT_BOD_IRQHandler + PUBWEAK WDT_BOD_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +WDT_BOD_IRQHandler + LDR R0, =WDT_BOD_DriverIRQHandler + BX R0 + + PUBWEAK DMA0_IRQHandler + PUBWEAK DMA0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA0_IRQHandler + LDR R0, =DMA0_DriverIRQHandler + BX R0 + + PUBWEAK GINT0_IRQHandler + PUBWEAK GINT0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +GINT0_IRQHandler + LDR R0, =GINT0_DriverIRQHandler + BX R0 + + PUBWEAK GINT1_IRQHandler + PUBWEAK GINT1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +GINT1_IRQHandler + LDR R0, =GINT1_DriverIRQHandler + BX R0 + + PUBWEAK PIN_INT0_IRQHandler + PUBWEAK PIN_INT0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +PIN_INT0_IRQHandler + LDR R0, =PIN_INT0_DriverIRQHandler + BX R0 + + PUBWEAK PIN_INT1_IRQHandler + PUBWEAK PIN_INT1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +PIN_INT1_IRQHandler + LDR R0, =PIN_INT1_DriverIRQHandler + BX R0 + + PUBWEAK PIN_INT2_IRQHandler + PUBWEAK PIN_INT2_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +PIN_INT2_IRQHandler + LDR R0, =PIN_INT2_DriverIRQHandler + BX R0 + + PUBWEAK PIN_INT3_IRQHandler + PUBWEAK PIN_INT3_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +PIN_INT3_IRQHandler + LDR R0, =PIN_INT3_DriverIRQHandler + BX R0 + + PUBWEAK UTICK0_IRQHandler + PUBWEAK UTICK0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +UTICK0_IRQHandler + LDR R0, =UTICK0_DriverIRQHandler + BX R0 + + PUBWEAK MRT0_IRQHandler + PUBWEAK MRT0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +MRT0_IRQHandler + LDR R0, =MRT0_DriverIRQHandler + BX R0 + + PUBWEAK CTIMER0_IRQHandler + PUBWEAK CTIMER0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CTIMER0_IRQHandler + LDR R0, =CTIMER0_DriverIRQHandler + BX R0 + + PUBWEAK CTIMER1_IRQHandler + PUBWEAK CTIMER1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CTIMER1_IRQHandler + LDR R0, =CTIMER1_DriverIRQHandler + BX R0 + + PUBWEAK SCT0_IRQHandler + PUBWEAK SCT0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SCT0_IRQHandler + LDR R0, =SCT0_DriverIRQHandler + BX R0 + + PUBWEAK CTIMER3_IRQHandler + PUBWEAK CTIMER3_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CTIMER3_IRQHandler + LDR R0, =CTIMER3_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM0_IRQHandler + PUBWEAK FLEXCOMM0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM0_IRQHandler + LDR R0, =FLEXCOMM0_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM1_IRQHandler + PUBWEAK FLEXCOMM1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM1_IRQHandler + LDR R0, =FLEXCOMM1_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM2_IRQHandler + PUBWEAK FLEXCOMM2_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM2_IRQHandler + LDR R0, =FLEXCOMM2_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM3_IRQHandler + PUBWEAK FLEXCOMM3_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM3_IRQHandler + LDR R0, =FLEXCOMM3_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM4_IRQHandler + PUBWEAK FLEXCOMM4_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM4_IRQHandler + LDR R0, =FLEXCOMM4_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM5_IRQHandler + PUBWEAK FLEXCOMM5_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM5_IRQHandler + LDR R0, =FLEXCOMM5_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM6_IRQHandler + PUBWEAK FLEXCOMM6_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM6_IRQHandler + LDR R0, =FLEXCOMM6_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM7_IRQHandler + PUBWEAK FLEXCOMM7_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM7_IRQHandler + LDR R0, =FLEXCOMM7_DriverIRQHandler + BX R0 + + PUBWEAK ADC0_SEQA_IRQHandler + PUBWEAK ADC0_SEQA_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +ADC0_SEQA_IRQHandler + LDR R0, =ADC0_SEQA_DriverIRQHandler + BX R0 + + PUBWEAK ADC0_SEQB_IRQHandler + PUBWEAK ADC0_SEQB_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +ADC0_SEQB_IRQHandler + LDR R0, =ADC0_SEQB_DriverIRQHandler + BX R0 + + PUBWEAK ADC0_THCMP_IRQHandler + PUBWEAK ADC0_THCMP_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +ADC0_THCMP_IRQHandler + LDR R0, =ADC0_THCMP_DriverIRQHandler + BX R0 + + PUBWEAK DMIC0_IRQHandler + PUBWEAK DMIC0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMIC0_IRQHandler + LDR R0, =DMIC0_DriverIRQHandler + BX R0 + + PUBWEAK HWVAD0_IRQHandler + PUBWEAK HWVAD0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +HWVAD0_IRQHandler + LDR R0, =HWVAD0_DriverIRQHandler + BX R0 + + PUBWEAK USB0_NEEDCLK_IRQHandler + PUBWEAK USB0_NEEDCLK_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +USB0_NEEDCLK_IRQHandler + LDR R0, =USB0_NEEDCLK_DriverIRQHandler + BX R0 + + PUBWEAK USB0_IRQHandler + PUBWEAK USB0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +USB0_IRQHandler + LDR R0, =USB0_DriverIRQHandler + BX R0 + + PUBWEAK RTC_IRQHandler + PUBWEAK RTC_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +RTC_IRQHandler + LDR R0, =RTC_DriverIRQHandler + BX R0 + + PUBWEAK Reserved46_IRQHandler + PUBWEAK Reserved46_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +Reserved46_IRQHandler + LDR R0, =Reserved46_DriverIRQHandler + BX R0 + + PUBWEAK Reserved47_IRQHandler + PUBWEAK Reserved47_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +Reserved47_IRQHandler + LDR R0, =Reserved47_DriverIRQHandler + BX R0 + + PUBWEAK PIN_INT4_IRQHandler + PUBWEAK PIN_INT4_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +PIN_INT4_IRQHandler + LDR R0, =PIN_INT4_DriverIRQHandler + BX R0 + + PUBWEAK PIN_INT5_IRQHandler + PUBWEAK PIN_INT5_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +PIN_INT5_IRQHandler + LDR R0, =PIN_INT5_DriverIRQHandler + BX R0 + + PUBWEAK PIN_INT6_IRQHandler + PUBWEAK PIN_INT6_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +PIN_INT6_IRQHandler + LDR R0, =PIN_INT6_DriverIRQHandler + BX R0 + + PUBWEAK PIN_INT7_IRQHandler + PUBWEAK PIN_INT7_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +PIN_INT7_IRQHandler + LDR R0, =PIN_INT7_DriverIRQHandler + BX R0 + + PUBWEAK CTIMER2_IRQHandler + PUBWEAK CTIMER2_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CTIMER2_IRQHandler + LDR R0, =CTIMER2_DriverIRQHandler + BX R0 + + PUBWEAK CTIMER4_IRQHandler + PUBWEAK CTIMER4_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CTIMER4_IRQHandler + LDR R0, =CTIMER4_DriverIRQHandler + BX R0 + + PUBWEAK RIT_IRQHandler + PUBWEAK RIT_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +RIT_IRQHandler + LDR R0, =RIT_DriverIRQHandler + BX R0 + + PUBWEAK SPIFI0_IRQHandler + PUBWEAK SPIFI0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SPIFI0_IRQHandler + LDR R0, =SPIFI0_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM8_IRQHandler + PUBWEAK FLEXCOMM8_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM8_IRQHandler + LDR R0, =FLEXCOMM8_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM9_IRQHandler + PUBWEAK FLEXCOMM9_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM9_IRQHandler + LDR R0, =FLEXCOMM9_DriverIRQHandler + BX R0 + + PUBWEAK SDIO_IRQHandler + PUBWEAK SDIO_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SDIO_IRQHandler + LDR R0, =SDIO_DriverIRQHandler + BX R0 + + PUBWEAK CAN0_IRQ0_IRQHandler + PUBWEAK CAN0_IRQ0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CAN0_IRQ0_IRQHandler + LDR R0, =CAN0_IRQ0_DriverIRQHandler + BX R0 + + PUBWEAK CAN0_IRQ1_IRQHandler + PUBWEAK CAN0_IRQ1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CAN0_IRQ1_IRQHandler + LDR R0, =CAN0_IRQ1_DriverIRQHandler + BX R0 + + PUBWEAK CAN1_IRQ0_IRQHandler + PUBWEAK CAN1_IRQ0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CAN1_IRQ0_IRQHandler + LDR R0, =CAN1_IRQ0_DriverIRQHandler + BX R0 + + PUBWEAK CAN1_IRQ1_IRQHandler + PUBWEAK CAN1_IRQ1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CAN1_IRQ1_IRQHandler + LDR R0, =CAN1_IRQ1_DriverIRQHandler + BX R0 + + PUBWEAK USB1_IRQHandler + PUBWEAK USB1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +USB1_IRQHandler + LDR R0, =USB1_DriverIRQHandler + BX R0 + + PUBWEAK USB1_NEEDCLK_IRQHandler + PUBWEAK USB1_NEEDCLK_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +USB1_NEEDCLK_IRQHandler + LDR R0, =USB1_NEEDCLK_DriverIRQHandler + BX R0 + + PUBWEAK ETHERNET_IRQHandler + PUBWEAK ETHERNET_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +ETHERNET_IRQHandler + LDR R0, =ETHERNET_DriverIRQHandler + BX R0 + + PUBWEAK ETHERNET_PMT_IRQHandler + PUBWEAK ETHERNET_PMT_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +ETHERNET_PMT_IRQHandler + LDR R0, =ETHERNET_PMT_DriverIRQHandler + BX R0 + + PUBWEAK ETHERNET_MACLP_IRQHandler + PUBWEAK ETHERNET_MACLP_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +ETHERNET_MACLP_IRQHandler + LDR R0, =ETHERNET_MACLP_DriverIRQHandler + BX R0 + + PUBWEAK EEPROM_IRQHandler + PUBWEAK EEPROM_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +EEPROM_IRQHandler + LDR R0, =EEPROM_DriverIRQHandler + BX R0 + + PUBWEAK LCD_IRQHandler + PUBWEAK LCD_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +LCD_IRQHandler + LDR R0, =LCD_DriverIRQHandler + BX R0 + + PUBWEAK SHA_IRQHandler + PUBWEAK SHA_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SHA_IRQHandler + LDR R0, =SHA_DriverIRQHandler + BX R0 + + PUBWEAK SMARTCARD0_IRQHandler + PUBWEAK SMARTCARD0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SMARTCARD0_IRQHandler + LDR R0, =SMARTCARD0_DriverIRQHandler + BX R0 + + PUBWEAK SMARTCARD1_IRQHandler + PUBWEAK SMARTCARD1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SMARTCARD1_IRQHandler + LDR R0, =SMARTCARD1_DriverIRQHandler + BX R0 + +WDT_BOD_DriverIRQHandler +DMA0_DriverIRQHandler +GINT0_DriverIRQHandler +GINT1_DriverIRQHandler +PIN_INT0_DriverIRQHandler +PIN_INT1_DriverIRQHandler +PIN_INT2_DriverIRQHandler +PIN_INT3_DriverIRQHandler +UTICK0_DriverIRQHandler +MRT0_DriverIRQHandler +CTIMER0_DriverIRQHandler +CTIMER1_DriverIRQHandler +SCT0_DriverIRQHandler +CTIMER3_DriverIRQHandler +FLEXCOMM0_DriverIRQHandler +FLEXCOMM1_DriverIRQHandler +FLEXCOMM2_DriverIRQHandler +FLEXCOMM3_DriverIRQHandler +FLEXCOMM4_DriverIRQHandler +FLEXCOMM5_DriverIRQHandler +FLEXCOMM6_DriverIRQHandler +FLEXCOMM7_DriverIRQHandler +ADC0_SEQA_DriverIRQHandler +ADC0_SEQB_DriverIRQHandler +ADC0_THCMP_DriverIRQHandler +DMIC0_DriverIRQHandler +HWVAD0_DriverIRQHandler +USB0_NEEDCLK_DriverIRQHandler +USB0_DriverIRQHandler +RTC_DriverIRQHandler +Reserved46_DriverIRQHandler +Reserved47_DriverIRQHandler +PIN_INT4_DriverIRQHandler +PIN_INT5_DriverIRQHandler +PIN_INT6_DriverIRQHandler +PIN_INT7_DriverIRQHandler +CTIMER2_DriverIRQHandler +CTIMER4_DriverIRQHandler +RIT_DriverIRQHandler +SPIFI0_DriverIRQHandler +FLEXCOMM8_DriverIRQHandler +FLEXCOMM9_DriverIRQHandler +SDIO_DriverIRQHandler +CAN0_IRQ0_DriverIRQHandler +CAN0_IRQ1_DriverIRQHandler +CAN1_IRQ0_DriverIRQHandler +CAN1_IRQ1_DriverIRQHandler +USB1_DriverIRQHandler +USB1_NEEDCLK_DriverIRQHandler +ETHERNET_DriverIRQHandler +ETHERNET_PMT_DriverIRQHandler +ETHERNET_MACLP_DriverIRQHandler +EEPROM_DriverIRQHandler +LCD_DriverIRQHandler +SHA_DriverIRQHandler +SMARTCARD0_DriverIRQHandler +SMARTCARD1_DriverIRQHandler +DefaultISR + B . + + END diff --git a/hw/bsp/lpc54/iar/startup_LPC54628.s b/hw/bsp/lpc54/iar/startup_LPC54628.s new file mode 100644 index 000000000..fec5f7fca --- /dev/null +++ b/hw/bsp/lpc54/iar/startup_LPC54628.s @@ -0,0 +1,654 @@ +; ------------------------------------------------------------------------- +; @file: startup_LPC54628.s +; @purpose: CMSIS Cortex-M4 Core Device Startup File +; LPC54628 +; @version: 2.0 +; @date: 2024-10-29 +; @build: b250521 +; ------------------------------------------------------------------------- +; +; Copyright 1997-2016 Freescale Semiconductor, Inc. +; Copyright 2016-2025 NXP +; SPDX-License-Identifier: BSD-3-Clause +; +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. +; +; Cortex-M version +; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + PUBLIC __vector_table_0x1c + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA + +__iar_init$$done: ; The vector table is not needed + ; until after copy initialization is done + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler + + DCD NMI_Handler ;NMI Handler + DCD HardFault_Handler ;Hard Fault Handler + DCD MemManage_Handler ;MPU Fault Handler + DCD BusFault_Handler ;Bus Fault Handler + DCD UsageFault_Handler ;Usage Fault Handler +__vector_table_0x1c + DCD 0 ;Reserved + DCD 0xFFFFFFFF ;ECRP + DCD 0 ;Reserved + DCD 0 ;Reserved + DCD SVC_Handler ;SVCall Handler + DCD DebugMon_Handler ;Debug Monitor Handler + DCD 0 ;Reserved + DCD PendSV_Handler ;PendSV Handler + DCD SysTick_Handler ;SysTick Handler + + ;External Interrupts + DCD WDT_BOD_IRQHandler ;Windowed watchdog timer, Brownout detect + DCD DMA0_IRQHandler ;DMA controller + DCD GINT0_IRQHandler ;GPIO group 0 + DCD GINT1_IRQHandler ;GPIO group 1 + DCD PIN_INT0_IRQHandler ;Pin interrupt 0 or pattern match engine slice 0 + DCD PIN_INT1_IRQHandler ;Pin interrupt 1or pattern match engine slice 1 + DCD PIN_INT2_IRQHandler ;Pin interrupt 2 or pattern match engine slice 2 + DCD PIN_INT3_IRQHandler ;Pin interrupt 3 or pattern match engine slice 3 + DCD UTICK0_IRQHandler ;Micro-tick Timer + DCD MRT0_IRQHandler ;Multi-rate timer + DCD CTIMER0_IRQHandler ;Standard counter/timer CTIMER0 + DCD CTIMER1_IRQHandler ;Standard counter/timer CTIMER1 + DCD SCT0_IRQHandler ;SCTimer/PWM + DCD CTIMER3_IRQHandler ;Standard counter/timer CTIMER3 + DCD FLEXCOMM0_IRQHandler ;Flexcomm Interface 0 (USART, SPI, I2C, FLEXCOMM) + DCD FLEXCOMM1_IRQHandler ;Flexcomm Interface 1 (USART, SPI, I2C, FLEXCOMM) + DCD FLEXCOMM2_IRQHandler ;Flexcomm Interface 2 (USART, SPI, I2C, FLEXCOMM) + DCD FLEXCOMM3_IRQHandler ;Flexcomm Interface 3 (USART, SPI, I2C, FLEXCOMM) + DCD FLEXCOMM4_IRQHandler ;Flexcomm Interface 4 (USART, SPI, I2C, FLEXCOMM) + DCD FLEXCOMM5_IRQHandler ;Flexcomm Interface 5 (USART, SPI, I2C,, FLEXCOMM) + DCD FLEXCOMM6_IRQHandler ;Flexcomm Interface 6 (USART, SPI, I2C, I2S,, FLEXCOMM) + DCD FLEXCOMM7_IRQHandler ;Flexcomm Interface 7 (USART, SPI, I2C, I2S,, FLEXCOMM) + DCD ADC0_SEQA_IRQHandler ;ADC0 sequence A completion. + DCD ADC0_SEQB_IRQHandler ;ADC0 sequence B completion. + DCD ADC0_THCMP_IRQHandler ;ADC0 threshold compare and error. + DCD DMIC0_IRQHandler ;Digital microphone and DMIC subsystem + DCD HWVAD0_IRQHandler ;Hardware Voice Activity Detector + DCD USB0_NEEDCLK_IRQHandler ;USB Activity Wake-up Interrupt + DCD USB0_IRQHandler ;USB device + DCD RTC_IRQHandler ;RTC alarm and wake-up interrupts + DCD Reserved46_IRQHandler ;Reserved interrupt + DCD Reserved47_IRQHandler ;Reserved interrupt + DCD PIN_INT4_IRQHandler ;Pin interrupt 4 or pattern match engine slice 4 int + DCD PIN_INT5_IRQHandler ;Pin interrupt 5 or pattern match engine slice 5 int + DCD PIN_INT6_IRQHandler ;Pin interrupt 6 or pattern match engine slice 6 int + DCD PIN_INT7_IRQHandler ;Pin interrupt 7 or pattern match engine slice 7 int + DCD CTIMER2_IRQHandler ;Standard counter/timer CTIMER2 + DCD CTIMER4_IRQHandler ;Standard counter/timer CTIMER4 + DCD RIT_IRQHandler ;Repetitive Interrupt Timer + DCD SPIFI0_IRQHandler ;SPI flash interface + DCD FLEXCOMM8_IRQHandler ;Flexcomm Interface 8 (USART, SPI, I2C, FLEXCOMM) + DCD FLEXCOMM9_IRQHandler ;Flexcomm Interface 9 (USART, SPI, I2C, FLEXCOMM) + DCD SDIO_IRQHandler ;SD/MMC + DCD CAN0_IRQ0_IRQHandler ;CAN0 interrupt0 + DCD CAN0_IRQ1_IRQHandler ;CAN0 interrupt1 + DCD CAN1_IRQ0_IRQHandler ;CAN1 interrupt0 + DCD CAN1_IRQ1_IRQHandler ;CAN1 interrupt1 + DCD USB1_IRQHandler ;USB1 interrupt + DCD USB1_NEEDCLK_IRQHandler ;USB1 activity + DCD ETHERNET_IRQHandler ;Ethernet + DCD ETHERNET_PMT_IRQHandler ;Ethernet power management interrupt + DCD ETHERNET_MACLP_IRQHandler ;Ethernet MAC interrupt + DCD EEPROM_IRQHandler ;EEPROM interrupt + DCD LCD_IRQHandler ;LCD interrupt + DCD SHA_IRQHandler ;SHA interrupt + DCD SMARTCARD0_IRQHandler ;Smart card 0 interrupt + DCD SMARTCARD1_IRQHandler ;Smart card 1 interrupt +__Vectors_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Reset_Handler + MOVS r0,#56 + LDR r1, =0x40000220 + STR r0, [r1] ;Enable SRAM clock used by Stack + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B . + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B . + + PUBWEAK MemManage_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +MemManage_Handler + B . + + PUBWEAK BusFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +BusFault_Handler + B . + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +UsageFault_Handler + B . + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B . + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +DebugMon_Handler + B . + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B . + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B . + + PUBWEAK WDT_BOD_IRQHandler + PUBWEAK WDT_BOD_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +WDT_BOD_IRQHandler + LDR R0, =WDT_BOD_DriverIRQHandler + BX R0 + + PUBWEAK DMA0_IRQHandler + PUBWEAK DMA0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA0_IRQHandler + LDR R0, =DMA0_DriverIRQHandler + BX R0 + + PUBWEAK GINT0_IRQHandler + PUBWEAK GINT0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +GINT0_IRQHandler + LDR R0, =GINT0_DriverIRQHandler + BX R0 + + PUBWEAK GINT1_IRQHandler + PUBWEAK GINT1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +GINT1_IRQHandler + LDR R0, =GINT1_DriverIRQHandler + BX R0 + + PUBWEAK PIN_INT0_IRQHandler + PUBWEAK PIN_INT0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +PIN_INT0_IRQHandler + LDR R0, =PIN_INT0_DriverIRQHandler + BX R0 + + PUBWEAK PIN_INT1_IRQHandler + PUBWEAK PIN_INT1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +PIN_INT1_IRQHandler + LDR R0, =PIN_INT1_DriverIRQHandler + BX R0 + + PUBWEAK PIN_INT2_IRQHandler + PUBWEAK PIN_INT2_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +PIN_INT2_IRQHandler + LDR R0, =PIN_INT2_DriverIRQHandler + BX R0 + + PUBWEAK PIN_INT3_IRQHandler + PUBWEAK PIN_INT3_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +PIN_INT3_IRQHandler + LDR R0, =PIN_INT3_DriverIRQHandler + BX R0 + + PUBWEAK UTICK0_IRQHandler + PUBWEAK UTICK0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +UTICK0_IRQHandler + LDR R0, =UTICK0_DriverIRQHandler + BX R0 + + PUBWEAK MRT0_IRQHandler + PUBWEAK MRT0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +MRT0_IRQHandler + LDR R0, =MRT0_DriverIRQHandler + BX R0 + + PUBWEAK CTIMER0_IRQHandler + PUBWEAK CTIMER0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CTIMER0_IRQHandler + LDR R0, =CTIMER0_DriverIRQHandler + BX R0 + + PUBWEAK CTIMER1_IRQHandler + PUBWEAK CTIMER1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CTIMER1_IRQHandler + LDR R0, =CTIMER1_DriverIRQHandler + BX R0 + + PUBWEAK SCT0_IRQHandler + PUBWEAK SCT0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SCT0_IRQHandler + LDR R0, =SCT0_DriverIRQHandler + BX R0 + + PUBWEAK CTIMER3_IRQHandler + PUBWEAK CTIMER3_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CTIMER3_IRQHandler + LDR R0, =CTIMER3_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM0_IRQHandler + PUBWEAK FLEXCOMM0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM0_IRQHandler + LDR R0, =FLEXCOMM0_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM1_IRQHandler + PUBWEAK FLEXCOMM1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM1_IRQHandler + LDR R0, =FLEXCOMM1_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM2_IRQHandler + PUBWEAK FLEXCOMM2_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM2_IRQHandler + LDR R0, =FLEXCOMM2_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM3_IRQHandler + PUBWEAK FLEXCOMM3_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM3_IRQHandler + LDR R0, =FLEXCOMM3_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM4_IRQHandler + PUBWEAK FLEXCOMM4_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM4_IRQHandler + LDR R0, =FLEXCOMM4_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM5_IRQHandler + PUBWEAK FLEXCOMM5_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM5_IRQHandler + LDR R0, =FLEXCOMM5_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM6_IRQHandler + PUBWEAK FLEXCOMM6_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM6_IRQHandler + LDR R0, =FLEXCOMM6_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM7_IRQHandler + PUBWEAK FLEXCOMM7_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM7_IRQHandler + LDR R0, =FLEXCOMM7_DriverIRQHandler + BX R0 + + PUBWEAK ADC0_SEQA_IRQHandler + PUBWEAK ADC0_SEQA_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +ADC0_SEQA_IRQHandler + LDR R0, =ADC0_SEQA_DriverIRQHandler + BX R0 + + PUBWEAK ADC0_SEQB_IRQHandler + PUBWEAK ADC0_SEQB_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +ADC0_SEQB_IRQHandler + LDR R0, =ADC0_SEQB_DriverIRQHandler + BX R0 + + PUBWEAK ADC0_THCMP_IRQHandler + PUBWEAK ADC0_THCMP_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +ADC0_THCMP_IRQHandler + LDR R0, =ADC0_THCMP_DriverIRQHandler + BX R0 + + PUBWEAK DMIC0_IRQHandler + PUBWEAK DMIC0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMIC0_IRQHandler + LDR R0, =DMIC0_DriverIRQHandler + BX R0 + + PUBWEAK HWVAD0_IRQHandler + PUBWEAK HWVAD0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +HWVAD0_IRQHandler + LDR R0, =HWVAD0_DriverIRQHandler + BX R0 + + PUBWEAK USB0_NEEDCLK_IRQHandler + PUBWEAK USB0_NEEDCLK_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +USB0_NEEDCLK_IRQHandler + LDR R0, =USB0_NEEDCLK_DriverIRQHandler + BX R0 + + PUBWEAK USB0_IRQHandler + PUBWEAK USB0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +USB0_IRQHandler + LDR R0, =USB0_DriverIRQHandler + BX R0 + + PUBWEAK RTC_IRQHandler + PUBWEAK RTC_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +RTC_IRQHandler + LDR R0, =RTC_DriverIRQHandler + BX R0 + + PUBWEAK Reserved46_IRQHandler + PUBWEAK Reserved46_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +Reserved46_IRQHandler + LDR R0, =Reserved46_DriverIRQHandler + BX R0 + + PUBWEAK Reserved47_IRQHandler + PUBWEAK Reserved47_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +Reserved47_IRQHandler + LDR R0, =Reserved47_DriverIRQHandler + BX R0 + + PUBWEAK PIN_INT4_IRQHandler + PUBWEAK PIN_INT4_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +PIN_INT4_IRQHandler + LDR R0, =PIN_INT4_DriverIRQHandler + BX R0 + + PUBWEAK PIN_INT5_IRQHandler + PUBWEAK PIN_INT5_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +PIN_INT5_IRQHandler + LDR R0, =PIN_INT5_DriverIRQHandler + BX R0 + + PUBWEAK PIN_INT6_IRQHandler + PUBWEAK PIN_INT6_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +PIN_INT6_IRQHandler + LDR R0, =PIN_INT6_DriverIRQHandler + BX R0 + + PUBWEAK PIN_INT7_IRQHandler + PUBWEAK PIN_INT7_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +PIN_INT7_IRQHandler + LDR R0, =PIN_INT7_DriverIRQHandler + BX R0 + + PUBWEAK CTIMER2_IRQHandler + PUBWEAK CTIMER2_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CTIMER2_IRQHandler + LDR R0, =CTIMER2_DriverIRQHandler + BX R0 + + PUBWEAK CTIMER4_IRQHandler + PUBWEAK CTIMER4_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CTIMER4_IRQHandler + LDR R0, =CTIMER4_DriverIRQHandler + BX R0 + + PUBWEAK RIT_IRQHandler + PUBWEAK RIT_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +RIT_IRQHandler + LDR R0, =RIT_DriverIRQHandler + BX R0 + + PUBWEAK SPIFI0_IRQHandler + PUBWEAK SPIFI0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SPIFI0_IRQHandler + LDR R0, =SPIFI0_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM8_IRQHandler + PUBWEAK FLEXCOMM8_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM8_IRQHandler + LDR R0, =FLEXCOMM8_DriverIRQHandler + BX R0 + + PUBWEAK FLEXCOMM9_IRQHandler + PUBWEAK FLEXCOMM9_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +FLEXCOMM9_IRQHandler + LDR R0, =FLEXCOMM9_DriverIRQHandler + BX R0 + + PUBWEAK SDIO_IRQHandler + PUBWEAK SDIO_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SDIO_IRQHandler + LDR R0, =SDIO_DriverIRQHandler + BX R0 + + PUBWEAK CAN0_IRQ0_IRQHandler + PUBWEAK CAN0_IRQ0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CAN0_IRQ0_IRQHandler + LDR R0, =CAN0_IRQ0_DriverIRQHandler + BX R0 + + PUBWEAK CAN0_IRQ1_IRQHandler + PUBWEAK CAN0_IRQ1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CAN0_IRQ1_IRQHandler + LDR R0, =CAN0_IRQ1_DriverIRQHandler + BX R0 + + PUBWEAK CAN1_IRQ0_IRQHandler + PUBWEAK CAN1_IRQ0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CAN1_IRQ0_IRQHandler + LDR R0, =CAN1_IRQ0_DriverIRQHandler + BX R0 + + PUBWEAK CAN1_IRQ1_IRQHandler + PUBWEAK CAN1_IRQ1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +CAN1_IRQ1_IRQHandler + LDR R0, =CAN1_IRQ1_DriverIRQHandler + BX R0 + + PUBWEAK USB1_IRQHandler + PUBWEAK USB1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +USB1_IRQHandler + LDR R0, =USB1_DriverIRQHandler + BX R0 + + PUBWEAK USB1_NEEDCLK_IRQHandler + PUBWEAK USB1_NEEDCLK_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +USB1_NEEDCLK_IRQHandler + LDR R0, =USB1_NEEDCLK_DriverIRQHandler + BX R0 + + PUBWEAK ETHERNET_IRQHandler + PUBWEAK ETHERNET_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +ETHERNET_IRQHandler + LDR R0, =ETHERNET_DriverIRQHandler + BX R0 + + PUBWEAK ETHERNET_PMT_IRQHandler + PUBWEAK ETHERNET_PMT_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +ETHERNET_PMT_IRQHandler + LDR R0, =ETHERNET_PMT_DriverIRQHandler + BX R0 + + PUBWEAK ETHERNET_MACLP_IRQHandler + PUBWEAK ETHERNET_MACLP_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +ETHERNET_MACLP_IRQHandler + LDR R0, =ETHERNET_MACLP_DriverIRQHandler + BX R0 + + PUBWEAK EEPROM_IRQHandler + PUBWEAK EEPROM_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +EEPROM_IRQHandler + LDR R0, =EEPROM_DriverIRQHandler + BX R0 + + PUBWEAK LCD_IRQHandler + PUBWEAK LCD_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +LCD_IRQHandler + LDR R0, =LCD_DriverIRQHandler + BX R0 + + PUBWEAK SHA_IRQHandler + PUBWEAK SHA_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SHA_IRQHandler + LDR R0, =SHA_DriverIRQHandler + BX R0 + + PUBWEAK SMARTCARD0_IRQHandler + PUBWEAK SMARTCARD0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SMARTCARD0_IRQHandler + LDR R0, =SMARTCARD0_DriverIRQHandler + BX R0 + + PUBWEAK SMARTCARD1_IRQHandler + PUBWEAK SMARTCARD1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SMARTCARD1_IRQHandler + LDR R0, =SMARTCARD1_DriverIRQHandler + BX R0 + +WDT_BOD_DriverIRQHandler +DMA0_DriverIRQHandler +GINT0_DriverIRQHandler +GINT1_DriverIRQHandler +PIN_INT0_DriverIRQHandler +PIN_INT1_DriverIRQHandler +PIN_INT2_DriverIRQHandler +PIN_INT3_DriverIRQHandler +UTICK0_DriverIRQHandler +MRT0_DriverIRQHandler +CTIMER0_DriverIRQHandler +CTIMER1_DriverIRQHandler +SCT0_DriverIRQHandler +CTIMER3_DriverIRQHandler +FLEXCOMM0_DriverIRQHandler +FLEXCOMM1_DriverIRQHandler +FLEXCOMM2_DriverIRQHandler +FLEXCOMM3_DriverIRQHandler +FLEXCOMM4_DriverIRQHandler +FLEXCOMM5_DriverIRQHandler +FLEXCOMM6_DriverIRQHandler +FLEXCOMM7_DriverIRQHandler +ADC0_SEQA_DriverIRQHandler +ADC0_SEQB_DriverIRQHandler +ADC0_THCMP_DriverIRQHandler +DMIC0_DriverIRQHandler +HWVAD0_DriverIRQHandler +USB0_NEEDCLK_DriverIRQHandler +USB0_DriverIRQHandler +RTC_DriverIRQHandler +Reserved46_DriverIRQHandler +Reserved47_DriverIRQHandler +PIN_INT4_DriverIRQHandler +PIN_INT5_DriverIRQHandler +PIN_INT6_DriverIRQHandler +PIN_INT7_DriverIRQHandler +CTIMER2_DriverIRQHandler +CTIMER4_DriverIRQHandler +RIT_DriverIRQHandler +SPIFI0_DriverIRQHandler +FLEXCOMM8_DriverIRQHandler +FLEXCOMM9_DriverIRQHandler +SDIO_DriverIRQHandler +CAN0_IRQ0_DriverIRQHandler +CAN0_IRQ1_DriverIRQHandler +CAN1_IRQ0_DriverIRQHandler +CAN1_IRQ1_DriverIRQHandler +USB1_DriverIRQHandler +USB1_NEEDCLK_DriverIRQHandler +ETHERNET_DriverIRQHandler +ETHERNET_PMT_DriverIRQHandler +ETHERNET_MACLP_DriverIRQHandler +EEPROM_DriverIRQHandler +LCD_DriverIRQHandler +SHA_DriverIRQHandler +SMARTCARD0_DriverIRQHandler +SMARTCARD1_DriverIRQHandler +DefaultISR + B . + + END diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index c4b1155f3..3dc3fb4b6 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -74,6 +74,10 @@ // TODO USB0 has 5, USB1 has 6 #define TUP_USBIP_IP3511 #define TUP_USBIP_IP3516 + #define TUP_USBIP_OHCI + #define TUP_USBIP_OHCI_NXP + #define TUP_OHCI_RHPORTS 1 // 1 downstream port + #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_LPC55) diff --git a/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c b/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c index 16936e2c1..32ef99418 100644 --- a/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c +++ b/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c @@ -36,7 +36,7 @@ #include "host/usbh.h" #include "hcd_lpc_ip3516.h" -#if CFG_TUSB_MCU == OPT_MCU_LPC55 +#if TU_CHECK_MCU(OPT_MCU_LPC55, OPT_MCU_LPC54) #include "fsl_device_registers.h" #else #error "Unsupported MCUs" @@ -46,6 +46,30 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +#if TU_CHECK_MCU(OPT_MCU_LPC54) + #define ATLPTD ATL_PTD_BASE_ADDR + #define INTPTD INT_PTD_BASE_ADDR + #define ISOPTD ISO_PTD_BASE_ADDR + #define ATLPTDD ATL_PTD_DONE_MAP + #define INTPTDD INT_PTD_DONE_MAP + #define ISOPTDD ISO_PTD_DONE_MAP + #define ATLPTDS ATL_PTD_SKIP_MAP + #define INTPTDS INT_PTD_SKIP_MAP + #define ISOPTDS ISO_PTD_SKIP_MAP + #define DATAPAYLOAD DATA_PAYLOAD_BASE_ADDR + #define LASTPTD LAST_PTD_INUSE + + #define USBHSH_ATLPTD_ATL_BASE_MASK USBHSH_ATL_PTD_BASE_ADDR_ATL_BASE_MASK + #define USBHSH_INTPTD_INT_BASE_MASK USBHSH_INT_PTD_BASE_ADDR_INT_BASE_MASK + #define USBHSH_ISOPTD_ISO_BASE_MASK USBHSH_ISO_PTD_BASE_ADDR_ISO_BASE_MASK + + #define USBHSH_DATAPAYLOAD_DAT_BASE_MASK USBHSH_DATA_PAYLOAD_BASE_ADDR_DAT_BASE_MASK + + #define USBHSH_LASTPTD_ATL_LAST USBHSH_LAST_PTD_INUSE_ATL_LAST + #define USBHSH_LASTPTD_INT_LAST USBHSH_LAST_PTD_INUSE_INT_LAST + #define USBHSH_LASTPTD_ISO_LAST USBHSH_LAST_PTD_INUSE_ISO_LAST +#endif + #define USBHSH_PORTSC1_W1C_MASK (USBHSH_PORTSC1_CSC_MASK | USBHSH_PORTSC1_PEDC_MASK | USBHSH_PORTSC1_OCC_MASK) //--------------------------------------------------------------------+ -- cgit v1.3.1 From 003d6ebac75e3b56814a68a957fc1ec52c98006e Mon Sep 17 00:00:00 2001 From: Aleksei Musin Date: Mon, 22 Dec 2025 15:16:09 +0400 Subject: ThreadX OSAL header is added. Docs are updated. --- docs/faq.rst | 2 +- src/osal/osal.h | 2 + src/osal/osal_threadx.h | 210 ++++++++++++++++++++++++++++++++++++++++++++++++ src/tusb_option.h | 1 + 4 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 src/osal/osal_threadx.h (limited to 'src') diff --git a/docs/faq.rst b/docs/faq.rst index a5fe09495..97e8e72ff 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -15,7 +15,7 @@ Yes, TinyUSB is released under the MIT license, allowing commercial use with min **Q: Does TinyUSB require an RTOS?** -No, TinyUSB works in bare metal environments. It also supports FreeRTOS, RT-Thread, and Mynewt. +No, TinyUSB works in bare metal environments. It also supports FreeRTOS, RT-Thread, ThreadX, and Mynewt. **Q: How much memory does TinyUSB use?** diff --git a/src/osal/osal.h b/src/osal/osal.h index 44521620f..7311fc962 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -65,6 +65,8 @@ typedef void (*osal_task_func_t)(void* param); #include "osal_rtx4.h" #elif CFG_TUSB_OS == OPT_OS_ZEPHYR #include "osal_zephyr.h" +#elif CFG_TUSB_OS == OPT_OS_THREADX + #include "osal_threadx.h" #elif CFG_TUSB_OS == OPT_OS_CUSTOM #include "tusb_os_custom.h" // implemented by application #else diff --git a/src/osal/osal_threadx.h b/src/osal/osal_threadx.h new file mode 100644 index 000000000..32c1c62c2 --- /dev/null +++ b/src/osal/osal_threadx.h @@ -0,0 +1,210 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef TUSB_OSAL_THREADX_H_ +#define TUSB_OSAL_THREADX_H_ + +// ThreadX Headers +#include "tx_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +typedef struct +{ + uint16_t depth; + uint16_t item_sz; + void* buf; + char const* name; + TX_QUEUE *queue; + +} osal_queue_def_t; + +typedef TX_QUEUE * osal_queue_t; +*/ +//--------------------------------------------------------------------+ +// TASK API +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline uint32_t _osal_ms2tick(uint32_t msec) { + if ( msec == TX_WAIT_FOREVER ) return TX_WAIT_FOREVER; + if ( msec == 0 ) return 0; + + uint32_t ticks = msec * TX_TIMER_TICKS_PER_SECOND / 1000; + + // TX_TIMER_TICKS_PER_SECOND is less than 1000 and 1 tick > 1 ms + // we still need to delay at least 1 tick + if ( ticks == 0 ) ticks = 1; + + return ticks; +} + +TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { + tx_thread_sleep(_osal_ms2tick(msec)); +} + +//--------------------------------------------------------------------+ +// Spinlock API +//--------------------------------------------------------------------+ +//--------------------------------------------------------------------+ +// Spinlock API +//--------------------------------------------------------------------+ +typedef struct { + void (* interrupt_set)(bool); +} osal_spinlock_t; + +// For SMP, spinlock must be locked by hardware, cannot just use interrupt +#define OSAL_SPINLOCK_DEF(_name, _int_set) \ + osal_spinlock_t _name = { .interrupt_set = _int_set } + +TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) { + (void) ctx; +} + +TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) { +// if (!in_isr) { +// ctx->interrupt_set(false); +// } +} + +TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) { +// if (!in_isr) { +// ctx->interrupt_set(true); +// } +} + + +//--------------------------------------------------------------------+ +// Binary Semaphore API +//--------------------------------------------------------------------+ +typedef TX_SEMAPHORE osal_semaphore_def_t, * osal_semaphore_t; + +/* +TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t *semdef) { + tx_semaphore_create(semdef->semaphore, semdef->name, 0); + return semdef; +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { + (void) semd_hdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { + (void) in_isr; + tx_semaphore_put(sem_hdl); + return true; +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { + return TX_SUCCESS == tx_semaphore_get(sem_hdl, _osal_ms2tick(msec)); +} + +TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { +} +*/ +//--------------------------------------------------------------------+ +// MUTEX API +//--------------------------------------------------------------------+ +typedef TX_MUTEX osal_mutex_def_t, *osal_mutex_t; + +TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) { + if (TX_SUCCESS == tx_mutex_create(mdef, mdef->tx_mutex_name, TX_NO_INHERIT)) { + return mdef; + } else { + return NULL; + } +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { + (void) mutex_hdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { + return TX_SUCCESS == tx_mutex_get(mutex_hdl, _osal_ms2tick(msec)); +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { + return TX_SUCCESS == tx_mutex_put(mutex_hdl); +} + +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ + +typedef TX_QUEUE osal_queue_def_t, * osal_queue_t; + +// _int_set is not used with an RTOS _usbd_qdef + +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ +static _type _name##_buf[_depth]; \ +osal_queue_def_t _name = { \ + .tx_queue_name = #_name, \ + .tx_queue_message_size = (sizeof(_type) + 3) / 4, \ + .tx_queue_capacity = _depth, \ + .tx_queue_start = _name##_buf } + + +// Event queue: usbd_int_set() is used as mutex in OS NONE config +/* +OSAL_QUEUE_DEF(usbd_int_set, _usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t); +static osal_queue_t _usbd_q; +*/ + + +TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { + return TX_SUCCESS == + tx_queue_create(qdef, qdef->tx_queue_name, qdef->tx_queue_message_size, qdef->tx_queue_start, qdef->tx_queue_capacity * qdef->tx_queue_message_size * 4) + ? qdef : 0; +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { + (void) qhdl; + return true; +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { + return 0 == tx_queue_receive(qhdl, data, _osal_ms2tick(msec)); +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void *data, bool in_isr) { + return 0 == tx_queue_send(qhdl, data, in_isr ? TX_NO_WAIT : TX_WAIT_FOREVER); +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { + ULONG enqueued; + tx_queue_info_get(qhdl, 0, &enqueued, 0, 0, 0, 0); + return enqueued == 0; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 64fe899db..08bf0ebc5 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -237,6 +237,7 @@ #define OPT_OS_RTTHREAD 6 ///< RT-Thread #define OPT_OS_RTX4 7 ///< Keil RTX 4 #define OPT_OS_ZEPHYR 8 ///< Zephyr +#define OPT_OS_THREADX 9 ///< ThreadX //--------------------------------------------------------------------+ // Mode and Speed -- cgit v1.3.1 From e574fbf723998bbbe8c9caf9bebfc36dc85e25b2 Mon Sep 17 00:00:00 2001 From: Aleksei Musin Date: Mon, 22 Dec 2025 15:33:12 +0400 Subject: Remove trailing whitespace --- src/osal/osal_threadx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/osal/osal_threadx.h b/src/osal/osal_threadx.h index 32c1c62c2..681aff772 100644 --- a/src/osal/osal_threadx.h +++ b/src/osal/osal_threadx.h @@ -202,7 +202,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { tx_queue_info_get(qhdl, 0, &enqueued, 0, 0, 0, 0); return enqueued == 0; } - + #ifdef __cplusplus } #endif -- cgit v1.3.1 From aa183a50fc4bd7ca0c50f97477fe15bcd7020528 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 22 Dec 2025 21:11:32 +0100 Subject: limit fifo read size to ep_bufsize regardless ep_buf is used or not Signed-off-by: HiFiPhile --- src/tusb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/tusb.c b/src/tusb.c index 8117c3e3e..9c5237d9f 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -485,9 +485,7 @@ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t *s) { if (available >= s->mps) { // multiple of packet size limit by ep bufsize uint16_t count = (uint16_t) (available & ~(s->mps - 1)); - if (s->ep_buf != NULL) { - count = tu_min16(count, s->ep_bufsize); - } + count = tu_min16(count, s->ep_bufsize); TU_ASSERT(stream_xfer(s, count), 0); return count; } else { -- cgit v1.3.1 From 536223cbaa7d05ef58f15a3fab8ff951353d637c Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Dec 2025 23:19:54 +0100 Subject: device/mtp: queue ZLP when needed Signed-off-by: HiFiPhile --- src/class/mtp/mtp_device.c | 54 +++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/class/mtp/mtp_device.c b/src/class/mtp/mtp_device.c index 4942a105a..7b9e3db51 100644 --- a/src/class/mtp/mtp_device.c +++ b/src/class/mtp/mtp_device.c @@ -93,7 +93,7 @@ typedef struct { uint8_t ep_in; uint8_t ep_out; uint8_t ep_event; - + uint8_t ep_sz_fs; // Bulk Only Transfer (BOT) Protocol uint8_t phase; @@ -207,15 +207,21 @@ static bool mtpd_data_xfer(mtp_container_info_t* p_container, uint8_t ep_addr) { p_container->header->transaction_id = p_mtp->command.header.transaction_id; p_mtp->io_header = *p_container->header; // save header for subsequent data } else { - // OUT transfer: total length is at least max packet size - p_mtp->total_len = tu_max32(p_container->header->len, CFG_TUD_MTP_EP_BUFSIZE); + p_mtp->total_len = p_container->header->len; } } else { // subsequent data block: payload only TU_ASSERT(p_mtp->phase == MTP_PHASE_DATA); } - const uint16_t xact_len = (uint16_t) tu_min32(p_mtp->total_len - p_mtp->xferred_len, CFG_TUD_MTP_EP_BUFSIZE); + uint16_t xact_len = 0; + if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { + xact_len = (uint16_t) tu_min32(p_mtp->total_len - p_mtp->xferred_len, CFG_TUD_MTP_EP_BUFSIZE); + } else { + // Use fixed tranfer length to make ZLP handling easier + xact_len = CFG_TUD_MTP_EP_BUFSIZE; + } + if (xact_len) { // already transferred all bytes in header's length. Application make an unnecessary extra call TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, ep_addr)); @@ -287,15 +293,20 @@ uint16_t mtpd_open(uint8_t rhport, tusb_desc_interface_t const* itf_desc, uint16 p_mtp->itf_num = itf_desc->bInterfaceNumber; // Open interrupt IN endpoint - const tusb_desc_endpoint_t* ep_desc = (const tusb_desc_endpoint_t*) tu_desc_next(itf_desc); - TU_ASSERT(ep_desc->bDescriptorType == TUSB_DESC_ENDPOINT && ep_desc->bmAttributes.xfer == TUSB_XFER_INTERRUPT, 0); - TU_ASSERT(usbd_edpt_open(rhport, ep_desc), 0); - p_mtp->ep_event = ep_desc->bEndpointAddress; + const tusb_desc_endpoint_t* ep_desc_int = (const tusb_desc_endpoint_t*) tu_desc_next(itf_desc); + TU_ASSERT(ep_desc_int->bDescriptorType == TUSB_DESC_ENDPOINT && ep_desc_int->bmAttributes.xfer == TUSB_XFER_INTERRUPT, 0); + TU_ASSERT(usbd_edpt_open(rhport, ep_desc_int), 0); + p_mtp->ep_event = ep_desc_int->bEndpointAddress; // Open endpoint pair - TU_ASSERT(usbd_open_edpt_pair(rhport, tu_desc_next(ep_desc), 2, TUSB_XFER_BULK, &p_mtp->ep_out, &p_mtp->ep_in), 0); + const tusb_desc_endpoint_t* ep_desc_bulk = (const tusb_desc_endpoint_t*) tu_desc_next(ep_desc_int); + TU_ASSERT(usbd_open_edpt_pair(rhport, (const uint8_t*)ep_desc_bulk, 2, TUSB_XFER_BULK, &p_mtp->ep_out, &p_mtp->ep_in), 0); TU_ASSERT(prepare_new_command(p_mtp), 0); + if (tud_speed_get() == TUSB_SPEED_FULL) { + p_mtp->ep_sz_fs = (uint8_t)tu_edpt_packet_size(ep_desc_bulk); + } + return mtpd_itf_size; } @@ -417,19 +428,28 @@ bool mtpd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t } case MTP_PHASE_DATA: { - const uint16_t bulk_mps = (tud_speed_get() == TUSB_SPEED_HIGH) ? 512 : 64; p_mtp->xferred_len += xferred_bytes; cb_data.total_xferred_bytes = p_mtp->xferred_len; - bool is_complete = false; - // complete if ZLP or short packet or total length reached - if (xferred_bytes == 0 || // ZLP - (xferred_bytes & (bulk_mps - 1)) || // short packet - p_mtp->xferred_len >= p_mtp->total_len) { // total length reached - is_complete = true; + const bool is_data_in = (ep_addr == p_mtp->ep_in); + const uint16_t bulk_mps = (tud_speed_get() == TUSB_SPEED_HIGH) ? 512 : p_mtp->ep_sz_fs; + // For IN endpoint, threshold is bulk max packet size + // For OUT endpoint, threshold is endpoint buffer size, since we always queue fixed size + const uint16_t threshold = is_data_in ? bulk_mps : CFG_TUD_MTP_EP_BUFSIZE; + + // Check completion: ZLP, short packet, or total length reached + bool is_complete = (xferred_bytes == 0 || + xferred_bytes < threshold || + p_mtp->xferred_len >= p_mtp->total_len); + + // Send/queue ZLP if packet is full-sized but transfer is complete + if (is_complete && xferred_bytes > 0 && !(xferred_bytes & (threshold - 1))) { + TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, ep_addr)); + TU_ASSERT(usbd_edpt_xfer(p_mtp->rhport, ep_addr, NULL, 0, false)); + return true; } - if (ep_addr == p_mtp->ep_in) { + if (is_data_in) { // Data In if (is_complete) { cb_data.io_container.header->len = sizeof(mtp_container_header_t); -- cgit v1.3.1 From d27e55a3dae252025fff429a3951e1b198079ad5 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 29 Dec 2025 00:04:53 +0100 Subject: device/mtp: improve logging Signed-off-by: HiFiPhile --- src/class/mtp/mtp_device.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/class/mtp/mtp_device.c b/src/class/mtp/mtp_device.c index 7b9e3db51..13f868d14 100644 --- a/src/class/mtp/mtp_device.c +++ b/src/class/mtp/mtp_device.c @@ -218,12 +218,14 @@ static bool mtpd_data_xfer(mtp_container_info_t* p_container, uint8_t ep_addr) { if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { xact_len = (uint16_t) tu_min32(p_mtp->total_len - p_mtp->xferred_len, CFG_TUD_MTP_EP_BUFSIZE); } else { - // Use fixed tranfer length to make ZLP handling easier + // Use fixed transfer length to make ZLP handling easier xact_len = CFG_TUD_MTP_EP_BUFSIZE; } + TU_LOG_DRV(" MTP Data Xfer %s: xferred_len/total_len=%lu/%lu, xact_len=%u\r\n", + (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) ? "IN" : "OUT", + p_mtp->xferred_len, p_mtp->total_len, xact_len); if (xact_len) { - // already transferred all bytes in header's length. Application make an unnecessary extra call TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, ep_addr)); TU_ASSERT(usbd_edpt_xfer(p_mtp->rhport, ep_addr, _mtpd_epbuf.buf, xact_len, false)); } @@ -388,8 +390,8 @@ bool mtpd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t mtp_generic_container_t* p_container = (mtp_generic_container_t*) _mtpd_epbuf.buf; #if CFG_TUSB_DEBUG >= CFG_TUD_MTP_LOG_LEVEL - tu_lookup_find(&_mtp_op_table, p_mtp->command.header.code); - TU_LOG_DRV(" MTP %s: %s phase\r\n", (const char *) tu_lookup_find(&_mtp_op_table, p_mtp->command.header.code), + const uint16_t code = (p_mtp->phase == MTP_PHASE_COMMAND) ? p_container->header.code : p_mtp->command.header.code; + TU_LOG_DRV(" MTP %s: %s phase\r\n", (const char *) tu_lookup_find(&_mtp_op_table, code), _mtp_phase_str[p_mtp->phase]); #endif @@ -442,8 +444,12 @@ bool mtpd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes < threshold || p_mtp->xferred_len >= p_mtp->total_len); + TU_LOG_DRV(" MTP Data %s CB: xferred_bytes=%lu, xferred_len/total_len=%lu/%lu, is_complete=%d\r\n", + is_data_in ? "IN" : "OUT", xferred_bytes, p_mtp->xferred_len, p_mtp->total_len, is_complete ? 1 : 0); + // Send/queue ZLP if packet is full-sized but transfer is complete if (is_complete && xferred_bytes > 0 && !(xferred_bytes & (threshold - 1))) { + TU_LOG_DRV(" QUEUE ZLP\r\n"); TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, ep_addr)); TU_ASSERT(usbd_edpt_xfer(p_mtp->rhport, ep_addr, NULL, 0, false)); return true; -- cgit v1.3.1 From 239e20ba7399fc026325c4cd8c98c08a160a9773 Mon Sep 17 00:00:00 2001 From: zhiqiang-ch Date: Tue, 30 Dec 2025 10:44:03 +0800 Subject: support for the AT32F45X series --- README.rst | 3 +- docs/reference/boards.rst | 3 + docs/reference/dependencies.rst | 1 + hw/bsp/at32f45x/FreeRTOSConfig/FreeRTOSConfig.h | 177 ++++++++++++++++ hw/bsp/at32f45x/at32f45x_clock.c | 114 ++++++++++ hw/bsp/at32f45x/at32f45x_clock.h | 45 ++++ hw/bsp/at32f45x/at32f45x_conf.h | 174 +++++++++++++++ hw/bsp/at32f45x/at32f45x_int.c | 101 +++++++++ hw/bsp/at32f45x/at32f45x_int.h | 60 ++++++ hw/bsp/at32f45x/boards/at_start_f455/board.cmake | 8 + hw/bsp/at32f45x/boards/at_start_f455/board.h | 96 +++++++++ hw/bsp/at32f45x/boards/at_start_f455/board.mk | 7 + hw/bsp/at32f45x/boards/at_start_f456/board.cmake | 8 + hw/bsp/at32f45x/boards/at_start_f456/board.h | 96 +++++++++ hw/bsp/at32f45x/boards/at_start_f456/board.mk | 7 + hw/bsp/at32f45x/boards/at_start_f457/board.cmake | 8 + hw/bsp/at32f45x/boards/at_start_f457/board.h | 96 +++++++++ hw/bsp/at32f45x/boards/at_start_f457/board.mk | 7 + hw/bsp/at32f45x/family.c | 258 +++++++++++++++++++++++ hw/bsp/at32f45x/family.cmake | 97 +++++++++ hw/bsp/at32f45x/family.mk | 40 ++++ src/common/tusb_mcu.h | 5 + src/portable/synopsys/dwc2/dwc2_at32.h | 5 + src/tusb_option.h | 1 + tools/get_deps.py | 3 + 25 files changed, 1419 insertions(+), 1 deletion(-) create mode 100644 hw/bsp/at32f45x/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/at32f45x/at32f45x_clock.c create mode 100644 hw/bsp/at32f45x/at32f45x_clock.h create mode 100644 hw/bsp/at32f45x/at32f45x_conf.h create mode 100644 hw/bsp/at32f45x/at32f45x_int.c create mode 100644 hw/bsp/at32f45x/at32f45x_int.h create mode 100644 hw/bsp/at32f45x/boards/at_start_f455/board.cmake create mode 100644 hw/bsp/at32f45x/boards/at_start_f455/board.h create mode 100644 hw/bsp/at32f45x/boards/at_start_f455/board.mk create mode 100644 hw/bsp/at32f45x/boards/at_start_f456/board.cmake create mode 100644 hw/bsp/at32f45x/boards/at_start_f456/board.h create mode 100644 hw/bsp/at32f45x/boards/at_start_f456/board.mk create mode 100644 hw/bsp/at32f45x/boards/at_start_f457/board.cmake create mode 100644 hw/bsp/at32f45x/boards/at_start_f457/board.h create mode 100644 hw/bsp/at32f45x/boards/at_start_f457/board.mk create mode 100644 hw/bsp/at32f45x/family.c create mode 100644 hw/bsp/at32f45x/family.cmake create mode 100644 hw/bsp/at32f45x/family.mk (limited to 'src') diff --git a/README.rst b/README.rst index 178a084ce..29b2f4fca 100644 --- a/README.rst +++ b/README.rst @@ -141,7 +141,8 @@ Supported CPUs +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | Artery AT32 | F403a_407, F413 | ✔ | | | fsdev | Packet SRAM 512 | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | F415, F435_437, F423, F425 | ✔ | ✔ | | dwc2 | | +| | F415, F435_437, F423, | ✔ | ✔ | | dwc2 | | +| | F425, F45x | | | | | | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ | | F402_F405 | ✔ | ✔ | ✔ | dwc2 | F405 is HS | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index 12da5c90b..cacf52e1a 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -44,6 +44,9 @@ at_start_f423 AT-START-F423 at32f423 https:/ at_start_f425 AT-START-F425 at32f425 https://www.arterychip.com/en/product/AT32F425.jsp at_start_f435 AT-START-F435 at32f435_437 https://www.arterychip.com/en/product/AT32F435.jsp at_start_f437 AT-START-F437 at32f435_437 https://www.arterychip.com/en/product/AT32F437.jsp +at_start_f455 AT-START-F455 at32f45x https://www.arterychip.com/en/product/AT32F455.jsp +at_start_f456 AT-START-F456 at32f45x https://www.arterychip.com/en/product/AT32F456.jsp +at_start_f457 AT-START-F457 at32f45x https://www.arterychip.com/en/product/AT32F457.jsp ========================= ============================= ============= ==================================================== ====== Bridgetek diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index de1603383..ce5f265d5 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -16,6 +16,7 @@ hw/mcu/artery/at32f415 https://github.com/ArteryTek/AT32F415_ hw/mcu/artery/at32f423 https://github.com/ArteryTek/AT32F423_Firmware_Library.git 2afa7f12852e57a9e8aab3a892c641e1a8635a18 at32f423 hw/mcu/artery/at32f425 https://github.com/ArteryTek/AT32F425_Firmware_Library.git 620233e1357d5c1b7e2bde6b9dd5196822b91817 at32f425 hw/mcu/artery/at32f435_437 https://github.com/ArteryTek/AT32F435_437_Firmware_Library.git 25439cc6650a8ae0345934e8707a5f38c7ae41f8 at32f435_437 +hw/mcu/artery/at32f45x https://github.com/ArteryTek/AT32F45x_Firmware_Library.git 3d4a1b38be8ebac292e2350ca53bc4bfa4430233 at32f45x hw/mcu/bridgetek/ft9xx/ft90x-sdk https://github.com/BRTSG-FOSS/ft90x-sdk.git 91060164afe239fcb394122e8bf9eb24d3194eb1 brtmm90x hw/mcu/broadcom https://github.com/adafruit/broadcom-peripherals.git 08370086080759ed54ac1136d62d2ad24c6fa267 broadcom_32bit broadcom_64bit hw/mcu/gd/nuclei-sdk https://github.com/Nuclei-Software/nuclei-sdk.git 7eb7bfa9ea4fbeacfafe1d5f77d5a0e6ed3922e7 gd32vf103 diff --git a/hw/bsp/at32f45x/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/at32f45x/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..8a9906d39 --- /dev/null +++ b/hw/bsp/at32f45x/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,177 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ +// Include MCU header + #include "at32f45x.h" + +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +#ifdef __RX__ +/* Renesas RX series */ +#define vSoftwareInterruptISR INT_Excep_ICU_SWINT +#define vTickISR INT_Excep_CMT0_CMI0 +#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) +#define configKERNEL_INTERRUPT_PRIORITY 1 +#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 + +#else + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ +#if defined(__NVIC_PRIO_BITS) + // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h + #define configPRIO_BITS __NVIC_PRIO_BITS + +#elif defined(__ECLIC_INTCTLBITS) + // RISC-V Bumblebee core from nuclei + #define configPRIO_BITS __ECLIC_INTCTLBITS + +#elif defined(__IASMARM__) + // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS. + // Therefore we will hard coded it to minimum value of 2 to get pass ci build. + // IAR user must update this to correct value of the target MCU + #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU" + #define configPRIO_BITS 2 + +#else + #error "FreeRTOS configPRIO_BITS to be defined" +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<dt = (*((uint8_t const *) buf) & 0x01FF); + buf++; + } + return len; +#else + (void) buf; + (void) len; + return 0; +#endif +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler(void) { + system_ticks++; +} + +uint32_t board_millis(void) { + return system_ticks; +} + +void SVC_Handler(void) { +} + +void PendSV_Handler(void) { +} +#endif + +void HardFault_Handler(void) { + __asm("BKPT #0\n"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void); +void _init(void) { +} + +#ifdef USE_FULL_ASSERT +void assert_failed(const char *file, uint32_t line) { + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ diff --git a/hw/bsp/at32f45x/family.cmake b/hw/bsp/at32f45x/family.cmake new file mode 100644 index 000000000..fe13347af --- /dev/null +++ b/hw/bsp/at32f45x/family.cmake @@ -0,0 +1,97 @@ +include_guard() + +set(AT32_FAMILY at32f45x) +set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries) + +string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "") + +#------------------------------------ +# Startup & Linker script +#------------------------------------ +set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s) +set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) +set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s) +if (NOT DEFINED LD_FILE_GNU) +set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld) +endif () +set(LD_FILE_Clang ${LD_FILE_GNU}) +set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf) + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +function(family_add_board BOARD_TARGET) + add_library(${BOARD_TARGET} STATIC + ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c + ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c + ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c + ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c + ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_acc.c + ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${AT32_SDK_LIB}/cmsis/cm4/core_support + ${AT32_SDK_LIB}/cmsis/cm4/device_support + ${AT32_SDK_LIB}/drivers/inc + ) + + update_board(${BOARD_TARGET}) +endfunction() + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER}) + + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c + ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c + ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c + ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () + + set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES + SKIP_LINTING ON + COMPILE_OPTIONS -w) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/at32f45x/family.mk b/hw/bsp/at32f45x/family.mk new file mode 100644 index 000000000..e42f27557 --- /dev/null +++ b/hw/bsp/at32f45x/family.mk @@ -0,0 +1,40 @@ +AT32_FAMILY = at32f45x +AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries + +include $(TOP)/$(BOARD_PATH)/board.mk + +CPU_CORE ?= cortex-m4 + +CFLAGS_GCC += \ + -flto + +CFLAGS += \ + -DCFG_TUSB_MCU=OPT_MCU_AT32F45X \ + +LDFLAGS_GCC += \ + -flto --specs=nosys.specs -nostdlib -nostartfiles + +SRC_C += \ + src/portable/synopsys/dwc2/dcd_dwc2.c \ + src/portable/synopsys/dwc2/hcd_dwc2.c \ + src/portable/synopsys/dwc2/dwc2_common.c \ + $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \ + $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \ + $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \ + $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \ + $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_acc.c \ + $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(AT32_SDK_LIB)/drivers/inc \ + $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \ + $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support + +SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s +SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s + +LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld +LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf + +flash: flash-atlink diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 55f7e0b7c..ce690acb8 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -661,6 +661,11 @@ #define TUP_USBIP_DWC2_AT32 #define TUP_DCD_ENDPOINT_MAX 8 +#elif TU_CHECK_MCU(OPT_MCU_AT32F45X) + #define TUP_USBIP_DWC2 + #define TUP_USBIP_DWC2_AT32 + #define TUP_DCD_ENDPOINT_MAX 8 + //--------------------------------------------------------------------+ // HPMicro //--------------------------------------------------------------------+ diff --git a/src/portable/synopsys/dwc2/dwc2_at32.h b/src/portable/synopsys/dwc2/dwc2_at32.h index 513495eb1..10824ae92 100644 --- a/src/portable/synopsys/dwc2/dwc2_at32.h +++ b/src/portable/synopsys/dwc2/dwc2_at32.h @@ -61,6 +61,11 @@ #define OTG1_FIFO_SIZE 1280 #define OTG1_IRQn OTGFS1_IRQn #define DWC2_OTG1_REG_BASE 0x50000000UL +#elif CFG_TUSB_MCU == OPT_MCU_AT32F45X + #include + #define OTG1_FIFO_SIZE 1280 + #define OTG1_IRQn OTGFS1_IRQn + #define DWC2_OTG1_REG_BASE 0x50000000UL #endif #ifdef __cplusplus diff --git a/src/tusb_option.h b/src/tusb_option.h index 64fe899db..35a0d97db 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -216,6 +216,7 @@ #define OPT_MCU_AT32F402_405 2504 ///< ArteryTek AT32F402_405 #define OPT_MCU_AT32F425 2505 ///< ArteryTek AT32F425 #define OPT_MCU_AT32F413 2506 ///< ArteryTek AT32F413 +#define OPT_MCU_AT32F45X 2507 ///< ArteryTek AT32F45x // HPMicro #define OPT_MCU_HPM 2600 ///< HPMicro diff --git a/tools/get_deps.py b/tools/get_deps.py index deacbb23b..773445adc 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -244,6 +244,9 @@ deps_optional = { 'hw/mcu/artery/at32f413': ['https://github.com/ArteryTek/AT32F413_Firmware_Library.git', 'f6fe62dfec9fd40c5b63d92fc5ef2c2b5e77a450', 'at32f413'], + 'hw/mcu/artery/at32f45x': ['https://github.com/ArteryTek/AT32F45x_Firmware_Library.git', + '3d4a1b38be8ebac292e2350ca53bc4bfa4430233', + 'at32f45x'], 'hw/mcu/hpmicro/hpm_sdk': ['https://github.com/hpmicro/hpm_sdk', '8d2af741ecc4aaa82d7ee395dc1ce25d7070c3ff', 'hpmicro'], -- cgit v1.3.1 From cab1b2f6f741ea151e87f139b2115d5234228bbd Mon Sep 17 00:00:00 2001 From: Rémi Berthoz Date: Sun, 4 Jan 2026 16:55:43 +0100 Subject: Implement Printer Device Class --- examples/device/printer_to_hid/CMakeLists.txt | 29 ++ examples/device/printer_to_hid/CMakePresets.json | 6 + examples/device/printer_to_hid/Makefile | 11 + examples/device/printer_to_hid/README.md | 0 examples/device/printer_to_hid/src/main.c | 219 +++++++++++++++ examples/device/printer_to_hid/src/tusb_config.h | 115 ++++++++ .../device/printer_to_hid/src/usb_descriptors.c | 247 +++++++++++++++++ .../device/printer_to_hid/src/usb_descriptors.h | 30 ++ src/CMakeLists.txt | 1 + src/class/printer/printer.h | 277 +++++++++++++++++++ src/class/printer/printer_device.c | 306 +++++++++++++++++++++ src/class/printer/printer_device.h | 79 ++++++ src/device/usbd.c | 13 + src/device/usbd.h | 15 + src/tinyusb.mk | 1 + src/tusb.h | 4 + src/tusb_option.h | 4 + tools/iar_template.ipcf | 5 + 18 files changed, 1362 insertions(+) create mode 100644 examples/device/printer_to_hid/CMakeLists.txt create mode 100644 examples/device/printer_to_hid/CMakePresets.json create mode 100644 examples/device/printer_to_hid/Makefile create mode 100644 examples/device/printer_to_hid/README.md create mode 100644 examples/device/printer_to_hid/src/main.c create mode 100644 examples/device/printer_to_hid/src/tusb_config.h create mode 100644 examples/device/printer_to_hid/src/usb_descriptors.c create mode 100644 examples/device/printer_to_hid/src/usb_descriptors.h create mode 100644 src/class/printer/printer.h create mode 100644 src/class/printer/printer_device.c create mode 100644 src/class/printer/printer_device.h (limited to 'src') diff --git a/examples/device/printer_to_hid/CMakeLists.txt b/examples/device/printer_to_hid/CMakeLists.txt new file mode 100644 index 000000000..f58759059 --- /dev/null +++ b/examples/device/printer_to_hid/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.20) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) + +project(printer_to_hid C CXX ASM) + +# Checks this example is valid for the family and initializes the project +family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + +add_executable(${PROJECT_NAME}) + +# Example source +target_sources(${PROJECT_NAME} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c + ) + +# Example include +target_include_directories(${PROJECT_NAME} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src + ) + +# Configure compilation flags and libraries for the example without RTOS. +# See the corresponding function in hw/bsp/FAMILY/family.cmake for details. +family_configure_device_example(${PROJECT_NAME} noos) diff --git a/examples/device/printer_to_hid/CMakePresets.json b/examples/device/printer_to_hid/CMakePresets.json new file mode 100644 index 000000000..5cd8971e9 --- /dev/null +++ b/examples/device/printer_to_hid/CMakePresets.json @@ -0,0 +1,6 @@ +{ + "version": 6, + "include": [ + "../../../hw/bsp/BoardPresets.json" + ] +} diff --git a/examples/device/printer_to_hid/Makefile b/examples/device/printer_to_hid/Makefile new file mode 100644 index 000000000..1a4b428dc --- /dev/null +++ b/examples/device/printer_to_hid/Makefile @@ -0,0 +1,11 @@ +include ../../../hw/bsp/family_support.mk + +INC += \ + src \ + + +# Example source +EXAMPLE_SOURCE += $(wildcard src/*.c) +SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) + +include ../../../hw/bsp/family_rules.mk diff --git a/examples/device/printer_to_hid/README.md b/examples/device/printer_to_hid/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/examples/device/printer_to_hid/src/main.c b/examples/device/printer_to_hid/src/main.c new file mode 100644 index 000000000..f5012478c --- /dev/null +++ b/examples/device/printer_to_hid/src/main.c @@ -0,0 +1,219 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2026 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include +#include +#include + +#include "bsp/board_api.h" +#include "tusb.h" + +#include "usb_descriptors.h" + +// -------------------------------------------------------------------+ +// Variables controlled with USB endpoint callbacks +// -------------------------------------------------------------------+ + +// usb interface pointer +uint8_t printer_itf = 0; +// pendings bytes in usb endpoint buffer ; must process these bytes +uint8_t pending_bytes_on_usb_ep = 0; + + +// -------------------------------------------------------------------+ +// Variables controlled locally +// -------------------------------------------------------------------+ + +// local data buffer (copy data from usb endpoint into this buffer) ; acts as fifo +uint8_t data_buffer[16] = {0}; +// write offset for usb/printer incoming data to data_buffer +size_t data_rx_offset = 0; +// read offset for usb/hid outgoing data from data_buffer +size_t data_tx_offset = 0; +// available space in data_buffer +size_t data_available = sizeof(data_buffer); + +// next keycode to send on usb/hid +uint8_t next_keycode = 0; +// next key modifiers to send on usb/hid +uint8_t next_modifiers = 0; +// whether the next usb/hid report must be NULL to release the last keystroke +uint8_t next_keycode_is_release = false; + + +// -------------------------------------------------------------------+ +// Tasks +// -------------------------------------------------------------------+ + +// Every 10ms, we will place HID data in the usb/hid endpoint, ready to +// sent to the host when required. The tasks will read the keycode in +// next_keycode and place it in the HID report, then set next_is_null +// such that the key is released by the next report. This seem to help +// stroking the same key twice when the character is repeated in the data. +void hid_tx_task(void) { + // Poll every 10ms + const uint32_t interval_ms = 10; + static uint32_t start_ms = 0; + + if (!tud_hid_ready()) { + return; + } + + if (board_millis() - start_ms < interval_ms) { + return; // not enough time + } + start_ms += interval_ms; + + if (next_keycode_is_release || next_keycode == 0) { + tud_hid_keyboard_report(1, 0, NULL); + next_keycode_is_release = false; + return; + } + + uint8_t keycode_array[6] = {0}; + keycode_array[0] = next_keycode; + tud_hid_keyboard_report(1, next_modifiers, keycode_array); + next_keycode_is_release = true; + next_keycode = 0; +} + +// Whenever there are pendings bytes on the USB endpoint, we will pull them from the +// endpoint buffer and write then in the local data buffer. We must take care to not +// overwrite local data that is not processed yet, so we use data_buffer as a fifo. +// We do not have to take care of reading correctly from the endpoint buffer, as all +// is done well by tud_printer_n_read(). +void printer_rx_task(void) { + if (pending_bytes_on_usb_ep > 0) { + size_t len1 = data_available; + size_t len2 = 0; + if (len1 < 0) { + len1 = 0; + } + if (data_rx_offset + len1 > sizeof(data_buffer)) { + len2 = len1 - (sizeof(data_buffer) - data_rx_offset); + len1 = sizeof(data_buffer) - data_rx_offset; + } + uint32_t count = tud_printer_n_read(printer_itf, data_buffer + data_rx_offset, len1); + if (len2 > 0) { + count += tud_printer_n_read(printer_itf, data_buffer, len2); + } + + if (count > 0) { + data_available -= count; + pending_bytes_on_usb_ep -= count; + data_rx_offset = (data_rx_offset + count) % sizeof(data_buffer); + } + } +} + +// The HID keycodes are not binary mapped like UTF8 codes. If we want to send the +// data received as a usb/printer, we have to translate the binary data for the +// usb/hid interface. Note that the simple mapping below will be valid only for +// hosts expecting hid data from a QWERTY keyboard. Also note that only a-zA-Z0-9 +// characters are converted, for simplicity of the example. Other characters are +// converted to spaces. +void translation_task(void) { + if (data_tx_offset != data_rx_offset || data_available == 0) { + // If data_tx_offset and data_rx_offset have different values, then we + // can proceed: translate, prepare for TX, and advance data_tx_offset. + // + // If the buffer is full (data_available == 0), then we must also + // translate data and prepare it for TX. But the data_tx_offset and + // data_rx_offset will have the same value, since RX caught up to TX. + // Hence the OR. + + // Translate UTF8 to HID keystroke + char c = data_buffer[data_tx_offset]; + uint8_t m = 0; + if ('a' <= c && c <= 'z') { + c -= 'a'; + c += HID_KEY_A; + } else if ('A' <= c && c <= 'Z') { + c -= 'a'; + c += HID_KEY_A; + m = KEYBOARD_MODIFIER_LEFTSHIFT; + } else if ('1' <= c && c <= '9') { + c -= '1'; + c += HID_KEY_1; + } else if (c == '0') { + c = HID_KEY_0; + } else { + c = HID_KEY_SPACE; + } + + // Proceed only if there are no characters pending for TX + if (next_keycode == 0) { + // Prepare next keystroke with translated data + next_keycode = c; + next_modifiers = m; + // Increment read offset + data_tx_offset += 1; + data_tx_offset %= sizeof(data_buffer); + data_available += 1; + } + } +} + +int main(void) { + + board_init(); + tud_init(BOARD_TUD_RHPORT); // init device stack on configured roothub port + if (board_init_after_tusb) { + board_init_after_tusb(); + } + + while (1) { + tud_task(); // tinyusb device task + printer_rx_task(); // read data sent by host on our printer interface + translation_task(); // translate printer's UTF8 to HID keycodes + hid_tx_task(); // send data to host with our HID interface + } +} + + +//--------------------------------------------------------------------+ +// Printer callbacks +//--------------------------------------------------------------------+ + +// Data was received on endpoint buffer +void tud_printer_rx_cb(uint8_t itf, size_t n) { + printer_itf = itf; // get interface from which to read endpoint buffer + pending_bytes_on_usb_ep += n; // count pending bytes, counter must decrement when reading from the endpoint buffer +} + + +//--------------------------------------------------------------------+ +// HID callbacks +//--------------------------------------------------------------------+ + +uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, + uint16_t reqlen) { + return 0; +} + +void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, const uint8_t *buffer, + uint16_t bufsize) { + return; +} diff --git a/examples/device/printer_to_hid/src/tusb_config.h b/examples/device/printer_to_hid/src/tusb_config.h new file mode 100644 index 000000000..a8dbac89d --- /dev/null +++ b/examples/device/printer_to_hid/src/tusb_config.h @@ -0,0 +1,115 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2026 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Board Specific Configuration +//--------------------------------------------------------------------+ + +#define BOARD_DEVICE_RHPORT_NUM 3 + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU + #error CFG_TUSB_MCU must be defined +#endif + +#ifndef CFG_TUSB_OS + #define CFG_TUSB_OS OPT_OS_NONE +#endif + +#ifndef CFG_TUSB_DEBUG + #define CFG_TUSB_DEBUG 0 +#endif + +// Enable Device stack +#define CFG_TUD_ENABLED 1 + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION + #define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN + #define CFG_TUSB_MEM_ALIGN __attribute__((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE + #define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +//------------- CLASS -------------// +#define CFG_TUD_HID 1 +#define CFG_TUD_CDC 0 +#define CFG_TUD_MSC 0 +#define CFG_TUD_MIDI 0 +#define CFG_TUD_VENDOR 0 +#define CFG_TUD_PRINTER 1 + +// HID buffer size Should be sufficient to hold ID (if any) + Data +#define CFG_TUD_HID_EP_BUFSIZE 16 + +// Printer buffer size Should be sufficient to hold data +#define CFG_TUD_PRINTER_RX_BUFSIZE 16 +#define CFG_TUD_PRINTER_TX_BUFSIZE 16 +#define CFG_TUD_PRINTER_EP_BUFSIZE 16 + +#ifdef __cplusplus +} +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/printer_to_hid/src/usb_descriptors.c b/examples/device/printer_to_hid/src/usb_descriptors.c new file mode 100644 index 000000000..161bbb7c5 --- /dev/null +++ b/examples/device/printer_to_hid/src/usb_descriptors.c @@ -0,0 +1,247 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "bsp/board_api.h" +#include "tusb.h" +#include "usb_descriptors.h" + +/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. + * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. + * + * Auto ProductID layout's Bitmap: + * [MSB] HID | MSC | CDC [LSB] + */ +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) + +#define USB_VID 0xCafe +#define USB_BCD 0x0200 + +//--------------------------------------------------------------------+ +// Device Descriptors +//--------------------------------------------------------------------+ +static tusb_desc_device_t const desc_device = +{ + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = USB_BCD, + .bDeviceClass = 0x00, + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = USB_VID, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 +}; + +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const * tud_descriptor_device_cb(void) +{ + return (uint8_t const *) &desc_device; +} + +//--------------------------------------------------------------------+ +// HID Report Descriptor +//--------------------------------------------------------------------+ + +uint8_t const desc_hid_report[] = +{ + TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD )) +}; + +// Invoked when received GET HID REPORT DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance) +{ + (void) instance; + return desc_hid_report; +} + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ + +enum +{ + ITF_NUM_HID, + ITF_NUM_PRINTER, + ITF_NUM_TOTAL +}; + +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN + TUD_PRINTER_DESC_LEN) + +// HID interface endpoints +#define EPADDR_HID 0x81 // Interrupt In, MSB must be 1 +// Printer interface endpoints +#define EPADDR_PRINTER_OUT 0x01 // Bulk Out, MSB must be 0 +#define EPADDR_PRINTER_IN 0x82 // Bulk In, MSB must be 1 + +uint8_t const desc_configuration[] = +{ + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), + + // HID: + // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval + TUD_HID_DESCRIPTOR(ITF_NUM_HID, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPADDR_HID, CFG_TUD_HID_EP_BUFSIZE, 5), + + // Printer: + // Interface number, string index, EP Bulk Out address, EP Bulk In address, EP size + TUD_PRINTER_DESCRIPTOR(ITF_NUM_PRINTER, 0, EPADDR_PRINTER_OUT, EPADDR_PRINTER_IN, CFG_TUD_PRINTER_EP_BUFSIZE) +}; + +#if TUD_OPT_HIGH_SPEED +// Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration + +// other speed configuration +static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; + +// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed +static tusb_desc_device_qualifier_t const desc_device_qualifier = +{ + .bLength = sizeof(tusb_desc_device_qualifier_t), + .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, + .bcdUSB = USB_BCD, + + .bDeviceClass = 0x00, + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + .bNumConfigurations = 0x01, + .bReserved = 0x00 +}; + +// Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. +// device_qualifier descriptor describes information about a high-speed capable device that would +// change if the device were operating at the other speed. If not highspeed capable stall this request. +uint8_t const* tud_descriptor_device_qualifier_cb(void) +{ + return (uint8_t const*) &desc_device_qualifier; +} + +// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa +uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) +{ + (void) index; // for multiple configurations + + // other speed config is basically configuration with type = OTHER_SPEED_CONFIG + memcpy(desc_other_speed_config, desc_configuration, CONFIG_TOTAL_LEN); + desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; + + // this example use the same configuration for both high and full speed mode + return desc_other_speed_config; +} + +#endif // highspeed + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) +{ + (void) index; // for multiple configurations + + // This example use the same configuration for both high and full speed mode + return desc_configuration; +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +// String Descriptor Index +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, +}; + +// array of pointer to string descriptors +static char const *string_desc_arr[] = +{ + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + NULL, // 3: Serials will use unique ID if possible +}; + +static uint16_t _desc_str[32 + 1]; + +// Invoked when received GET STRING DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { + (void) langid; + size_t chr_count; + + switch ( index ) { + case STRID_LANGID: + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + break; + + case STRID_SERIAL: + chr_count = board_usb_get_serial(_desc_str + 1, 32); + break; + + default: + // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. + // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors + + if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; + + const char *str = string_desc_arr[index]; + + // Cap at max char + chr_count = strlen(str); + size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type + if ( chr_count > max_count ) chr_count = max_count; + + // Convert ASCII string into UTF-16 + for ( size_t i = 0; i < chr_count; i++ ) { + _desc_str[1 + i] = str[i]; + } + break; + } + + // first byte is length (including header), second byte is string type + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); + + return _desc_str; +} diff --git a/examples/device/printer_to_hid/src/usb_descriptors.h b/examples/device/printer_to_hid/src/usb_descriptors.h new file mode 100644 index 000000000..53c4e1fbd --- /dev/null +++ b/examples/device/printer_to_hid/src/usb_descriptors.h @@ -0,0 +1,30 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef USB_DESCRIPTORS_H_ +#define USB_DESCRIPTORS_H_ + +REPORT_ID_KEYBOARD = 1 + +#endif /* USB_DESCRIPTORS_H_ */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 48dc75e50..00f466007 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,6 +19,7 @@ function(tinyusb_sources_get OUTPUT_VAR) ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/mtp/mtp_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/net/ecm_rndis_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/net/ncm_device.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/printer/printer_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/usbtmc/usbtmc_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/vendor/vendor_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/video/video_device.c diff --git a/src/class/printer/printer.h b/src/class/printer/printer.h new file mode 100644 index 000000000..4cd1d62fc --- /dev/null +++ b/src/class/printer/printer.h @@ -0,0 +1,277 @@ +#include +#include "tusb_option.h" + +#if (CFG_TUD_ENABLED && CFG_TUD_PRINTER) + + #include "device/usbd.h" + #include "device/usbd_pvt.h" + +// #include "bsp/board_api.h" + + #include "printer_device.h" + #include "printer.h" + + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +typedef struct { + uint8_t itf_num; + uint8_t ep_in; + uint8_t ep_out; + /*------------- From this point, data is not cleared by bus reset -------------*/ + + // FIFO + tu_fifo_t rx_ff; + tu_fifo_t tx_ff; + + uint8_t rx_ff_buf[CFG_TUD_PRINTER_RX_BUFSIZE]; + uint8_t tx_ff_buf[CFG_TUD_PRINTER_TX_BUFSIZE]; + + OSAL_MUTEX_DEF(rx_ff_mutex); + OSAL_MUTEX_DEF(tx_ff_mutex); +} printer_interface_t; + + #define ITF_MEM_RESET_SIZE offsetof(printer_interface_t, wanted_char) + +typedef struct { + TUD_EPBUF_DEF(epout, CFG_TUD_PRINTER_EP_BUFSIZE); + TUD_EPBUF_DEF(epin, CFG_TUD_PRINTER_EP_BUFSIZE); +} printer_epbuf_t; + +static printer_interface_t _printer_itf[CFG_TUD_PRINTER]; +CFG_TUD_MEM_SECTION static printer_epbuf_t _printer_epbuf[CFG_TUD_PRINTER]; + + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ + +static tud_printer_configure_fifo_t _printer_fifo_cfg; + +static bool _prep_out_transaction(uint8_t itf) { + const uint8_t rhport = 0; + printer_interface_t *p_printer = &_printer_itf[itf]; + printer_epbuf_t *p_epbuf = &_printer_epbuf[itf]; + + // Skip if usb is not ready yet + TU_VERIFY(tud_ready() && p_printer->ep_out); + + uint16_t available = tu_fifo_remaining(&p_printer->rx_ff); + + // Prepare for incoming data but only allow what we can store in the ring buffer. + // TODO Actually we can still carry out the transfer, keeping count of received bytes + // and slowly move it to the FIFO when read(). + // This pre-check reduces endpoint claiming + TU_VERIFY(available >= CFG_TUD_PRINTER_EP_BUFSIZE); + + // claim endpoint + TU_VERIFY(usbd_edpt_claim(rhport, p_printer->ep_out)); + + // fifo can be changed before endpoint is claimed + available = tu_fifo_remaining(&p_printer->rx_ff); + + if (available >= CFG_TUD_PRINTER_EP_BUFSIZE) { + return usbd_edpt_xfer(rhport, p_printer->ep_out, p_epbuf->epout, CFG_TUD_PRINTER_EP_BUFSIZE); + } else { + // Release endpoint since we don't make any transfer + usbd_edpt_release(rhport, p_printer->ep_out); + return false; + } +} + +//--------------------------------------------------------------------+ +// APPLICATION API +//--------------------------------------------------------------------+ + +uint32_t tud_printer_n_available(uint8_t itf) { + return tu_fifo_count(&_printer_itf[itf].rx_ff); +} + +uint32_t tud_printer_n_read(uint8_t itf, void *buffer, uint32_t bufsize) { + printer_interface_t *p_printer = &_printer_itf[itf]; + uint32_t num_read = tu_fifo_read_n(&p_printer->rx_ff, buffer, (uint16_t)TU_MIN(bufsize, UINT16_MAX)); + _prep_out_transaction(itf); + return num_read; +} + +bool tud_printer_n_peek(uint8_t itf, uint8_t *chr) { + return tu_fifo_peek(&_printer_itf[itf].rx_ff, chr); +} + +void tud_printer_n_read_flush(uint8_t itf) { + printer_interface_t *p_printer = &_printer_itf[itf]; + tu_fifo_clear(&p_printer->rx_ff); + _prep_out_transaction(itf); +} + + +//--------------------------------------------------------------------+ +// USBD PRINTER DRIVER API +//--------------------------------------------------------------------+ + +void printer_init(void) { + tu_memclr(_printer_itf, sizeof(_printer_itf)); + tu_memclr(&_printer_fifo_cfg, sizeof(_printer_fifo_cfg)); + + for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { + printer_interface_t *p_printer = &_printer_itf[i]; + + tu_fifo_config(&p_printer->rx_ff, p_printer->rx_ff_buf, TU_ARRAY_SIZE(p_printer->rx_ff_buf), 1, false); + tu_fifo_config(&p_printer->tx_ff, p_printer->tx_ff_buf, TU_ARRAY_SIZE(p_printer->tx_ff_buf), 1, true); + + #if OSAL_MUTEX_REQUIRED + osal_mutex_t mutex_rd = osal_mutex_create(&p_printer->rx_ff_mutex); + osal_mutex_t mutex_wr = osal_mutex_create(&p_printer->tx_ff_mutex); + TU_ASSERT(mutex_rd != NULL && mutex_wr != NULL, ); + + tu_fifo_config_mutex(&p_printer->rx_ff, NULL, mutex_rd); + tu_fifo_config_mutex(&p_printer->tx_ff, mutex_wr, NULL); + #endif + } +} + +bool printer_deinit(void) { + #if OSAL_MUTEX_REQUIRED + for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { + printer_interface_t *p_printer = &_printer_itf[i]; + osal_mutex_t mutex_rd = p_printer->rx_ff.mutex_rd; + osal_mutex_t mutex_wr = p_printer->tx_ff.mutex_rd; + + if (mutex_rd) { + osal_mutex_delete(mutex_rd); + tu_fifo_config_mutex(&p_printer->rx_ff, NULL, NULL); + } + + if (mutex_wr) { + osal_mutex_delete(mutex_wr); + tu_fifo_config_mutex(&p_printer->tx_ff, NULL, NULL); + } + } + #endif + + return true; +} + +void printer_reset(uint8_t rhport) { + (void)rhport; + + for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { + printer_interface_t *p_printer = &_printer_itf[i]; + + tu_memclr(p_printer, sizeof(p_printer)); + if (!_printer_fifo_cfg.rx_persistent) { + tu_fifo_clear(&p_printer->rx_ff); + } + if (!_printer_fifo_cfg.tx_persistent) { + tu_fifo_clear(&p_printer->tx_ff); + } + // tu_fifo_set_overwritable(&p_printer->rx_ff, true); + tu_fifo_set_overwritable(&p_printer->tx_ff, true); + } +} + +uint16_t printer_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { + TU_VERIFY(TUSB_CLASS_PRINTER == itf_desc->bInterfaceClass, 0); + + // Identify available interface to open + printer_interface_t *p_printer; + uint8_t printer_id; + for (printer_id = 0; printer_id < CFG_TUD_PRINTER; printer_id++) { + p_printer = &_printer_itf[printer_id]; + if (p_printer->ep_out == 0) { + break; + } + } + TU_ASSERT(printer_id < CFG_TUD_PRINTER); + + //------------- Interface -------------// + uint16_t drv_len = sizeof(tusb_desc_interface_t); + + //------------- Endpoints -------------// + TU_ASSERT(itf_desc->bNumEndpoints == 2); + drv_len += 2 * sizeof(tusb_desc_endpoint_t); + p_printer->itf_num = 2; + const uint8_t *p_desc = tu_desc_next(itf_desc); + TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_printer->ep_out, &p_printer->ep_in), 0); + + _prep_out_transaction(printer_id); + + return drv_len; +} + +bool printer_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t *request) { + TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); + + if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) { + //------------- STD Request -------------// + if (stage != CONTROL_STAGE_SETUP) { + return true; + } + } else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) { + switch (request->bRequest) { + // https://www.usb.org/sites/default/files/usbprint11a021811.pdf + case PRINTER_REQ_CONTROL_GET_DEVICE_ID: + if (stage == CONTROL_STAGE_SETUP) { + const char deviceId[] = "MANUFACTURER:ACME Manufacturing;" + "MODEL:LaserBeam 9;" + "COMMAND SET:PS;" + "COMMENT:Anything you like;" + "ACTIVE COMMAND SET:PS;"; + char buffer[256]; + strcpy(buffer + 2, deviceId); + buffer[0] = 0x00; + buffer[1] = strlen(deviceId); + return tud_control_xfer(rhport, request, buffer, strlen(deviceId) + 2); + } + break; + case PRINTER_REQ_CONTROL_GET_PORT_STATUS: + if (stage == CONTROL_STAGE_SETUP) { + static uint8_t port_status = (0 << 3) | (1 << 1) | (1 << 2); // ~Paper empty + Selected + NoError + return tud_control_xfer(rhport, request, &port_status, sizeof(port_status)); + } + break; + case PRINTER_REQ_CONTROL_SOFT_RESET: + if (stage == CONTROL_STAGE_SETUP) { + return false; // what to do ? + } + break; + default: + return false; + } + } else { + return false; + } + return true; +} + +bool printer_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + uint8_t itf; + printer_interface_t *p_printer; + + // Identify which interface to use + for (itf = 0; itf < CFG_TUD_PRINTER; itf++) { + p_printer = &_printer_itf[itf]; + if (ep_addr == p_printer->ep_out) { + break; + } + } + TU_ASSERT(itf < CFG_TUD_PRINTER); + printer_epbuf_t *p_epbuf = &_printer_epbuf[itf]; + + // Received new data + if (ep_addr == p_printer->ep_out) { + tu_fifo_write_n(&p_printer->rx_ff, p_epbuf->epout, (uint16_t)xferred_bytes); + // invoke receive callback (if there is still data) + if (tud_printer_rx_cb && !tu_fifo_empty(&p_printer->rx_ff)) { + tud_printer_rx_cb(itf, xferred_bytes); + } + // prepare for OUT transaction + _prep_out_transaction(itf); + } + + return true; +} + +#endif diff --git a/src/class/printer/printer_device.c b/src/class/printer/printer_device.c new file mode 100644 index 000000000..efeae100f --- /dev/null +++ b/src/class/printer/printer_device.c @@ -0,0 +1,306 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2026 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUD_ENABLED && CFG_TUD_PRINTER) + + //--------------------------------------------------------------------+ + // INCLUDE + //--------------------------------------------------------------------+ + #include "device/usbd.h" + #include "device/usbd_pvt.h" + + #include "printer_device.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +typedef struct { + uint8_t itf_num; + uint8_t ep_out; // Bulk Out endpoint + uint8_t ep_in; // optional Bulk In endpoint + + /*------------- From this point, data is not cleared by bus reset -------------*/ + + // FIFO + tu_fifo_t rx_ff; + tu_fifo_t tx_ff; + + uint8_t rx_ff_buf[CFG_TUD_PRINTER_RX_BUFSIZE]; + uint8_t tx_ff_buf[CFG_TUD_PRINTER_TX_BUFSIZE]; + + OSAL_MUTEX_DEF(rx_ff_mutex); + OSAL_MUTEX_DEF(tx_ff_mutex); +} printer_interface_t; + +typedef struct { + TUD_EPBUF_DEF(epout, CFG_TUD_PRINTER_EP_BUFSIZE); + TUD_EPBUF_DEF(epin, CFG_TUD_PRINTER_EP_BUFSIZE); +} printer_epbuf_t; + +static printer_interface_t _printer_itf[CFG_TUD_PRINTER]; +CFG_TUD_MEM_SECTION static printer_epbuf_t _printer_epbuf[CFG_TUD_PRINTER]; + + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ + +static tud_printer_configure_fifo_t _printer_fifo_cfg; + +static bool _prep_out_transaction(uint8_t itf) { + const uint8_t rhport = 0; + printer_interface_t *p_printer = &_printer_itf[itf]; + printer_epbuf_t *p_epbuf = &_printer_epbuf[itf]; + + // Skip if usb is not ready yet + TU_VERIFY(tud_ready() && p_printer->ep_out); + + uint16_t available = tu_fifo_remaining(&p_printer->rx_ff); + + // Prepare for incoming data but only allow what we can store in the ring buffer. + // TODO Actually we can still carry out the transfer, keeping count of received bytes + // and slowly move it to the FIFO when read(). + // This pre-check reduces endpoint claiming + TU_VERIFY(available >= CFG_TUD_PRINTER_EP_BUFSIZE); + + // claim endpoint + TU_VERIFY(usbd_edpt_claim(rhport, p_printer->ep_out)); + + // fifo can be changed before endpoint is claimed + available = tu_fifo_remaining(&p_printer->rx_ff); + + if (available >= CFG_TUD_PRINTER_EP_BUFSIZE) { + return usbd_edpt_xfer(rhport, p_printer->ep_out, p_epbuf->epout, CFG_TUD_PRINTER_EP_BUFSIZE); + } else { + // Release endpoint since we don't make any transfer + usbd_edpt_release(rhport, p_printer->ep_out); + return false; + } +} + +//--------------------------------------------------------------------+ +// Weak stubs: invoked if no strong implementation is available +//--------------------------------------------------------------------+ +TU_ATTR_WEAK void tud_printer_rx_cb(uint8_t itf, size_t n) { + (void)itf; + (void)n; +} + +//--------------------------------------------------------------------+ +// APPLICATION API +//--------------------------------------------------------------------+ +uint32_t tud_printer_n_available(uint8_t itf) { + return tu_fifo_count(&_printer_itf[itf].rx_ff); +} + +uint32_t tud_printer_n_read(uint8_t itf, void *buffer, uint32_t bufsize) { + printer_interface_t *p_printer = &_printer_itf[itf]; + uint32_t num_read = tu_fifo_read_n(&p_printer->rx_ff, buffer, (uint16_t)TU_MIN(bufsize, UINT16_MAX)); + _prep_out_transaction(itf); + return num_read; +} + +bool tud_printer_n_peek(uint8_t itf, uint8_t *chr) { + return tu_fifo_peek(&_printer_itf[itf].rx_ff, chr); +} + +void tud_printer_n_read_flush(uint8_t itf) { + printer_interface_t *p_printer = &_printer_itf[itf]; + tu_fifo_clear(&p_printer->rx_ff); + _prep_out_transaction(itf); +} + + +//--------------------------------------------------------------------+ +// USBD-CLASS API +//--------------------------------------------------------------------+ +void printerd_init(void) { + tu_memclr(_printer_itf, sizeof(_printer_itf)); + tu_memclr(&_printer_fifo_cfg, sizeof(_printer_fifo_cfg)); + + for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { + printer_interface_t *p_printer = &_printer_itf[i]; + + tu_fifo_config(&p_printer->rx_ff, p_printer->rx_ff_buf, TU_ARRAY_SIZE(p_printer->rx_ff_buf), 1, false); + tu_fifo_config(&p_printer->tx_ff, p_printer->tx_ff_buf, TU_ARRAY_SIZE(p_printer->tx_ff_buf), 1, true); + + #if OSAL_MUTEX_REQUIRED + osal_mutex_t mutex_rd = osal_mutex_create(&p_printer->rx_ff_mutex); + osal_mutex_t mutex_wr = osal_mutex_create(&p_printer->tx_ff_mutex); + TU_ASSERT(mutex_rd != NULL && mutex_wr != NULL, ); + + tu_fifo_config_mutex(&p_printer->rx_ff, NULL, mutex_rd); + tu_fifo_config_mutex(&p_printer->tx_ff, mutex_wr, NULL); + #endif + } +} + +bool printerd_deinit(void) { + #if OSAL_MUTEX_REQUIRED + for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { + printer_interface_t *p_printer = &_printer_itf[i]; + osal_mutex_t mutex_rd = p_printer->rx_ff.mutex_rd; + osal_mutex_t mutex_wr = p_printer->tx_ff.mutex_rd; + + if (mutex_rd) { + osal_mutex_delete(mutex_rd); + tu_fifo_config_mutex(&p_printer->rx_ff, NULL, NULL); + } + + if (mutex_wr) { + osal_mutex_delete(mutex_wr); + tu_fifo_config_mutex(&p_printer->tx_ff, NULL, NULL); + } + } + #endif + + return true; +} + +void printerd_reset(uint8_t rhport) { + (void)rhport; + + for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { + printer_interface_t *p_printer = &_printer_itf[i]; + + tu_memclr(p_printer, sizeof(p_printer)); + if (!_printer_fifo_cfg.rx_persistent) { + tu_fifo_clear(&p_printer->rx_ff); + } + if (!_printer_fifo_cfg.tx_persistent) { + tu_fifo_clear(&p_printer->tx_ff); + } + // tu_fifo_set_overwritable(&p_printer->rx_ff, true); + tu_fifo_set_overwritable(&p_printer->tx_ff, true); + } +} + +uint16_t printerd_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { + TU_VERIFY(TUSB_CLASS_PRINTER == itf_desc->bInterfaceClass, 0); + + // Identify available interface to open + printer_interface_t *p_printer; + uint8_t printer_id; + for (printer_id = 0; printer_id < CFG_TUD_PRINTER; printer_id++) { + p_printer = &_printer_itf[printer_id]; + if (p_printer->ep_out == 0) { + break; + } + } + TU_ASSERT(printer_id < CFG_TUD_PRINTER); + + //------------- Interface -------------// + uint16_t drv_len = sizeof(tusb_desc_interface_t); + + //------------- Endpoints -------------// + TU_ASSERT(itf_desc->bNumEndpoints == 2); + drv_len += 2 * sizeof(tusb_desc_endpoint_t); + p_printer->itf_num = 2; + const uint8_t *p_desc = tu_desc_next(itf_desc); + TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_printer->ep_out, &p_printer->ep_in), 0); + + _prep_out_transaction(printer_id); + + return drv_len; +} + +bool printerd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t *request) { + TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); + + if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) { + //------------- STD Request -------------// + if (stage != CONTROL_STAGE_SETUP) { + return true; + } + } else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) { + switch (request->bRequest) { + // https://www.usb.org/sites/default/files/usbprint11a021811.pdf + case PRINTER_REQ_CONTROL_GET_DEVICE_ID: + if (stage == CONTROL_STAGE_SETUP) { + const char deviceId[] = "MANUFACTURER:ACME Manufacturing;" + "MODEL:LaserBeam 9;" + "COMMAND SET:PS;" + "COMMENT:Anything you like;" + "ACTIVE COMMAND SET:PS;"; + char buffer[256]; + strcpy(buffer + 2, deviceId); + buffer[0] = 0x00; + buffer[1] = strlen(deviceId); + return tud_control_xfer(rhport, request, buffer, strlen(deviceId) + 2); + } + break; + case PRINTER_REQ_CONTROL_GET_PORT_STATUS: + if (stage == CONTROL_STAGE_SETUP) { + static uint8_t port_status = (0 << 3) | (1 << 1) | (1 << 2); // ~Paper empty + Selected + NoError + return tud_control_xfer(rhport, request, &port_status, sizeof(port_status)); + } + break; + case PRINTER_REQ_CONTROL_SOFT_RESET: + if (stage == CONTROL_STAGE_SETUP) { + return false; // what to do ? + } + break; + default: + return false; + } + } else { + return false; + } + return true; +} + +bool printerd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + uint8_t itf; + printer_interface_t *p_printer; + + // Identify which interface to use + for (itf = 0; itf < CFG_TUD_PRINTER; itf++) { + p_printer = &_printer_itf[itf]; + if (ep_addr == p_printer->ep_out) { + break; + } + } + TU_ASSERT(itf < CFG_TUD_PRINTER); + printer_epbuf_t *p_epbuf = &_printer_epbuf[itf]; + + // Received new data + if (ep_addr == p_printer->ep_out) { + tu_fifo_write_n(&p_printer->rx_ff, p_epbuf->epout, (uint16_t)xferred_bytes); + // invoke receive callback (if there is still data) + if (tud_printer_rx_cb && !tu_fifo_empty(&p_printer->rx_ff)) { + tud_printer_rx_cb(itf, xferred_bytes); + } + // prepare for OUT transaction + _prep_out_transaction(itf); + } + + return true; +} + +#endif diff --git a/src/class/printer/printer_device.h b/src/class/printer/printer_device.h new file mode 100644 index 000000000..8c21e39ce --- /dev/null +++ b/src/class/printer/printer_device.h @@ -0,0 +1,79 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2026 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef TUSB_PRINTER_DEVICE_H_ +#define TUSB_PRINTER_DEVICE_H_ + +#include "printer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct TU_ATTR_PACKED { + uint8_t rx_persistent : 1; // keep rx fifo on bus reset or disconnect + uint8_t tx_persistent : 1; // keep tx fifo on bus reset or disconnect +} tud_printer_configure_fifo_t; + +//--------------------------------------------------------------------+ +// Application API (Multiple Ports) i.e. CFG_TUD_PRINTER > 1 +//--------------------------------------------------------------------+ + +// Get the number of bytes available for reading +uint32_t tud_printer_n_available(uint8_t itf); + +// Read received bytes +uint32_t tud_printer_n_read(uint8_t itf, void *buffer, uint32_t bufsize); + +// Clear the received FIFO +void tud_printer_n_read_flush(uint8_t itf); + +// Get a byte from FIFO without removing it +bool tud_printer_n_peek(uint8_t itf, uint8_t *ui8); + +//--------------------------------------------------------------------+ +// Application Callback API (weak is optional) +//--------------------------------------------------------------------+ + +// Invoked when received new data +TU_ATTR_WEAK void tud_printer_rx_cb(uint8_t itf, size_t n); + +//--------------------------------------------------------------------+ +// Internal Class Driver API +//--------------------------------------------------------------------+ +void printerd_init(void); +bool printerd_deinit(void); +void printerd_reset(uint8_t rhport); +uint16_t printerd_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, uint16_t max_len); +bool printerd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t *request); +bool printerd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/device/usbd.c b/src/device/usbd.c index 1e21c667a..32b3a3ee2 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -334,6 +334,19 @@ static const usbd_class_driver_t _usbd_driver[] = { .sof = NULL }, #endif + + #if CFG_TUD_PRINTER + { + .name = DRIVER_NAME("PRINTER"), + .init = printerd_init, + .deinit = printerd_deinit, + .reset = printerd_reset, + .open = printerd_open, + .control_xfer_cb = printerd_control_xfer_cb, + .xfer_cb = printerd_xfer_cb, + .sof = NULL + }, + #endif }; enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) }; diff --git a/src/device/usbd.h b/src/device/usbd.h index bd5a3c395..3b296feea 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -312,6 +312,21 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 +//--------------------------------------------------------------------+ +// Printer Descriptor Templates +//--------------------------------------------------------------------+ + +#define TUD_PRINTER_DESC_LEN (9 + 7 + 7) // one interface, two endpoints + +#define TUD_PRINTER_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \ + /* Interface */\ + 9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_PRINTER, 1, 2, _stridx,\ + /* Endpoint Out */\ + 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ + /* Endpoint In */\ + 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 + + //--------------------------------------------------------------------+ // HID Descriptor Templates //--------------------------------------------------------------------+ diff --git a/src/tinyusb.mk b/src/tinyusb.mk index 8f9d52de9..e7d1c0b5b 100644 --- a/src/tinyusb.mk +++ b/src/tinyusb.mk @@ -15,6 +15,7 @@ TINYUSB_SRC_C += \ src/class/mtp/mtp_device.c \ src/class/net/ecm_rndis_device.c \ src/class/net/ncm_device.c \ + src/class/printer/printer_device.c \ src/class/usbtmc/usbtmc_device.c \ src/class/video/video_device.c \ src/class/vendor/vendor_device.c \ diff --git a/src/tusb.h b/src/tusb.h index 62b3b9783..256a239e7 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -92,6 +92,10 @@ #include "class/mtp/mtp_device.h" #endif + #if CFG_TUD_PRINTER + #include "class/printer/printer_device.h" + #endif + #if CFG_TUD_AUDIO #include "class/audio/audio_device.h" #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 64fe899db..80cbeab36 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -614,6 +614,10 @@ #define CFG_TUD_NCM 0 #endif +#ifndef CFG_TUD_PRINTER + #define CFG_TUD_PRINTER 0 +#endif + #ifndef CFG_TUD_EDPT_DEDICATED_HWFIFO #define CFG_TUD_EDPT_DEDICATED_HWFIFO 0 #endif diff --git a/tools/iar_template.ipcf b/tools/iar_template.ipcf index caddda826..035e40b94 100644 --- a/tools/iar_template.ipcf +++ b/tools/iar_template.ipcf @@ -69,6 +69,11 @@ $TUSB_DIR$/src/class/net/ncm.h $TUSB_DIR$/src/class/net/net_device.h + + $TUSB_DIR$/src/class/printer/printer_device.c + $TUSB_DIR$/src/class/printer/printer.h + $TUSB_DIR$/src/class/printer/printer_device.h + $TUSB_DIR$/src/class/usbtmc/usbtmc_device.c $TUSB_DIR$/src/class/usbtmc/usbtmc.h -- cgit v1.3.1 From 473c2c7313f8d9d66951ae2a50b04eb5ccbf05b0 Mon Sep 17 00:00:00 2001 From: Rémi Berthoz Date: Mon, 5 Jan 2026 19:11:34 +0100 Subject: Add missing license to printer device class header --- src/class/printer/printer.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src') diff --git a/src/class/printer/printer.h b/src/class/printer/printer.h index 4cd1d62fc..c637717b1 100644 --- a/src/class/printer/printer.h +++ b/src/class/printer/printer.h @@ -1,3 +1,29 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2026 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + #include #include "tusb_option.h" -- cgit v1.3.1 From 158fe86b55ee4704b57ad07a95ceb546b82534af Mon Sep 17 00:00:00 2001 From: Rémi Berthoz Date: Mon, 5 Jan 2026 19:13:23 +0100 Subject: Fix content of printer device class header (.h) file I apparently made a mistake when copying/renaming this file, file content was that of printer_device.c. --- src/class/printer/printer.h | 289 +++----------------------------------------- 1 file changed, 17 insertions(+), 272 deletions(-) (limited to 'src') diff --git a/src/class/printer/printer.h b/src/class/printer/printer.h index c637717b1..27e95b997 100644 --- a/src/class/printer/printer.h +++ b/src/class/printer/printer.h @@ -24,280 +24,25 @@ * This file is part of the TinyUSB stack. */ -#include -#include "tusb_option.h" +#ifndef _TUSB_PRINTER_H_ +#define _TUSB_PRINTER_H_ -#if (CFG_TUD_ENABLED && CFG_TUD_PRINTER) +#include "common/tusb_common.h" - #include "device/usbd.h" - #include "device/usbd_pvt.h" - -// #include "bsp/board_api.h" - - #include "printer_device.h" - #include "printer.h" - - -//--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF -//--------------------------------------------------------------------+ - -typedef struct { - uint8_t itf_num; - uint8_t ep_in; - uint8_t ep_out; - /*------------- From this point, data is not cleared by bus reset -------------*/ - - // FIFO - tu_fifo_t rx_ff; - tu_fifo_t tx_ff; - - uint8_t rx_ff_buf[CFG_TUD_PRINTER_RX_BUFSIZE]; - uint8_t tx_ff_buf[CFG_TUD_PRINTER_TX_BUFSIZE]; - - OSAL_MUTEX_DEF(rx_ff_mutex); - OSAL_MUTEX_DEF(tx_ff_mutex); -} printer_interface_t; - - #define ITF_MEM_RESET_SIZE offsetof(printer_interface_t, wanted_char) - -typedef struct { - TUD_EPBUF_DEF(epout, CFG_TUD_PRINTER_EP_BUFSIZE); - TUD_EPBUF_DEF(epin, CFG_TUD_PRINTER_EP_BUFSIZE); -} printer_epbuf_t; - -static printer_interface_t _printer_itf[CFG_TUD_PRINTER]; -CFG_TUD_MEM_SECTION static printer_epbuf_t _printer_epbuf[CFG_TUD_PRINTER]; - - -//--------------------------------------------------------------------+ -// INTERNAL OBJECT & FUNCTION DECLARATION -//--------------------------------------------------------------------+ - -static tud_printer_configure_fifo_t _printer_fifo_cfg; - -static bool _prep_out_transaction(uint8_t itf) { - const uint8_t rhport = 0; - printer_interface_t *p_printer = &_printer_itf[itf]; - printer_epbuf_t *p_epbuf = &_printer_epbuf[itf]; - - // Skip if usb is not ready yet - TU_VERIFY(tud_ready() && p_printer->ep_out); - - uint16_t available = tu_fifo_remaining(&p_printer->rx_ff); - - // Prepare for incoming data but only allow what we can store in the ring buffer. - // TODO Actually we can still carry out the transfer, keeping count of received bytes - // and slowly move it to the FIFO when read(). - // This pre-check reduces endpoint claiming - TU_VERIFY(available >= CFG_TUD_PRINTER_EP_BUFSIZE); - - // claim endpoint - TU_VERIFY(usbd_edpt_claim(rhport, p_printer->ep_out)); - - // fifo can be changed before endpoint is claimed - available = tu_fifo_remaining(&p_printer->rx_ff); - - if (available >= CFG_TUD_PRINTER_EP_BUFSIZE) { - return usbd_edpt_xfer(rhport, p_printer->ep_out, p_epbuf->epout, CFG_TUD_PRINTER_EP_BUFSIZE); - } else { - // Release endpoint since we don't make any transfer - usbd_edpt_release(rhport, p_printer->ep_out); - return false; - } -} - -//--------------------------------------------------------------------+ -// APPLICATION API -//--------------------------------------------------------------------+ - -uint32_t tud_printer_n_available(uint8_t itf) { - return tu_fifo_count(&_printer_itf[itf].rx_ff); -} - -uint32_t tud_printer_n_read(uint8_t itf, void *buffer, uint32_t bufsize) { - printer_interface_t *p_printer = &_printer_itf[itf]; - uint32_t num_read = tu_fifo_read_n(&p_printer->rx_ff, buffer, (uint16_t)TU_MIN(bufsize, UINT16_MAX)); - _prep_out_transaction(itf); - return num_read; -} - -bool tud_printer_n_peek(uint8_t itf, uint8_t *chr) { - return tu_fifo_peek(&_printer_itf[itf].rx_ff, chr); -} - -void tud_printer_n_read_flush(uint8_t itf) { - printer_interface_t *p_printer = &_printer_itf[itf]; - tu_fifo_clear(&p_printer->rx_ff); - _prep_out_transaction(itf); -} - - -//--------------------------------------------------------------------+ -// USBD PRINTER DRIVER API -//--------------------------------------------------------------------+ - -void printer_init(void) { - tu_memclr(_printer_itf, sizeof(_printer_itf)); - tu_memclr(&_printer_fifo_cfg, sizeof(_printer_fifo_cfg)); - - for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { - printer_interface_t *p_printer = &_printer_itf[i]; - - tu_fifo_config(&p_printer->rx_ff, p_printer->rx_ff_buf, TU_ARRAY_SIZE(p_printer->rx_ff_buf), 1, false); - tu_fifo_config(&p_printer->tx_ff, p_printer->tx_ff_buf, TU_ARRAY_SIZE(p_printer->tx_ff_buf), 1, true); - - #if OSAL_MUTEX_REQUIRED - osal_mutex_t mutex_rd = osal_mutex_create(&p_printer->rx_ff_mutex); - osal_mutex_t mutex_wr = osal_mutex_create(&p_printer->tx_ff_mutex); - TU_ASSERT(mutex_rd != NULL && mutex_wr != NULL, ); - - tu_fifo_config_mutex(&p_printer->rx_ff, NULL, mutex_rd); - tu_fifo_config_mutex(&p_printer->tx_ff, mutex_wr, NULL); - #endif - } -} - -bool printer_deinit(void) { - #if OSAL_MUTEX_REQUIRED - for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { - printer_interface_t *p_printer = &_printer_itf[i]; - osal_mutex_t mutex_rd = p_printer->rx_ff.mutex_rd; - osal_mutex_t mutex_wr = p_printer->tx_ff.mutex_rd; - - if (mutex_rd) { - osal_mutex_delete(mutex_rd); - tu_fifo_config_mutex(&p_printer->rx_ff, NULL, NULL); - } - - if (mutex_wr) { - osal_mutex_delete(mutex_wr); - tu_fifo_config_mutex(&p_printer->tx_ff, NULL, NULL); - } - } - #endif - - return true; -} - -void printer_reset(uint8_t rhport) { - (void)rhport; - - for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { - printer_interface_t *p_printer = &_printer_itf[i]; - - tu_memclr(p_printer, sizeof(p_printer)); - if (!_printer_fifo_cfg.rx_persistent) { - tu_fifo_clear(&p_printer->rx_ff); - } - if (!_printer_fifo_cfg.tx_persistent) { - tu_fifo_clear(&p_printer->tx_ff); - } - // tu_fifo_set_overwritable(&p_printer->rx_ff, true); - tu_fifo_set_overwritable(&p_printer->tx_ff, true); - } -} - -uint16_t printer_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { - TU_VERIFY(TUSB_CLASS_PRINTER == itf_desc->bInterfaceClass, 0); - - // Identify available interface to open - printer_interface_t *p_printer; - uint8_t printer_id; - for (printer_id = 0; printer_id < CFG_TUD_PRINTER; printer_id++) { - p_printer = &_printer_itf[printer_id]; - if (p_printer->ep_out == 0) { - break; - } - } - TU_ASSERT(printer_id < CFG_TUD_PRINTER); - - //------------- Interface -------------// - uint16_t drv_len = sizeof(tusb_desc_interface_t); - - //------------- Endpoints -------------// - TU_ASSERT(itf_desc->bNumEndpoints == 2); - drv_len += 2 * sizeof(tusb_desc_endpoint_t); - p_printer->itf_num = 2; - const uint8_t *p_desc = tu_desc_next(itf_desc); - TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_printer->ep_out, &p_printer->ep_in), 0); - - _prep_out_transaction(printer_id); - - return drv_len; -} - -bool printer_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t *request) { - TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); - - if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) { - //------------- STD Request -------------// - if (stage != CONTROL_STAGE_SETUP) { - return true; - } - } else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) { - switch (request->bRequest) { - // https://www.usb.org/sites/default/files/usbprint11a021811.pdf - case PRINTER_REQ_CONTROL_GET_DEVICE_ID: - if (stage == CONTROL_STAGE_SETUP) { - const char deviceId[] = "MANUFACTURER:ACME Manufacturing;" - "MODEL:LaserBeam 9;" - "COMMAND SET:PS;" - "COMMENT:Anything you like;" - "ACTIVE COMMAND SET:PS;"; - char buffer[256]; - strcpy(buffer + 2, deviceId); - buffer[0] = 0x00; - buffer[1] = strlen(deviceId); - return tud_control_xfer(rhport, request, buffer, strlen(deviceId) + 2); - } - break; - case PRINTER_REQ_CONTROL_GET_PORT_STATUS: - if (stage == CONTROL_STAGE_SETUP) { - static uint8_t port_status = (0 << 3) | (1 << 1) | (1 << 2); // ~Paper empty + Selected + NoError - return tud_control_xfer(rhport, request, &port_status, sizeof(port_status)); - } - break; - case PRINTER_REQ_CONTROL_SOFT_RESET: - if (stage == CONTROL_STAGE_SETUP) { - return false; // what to do ? - } - break; - default: - return false; - } - } else { - return false; - } - return true; -} - -bool printer_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { - uint8_t itf; - printer_interface_t *p_printer; - - // Identify which interface to use - for (itf = 0; itf < CFG_TUD_PRINTER; itf++) { - p_printer = &_printer_itf[itf]; - if (ep_addr == p_printer->ep_out) { - break; - } - } - TU_ASSERT(itf < CFG_TUD_PRINTER); - printer_epbuf_t *p_epbuf = &_printer_epbuf[itf]; - - // Received new data - if (ep_addr == p_printer->ep_out) { - tu_fifo_write_n(&p_printer->rx_ff, p_epbuf->epout, (uint16_t)xferred_bytes); - // invoke receive callback (if there is still data) - if (tud_printer_rx_cb && !tu_fifo_empty(&p_printer->rx_ff)) { - tud_printer_rx_cb(itf, xferred_bytes); - } - // prepare for OUT transaction - _prep_out_transaction(itf); - } +#ifdef __cplusplus + extern "C" { +#endif - return true; -} +/// Printer Class Specific Control Request +typedef enum +{ + PRINTER_REQ_CONTROL_GET_DEVICE_ID = 0x01, ///< Get device ID + PRINTER_REQ_CONTROL_GET_PORT_STATUS = 0x02, ///< Get port status + PRINTER_REQ_CONTROL_SOFT_RESET = 0x03, ///< Soft reset +}printer_request_enum_t; +#ifdef __cplusplus + } #endif + +#endif /* _TUSB_PRINTER_H__ */ -- cgit v1.3.1 From 3302c07d129e8a6c2631a9b15d5a3549b455a3ea Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 28 Nov 2025 15:37:57 +0100 Subject: dwc2: implement deinit Signed-off-by: HiFiPhile --- src/portable/synopsys/dwc2/dcd_dwc2.c | 12 ++++++++++++ src/portable/synopsys/dwc2/dwc2_common.c | 13 +++++++++++++ src/portable/synopsys/dwc2/dwc2_common.h | 1 + src/portable/synopsys/dwc2/hcd_dwc2.c | 10 ++++++++++ 4 files changed, 36 insertions(+) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 44f7137f9..57dcb6fba 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -491,6 +491,18 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { return true; } +bool dcd_deinit(uint8_t rhport) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + + // Disable global interrupt + dwc2->gahbcfg &= ~GAHBCFG_GINT; + + dcd_disconnect(rhport); + + dwc2_core_deinit(rhport); + return true; +} + void dcd_int_enable(uint8_t rhport) { dwc2_dcd_int_enable(rhport); } diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index a7e6188df..ce38ed6ec 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -251,6 +251,19 @@ bool dwc2_core_init(uint8_t rhport, bool is_highspeed, bool is_dma) { return true; } +void dwc2_core_deinit(uint8_t rhport) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + + // Soft disconnect + dwc2->dctl |= DCTL_SDIS; + + // Reset global registers + dwc2->gotgctl = 0; + + // Reset core + reset_core(dwc2); +} + // void dwc2_core_handle_common_irq(uint8_t rhport, bool in_isr) { // (void) in_isr; // dwc2_regs_t * const dwc2 = DWC2_REG(rhport); diff --git a/src/portable/synopsys/dwc2/dwc2_common.h b/src/portable/synopsys/dwc2/dwc2_common.h index 428304ba9..af532dc5e 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.h +++ b/src/portable/synopsys/dwc2/dwc2_common.h @@ -86,6 +86,7 @@ TU_ATTR_ALWAYS_INLINE static inline dwc2_regs_t* DWC2_REG(uint8_t rhport) { bool dwc2_core_is_highspeed(dwc2_regs_t* dwc2, tusb_role_t role); bool dwc2_core_init(uint8_t rhport, bool is_highspeed, bool is_dma); +void dwc2_core_deinit(uint8_t rhport); void dwc2_core_handle_common_irq(uint8_t rhport, bool in_isr); //--------------------------------------------------------------------+ diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index c40703b09..fc27b3f55 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -445,6 +445,16 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { return true; } +bool hcd_deinit(uint8_t rhport) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + + // Disable global interrupt + dwc2->gahbcfg &= ~GAHBCFG_GINT; + + dwc2_core_deinit(rhport); + return true; +} + // Enable USB interrupt void hcd_int_enable (uint8_t rhport) { dwc2_int_set(rhport, TUSB_ROLE_HOST, true); -- cgit v1.3.1 From 5b49139e779516a66616054398f9738bccaf981b Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 28 Nov 2025 15:39:10 +0100 Subject: catch deinit error Signed-off-by: HiFiPhile --- src/device/usbd.c | 2 +- src/host/usbh.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index 1e21c667a..9cfc2cc59 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -585,7 +585,7 @@ bool tud_deinit(uint8_t rhport) { // Deinit device controller driver dcd_int_disable(rhport); dcd_disconnect(rhport); - TU_VERIFY(dcd_deinit(rhport)); + TU_ASSERT(dcd_deinit(rhport)); // Deinit class drivers for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { diff --git a/src/host/usbh.c b/src/host/usbh.c index a725b7c8b..da6afdddb 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -538,7 +538,7 @@ bool tuh_deinit(uint8_t rhport) { // deinit host controller hcd_int_disable(rhport); - hcd_deinit(rhport); + TU_ASSERT(hcd_deinit(rhport)); _usbh_data.controller_id = TUSB_INDEX_INVALID_8; // remove all devices on this rhport (hub_addr = 0, hub_port = 0) -- cgit v1.3.1 From 104cf33239eda282b34c1f7971fbfc8e310eabf8 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 29 Nov 2025 16:07:41 +0100 Subject: hcd/dwc2: disable ID change interrupt due to stuck on stm32f7 Signed-off-by: HiFiPhile --- src/portable/synopsys/dwc2/hcd_dwc2.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index fc27b3f55..9d58dd4a3 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -435,7 +435,7 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { dwc2->hprt = HPRT_POWER; // turn on VBUS // Enable required interrupts - dwc2->gintmsk |= GINTSTS_OTGINT | GINTSTS_CONIDSTSCHNG | GINTSTS_HPRTINT | GINTSTS_HCINT | GINTSTS_DISCINT; + dwc2->gintmsk |= GINTSTS_OTGINT | GINTSTS_HPRTINT | GINTSTS_HCINT | GINTSTS_DISCINT; // NPTX can hold at least 2 packet, change interrupt level to half-empty uint32_t gahbcfg = dwc2->gahbcfg & ~GAHBCFG_TX_FIFO_EPMTY_LVL; @@ -1448,16 +1448,6 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { // TU_LOG1_HEX(gintsts); - if (gintsts & GINTSTS_CONIDSTSCHNG) { - // Connector ID status change - dwc2->gintsts = GINTSTS_CONIDSTSCHNG; - - //if (dwc2->gotgctl) - // dwc2->hprt = HPRT_POWER; // power on port to turn on VBUS - //dwc2->gintmsk |= GINTMSK_PRTIM; - // TODO wait for SRP if OTG - } - if (gintsts & GINTSTS_SOF) { const bool more_sof = handle_sof_irq(rhport, in_isr); if (!more_sof) { -- cgit v1.3.1 From 4914ae83e516f9f81f75f5d0dc461904b6fcd551 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 28 Nov 2025 22:05:02 +0100 Subject: hcd/dwc2: retry transfer on data toggle error Signed-off-by: HiFiPhile --- src/portable/synopsys/dwc2/hcd_dwc2.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index 9d58dd4a3..fb075582f 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -879,7 +879,7 @@ static void handle_rxflvl_irq(uint8_t rhport) { break; case GRXSTS_PKTSTS_HOST_DATATOGGLE_ERR: - TU_ASSERT(0, ); // maybe try to change DToggle + // handle in channel interrupt break; case GRXSTS_PKTSTS_HOST_CHANNEL_HALTED: @@ -1019,8 +1019,11 @@ static bool handle_channel_in_slave(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t h channel_xfer_in_retry(dwc2, ch_id, hcint); } } else if (hcint & HCINT_DATATOGGLE_ERR) { + channel->hcintmsk &= ~HCINT_DATATOGGLE_ERR; xfer->err_count = 0; - TU_ASSERT(false); + hcsplt.split_compl = 0; // restart with start-split + channel->hcsplt = hcsplt.value; + channel_disable(dwc2, channel); } else { // nothing to do } -- cgit v1.3.1 From bbe1be349a3011da3839906d6b90110e140ddbe1 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 15 Dec 2025 22:19:35 +0100 Subject: hcd/stm32_fsdev: fix init after device mode Signed-off-by: HiFiPhile --- src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c index acdeccf6d..1813ef70b 100644 --- a/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c @@ -223,9 +223,13 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { tu_memclr(&_hcd_data, sizeof(_hcd_data)); + // Clear pending interrupts + // Normally no interrupts should be pending here since we just reset the core, + // but device mode suspend needs to cleared by WKUP flag + FSDEV_REG->ISTR = 0; + // Enable interrupts for host mode - FSDEV_REG->CNTR |= USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SOFM | USB_CNTR_SUSPM | - USB_CNTR_WKUPM | USB_CNTR_ERRM | USB_CNTR_PMAOVRM; + FSDEV_REG->CNTR |= USB_CNTR_DCON | USB_CNTR_CTRM | USB_CNTR_SOFM | USB_CNTR_ERRM | USB_CNTR_PMAOVRM; // Initialize port state _hcd_data.connected = false; -- cgit v1.3.1 From a124edf9f6d008074f838c6daaed7c0502569ab7 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 7 Jan 2026 09:58:23 +0700 Subject: refactor remove endpoint_control/buffer_control from hw_endpoint_t --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 49 ++++++++------- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 33 +++++------ src/portable/raspberrypi/rp2040/rp2040_usb.c | 29 ++++----- src/portable/raspberrypi/rp2040/rp2040_usb.h | 89 +++++++++++++++++++++------- 4 files changed, 123 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 15852f29f..31683502a 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -55,14 +55,14 @@ static struct hw_endpoint hw_endpoints[USB_MAX_ENDPOINTS][2]; // SOF may be used by remote wakeup as RESUME, this indicate whether SOF is actually used by usbd static bool _sof_enable = false; -TU_ATTR_ALWAYS_INLINE static inline struct hw_endpoint* hw_endpoint_get_by_num(uint8_t num, tusb_dir_t dir) { +TU_ATTR_ALWAYS_INLINE static inline struct hw_endpoint *hw_endpoint_get(uint8_t num, tusb_dir_t dir) { return &hw_endpoints[num][dir]; } TU_ATTR_ALWAYS_INLINE static inline struct hw_endpoint* hw_endpoint_get_by_addr(uint8_t ep_addr) { uint8_t num = tu_edpt_number(ep_addr); tusb_dir_t dir = tu_edpt_dir(ep_addr); - return hw_endpoint_get_by_num(num, dir); + return hw_endpoint_get(num, dir); } // Allocate from the USB buffer space (max 3840 bytes) @@ -86,15 +86,14 @@ static void hw_endpoint_alloc(struct hw_endpoint* ep, size_t size) { // Enable endpoint TU_ATTR_ALWAYS_INLINE static inline void hw_endpoint_enable(struct hw_endpoint* ep) { uint32_t const reg = EP_CTRL_ENABLE_BITS | ((uint) ep->transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | hw_data_offset(ep->hw_data_buf); - *ep->endpoint_control = reg; + *hwep_ctrl_reg(ep) = reg; } // main processing for dcd_edpt_iso_activate static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) { - struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr); - const uint8_t num = tu_edpt_number(ep_addr); const tusb_dir_t dir = tu_edpt_dir(ep_addr); + hw_endpoint_t* ep = hw_endpoint_get(num, dir); ep->ep_addr = ep_addr; @@ -106,28 +105,28 @@ static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t t ep->transfer_type = transfer_type; // Every endpoint has a buffer control register in dpram - if (dir == TUSB_DIR_IN) { - ep->buffer_control = &usb_dpram->ep_buf_ctrl[num].in; - } else { - ep->buffer_control = &usb_dpram->ep_buf_ctrl[num].out; - } + // if (dir == TUSB_DIR_IN) { + // ep->buffer_control = &usb_dpram->ep_buf_ctrl[num].in; + // } else { + // ep->buffer_control = &usb_dpram->ep_buf_ctrl[num].out; + // } // Clear existing buffer control state - *ep->buffer_control = 0; + *hwep_buf_ctrl_reg(ep) = 0; if (num == 0) { // EP0 has no endpoint control register because the buffer offsets are fixed - ep->endpoint_control = NULL; + // ep->endpoint_control = NULL; // Buffer offset is fixed (also double buffered) ep->hw_data_buf = (uint8_t*) &usb_dpram->ep0_buf_a[0]; } else { // Set the endpoint control register (starts at EP1, hence num-1) - if (dir == TUSB_DIR_IN) { - ep->endpoint_control = &usb_dpram->ep_ctrl[num - 1].in; - } else { - ep->endpoint_control = &usb_dpram->ep_ctrl[num - 1].out; - } + // if (dir == TUSB_DIR_IN) { + // ep->endpoint_control = &usb_dpram->ep_ctrl[num - 1].in; + // } else { + // ep->endpoint_control = &usb_dpram->ep_ctrl[num - 1].out; + // } } } @@ -165,7 +164,7 @@ static void hw_endpoint_abort_xfer(struct hw_endpoint* ep) { buf_ctrl |= USB_BUF_CTRL_DATA1_PID; } - _hw_endpoint_buffer_control_set_value32(ep, buf_ctrl); + hwep_buf_ctrl_set(ep, buf_ctrl); hw_endpoint_reset_transfer(ep); if (rp2040_chip_version() >= 2) { @@ -184,7 +183,7 @@ static void __tusb_irq_path_func(hw_handle_buff_status)(void) { usb_hw_clear->buf_status = bit; // IN transfer for even i, OUT transfer for odd i - struct hw_endpoint* ep = hw_endpoint_get_by_num(i >> 1u, (i & 1u) ? TUSB_DIR_OUT : TUSB_DIR_IN); + struct hw_endpoint *ep = hw_endpoint_get(i >> 1u, (i & 1u) ? TUSB_DIR_OUT : TUSB_DIR_IN); // Continue xfer bool done = hw_endpoint_xfer_continue(ep); @@ -204,7 +203,7 @@ TU_ATTR_ALWAYS_INLINE static inline void reset_ep0(void) { // If we have finished this transfer on EP0 set pid back to 1 for next // setup transfer. Also clear a stall in case for (uint8_t dir = 0; dir < 2; dir++) { - struct hw_endpoint* ep = hw_endpoint_get_by_num(0, dir); + struct hw_endpoint *ep = hw_endpoint_get(0, dir); ep->next_pid = 1u; if (ep->active) { hw_endpoint_abort_xfer(ep); // Abort any pending transfer per USB specs @@ -240,7 +239,7 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { e15_last_sof = time_us_32(); for (uint8_t i = 0; i < USB_MAX_ENDPOINTS; i++) { - struct hw_endpoint* ep = hw_endpoint_get_by_num(i, TUSB_DIR_IN); + struct hw_endpoint *ep = hw_endpoint_get(i, TUSB_DIR_IN); // Active Bulk IN endpoint requires SOF if ((ep->transfer_type == TUSB_XFER_BULK) && ep->active) { @@ -369,9 +368,9 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { TU_LOG(2, "Chip Version B%u\r\n", rp2040_chip_version()); // Reset hardware to default state - rp2040_usb_init(); + rp2usb_init(); -#if FORCE_VBUS_DETECT + #if FORCE_VBUS_DETECT // Force VBUS detect so the device thinks it is plugged into a host usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS; #endif @@ -546,7 +545,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { // stall and clear current pending buffer // may need to use EP_ABORT - _hw_endpoint_buffer_control_set_value32(ep, USB_BUF_CTRL_STALL); + hwep_buf_ctrl_set(ep, USB_BUF_CTRL_STALL); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { @@ -557,7 +556,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { // clear stall also reset toggle to DATA0, ready for next transfer ep->next_pid = 0; - _hw_endpoint_buffer_control_clear_mask32(ep, USB_BUF_CTRL_STALL); + hwep_buf_ctrl_clear_mask(ep, USB_BUF_CTRL_STALL); } } diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index cd8c905d5..12a2f2d25 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -122,7 +122,7 @@ static void __tusb_irq_path_func(hw_handle_buff_status)(void) remaining_buffers &= ~bit; struct hw_endpoint * ep = &epx; - uint32_t ep_ctrl = *ep->endpoint_control; + uint32_t ep_ctrl = *hwep_ctrl_reg(ep); if ( ep_ctrl & EP_CTRL_DOUBLE_BUFFERED_BITS ) { TU_LOG(3, "Double Buffered: "); @@ -240,9 +240,8 @@ static void __tusb_irq_path_func(hcd_rp2040_irq)(void) if ( status & USB_INTS_ERROR_DATA_SEQ_BITS ) { usb_hw_clear->sie_status = USB_SIE_STATUS_DATA_SEQ_ERROR_BITS; - TU_LOG(3, " Seq Error: [0] = 0x%04u [1] = 0x%04x\r\n", - tu_u32_low16(*epx.buffer_control), - tu_u32_high16(*epx.buffer_control)); + TU_LOG(3, " Seq Error: [0] = 0x%04u [1] = 0x%04x\r\n", tu_u32_low16(*hw_endpoint_get_buf_ctrl(&epx)), + tu_u32_high16(*hw_endpoint_get_buf_ctrl(&epx))); panic("Data Seq Error \n"); } @@ -285,8 +284,8 @@ static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type) ep = _next_free_interrupt_ep(); pico_info("Allocate %s ep %d\n", tu_edpt_type_str(transfer_type), ep->interrupt_num); assert(ep); - ep->buffer_control = &usbh_dpram->int_ep_buffer_ctrl[ep->interrupt_num].ctrl; - ep->endpoint_control = &usbh_dpram->int_ep_ctrl[ep->interrupt_num].ctrl; + // ep->buffer_control = &usbh_dpram->int_ep_buffer_ctrl[ep->interrupt_num].ctrl; + // ep->endpoint_control = &usbh_dpram->int_ep_ctrl[ep->interrupt_num].ctrl; // 0 for epx (double buffered): TODO increase to 1024 for ISO // 2x64 for intep0 // 3x64 for intep1 @@ -296,8 +295,8 @@ static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type) else { ep = &epx; - ep->buffer_control = &usbh_dpram->epx_buf_ctrl; - ep->endpoint_control = &usbh_dpram->epx_ctrl; + // ep->buffer_control = &usbh_dpram->epx_buf_ctrl; + // ep->endpoint_control = &usbh_dpram->epx_ctrl; ep->hw_data_buf = &usbh_dpram->epx_data[0]; } @@ -307,8 +306,8 @@ static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type) static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type, uint8_t bmInterval) { // Already has data buffer, endpoint control, and buffer control allocated at this point - assert(ep->endpoint_control); - assert(ep->buffer_control); + // assert(ep->endpoint_control); + // assert(ep->buffer_control); assert(ep->hw_data_buf); uint8_t const num = tu_edpt_number(ep_addr); @@ -340,8 +339,8 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t { ep_reg |= (uint32_t) ((bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB); } - *ep->endpoint_control = ep_reg; - pico_trace("endpoint control (0x%p) <- 0x%lx\n", ep->endpoint_control, ep_reg); + *hwep_ctrl_reg(ep) = ep_reg; + // pico_trace("endpoint control (0x%p) <- 0x%lx\n", ep->endpoint_control, ep_reg); ep->configured = true; if ( ep != &epx ) @@ -382,7 +381,7 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { assert(rhport == 0); // Reset any previous state - rp2040_usb_init(); + rp2usb_init(); // Force VBUS detect to always present, for now we assume vbus is always provided (without using VBUS En) usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS; @@ -466,8 +465,8 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { // reset epx if it is currently active with unplugged device if (epx.configured && epx.active && epx.dev_addr == dev_addr) { epx.configured = false; - *epx.endpoint_control = 0; - *epx.buffer_control = 0; + *hwep_ctrl_reg(&epx) = 0; + *hwep_buf_ctrl_reg(&epx) = 0; hw_endpoint_reset_transfer(&epx); } @@ -482,8 +481,8 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { // unconfigure the endpoint ep->configured = false; - *ep->endpoint_control = 0; - *ep->buffer_control = 0; + *hwep_ctrl_reg(ep) = 0; + *hwep_buf_ctrl_reg(ep) = 0; hw_endpoint_reset_transfer(ep); } } diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 9d0bd762d..61f978b0d 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -62,7 +62,7 @@ static void unaligned_memcpy(void *dst, const void *src, size_t n) { } } -void rp2040_usb_init(void) { +void rp2usb_init(void) { // Reset usb controller reset_block(RESETS_RESET_USBCTRL_BITS); unreset_block_wait(RESETS_RESET_USBCTRL_BITS); @@ -93,21 +93,21 @@ void __tusb_irq_path_func(hw_endpoint_reset_transfer)(struct hw_endpoint* ep) { ep->user_buf = 0; } -void __tusb_irq_path_func(_hw_endpoint_buffer_control_update32)(struct hw_endpoint* ep, uint32_t and_mask, - uint32_t or_mask) { +void __tusb_irq_path_func(hwep_buf_ctrl_update)(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask) { uint32_t value = 0; + io_rw_32 *buf_ctrl = hwep_buf_ctrl_reg(ep); if (and_mask) { - value = *ep->buffer_control & and_mask; + value = *buf_ctrl & and_mask; } if (or_mask) { value |= or_mask; if (or_mask & USB_BUF_CTRL_AVAIL) { - if (*ep->buffer_control & USB_BUF_CTRL_AVAIL) { + if (*buf_ctrl & USB_BUF_CTRL_AVAIL) { panic("ep %02X was already available", ep->ep_addr); } - *ep->buffer_control = value & ~USB_BUF_CTRL_AVAIL; + *buf_ctrl = value & ~USB_BUF_CTRL_AVAIL; // 4.1.2.5.1 Con-current access: 12 cycles (should be good for 48*12Mhz = 576Mhz) after write to buffer control // Don't need delay in host mode as host is in charge if (!is_host_mode()) { @@ -116,7 +116,7 @@ void __tusb_irq_path_func(_hw_endpoint_buffer_control_update32)(struct hw_endpoi } } - *ep->buffer_control = value; + *buf_ctrl = value; } // prepare buffer, return buffer control @@ -153,7 +153,8 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint* ep, // Prepare buffer control register value void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint* ep) { - uint32_t ep_ctrl = *ep->endpoint_control; + io_rw_32 *ep_ctrl_reg = hwep_ctrl_reg(ep); + uint32_t ep_ctrl = *ep_ctrl_reg; // always compute and start with buffer 0 uint32_t buf_ctrl = prepare_ep_buffer(ep, 0) | USB_BUF_CTRL_SEL; @@ -182,13 +183,13 @@ void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint* ep) ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER; } - *ep->endpoint_control = ep_ctrl; + *ep_ctrl_reg = ep_ctrl; TU_LOG(3, " Prepare BufCtrl: [0] = 0x%04x [1] = 0x%04x\r\n", tu_u32_low16(buf_ctrl), tu_u32_high16(buf_ctrl)); // Finally, write to buffer_control which will trigger the transfer // the next time the controller polls this dpram address - _hw_endpoint_buffer_control_set_value32(ep, buf_ctrl); + hwep_buf_ctrl_set(ep, buf_ctrl); } void hw_endpoint_xfer_start(struct hw_endpoint* ep, uint8_t* buffer, uint16_t total_len) { @@ -221,7 +222,7 @@ void hw_endpoint_xfer_start(struct hw_endpoint* ep, uint8_t* buffer, uint16_t to // sync endpoint buffer and return transferred bytes static uint16_t __tusb_irq_path_func(sync_ep_buffer)(struct hw_endpoint* ep, uint8_t buf_id) { - uint32_t buf_ctrl = _hw_endpoint_buffer_control_get_value32(ep); + uint32_t buf_ctrl = hwep_buf_ctrl_get(ep); if (buf_id) buf_ctrl = buf_ctrl >> 16; uint16_t xferred_bytes = buf_ctrl & USB_BUF_CTRL_LEN_MASK; @@ -256,14 +257,14 @@ static void __tusb_irq_path_func(_hw_endpoint_xfer_sync)(struct hw_endpoint* ep) // Update hw endpoint struct with info from hardware // after a buff status interrupt - uint32_t __unused buf_ctrl = _hw_endpoint_buffer_control_get_value32(ep); + uint32_t __unused buf_ctrl = hwep_buf_ctrl_get(ep); TU_LOG(3, " Sync BufCtrl: [0] = 0x%04x [1] = 0x%04x\r\n", tu_u32_low16(buf_ctrl), tu_u32_high16(buf_ctrl)); // always sync buffer 0 uint16_t buf0_bytes = sync_ep_buffer(ep, 0); // sync buffer 1 if double buffered - if ((*ep->endpoint_control) & EP_CTRL_DOUBLE_BUFFERED_BITS) { + if ((*hwep_ctrl_reg(ep)) & EP_CTRL_DOUBLE_BUFFERED_BITS) { if (buf0_bytes == ep->wMaxPacketSize) { // sync buffer 1 if not short packet sync_ep_buffer(ep, 1); @@ -287,7 +288,7 @@ static void __tusb_irq_path_func(_hw_endpoint_xfer_sync)(struct hw_endpoint* ep) ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER); ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER; - _hw_endpoint_buffer_control_set_value32(ep, 0); + hwep_buf_ctrl_set(ep, 0); usb_hw->abort &= ~TU_BIT(ep_id); diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.h b/src/portable/raspberrypi/rp2040/rp2040_usb.h index d4d29a816..603640c6d 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.h +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.h @@ -56,10 +56,10 @@ typedef struct hw_endpoint uint8_t next_pid; // Endpoint control register - io_rw_32 *endpoint_control; + // io_rw_32 *endpoint_control; // Buffer control register - io_rw_32 *buffer_control; + // io_rw_32 *buffer_control; // Buffer pointer in usb dpram uint8_t *hw_data_buf; @@ -97,7 +97,12 @@ typedef struct hw_endpoint extern volatile uint32_t e15_last_sof; #endif -void rp2040_usb_init(void); +void rp2usb_init(void); + +// if usb hardware is in host mode +TU_ATTR_ALWAYS_INLINE static inline bool rp2usb_is_host_mode(void) { + return (usb_hw->main_ctrl & USB_MAIN_CTRL_HOST_NDEVICE_BITS) ? true : false; +} void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, uint16_t total_len); bool hw_endpoint_xfer_continue(struct hw_endpoint *ep); @@ -110,34 +115,76 @@ TU_ATTR_ALWAYS_INLINE static inline void hw_endpoint_lock_update(__unused struct // sense to have worker and IRQ on same core, however I think using critsec is about equivalent. } -void _hw_endpoint_buffer_control_update32(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask); +TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_ctrl_reg(struct hw_endpoint *ep) { + (void)ep; +#if CFG_TUH_ENABLED + if (rp2usb_is_host_mode()) { + if (ep->transfer_type == TUSB_XFER_CONTROL) { + return &usbh_dpram->epx_ctrl; + } + return &usbh_dpram->int_ep_ctrl[ep->interrupt_num].ctrl; + } +#endif -TU_ATTR_ALWAYS_INLINE static inline uint32_t _hw_endpoint_buffer_control_get_value32 (struct hw_endpoint *ep) -{ - return *ep->buffer_control; +#if CFG_TUD_ENABLED + if (!rp2usb_is_host_mode()) { + const uint8_t num = tu_edpt_number(ep->ep_addr); + if (num == 0) { + return NULL; + } + return (tu_edpt_dir(ep->ep_addr) == TUSB_DIR_IN) ? &usb_dpram->ep_ctrl[num - 1].in + : &usb_dpram->ep_ctrl[num - 1].out; + } +#endif + + return NULL; } -TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_buffer_control_set_value32 (struct hw_endpoint *ep, uint32_t value) -{ - _hw_endpoint_buffer_control_update32(ep, 0, value); +TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_buf_ctrl_reg(struct hw_endpoint *ep) { + (void)ep; +#if CFG_TUH_ENABLED + if (rp2usb_is_host_mode()) { + if (ep->transfer_type == TUSB_XFER_CONTROL) { + return &usbh_dpram->epx_buf_ctrl; + } + return &usbh_dpram->int_ep_buffer_ctrl[ep->interrupt_num].ctrl; + } +#endif + +#if CFG_TUD_ENABLED + if (!rp2usb_is_host_mode()) { + const uint8_t num = tu_edpt_number(ep->ep_addr); + return (tu_edpt_dir(ep->ep_addr) == TUSB_DIR_IN) ? &usb_dpram->ep_buf_ctrl[num].in + : &usb_dpram->ep_buf_ctrl[num].out; + } +#endif + return NULL; } -TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_buffer_control_set_mask32 (struct hw_endpoint *ep, uint32_t value) -{ - _hw_endpoint_buffer_control_update32(ep, ~value, value); +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ +void hwep_buf_ctrl_update(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask); + +TU_ATTR_ALWAYS_INLINE static inline uint32_t hwep_buf_ctrl_get(struct hw_endpoint *ep) { + return *hwep_buf_ctrl_reg(ep); } -TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_buffer_control_clear_mask32 (struct hw_endpoint *ep, uint32_t value) -{ - _hw_endpoint_buffer_control_update32(ep, ~value, 0); +TU_ATTR_ALWAYS_INLINE static inline void hwep_buf_ctrl_set(struct hw_endpoint *ep, uint32_t value) { + hwep_buf_ctrl_update(ep, 0, value); } -static inline uintptr_t hw_data_offset (uint8_t *buf) -{ - // Remove usb base from buffer pointer - return (uintptr_t) buf ^ (uintptr_t) usb_dpram; +TU_ATTR_ALWAYS_INLINE static inline void hwep_buf_ctrl_set_mask32(struct hw_endpoint *ep, uint32_t value) { + hwep_buf_ctrl_update(ep, ~value, value); +} + +TU_ATTR_ALWAYS_INLINE static inline void hwep_buf_ctrl_clear_mask(struct hw_endpoint *ep, uint32_t value) { + hwep_buf_ctrl_update(ep, ~value, 0); } -extern const char *ep_dir_string[]; +static inline uintptr_t hw_data_offset(uint8_t *buf) { + // Remove usb base from buffer pointer + return (uintptr_t)buf ^ (uintptr_t)usb_dpram; +} #endif -- cgit v1.3.1 From 0e5241aa83c52792959ad8a2ef0535a3759530a7 Mon Sep 17 00:00:00 2001 From: Rémi Berthoz Date: Wed, 7 Jan 2026 17:04:48 +0100 Subject: Adjust printer device class to 0.20.0 and fix compilation warnings --- examples/device/printer_to_hid/src/main.c | 73 +++--- .../device/printer_to_hid/src/usb_descriptors.c | 278 +++++++-------------- .../device/printer_to_hid/src/usb_descriptors.h | 48 +++- hw/bsp/rp2040/family.cmake | 1 + src/class/printer/printer.h | 9 +- src/class/printer/printer_device.c | 13 +- src/device/usbd.h | 13 + src/tusb.h | 4 + 8 files changed, 208 insertions(+), 231 deletions(-) (limited to 'src') diff --git a/examples/device/printer_to_hid/src/main.c b/examples/device/printer_to_hid/src/main.c index f5012478c..46203b9db 100644 --- a/examples/device/printer_to_hid/src/main.c +++ b/examples/device/printer_to_hid/src/main.c @@ -39,7 +39,7 @@ // usb interface pointer uint8_t printer_itf = 0; // pendings bytes in usb endpoint buffer ; must process these bytes -uint8_t pending_bytes_on_usb_ep = 0; +size_t pending_bytes_on_usb_ep = 0; // -------------------------------------------------------------------+ @@ -72,7 +72,7 @@ uint8_t next_keycode_is_release = false; // next_keycode and place it in the HID report, then set next_is_null // such that the key is released by the next report. This seem to help // stroking the same key twice when the character is repeated in the data. -void hid_tx_task(void) { +static void hid_tx_task(void) { // Poll every 10ms const uint32_t interval_ms = 10; static uint32_t start_ms = 0; @@ -104,28 +104,30 @@ void hid_tx_task(void) { // overwrite local data that is not processed yet, so we use data_buffer as a fifo. // We do not have to take care of reading correctly from the endpoint buffer, as all // is done well by tud_printer_n_read(). -void printer_rx_task(void) { - if (pending_bytes_on_usb_ep > 0) { - size_t len1 = data_available; - size_t len2 = 0; - if (len1 < 0) { - len1 = 0; - } - if (data_rx_offset + len1 > sizeof(data_buffer)) { - len2 = len1 - (sizeof(data_buffer) - data_rx_offset); - len1 = sizeof(data_buffer) - data_rx_offset; - } - uint32_t count = tud_printer_n_read(printer_itf, data_buffer + data_rx_offset, len1); - if (len2 > 0) { - count += tud_printer_n_read(printer_itf, data_buffer, len2); - } +static void printer_rx_task(void) { - if (count > 0) { - data_available -= count; - pending_bytes_on_usb_ep -= count; - data_rx_offset = (data_rx_offset + count) % sizeof(data_buffer); - } + if (pending_bytes_on_usb_ep == 0) { + return; + } + + size_t len1 = data_available; + size_t len2 = 0; + if (data_rx_offset + len1 > sizeof(data_buffer)) { + len2 = len1 - (sizeof(data_buffer) - data_rx_offset); + len1 = sizeof(data_buffer) - data_rx_offset; + } + uint32_t count = tud_printer_n_read(printer_itf, data_buffer + data_rx_offset, len1); + if (len2 > 0) { + count += tud_printer_n_read(printer_itf, data_buffer, len2); } + + if (count == 0) { + return; + } + + data_available -= count; + pending_bytes_on_usb_ep -= count; + data_rx_offset = (data_rx_offset + count) % sizeof(data_buffer); } // The HID keycodes are not binary mapped like UTF8 codes. If we want to send the @@ -134,7 +136,7 @@ void printer_rx_task(void) { // hosts expecting hid data from a QWERTY keyboard. Also note that only a-zA-Z0-9 // characters are converted, for simplicity of the example. Other characters are // converted to spaces. -void translation_task(void) { +static void translation_task(void) { if (data_tx_offset != data_rx_offset || data_available == 0) { // If data_tx_offset and data_rx_offset have different values, then we // can proceed: translate, prepare for TX, and advance data_tx_offset. @@ -177,18 +179,22 @@ void translation_task(void) { } int main(void) { - board_init(); - tud_init(BOARD_TUD_RHPORT); // init device stack on configured roothub port - if (board_init_after_tusb) { - board_init_after_tusb(); - } + // init device and host stack on configured roothub port + tusb_rhport_init_t dev_init = {.role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; + tusb_init(BOARD_TUD_RHPORT, &dev_init); + board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task printer_rx_task(); // read data sent by host on our printer interface translation_task(); // translate printer's UTF8 to HID keycodes hid_tx_task(); // send data to host with our HID interface + if (pending_bytes_on_usb_ep > 0) { + board_led_on(); + } else { + board_led_off(); + } } } @@ -197,7 +203,6 @@ int main(void) { // Printer callbacks //--------------------------------------------------------------------+ -// Data was received on endpoint buffer void tud_printer_rx_cb(uint8_t itf, size_t n) { printer_itf = itf; // get interface from which to read endpoint buffer pending_bytes_on_usb_ep += n; // count pending bytes, counter must decrement when reading from the endpoint buffer @@ -210,10 +215,20 @@ void tud_printer_rx_cb(uint8_t itf, size_t n) { uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) { + (void)instance; + (void)report_id; + (void)report_type; + (void)buffer; + (void)reqlen; return 0; } void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, const uint8_t *buffer, uint16_t bufsize) { + (void)instance; + (void)report_id; + (void)report_type; + (void)buffer; + (void)bufsize; return; } diff --git a/examples/device/printer_to_hid/src/usb_descriptors.c b/examples/device/printer_to_hid/src/usb_descriptors.c index 161bbb7c5..7d529e724 100644 --- a/examples/device/printer_to_hid/src/usb_descriptors.c +++ b/examples/device/printer_to_hid/src/usb_descriptors.c @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2026 Ha Thach (tinyusb.org) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,223 +25,119 @@ #include "bsp/board_api.h" #include "tusb.h" -#include "usb_descriptors.h" - -/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. - * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. - * - * Auto ProductID layout's Bitmap: - * [MSB] HID | MSC | CDC [LSB] - */ -#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ - PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) - -#define USB_VID 0xCafe -#define USB_BCD 0x0200 - -//--------------------------------------------------------------------+ -// Device Descriptors -//--------------------------------------------------------------------+ -static tusb_desc_device_t const desc_device = -{ - .bLength = sizeof(tusb_desc_device_t), - .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = USB_BCD, - .bDeviceClass = 0x00, - .bDeviceSubClass = 0x00, - .bDeviceProtocol = 0x00, - .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - - .idVendor = USB_VID, - .idProduct = USB_PID, - .bcdDevice = 0x0100, - - .iManufacturer = 0x01, - .iProduct = 0x02, - .iSerialNumber = 0x03, - - .bNumConfigurations = 0x01 -}; - -// Invoked when received GET DEVICE DESCRIPTOR -// Application return pointer to descriptor -uint8_t const * tud_descriptor_device_cb(void) -{ - return (uint8_t const *) &desc_device; -} -//--------------------------------------------------------------------+ -// HID Report Descriptor -//--------------------------------------------------------------------+ - -uint8_t const desc_hid_report[] = -{ - TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD )) -}; +#include "usb_descriptors.h" -// Invoked when received GET HID REPORT DESCRIPTOR -// Application return pointer to descriptor -// Descriptor contents must exist long enough for transfer to complete -uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance) -{ - (void) instance; - return desc_hid_report; -} //--------------------------------------------------------------------+ -// Configuration Descriptor +// Report definitions //--------------------------------------------------------------------+ -enum -{ - ITF_NUM_HID, - ITF_NUM_PRINTER, - ITF_NUM_TOTAL +// Values of the string descriptors. Order must match the order defined by STRING_DESCRIPTOR_INDICES. +const char *STRING_DESCRIPTOR_VALUES[] = { + (const char[]){0x09, 0x04}, // 0: Supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + NULL, // 3: Serial number, will use unique ID from the Pi Pico board hardware + "Config1", // 4: Configuration + "Hid1", // 5: HID interface + "Print1", // 6: Printer interface }; -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN + TUD_PRINTER_DESC_LEN) +uint8_t HID_REPORT_DESCRIPTOR[] = {TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(REPORT_ID_KEYBOARD))}; -// HID interface endpoints -#define EPADDR_HID 0x81 // Interrupt In, MSB must be 1 -// Printer interface endpoints -#define EPADDR_PRINTER_OUT 0x01 // Bulk Out, MSB must be 0 -#define EPADDR_PRINTER_IN 0x82 // Bulk In, MSB must be 1 - -uint8_t const desc_configuration[] = -{ +uint8_t CONFIG_INTERFACE_ENDPOINT_DESCRIPTOR[] = { // Config number, interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), + TUD_CONFIG_DESCRIPTOR(1, ITF_COUNT, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), // HID: // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval - TUD_HID_DESCRIPTOR(ITF_NUM_HID, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPADDR_HID, CFG_TUD_HID_EP_BUFSIZE, 5), + TUD_HID_DESCRIPTOR(ITF_HID, 0, HID_ITF_PROTOCOL_NONE, sizeof(HID_REPORT_DESCRIPTOR), EPADDR_HID, + CFG_TUD_HID_EP_BUFSIZE, 5), // Printer: // Interface number, string index, EP Bulk Out address, EP Bulk In address, EP size - TUD_PRINTER_DESCRIPTOR(ITF_NUM_PRINTER, 0, EPADDR_PRINTER_OUT, EPADDR_PRINTER_IN, CFG_TUD_PRINTER_EP_BUFSIZE) + TUD_PRINTER_DESCRIPTOR(ITF_PRINTER, 0, EPADDR_PRINTER_OUT, EPADDR_PRINTER_IN, CFG_TUD_PRINTER_EP_BUFSIZE)}; + +static const tusb_desc_device_t DEVICE_DESCRIPTOR = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = USB_BCD, + .bDeviceClass = 0x00, // Define class at interface level + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = USB_VID, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = STR_MANUFACTURER, + .iProduct = STR_PRODUCT, + .iSerialNumber = STR_SERIAL, + + .bNumConfigurations = 0x01 }; -#if TUD_OPT_HIGH_SPEED -// Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration - -// other speed configuration -static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; - -// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed -static tusb_desc_device_qualifier_t const desc_device_qualifier = -{ - .bLength = sizeof(tusb_desc_device_qualifier_t), - .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, - .bcdUSB = USB_BCD, - .bDeviceClass = 0x00, - .bDeviceSubClass = 0x00, - .bDeviceProtocol = 0x00, - - .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - .bNumConfigurations = 0x01, - .bReserved = 0x00 -}; +//--------------------------------------------------------------------+ +// TinyUSB callbacks (descriptor requests) +//--------------------------------------------------------------------+ -// Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request -// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. -// device_qualifier descriptor describes information about a high-speed capable device that would -// change if the device were operating at the other speed. If not highspeed capable stall this request. -uint8_t const* tud_descriptor_device_qualifier_cb(void) -{ - return (uint8_t const*) &desc_device_qualifier; +// TinyUSB GET HID REPORT DESCRIPTOR callback. +const uint8_t *tud_hid_descriptor_report_cb(uint8_t instance) { + (void)instance; + return HID_REPORT_DESCRIPTOR; } -// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request -// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete -// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa -uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) -{ - (void) index; // for multiple configurations - - // other speed config is basically configuration with type = OTHER_SPEED_CONFIG - memcpy(desc_other_speed_config, desc_configuration, CONFIG_TOTAL_LEN); - desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; - - // this example use the same configuration for both high and full speed mode - return desc_other_speed_config; +// TinyUSB GET CONFIGURATION DESCRIPTOR callback. +const uint8_t *tud_descriptor_configuration_cb(uint8_t index) { + (void)index; + return CONFIG_INTERFACE_ENDPOINT_DESCRIPTOR; } -#endif // highspeed - -// Invoked when received GET CONFIGURATION DESCRIPTOR -// Application return pointer to descriptor -// Descriptor contents must exist long enough for transfer to complete -uint8_t const * tud_descriptor_configuration_cb(uint8_t index) -{ - (void) index; // for multiple configurations - - // This example use the same configuration for both high and full speed mode - return desc_configuration; +// TinyUSB GET DEVICE DESCRIPTOR callback. +const uint8_t *tud_descriptor_device_cb(void) { + return (const uint8_t *)&DEVICE_DESCRIPTOR; } -//--------------------------------------------------------------------+ -// String Descriptors -//--------------------------------------------------------------------+ - -// String Descriptor Index -enum { - STRID_LANGID = 0, - STRID_MANUFACTURER, - STRID_PRODUCT, - STRID_SERIAL, -}; - -// array of pointer to string descriptors -static char const *string_desc_arr[] = -{ - (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) - "TinyUSB", // 1: Manufacturer - "TinyUSB Device", // 2: Product - NULL, // 3: Serials will use unique ID if possible -}; - -static uint16_t _desc_str[32 + 1]; - -// Invoked when received GET STRING DESCRIPTOR request -// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete -uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { - (void) langid; - size_t chr_count; - - switch ( index ) { - case STRID_LANGID: - memcpy(&_desc_str[1], string_desc_arr[0], 2); - chr_count = 1; - break; - - case STRID_SERIAL: - chr_count = board_usb_get_serial(_desc_str + 1, 32); - break; - - default: - // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. - // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - - if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; - - const char *str = string_desc_arr[index]; - - // Cap at max char - chr_count = strlen(str); - size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type - if ( chr_count > max_count ) chr_count = max_count; - - // Convert ASCII string into UTF-16 - for ( size_t i = 0; i < chr_count; i++ ) { - _desc_str[1 + i] = str[i]; - } - break; +// Storage buffer array for string descriptor to be sent to host. +static uint16_t string_descriptor_buffer[STRING_DESCRIPTOR_MAX_LENGTH + 1]; + +// TinyUSB GET STRING DESCRIPTOR callback. +const uint16_t *tud_descriptor_string_cb(uint8_t index, [[maybe_unused]] uint16_t langid) { + size_t utf16_string_length; + + if (index == LANGID) { + // langid is not a string as in a series of characters: language ID code is binary, 2 bytes + memcpy(string_descriptor_buffer + 1, STRING_DESCRIPTOR_VALUES[LANGID], 2); + utf16_string_length = 1; // 2 bytes = 1 UTF16 word + + } else if (index == STR_SERIAL) { + // serialnumber is generated from pi pico: see note in STRING_DESCRIPTOR_VALUES definition + utf16_string_length = board_usb_get_serial(string_descriptor_buffer + 1, STRING_DESCRIPTOR_MAX_LENGTH); + + } else if (index < STRING_COUNT) { + // Get adequate descriptor string + const char *str = STRING_DESCRIPTOR_VALUES[index]; + utf16_string_length = strlen(str); + if (utf16_string_length > STRING_DESCRIPTOR_MAX_LENGTH) { + utf16_string_length = STRING_DESCRIPTOR_MAX_LENGTH; + } + // Convert ASCII string from memory (char*) to UTF16 (for buffer), + // store in buffer with 1 UTF16 word offset (2 bytes, for buffer header) + for (size_t i = 0; i < utf16_string_length; i++) { + string_descriptor_buffer[i + 1] = str[i]; + } + + } else { + return NULL; } - // first byte is length (including header), second byte is string type - _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); + // Set buffer header: + // byte 1 - buffer length in bytes (including header) + // byte 0 - string descriptor type (0x03). + string_descriptor_buffer[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * utf16_string_length + 2)); - return _desc_str; + return string_descriptor_buffer; } diff --git a/examples/device/printer_to_hid/src/usb_descriptors.h b/examples/device/printer_to_hid/src/usb_descriptors.h index 53c4e1fbd..0d9793a9c 100644 --- a/examples/device/printer_to_hid/src/usb_descriptors.h +++ b/examples/device/printer_to_hid/src/usb_descriptors.h @@ -25,6 +25,52 @@ #ifndef USB_DESCRIPTORS_H_ #define USB_DESCRIPTORS_H_ -REPORT_ID_KEYBOARD = 1 +#include "bsp/board_api.h" +#include "tusb.h" + +#define USB_VID 0xCafe // unassigned vendor id +#define USB_PID 0x4004 // random product id +#define USB_BCD 0x0200 // binary coded version: 2.00 + +// Configuration +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN + TUD_PRINTER_DESC_LEN) + +// HID interface endpoints +#define EPADDR_HID 0x81 // Interrupt In, MSB must be 1 +// Printer interface endpoints +#define EPADDR_PRINTER_OUT 0x01 // Bulk Out, MSB must be 0 +#define EPADDR_PRINTER_IN 0x82 // Bulk In, MSB must be 1 + +// HID report ID +#define REPORT_ID_KEYBOARD 1 + +// The maximum length of the string that will be sent to the host via the STRING DESCRIPTOR. Note that the +// string descriptor itself is two bytes wider than the string. +#define STRING_DESCRIPTOR_MAX_LENGTH 32 + +//--------------------------------------------------------------------+ +// Configuration, interface, endpoint descriptors +//--------------------------------------------------------------------+ + +enum { + ITF_HID, + ITF_PRINTER, + ITF_COUNT, +}; + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +enum { + LANGID = 0, + STR_MANUFACTURER, + STR_PRODUCT, + STR_SERIAL, + STR_CONFIGURATION, + STR_HID_INTERFACE, + STR_PRINTER_INTERFACE, + STRING_COUNT, +}; #endif /* USB_DESCRIPTORS_H_ */ diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 1602e35eb..55ce6e1f8 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -98,6 +98,7 @@ target_sources(tinyusb_device_base INTERFACE ${TOP}/src/class/mtp/mtp_device.c ${TOP}/src/class/net/ecm_rndis_device.c ${TOP}/src/class/net/ncm_device.c + ${TOP}/src/class/printer/printer_device.c ${TOP}/src/class/usbtmc/usbtmc_device.c ${TOP}/src/class/vendor/vendor_device.c ${TOP}/src/class/video/video_device.c diff --git a/src/class/printer/printer.h b/src/class/printer/printer.h index 27e95b997..c9ed3cebc 100644 --- a/src/class/printer/printer.h +++ b/src/class/printer/printer.h @@ -30,19 +30,18 @@ #include "common/tusb_common.h" #ifdef __cplusplus - extern "C" { +extern "C" { #endif /// Printer Class Specific Control Request -typedef enum -{ +typedef enum { PRINTER_REQ_CONTROL_GET_DEVICE_ID = 0x01, ///< Get device ID PRINTER_REQ_CONTROL_GET_PORT_STATUS = 0x02, ///< Get port status PRINTER_REQ_CONTROL_SOFT_RESET = 0x03, ///< Soft reset -}printer_request_enum_t; +} printer_request_enum_t; #ifdef __cplusplus - } +} #endif #endif /* _TUSB_PRINTER_H__ */ diff --git a/src/class/printer/printer_device.c b/src/class/printer/printer_device.c index efeae100f..76151949b 100644 --- a/src/class/printer/printer_device.c +++ b/src/class/printer/printer_device.c @@ -96,7 +96,7 @@ static bool _prep_out_transaction(uint8_t itf) { available = tu_fifo_remaining(&p_printer->rx_ff); if (available >= CFG_TUD_PRINTER_EP_BUFSIZE) { - return usbd_edpt_xfer(rhport, p_printer->ep_out, p_epbuf->epout, CFG_TUD_PRINTER_EP_BUFSIZE); + return usbd_edpt_xfer(rhport, p_printer->ep_out, p_epbuf->epout, CFG_TUD_PRINTER_EP_BUFSIZE, false); } else { // Release endpoint since we don't make any transfer usbd_edpt_release(rhport, p_printer->ep_out); @@ -189,7 +189,7 @@ void printerd_reset(uint8_t rhport) { for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { printer_interface_t *p_printer = &_printer_itf[i]; - tu_memclr(p_printer, sizeof(p_printer)); + tu_memclr(p_printer, sizeof(&p_printer)); if (!_printer_fifo_cfg.rx_persistent) { tu_fifo_clear(&p_printer->rx_ff); } @@ -202,6 +202,7 @@ void printerd_reset(uint8_t rhport) { } uint16_t printerd_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { + (void)max_len; TU_VERIFY(TUSB_CLASS_PRINTER == itf_desc->bInterfaceClass, 0); // Identify available interface to open @@ -257,13 +258,13 @@ bool printerd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_ break; case PRINTER_REQ_CONTROL_GET_PORT_STATUS: if (stage == CONTROL_STAGE_SETUP) { - static uint8_t port_status = (0 << 3) | (1 << 1) | (1 << 2); // ~Paper empty + Selected + NoError + static uint8_t port_status = 0b00011000; // paper not empty, selected, no error return tud_control_xfer(rhport, request, &port_status, sizeof(port_status)); } break; case PRINTER_REQ_CONTROL_SOFT_RESET: if (stage == CONTROL_STAGE_SETUP) { - return false; // what to do ? + return false; // TODO: reset buffers, reset Bulk In and Out endpoints, clear stall conditions } break; default: @@ -276,6 +277,8 @@ bool printerd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_ } bool printerd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + (void)rhport; + (void)result; uint8_t itf; printer_interface_t *p_printer; @@ -293,7 +296,7 @@ bool printerd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uin if (ep_addr == p_printer->ep_out) { tu_fifo_write_n(&p_printer->rx_ff, p_epbuf->epout, (uint16_t)xferred_bytes); // invoke receive callback (if there is still data) - if (tud_printer_rx_cb && !tu_fifo_empty(&p_printer->rx_ff)) { + if (!tu_fifo_empty(&p_printer->rx_ff)) { tud_printer_rx_cb(itf, xferred_bytes); } // prepare for OUT transaction diff --git a/src/device/usbd.h b/src/device/usbd.h index 3b296feea..d473aea2a 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -292,6 +292,19 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ /* Endpoint In */\ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 +//--------------------------------------------------------------------+ +// Printer Descriptor Templates +//--------------------------------------------------------------------+ + +#define TUD_PRINTER_DESC_LEN (9 + 7 + 7) // one interface, two endpoints + +#define TUD_PRINTER_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \ + /* Interface */\ + 9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_PRINTER, 1, 2, _stridx,\ + /* Endpoint Out */\ + 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ + /* Endpoint In */\ + 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 //--------------------------------------------------------------------+ // MTP Descriptor Templates diff --git a/src/tusb.h b/src/tusb.h index 256a239e7..1f4d4b73a 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -88,6 +88,10 @@ #include "class/msc/msc_device.h" #endif + #if CFG_TUD_PRINTER + #include "class/printer/printer_device.h" + #endif + #if CFG_TUD_MTP #include "class/mtp/mtp_device.h" #endif -- cgit v1.3.1 From 475e97cc8b048e2ea0244f310657b8e02a5cfe73 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 7 Jan 2026 22:49:18 +0700 Subject: remove hw_endpoint_t rx, rename/change signature of helper functions --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 205 ++++++++++++--------------- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 15 +- src/portable/raspberrypi/rp2040/rp2040_usb.c | 182 +++++++++++++++--------- src/portable/raspberrypi/rp2040/rp2040_usb.h | 69 ++++----- 4 files changed, 239 insertions(+), 232 deletions(-) (limited to 'src') diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 31683502a..6c74029d8 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -41,83 +41,49 @@ // Current implementation force vbus detection as always present, causing device think it is always plugged into host. // Therefore it cannot detect disconnect event, mistaken it as suspend. // Note: won't work if change to 0 (for now) -#define FORCE_VBUS_DETECT 1 +#define FORCE_VBUS_DETECT 1 + + #define USB_INTS_ERROR_BITS \ + (USB_INTS_ERROR_DATA_SEQ_BITS | USB_INTS_ERROR_BIT_STUFF_BITS | USB_INTS_ERROR_CRC_BITS | \ + USB_INTS_ERROR_RX_OVERFLOW_BITS | USB_INTS_ERROR_RX_TIMEOUT_BITS) /*------------------------------------------------------------------*/ /* Low level controller *------------------------------------------------------------------*/ -// Init these in dcd_init -static uint8_t* next_buffer_ptr; +// HW buffer pointer from USB buffer space (max 3840 bytes) +static uint8_t *hw_buffer_ptr; // USB_MAX_ENDPOINTS Endpoints, direction TUSB_DIR_OUT for out and TUSB_DIR_IN for in. static struct hw_endpoint hw_endpoints[USB_MAX_ENDPOINTS][2]; -// SOF may be used by remote wakeup as RESUME, this indicate whether SOF is actually used by usbd +// SOF may be used by remote wakeup as RESUME, this indicates whether SOF is actually used by usbd static bool _sof_enable = false; -TU_ATTR_ALWAYS_INLINE static inline struct hw_endpoint *hw_endpoint_get(uint8_t num, tusb_dir_t dir) { - return &hw_endpoints[num][dir]; +TU_ATTR_ALWAYS_INLINE static inline hw_endpoint_t *hw_endpoint_get(uint8_t epnum, tusb_dir_t dir) { + return &hw_endpoints[epnum][dir]; } -TU_ATTR_ALWAYS_INLINE static inline struct hw_endpoint* hw_endpoint_get_by_addr(uint8_t ep_addr) { - uint8_t num = tu_edpt_number(ep_addr); - tusb_dir_t dir = tu_edpt_dir(ep_addr); +TU_ATTR_ALWAYS_INLINE static inline hw_endpoint_t *hw_endpoint_get_by_addr(uint8_t ep_addr) { + const uint8_t num = tu_edpt_number(ep_addr); + const tusb_dir_t dir = tu_edpt_dir(ep_addr); return hw_endpoint_get(num, dir); } -// Allocate from the USB buffer space (max 3840 bytes) -static void hw_endpoint_alloc(struct hw_endpoint* ep, size_t size) { - // round up size to multiple of 64 - size = tu_round_up(ep->wMaxPacketSize, 64); - - // double buffered Bulk endpoint - if (ep->transfer_type == TUSB_XFER_BULK) { - size *= 2u; - } - - // assign buffer - ep->hw_data_buf = next_buffer_ptr; - next_buffer_ptr += size; - - hard_assert(next_buffer_ptr < usb_dpram->epx_data + sizeof(usb_dpram->epx_data)); - pico_info(" Allocated %d bytes (0x%p)\r\n", size, ep->hw_data_buf); -} - -// Enable endpoint -TU_ATTR_ALWAYS_INLINE static inline void hw_endpoint_enable(struct hw_endpoint* ep) { - uint32_t const reg = EP_CTRL_ENABLE_BITS | ((uint) ep->transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | hw_data_offset(ep->hw_data_buf); - *hwep_ctrl_reg(ep) = reg; -} - // main processing for dcd_edpt_iso_activate -static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) { - const uint8_t num = tu_edpt_number(ep_addr); - const tusb_dir_t dir = tu_edpt_dir(ep_addr); - hw_endpoint_t* ep = hw_endpoint_get(num, dir); - - ep->ep_addr = ep_addr; - - // For device, IN is a tx transfer and OUT is an rx transfer - ep->rx = (dir == TUSB_DIR_OUT); +static void hw_endpoint_init(hw_endpoint_t *ep, uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) { + const uint8_t epnum = tu_edpt_number(ep_addr); - ep->next_pid = 0u; + ep->ep_addr = ep_addr; + ep->next_pid = 0u; ep->wMaxPacketSize = wMaxPacketSize; - ep->transfer_type = transfer_type; - - // Every endpoint has a buffer control register in dpram - // if (dir == TUSB_DIR_IN) { - // ep->buffer_control = &usb_dpram->ep_buf_ctrl[num].in; - // } else { - // ep->buffer_control = &usb_dpram->ep_buf_ctrl[num].out; - // } + ep->transfer_type = transfer_type; // Clear existing buffer control state - *hwep_buf_ctrl_reg(ep) = 0; - - if (num == 0) { - // EP0 has no endpoint control register because the buffer offsets are fixed - // ep->endpoint_control = NULL; + io_rw_32 *buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep); + *buf_ctrl_reg = 0; + // allocated hw buffer + if (epnum == 0) { // Buffer offset is fixed (also double buffered) ep->hw_data_buf = (uint8_t*) &usb_dpram->ep0_buf_a[0]; } else { @@ -127,33 +93,49 @@ static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t t // } else { // ep->endpoint_control = &usb_dpram->ep_ctrl[num - 1].out; // } + + // round up size to multiple of 64 + uint16_t size = (uint16_t)tu_round_up(wMaxPacketSize, 64); + + // double buffered Bulk endpoint + if (transfer_type == TUSB_XFER_BULK) { + size *= 2u; + } + + // assign buffer + ep->hw_data_buf = hw_buffer_ptr; + hw_buffer_ptr += size; + + hard_assert(hw_buffer_ptr < usb_dpram->epx_data + sizeof(usb_dpram->epx_data)); + pico_info(" Allocated %d bytes (0x%p)\r\n", size, ep->hw_data_buf); } } // Init, allocate buffer and enable endpoint static void hw_endpoint_open(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) { - struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr); - hw_endpoint_init(ep_addr, wMaxPacketSize, transfer_type); - const uint8_t num = tu_edpt_number(ep_addr); - if (num != 0) { - // EP0 is already enabled - hw_endpoint_alloc(ep, ep->wMaxPacketSize); - hw_endpoint_enable(ep); + const uint8_t epnum = tu_edpt_number(ep_addr); + const tusb_dir_t dir = tu_edpt_dir(ep_addr); + hw_endpoint_t *ep = hw_endpoint_get(epnum, dir); + + hw_endpoint_init(ep, ep_addr, wMaxPacketSize, transfer_type); + + // Set endpoint control register to enable (EP0 has no endpoint control register) + io_rw_32 *ctrl_reg = hwep_ctrl_reg_device(ep); + if (ctrl_reg != NULL) { + const uint32_t ctrl_value = + EP_CTRL_ENABLE_BITS | ((uint32_t)transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | hw_data_offset(ep->hw_data_buf); + *ctrl_reg = ctrl_value; } } -static void hw_endpoint_xfer(uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { - struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr); - hw_endpoint_xfer_start(ep, buffer, total_bytes); -} - static void hw_endpoint_abort_xfer(struct hw_endpoint* ep) { // Abort any pending transfer // Due to Errata RP2040-E2: ABORT flag is only applicable for B2 and later (unusable for B0, B1). // Which means we are not guaranteed to safely abort pending transfer on B0 and B1. - const uint8_t dir = tu_edpt_dir(ep->ep_addr); + const uint8_t dir = (uint8_t)tu_edpt_dir(ep->ep_addr); const uint8_t epnum = tu_edpt_number(ep->ep_addr); const uint32_t abort_mask = TU_BIT((epnum << 1) | (dir ? 0 : 1)); + if (rp2040_chip_version() >= 2) { usb_hw_set->abort = abort_mask; while ((usb_hw->abort_done & abort_mask) != abort_mask) {} @@ -173,7 +155,7 @@ static void hw_endpoint_abort_xfer(struct hw_endpoint* ep) { } } -static void __tusb_irq_path_func(hw_handle_buff_status)(void) { +static void __tusb_irq_path_func(handle_hw_buff_status)(void) { uint32_t remaining_buffers = usb_hw->buf_status; pico_trace("buf_status = 0x%08lx\r\n", remaining_buffers); uint bit = 1u; @@ -183,12 +165,13 @@ static void __tusb_irq_path_func(hw_handle_buff_status)(void) { usb_hw_clear->buf_status = bit; // IN transfer for even i, OUT transfer for odd i - struct hw_endpoint *ep = hw_endpoint_get(i >> 1u, (i & 1u) ? TUSB_DIR_OUT : TUSB_DIR_IN); + const uint8_t epnum = i >> 1u; + const tusb_dir_t dir = (i & 1u) ? TUSB_DIR_OUT : TUSB_DIR_IN; + hw_endpoint_t *ep = hw_endpoint_get(epnum, dir); - // Continue xfer - bool done = hw_endpoint_xfer_continue(ep); + const bool done = hw_endpoint_xfer_continue(ep); if (done) { - // Notify + // Notify usbd const uint16_t xferred_len = ep->xferred_len; hw_endpoint_reset_transfer(ep); dcd_event_xfer_complete(0, ep->ep_addr, xferred_len, XFER_RESULT_SUCCESS, true); @@ -222,11 +205,11 @@ static void __tusb_irq_path_func(reset_non_control_endpoints)(void) { tu_memclr(hw_endpoints[1], sizeof(hw_endpoints) - 2 * sizeof(hw_endpoint_t)); // reclaim buffer space - next_buffer_ptr = &usb_dpram->epx_data[0]; + hw_buffer_ptr = &usb_dpram->epx_data[0]; } static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { - uint32_t const status = usb_hw->ints; + const uint32_t status = usb_hw->ints; uint32_t handled = 0; if (status & USB_INTF_DEV_SOF_BITS) { @@ -259,7 +242,9 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { #endif // disable SOF interrupt if it is used for RESUME in remote wakeup - if (!keep_sof_alive && !_sof_enable) usb_hw_clear->inte = USB_INTS_DEV_SOF_BITS; + if (!keep_sof_alive && !_sof_enable) { + usb_hw_clear->inte = USB_INTS_DEV_SOF_BITS; + } dcd_event_sof(0, usb_hw->sof_rd & USB_SOF_RD_BITS, true); } @@ -268,7 +253,7 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { // before closing the EP, the events will be delivered in same order. if (status & USB_INTS_BUFF_STATUS_BITS) { handled |= USB_INTS_BUFF_STATUS_BITS; - hw_handle_buff_status(); + handle_hw_buff_status(); } if (status & USB_INTS_SETUP_REQ_BITS) { @@ -345,13 +330,6 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { } } -#define USB_INTS_ERROR_BITS ( \ - USB_INTS_ERROR_DATA_SEQ_BITS | \ - USB_INTS_ERROR_BIT_STUFF_BITS | \ - USB_INTS_ERROR_CRC_BITS | \ - USB_INTS_ERROR_RX_OVERFLOW_BITS | \ - USB_INTS_ERROR_RX_TIMEOUT_BITS) - /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ @@ -424,12 +402,11 @@ void dcd_int_disable(__unused uint8_t rhport) { irq_set_enabled(USBCTRL_IRQ, false); } -void dcd_set_address(__unused uint8_t rhport, __unused uint8_t dev_addr) { - assert(rhport == 0); - +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { + (void)dev_addr; // Can't set device address in hardware until status xfer has complete // Send 0len complete response on EP0 IN - hw_endpoint_xfer(0x80, NULL, 0); + dcd_edpt_xfer(rhport, 0x80, NULL, 0, false); } void dcd_remote_wakeup(__unused uint8_t rhport) { @@ -474,7 +451,6 @@ void dcd_sof_enable(uint8_t rhport, bool en) { /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ - void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request) { (void) rhport; @@ -496,25 +472,32 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { // New API: Allocate packet buffer used by ISO endpoints // Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { - (void) rhport; - struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr); - hw_endpoint_init(ep_addr, largest_packet_size, TUSB_XFER_ISOCHRONOUS); - hw_endpoint_alloc(ep, largest_packet_size); + (void)rhport; + struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); + hw_endpoint_init(ep, ep_addr, largest_packet_size, TUSB_XFER_ISOCHRONOUS); return true; } // New API: Configure and enable an ISO endpoint according to descriptor -bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { - (void) rhport; - struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_desc->bEndpointAddress); +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *ep_desc) { + (void)rhport; + const uint8_t epnum = tu_edpt_number(ep_desc->bEndpointAddress); + const tusb_dir_t dir = tu_edpt_dir(ep_desc->bEndpointAddress); + struct hw_endpoint *ep = hw_endpoint_get(epnum, dir); TU_ASSERT(ep->hw_data_buf != NULL); // must be inited and allocated previously if (ep->active) { hw_endpoint_abort_xfer(ep); // abort any pending transfer } - ep->wMaxPacketSize = ep_desc->wMaxPacketSize; - hw_endpoint_enable(ep); + + // Set control register to enable endpoint + io_rw_32 *ctrl_reg = hwep_ctrl_reg_device(ep); + if (ctrl_reg != NULL) { + const uint32_t ctrl_value = EP_CTRL_ENABLE_BITS | ((uint32_t)TUSB_XFER_ISOCHRONOUS << EP_CTRL_BUFFER_TYPE_LSB) | + hw_data_offset(ep->hw_data_buf); + *ctrl_reg = ctrl_value; + } return true; } @@ -525,26 +508,26 @@ void dcd_edpt_close_all(uint8_t rhport) { reset_non_control_endpoints(); } -bool dcd_edpt_xfer(__unused uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes, bool is_isr) { - (void) is_isr; - assert(rhport == 0); - hw_endpoint_xfer(ep_addr, buffer, total_bytes); +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes, bool is_isr) { + (void)rhport; + (void)is_isr; + hw_endpoint_t *ep = hw_endpoint_get_by_addr(ep_addr); + hw_endpoint_xfer_start(ep, buffer, total_bytes); return true; } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; + (void)rhport; + const uint8_t epnum = tu_edpt_number(ep_addr); + const tusb_dir_t dir = tu_edpt_dir(ep_addr); + hw_endpoint_t *ep = hw_endpoint_get(epnum, dir); - if (tu_edpt_number(ep_addr) == 0) { + if (epnum == 0) { // A stall on EP0 has to be armed so it can be cleared on the next setup packet - usb_hw_set->ep_stall_arm = (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) ? USB_EP_STALL_ARM_EP0_IN_BITS - : USB_EP_STALL_ARM_EP0_OUT_BITS; + usb_hw_set->ep_stall_arm = (dir == TUSB_DIR_IN) ? USB_EP_STALL_ARM_EP0_IN_BITS : USB_EP_STALL_ARM_EP0_OUT_BITS; } - struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr); - - // stall and clear current pending buffer - // may need to use EP_ABORT + // stall and clear current pending buffer, may need to use EP_ABORT hwep_buf_ctrl_set(ep, USB_BUF_CTRL_STALL); } diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 12a2f2d25..5ec84be16 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -122,7 +122,7 @@ static void __tusb_irq_path_func(hw_handle_buff_status)(void) remaining_buffers &= ~bit; struct hw_endpoint * ep = &epx; - uint32_t ep_ctrl = *hwep_ctrl_reg(ep); + uint32_t ep_ctrl = *hwep_ctrl_reg_host(ep); if ( ep_ctrl & EP_CTRL_DOUBLE_BUFFERED_BITS ) { TU_LOG(3, "Double Buffered: "); @@ -316,9 +316,6 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t ep->ep_addr = ep_addr; ep->dev_addr = dev_addr; - // For host, IN to host == RX, anything else rx == false - ep->rx = (dir == TUSB_DIR_IN); - // Response to a setup packet on EP0 starts with pid of 1 ep->next_pid = (num == 0 ? 1u : 0u); ep->wMaxPacketSize = wMaxPacketSize; @@ -339,7 +336,7 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t { ep_reg |= (uint32_t) ((bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB); } - *hwep_ctrl_reg(ep) = ep_reg; + *hwep_ctrl_reg_host(ep) = ep_reg; // pico_trace("endpoint control (0x%p) <- 0x%lx\n", ep->endpoint_control, ep_reg); ep->configured = true; @@ -465,8 +462,8 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { // reset epx if it is currently active with unplugged device if (epx.configured && epx.active && epx.dev_addr == dev_addr) { epx.configured = false; - *hwep_ctrl_reg(&epx) = 0; - *hwep_buf_ctrl_reg(&epx) = 0; + *hwep_ctrl_reg_host(&epx) = 0; + *hwep_buf_ctrl_reg_host(&epx) = 0; hw_endpoint_reset_transfer(&epx); } @@ -481,8 +478,8 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { // unconfigure the endpoint ep->configured = false; - *hwep_ctrl_reg(ep) = 0; - *hwep_buf_ctrl_reg(ep) = 0; + *hwep_ctrl_reg_host(ep) = 0; + *hwep_buf_ctrl_reg_host(ep) = 0; hw_endpoint_reset_transfer(ep); } } diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 61f978b0d..8e7bf2dae 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -35,20 +35,15 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPE //--------------------------------------------------------------------+ -static void _hw_endpoint_xfer_sync(struct hw_endpoint* ep); +static void hwep_xfer_sync(hw_endpoint_t *ep); -#if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX - static bool e15_is_bulkin_ep(struct hw_endpoint* ep); - static bool e15_is_critical_frame_period(struct hw_endpoint* ep); -#else - #define e15_is_bulkin_ep(x) (false) - #define e15_is_critical_frame_period(x) (false) -#endif - -// if usb hardware is in host mode -TU_ATTR_ALWAYS_INLINE static inline bool is_host_mode(void) { - return (usb_hw->main_ctrl & USB_MAIN_CTRL_HOST_NDEVICE_BITS) ? true : false; -} + #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX +static bool e15_is_bulkin_ep(struct hw_endpoint *ep); +static bool e15_is_critical_frame_period(struct hw_endpoint *ep); + #else + #define e15_is_bulkin_ep(x) (false) + #define e15_is_critical_frame_period(x) (false) + #endif //--------------------------------------------------------------------+ // Implementation @@ -94,8 +89,18 @@ void __tusb_irq_path_func(hw_endpoint_reset_transfer)(struct hw_endpoint* ep) { } void __tusb_irq_path_func(hwep_buf_ctrl_update)(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask) { + const bool is_host = rp2usb_is_host_mode(); uint32_t value = 0; - io_rw_32 *buf_ctrl = hwep_buf_ctrl_reg(ep); + io_rw_32 *buf_ctrl; + + #if CFG_TUH_ENABLED + if (is_host) { + buf_ctrl = hwep_buf_ctrl_reg_host(ep); + } else + #endif + { + buf_ctrl = hwep_buf_ctrl_reg_device(ep); + } if (and_mask) { value = *buf_ctrl & and_mask; @@ -110,7 +115,7 @@ void __tusb_irq_path_func(hwep_buf_ctrl_update)(struct hw_endpoint *ep, uint32_t *buf_ctrl = value & ~USB_BUF_CTRL_AVAIL; // 4.1.2.5.1 Con-current access: 12 cycles (should be good for 48*12Mhz = 576Mhz) after write to buffer control // Don't need delay in host mode as host is in charge - if (!is_host_mode()) { + if (!is_host) { busy_wait_at_least_cycles(12); } } @@ -119,9 +124,9 @@ void __tusb_irq_path_func(hwep_buf_ctrl_update)(struct hw_endpoint *ep, uint32_t *buf_ctrl = value; } -// prepare buffer, return buffer control -static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint* ep, uint8_t buf_id) { - uint16_t const buflen = tu_min16(ep->remaining_len, ep->wMaxPacketSize); +// prepare buffer, move data if tx, return buffer control +static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint *ep, uint8_t buf_id, bool is_rx) { + const uint16_t buflen = tu_min16(ep->remaining_len, ep->wMaxPacketSize); ep->remaining_len = (uint16_t) (ep->remaining_len - buflen); uint32_t buf_ctrl = buflen | USB_BUF_CTRL_AVAIL; @@ -130,7 +135,7 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint* ep, buf_ctrl |= ep->next_pid ? USB_BUF_CTRL_DATA1_PID : USB_BUF_CTRL_DATA0_PID; ep->next_pid ^= 1u; - if (!ep->rx) { + if (!is_rx) { // Copy data from user buffer to hw buffer unaligned_memcpy(ep->hw_data_buf + buf_id * 64, ep->user_buf, buflen); ep->user_buf += buflen; @@ -146,44 +151,66 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint* ep, buf_ctrl |= USB_BUF_CTRL_LAST; } - if (buf_id) buf_ctrl = buf_ctrl << 16; + if (buf_id) { + buf_ctrl = buf_ctrl << 16; + } return buf_ctrl; } // Prepare buffer control register value void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint* ep) { - io_rw_32 *ep_ctrl_reg = hwep_ctrl_reg(ep); - uint32_t ep_ctrl = *ep_ctrl_reg; + const tusb_dir_t dir = tu_edpt_dir(ep->ep_addr); + bool is_rx; + + io_rw_32 *ep_ctrl_reg; + // io_rw_32 *buf_ctrl_reg; + + #if CFG_TUH_ENABLED + const bool is_host = rp2usb_is_host_mode(); + if (is_host) { + // buf_ctrl_reg = hwep_buf_ctrl_reg_host(ep); + ep_ctrl_reg = hwep_ctrl_reg_host(ep); + is_rx = (dir == TUSB_DIR_IN); + } else + #endif + { + // buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep); + ep_ctrl_reg = hwep_ctrl_reg_device(ep); + is_rx = (dir == TUSB_DIR_OUT); + } // always compute and start with buffer 0 - uint32_t buf_ctrl = prepare_ep_buffer(ep, 0) | USB_BUF_CTRL_SEL; - - // For now: skip double buffered for OUT endpoint in Device mode, since - // host could send < 64 bytes and cause short packet on buffer0 - // NOTE: this could happen to Host mode IN endpoint - // Also, Host mode "interrupt" endpoint hardware is only single buffered, - // NOTE2: Currently Host bulk is implemented using "interrupt" endpoint - bool const is_host = is_host_mode(); - bool const force_single = (!is_host && !tu_edpt_dir(ep->ep_addr)) || - (is_host && tu_edpt_number(ep->ep_addr) != 0); - - if (ep->remaining_len && !force_single) { - // Use buffer 1 (double buffered) if there is still data - // TODO: Isochronous for buffer1 bit-field is different than CBI (control bulk, interrupt) - - buf_ctrl |= prepare_ep_buffer(ep, 1); - - // Set endpoint control double buffered bit if needed - ep_ctrl &= ~EP_CTRL_INTERRUPT_PER_BUFFER; - ep_ctrl |= EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER; - } else { - // Single buffered since 1 is enough - ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER); - ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER; - } + uint32_t buf_ctrl = prepare_ep_buffer(ep, 0, is_rx) | USB_BUF_CTRL_SEL; + + // EP0 has no endpoint control register, also usbd only schedule 1 packet at a time (single buffer) + if (ep_ctrl_reg != NULL) { + uint32_t ep_ctrl = *ep_ctrl_reg; + + // For now: skip double buffered for RX e.g OUT endpoint in Device mode, since host could send < 64 bytes and cause + // short packet on buffer0 + // NOTE: this could happen to Host mode IN endpoint Also, Host mode "interrupt" endpoint hardware is only single + // buffered, + // NOTE2: Currently Host bulk is implemented using "interrupt" endpoint + const bool force_single = is_rx; - *ep_ctrl_reg = ep_ctrl; + if (ep->remaining_len && !force_single) { + // Use buffer 1 (double buffered) if there is still data + // TODO: Isochronous for buffer1 bit-field is different than CBI (control bulk, interrupt) + + buf_ctrl |= prepare_ep_buffer(ep, 1, is_rx); + + // Set endpoint control double buffered bit if needed + ep_ctrl &= ~EP_CTRL_INTERRUPT_PER_BUFFER; + ep_ctrl |= EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER; + } else { + // Single buffered since 1 is enough + ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER); + ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER; + } + + *ep_ctrl_reg = ep_ctrl; + } TU_LOG(3, " Prepare BufCtrl: [0] = 0x%04x [1] = 0x%04x\r\n", tu_u32_low16(buf_ctrl), tu_u32_high16(buf_ctrl)); @@ -221,13 +248,16 @@ void hw_endpoint_xfer_start(struct hw_endpoint* ep, uint8_t* buffer, uint16_t to } // sync endpoint buffer and return transferred bytes -static uint16_t __tusb_irq_path_func(sync_ep_buffer)(struct hw_endpoint* ep, uint8_t buf_id) { - uint32_t buf_ctrl = hwep_buf_ctrl_get(ep); - if (buf_id) buf_ctrl = buf_ctrl >> 16; +static uint16_t __tusb_irq_path_func(sync_ep_buffer)(hw_endpoint_t *ep, io_rw_32 *buf_ctrl_reg, uint8_t buf_id, + bool is_rx) { + uint32_t buf_ctrl = *buf_ctrl_reg; + if (buf_id) { + buf_ctrl = buf_ctrl >> 16; + } - uint16_t xferred_bytes = buf_ctrl & USB_BUF_CTRL_LEN_MASK; + const uint16_t xferred_bytes = buf_ctrl & USB_BUF_CTRL_LEN_MASK; - if (!ep->rx) { + if (!is_rx) { // We are continuing a transfer here. If we are TX, we have successfully // sent some data can increase the length we have sent assert(!(buf_ctrl & USB_BUF_CTRL_FULL)); @@ -245,7 +275,6 @@ static uint16_t __tusb_irq_path_func(sync_ep_buffer)(struct hw_endpoint* ep, uin // Short packet if (xferred_bytes < ep->wMaxPacketSize) { - pico_trace(" Short packet on buffer %d with %u bytes\r\n", buf_id, xferred_bytes); // Reduce total length as this is last packet ep->remaining_len = 0; } @@ -253,21 +282,38 @@ static uint16_t __tusb_irq_path_func(sync_ep_buffer)(struct hw_endpoint* ep, uin return xferred_bytes; } -static void __tusb_irq_path_func(_hw_endpoint_xfer_sync)(struct hw_endpoint* ep) { - // Update hw endpoint struct with info from hardware - // after a buff status interrupt - - uint32_t __unused buf_ctrl = hwep_buf_ctrl_get(ep); - TU_LOG(3, " Sync BufCtrl: [0] = 0x%04x [1] = 0x%04x\r\n", tu_u32_low16(buf_ctrl), tu_u32_high16(buf_ctrl)); +// Update hw endpoint struct with info from hardware after a buff status interrupt +static void __tusb_irq_path_func(hwep_xfer_sync)(hw_endpoint_t *ep) { + // const uint8_t ep_num = tu_edpt_number(ep->ep_addr); + const tusb_dir_t dir = tu_edpt_dir(ep->ep_addr); + + io_rw_32 *buf_ctrl_reg; + io_rw_32 *ep_ctrl_reg; + bool is_rx; + + #if CFG_TUH_ENABLED + const bool is_host = rp2usb_is_host_mode(); + if (is_host) { + buf_ctrl_reg = hwep_buf_ctrl_reg_host(ep); + ep_ctrl_reg = hwep_ctrl_reg_host(ep); + is_rx = (dir == TUSB_DIR_IN); + } else + #endif + { + buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep); + ep_ctrl_reg = hwep_ctrl_reg_device(ep); + is_rx = (dir == TUSB_DIR_OUT); + } - // always sync buffer 0 - uint16_t buf0_bytes = sync_ep_buffer(ep, 0); + TU_LOG(3, " Sync BufCtrl: [0] = 0x%04x [1] = 0x%04x\r\n", tu_u32_low16(*buf_ctrl_reg), + tu_u32_high16(*buf_ctrl_reg)); + uint16_t buf0_bytes = sync_ep_buffer(ep, buf_ctrl_reg, 0, is_rx); // always sync buffer 0 // sync buffer 1 if double buffered - if ((*hwep_ctrl_reg(ep)) & EP_CTRL_DOUBLE_BUFFERED_BITS) { + if (ep_ctrl_reg != NULL && (*ep_ctrl_reg) & EP_CTRL_DOUBLE_BUFFERED_BITS) { if (buf0_bytes == ep->wMaxPacketSize) { // sync buffer 1 if not short packet - sync_ep_buffer(ep, 1); + sync_ep_buffer(ep, buf_ctrl_reg, 1, is_rx); } else { // short packet on buffer 0 // TODO couldn't figure out how to handle this case which happen with net_lwip_webserver example @@ -309,7 +355,7 @@ bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint* ep) { } // Update EP struct from hardware state - _hw_endpoint_xfer_sync(ep); + hwep_xfer_sync(ep); // Now we have synced our state with the hardware. Is there more data to transfer? // If we are done then notify tinyusb @@ -336,6 +382,7 @@ bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint* ep) { //--------------------------------------------------------------------+ #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX +// E15 is fixed with RP2350 /* Don't mark IN buffers as available during the last 200us of a full-speed frame. This avoids a situation seen with the USB2.0 hub on a Raspberry @@ -356,9 +403,8 @@ bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint* ep) { volatile uint32_t e15_last_sof = 0; // check if Errata 15 is needed for this endpoint i.e device bulk-in -static bool __tusb_irq_path_func(e15_is_bulkin_ep)(struct hw_endpoint* ep) { - return (!is_host_mode() && tu_edpt_dir(ep->ep_addr) == TUSB_DIR_IN && - ep->transfer_type == TUSB_XFER_BULK); +static bool __tusb_irq_path_func(e15_is_bulkin_ep)(struct hw_endpoint *ep) { + return (!rp2usb_is_host_mode() && tu_edpt_dir(ep->ep_addr) == TUSB_DIR_IN && ep->transfer_type == TUSB_XFER_BULK); } // check if we need to apply Errata 15 workaround : i.e diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.h b/src/portable/raspberrypi/rp2040/rp2040_usb.h index 603640c6d..2ec00694e 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.h +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.h @@ -48,10 +48,6 @@ typedef struct hw_endpoint // Is this a valid struct bool configured; - // Transfer direction (i.e. IN is rx for host but tx for device) - // allows us to common up transfer functions - bool rx; - uint8_t ep_addr; uint8_t next_pid; @@ -115,61 +111,46 @@ TU_ATTR_ALWAYS_INLINE static inline void hw_endpoint_lock_update(__unused struct // sense to have worker and IRQ on same core, however I think using critsec is about equivalent. } -TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_ctrl_reg(struct hw_endpoint *ep) { - (void)ep; -#if CFG_TUH_ENABLED - if (rp2usb_is_host_mode()) { - if (ep->transfer_type == TUSB_XFER_CONTROL) { - return &usbh_dpram->epx_ctrl; - } - return &usbh_dpram->int_ep_ctrl[ep->interrupt_num].ctrl; +// #if CFG_TUD_ENABLED +TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_ctrl_reg_device(struct hw_endpoint *ep) { + uint8_t const epnum = tu_edpt_number(ep->ep_addr); + const uint8_t dir = (uint8_t)tu_edpt_dir(ep->ep_addr); + if (epnum == 0) { + // EP0 has no endpoint control register because the buffer offsets are fixed and always enabled + return NULL; } -#endif - -#if CFG_TUD_ENABLED - if (!rp2usb_is_host_mode()) { - const uint8_t num = tu_edpt_number(ep->ep_addr); - if (num == 0) { - return NULL; - } - return (tu_edpt_dir(ep->ep_addr) == TUSB_DIR_IN) ? &usb_dpram->ep_ctrl[num - 1].in - : &usb_dpram->ep_ctrl[num - 1].out; - } -#endif + return (dir == TUSB_DIR_IN) ? &usb_dpram->ep_ctrl[epnum - 1].in : &usb_dpram->ep_ctrl[epnum - 1].out; +} - return NULL; +TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_buf_ctrl_reg_device(struct hw_endpoint *ep) { + const uint8_t epnum = tu_edpt_number(ep->ep_addr); + const uint8_t dir = (uint8_t)tu_edpt_dir(ep->ep_addr); + return (dir == TUSB_DIR_IN) ? &usb_dpram->ep_buf_ctrl[epnum].in : &usb_dpram->ep_buf_ctrl[epnum].out; } +// #endif -TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_buf_ctrl_reg(struct hw_endpoint *ep) { - (void)ep; #if CFG_TUH_ENABLED - if (rp2usb_is_host_mode()) { - if (ep->transfer_type == TUSB_XFER_CONTROL) { - return &usbh_dpram->epx_buf_ctrl; - } - return &usbh_dpram->int_ep_buffer_ctrl[ep->interrupt_num].ctrl; +TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_ctrl_reg_host(struct hw_endpoint *ep) { + if (ep->transfer_type == TUSB_XFER_CONTROL) { + return &usbh_dpram->epx_ctrl; } -#endif + return &usbh_dpram->int_ep_ctrl[ep->interrupt_num].ctrl; +} -#if CFG_TUD_ENABLED - if (!rp2usb_is_host_mode()) { - const uint8_t num = tu_edpt_number(ep->ep_addr); - return (tu_edpt_dir(ep->ep_addr) == TUSB_DIR_IN) ? &usb_dpram->ep_buf_ctrl[num].in - : &usb_dpram->ep_buf_ctrl[num].out; +TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_buf_ctrl_reg_host(struct hw_endpoint *ep) { + if (ep->transfer_type == TUSB_XFER_CONTROL) { + return &usbh_dpram->epx_buf_ctrl; } -#endif - return NULL; + return &usbh_dpram->int_ep_buffer_ctrl[ep->interrupt_num].ctrl; } +#endif + //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ void hwep_buf_ctrl_update(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask); -TU_ATTR_ALWAYS_INLINE static inline uint32_t hwep_buf_ctrl_get(struct hw_endpoint *ep) { - return *hwep_buf_ctrl_reg(ep); -} - TU_ATTR_ALWAYS_INLINE static inline void hwep_buf_ctrl_set(struct hw_endpoint *ep, uint32_t value) { hwep_buf_ctrl_update(ep, 0, value); } -- cgit v1.3.1 From f0a3d448347047c9df62518fbd641502b2d55333 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 8 Jan 2026 00:54:21 +0700 Subject: change signature for hwep_buf_ctrl_* to take pointer to buf control instead of hwep --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 16 ++++----- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 6 ---- src/portable/raspberrypi/rp2040/rp2040_usb.c | 42 ++++++++++------------- src/portable/raspberrypi/rp2040/rp2040_usb.h | 50 ++++++++++------------------ 4 files changed, 42 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 6c74029d8..5c21590c4 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -87,13 +87,6 @@ static void hw_endpoint_init(hw_endpoint_t *ep, uint8_t ep_addr, uint16_t wMaxPa // Buffer offset is fixed (also double buffered) ep->hw_data_buf = (uint8_t*) &usb_dpram->ep0_buf_a[0]; } else { - // Set the endpoint control register (starts at EP1, hence num-1) - // if (dir == TUSB_DIR_IN) { - // ep->endpoint_control = &usb_dpram->ep_ctrl[num - 1].in; - // } else { - // ep->endpoint_control = &usb_dpram->ep_ctrl[num - 1].out; - // } - // round up size to multiple of 64 uint16_t size = (uint16_t)tu_round_up(wMaxPacketSize, 64); @@ -146,7 +139,8 @@ static void hw_endpoint_abort_xfer(struct hw_endpoint* ep) { buf_ctrl |= USB_BUF_CTRL_DATA1_PID; } - hwep_buf_ctrl_set(ep, buf_ctrl); + io_rw_32 *buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep); + hwep_buf_ctrl_set(buf_ctrl_reg, buf_ctrl); hw_endpoint_reset_transfer(ep); if (rp2040_chip_version() >= 2) { @@ -528,7 +522,8 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { } // stall and clear current pending buffer, may need to use EP_ABORT - hwep_buf_ctrl_set(ep, USB_BUF_CTRL_STALL); + io_rw_32 *buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep); + hwep_buf_ctrl_set(buf_ctrl_reg, USB_BUF_CTRL_STALL); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { @@ -539,7 +534,8 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { // clear stall also reset toggle to DATA0, ready for next transfer ep->next_pid = 0; - hwep_buf_ctrl_clear_mask(ep, USB_BUF_CTRL_STALL); + io_rw_32 *buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep); + hwep_buf_ctrl_clear_mask(buf_ctrl_reg, USB_BUF_CTRL_STALL); } } diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 5ec84be16..2e5f0fe1f 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -284,8 +284,6 @@ static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type) ep = _next_free_interrupt_ep(); pico_info("Allocate %s ep %d\n", tu_edpt_type_str(transfer_type), ep->interrupt_num); assert(ep); - // ep->buffer_control = &usbh_dpram->int_ep_buffer_ctrl[ep->interrupt_num].ctrl; - // ep->endpoint_control = &usbh_dpram->int_ep_ctrl[ep->interrupt_num].ctrl; // 0 for epx (double buffered): TODO increase to 1024 for ISO // 2x64 for intep0 // 3x64 for intep1 @@ -295,8 +293,6 @@ static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type) else { ep = &epx; - // ep->buffer_control = &usbh_dpram->epx_buf_ctrl; - // ep->endpoint_control = &usbh_dpram->epx_ctrl; ep->hw_data_buf = &usbh_dpram->epx_data[0]; } @@ -306,8 +302,6 @@ static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type) static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type, uint8_t bmInterval) { // Already has data buffer, endpoint control, and buffer control allocated at this point - // assert(ep->endpoint_control); - // assert(ep->buffer_control); assert(ep->hw_data_buf); uint8_t const num = tu_edpt_number(ep_addr); diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 8e7bf2dae..5258b9705 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -88,32 +88,25 @@ void __tusb_irq_path_func(hw_endpoint_reset_transfer)(struct hw_endpoint* ep) { ep->user_buf = 0; } -void __tusb_irq_path_func(hwep_buf_ctrl_update)(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask) { +void __tusb_irq_path_func(hwep_buf_ctrl_update)(io_rw_32 *buf_ctrl_reg, uint32_t and_mask, uint32_t or_mask) { const bool is_host = rp2usb_is_host_mode(); - uint32_t value = 0; - io_rw_32 *buf_ctrl; - - #if CFG_TUH_ENABLED - if (is_host) { - buf_ctrl = hwep_buf_ctrl_reg_host(ep); - } else - #endif - { - buf_ctrl = hwep_buf_ctrl_reg_device(ep); - } + uint32_t value = 0; + uint32_t buf_ctrl = *buf_ctrl_reg; if (and_mask) { - value = *buf_ctrl & and_mask; + value = buf_ctrl & and_mask; } if (or_mask) { value |= or_mask; if (or_mask & USB_BUF_CTRL_AVAIL) { - if (*buf_ctrl & USB_BUF_CTRL_AVAIL) { - panic("ep %02X was already available", ep->ep_addr); + if (buf_ctrl & USB_BUF_CTRL_AVAIL) { + panic("buf_ctrl @%lX already available", (uintptr_t)buf_ctrl_reg); } - *buf_ctrl = value & ~USB_BUF_CTRL_AVAIL; - // 4.1.2.5.1 Con-current access: 12 cycles (should be good for 48*12Mhz = 576Mhz) after write to buffer control + *buf_ctrl_reg = value & ~USB_BUF_CTRL_AVAIL; + + // Section 4.1.2.7.1 (rp2040) / 12.7.3.7.1 (rp2350) Concurrent access: after write to buffer control, we need to + // wait at least 1/48 mhz (usb clock), 12 cycles should be good for 48*12Mhz = 576Mhz. // Don't need delay in host mode as host is in charge if (!is_host) { busy_wait_at_least_cycles(12); @@ -121,7 +114,7 @@ void __tusb_irq_path_func(hwep_buf_ctrl_update)(struct hw_endpoint *ep, uint32_t } } - *buf_ctrl = value; + *buf_ctrl_reg = value; } // prepare buffer, move data if tx, return buffer control @@ -161,21 +154,21 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint *ep, // Prepare buffer control register value void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint* ep) { const tusb_dir_t dir = tu_edpt_dir(ep->ep_addr); - bool is_rx; + bool is_rx; io_rw_32 *ep_ctrl_reg; - // io_rw_32 *buf_ctrl_reg; + io_rw_32 *buf_ctrl_reg; #if CFG_TUH_ENABLED const bool is_host = rp2usb_is_host_mode(); if (is_host) { - // buf_ctrl_reg = hwep_buf_ctrl_reg_host(ep); + buf_ctrl_reg = hwep_buf_ctrl_reg_host(ep); ep_ctrl_reg = hwep_ctrl_reg_host(ep); is_rx = (dir == TUSB_DIR_IN); } else #endif { - // buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep); + buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep); ep_ctrl_reg = hwep_ctrl_reg_device(ep); is_rx = (dir == TUSB_DIR_OUT); } @@ -216,7 +209,7 @@ void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint* ep) // Finally, write to buffer_control which will trigger the transfer // the next time the controller polls this dpram address - hwep_buf_ctrl_set(ep, buf_ctrl); + hwep_buf_ctrl_set(buf_ctrl_reg, buf_ctrl); } void hw_endpoint_xfer_start(struct hw_endpoint* ep, uint8_t* buffer, uint16_t total_len) { @@ -334,7 +327,8 @@ static void __tusb_irq_path_func(hwep_xfer_sync)(hw_endpoint_t *ep) { ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER); ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER; - hwep_buf_ctrl_set(ep, 0); + io_rw_32 *buf_ctrl_reg = is_host ? hwep_buf_ctrl_reg_host(ep) : hwep_buf_ctrl_reg_device(ep); + hwep_buf_ctrl_set(buf_ctrl_reg, 0); usb_hw->abort &= ~TU_BIT(ep_id); diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.h b/src/portable/raspberrypi/rp2040/rp2040_usb.h index 2ec00694e..e9fed73de 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.h +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.h @@ -45,41 +45,27 @@ // Hardware information per endpoint typedef struct hw_endpoint { - // Is this a valid struct - bool configured; - uint8_t ep_addr; uint8_t next_pid; + // Interrupt, bulk, etc + uint8_t transfer_type; - // Endpoint control register - // io_rw_32 *endpoint_control; - - // Buffer control register - // io_rw_32 *buffer_control; + bool active; // Endpoint is in use + uint8_t pending; // Transfer scheduled but not active - // Buffer pointer in usb dpram - uint8_t *hw_data_buf; + uint16_t wMaxPacketSize; - // User buffer in main memory - uint8_t *user_buf; + uint8_t *hw_data_buf; // Buffer pointer in usb dpram + uint8_t *user_buf; // User buffer in main memory // Current transfer information uint16_t remaining_len; uint16_t xferred_len; - // Data needed from EP descriptor - uint16_t wMaxPacketSize; - - // Endpoint is in use - bool active; - - // Interrupt, bulk, etc - uint8_t transfer_type; - - // Transfer scheduled but not active - uint8_t pending; - #if CFG_TUH_ENABLED + // Is this a valid struct + bool configured; + // Only needed for host uint8_t dev_addr; @@ -131,7 +117,7 @@ TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_buf_ctrl_reg_device(struct hw #if CFG_TUH_ENABLED TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_ctrl_reg_host(struct hw_endpoint *ep) { - if (ep->transfer_type == TUSB_XFER_CONTROL) { + if (tu_edpt_number(ep->ep_addr) == 0) { return &usbh_dpram->epx_ctrl; } return &usbh_dpram->int_ep_ctrl[ep->interrupt_num].ctrl; @@ -149,18 +135,18 @@ TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_buf_ctrl_reg_host(struct hw_e //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ -void hwep_buf_ctrl_update(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask); +void hwep_buf_ctrl_update(io_rw_32 *buf_ctrl_reg, uint32_t and_mask, uint32_t or_mask); -TU_ATTR_ALWAYS_INLINE static inline void hwep_buf_ctrl_set(struct hw_endpoint *ep, uint32_t value) { - hwep_buf_ctrl_update(ep, 0, value); +TU_ATTR_ALWAYS_INLINE static inline void hwep_buf_ctrl_set(io_rw_32 *buf_ctrl_reg, uint32_t value) { + hwep_buf_ctrl_update(buf_ctrl_reg, 0, value); } -TU_ATTR_ALWAYS_INLINE static inline void hwep_buf_ctrl_set_mask32(struct hw_endpoint *ep, uint32_t value) { - hwep_buf_ctrl_update(ep, ~value, value); +TU_ATTR_ALWAYS_INLINE static inline void hwep_buf_ctrl_set_mask(io_rw_32 *buf_ctrl_reg, uint32_t value) { + hwep_buf_ctrl_update(buf_ctrl_reg, ~value, value); } -TU_ATTR_ALWAYS_INLINE static inline void hwep_buf_ctrl_clear_mask(struct hw_endpoint *ep, uint32_t value) { - hwep_buf_ctrl_update(ep, ~value, 0); +TU_ATTR_ALWAYS_INLINE static inline void hwep_buf_ctrl_clear_mask(io_rw_32 *buf_ctrl_reg, uint32_t value) { + hwep_buf_ctrl_update(buf_ctrl_reg, ~value, 0); } static inline uintptr_t hw_data_offset(uint8_t *buf) { -- cgit v1.3.1 From 07416f704f1a55b286d5c9b082e6f1e3e51ce9b0 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 8 Jan 2026 11:33:08 +0700 Subject: minor clean up --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 68 +++++++++++++--------------- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 31 ++++++------- src/portable/raspberrypi/rp2040/rp2040_usb.c | 26 +++++------ src/portable/raspberrypi/rp2040/rp2040_usb.h | 34 +++++++------- 4 files changed, 77 insertions(+), 82 deletions(-) (limited to 'src') diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 5c21590c4..952245cb1 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -71,18 +71,17 @@ TU_ATTR_ALWAYS_INLINE static inline hw_endpoint_t *hw_endpoint_get_by_addr(uint8 // main processing for dcd_edpt_iso_activate static void hw_endpoint_init(hw_endpoint_t *ep, uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) { - const uint8_t epnum = tu_edpt_number(ep_addr); - ep->ep_addr = ep_addr; ep->next_pid = 0u; ep->wMaxPacketSize = wMaxPacketSize; ep->transfer_type = transfer_type; // Clear existing buffer control state - io_rw_32 *buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep); + io_rw_32 *buf_ctrl_reg = hwbuf_ctrl_reg_device(ep); *buf_ctrl_reg = 0; // allocated hw buffer + const uint8_t epnum = tu_edpt_number(ep_addr); if (epnum == 0) { // Buffer offset is fixed (also double buffered) ep->hw_data_buf = (uint8_t*) &usb_dpram->ep0_buf_a[0]; @@ -104,16 +103,9 @@ static void hw_endpoint_init(hw_endpoint_t *ep, uint8_t ep_addr, uint16_t wMaxPa } } -// Init, allocate buffer and enable endpoint -static void hw_endpoint_open(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) { - const uint8_t epnum = tu_edpt_number(ep_addr); - const tusb_dir_t dir = tu_edpt_dir(ep_addr); - hw_endpoint_t *ep = hw_endpoint_get(epnum, dir); - - hw_endpoint_init(ep, ep_addr, wMaxPacketSize, transfer_type); - - // Set endpoint control register to enable (EP0 has no endpoint control register) +static void hw_endpoint_enable(hw_endpoint_t *ep, uint8_t transfer_type) { io_rw_32 *ctrl_reg = hwep_ctrl_reg_device(ep); + // Set endpoint control register to enable (EP0 has no endpoint control register) if (ctrl_reg != NULL) { const uint32_t ctrl_value = EP_CTRL_ENABLE_BITS | ((uint32_t)transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | hw_data_offset(ep->hw_data_buf); @@ -121,14 +113,24 @@ static void hw_endpoint_open(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t t } } +// Init and enable endpoint +static void hw_endpoint_open(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) { + const uint8_t epnum = tu_edpt_number(ep_addr); + const tusb_dir_t dir = tu_edpt_dir(ep_addr); + hw_endpoint_t *ep = hw_endpoint_get(epnum, dir); + + hw_endpoint_init(ep, ep_addr, wMaxPacketSize, transfer_type); + hw_endpoint_enable(ep, transfer_type); +} + static void hw_endpoint_abort_xfer(struct hw_endpoint* ep) { // Abort any pending transfer - // Due to Errata RP2040-E2: ABORT flag is only applicable for B2 and later (unusable for B0, B1). - // Which means we are not guaranteed to safely abort pending transfer on B0 and B1. const uint8_t dir = (uint8_t)tu_edpt_dir(ep->ep_addr); - const uint8_t epnum = tu_edpt_number(ep->ep_addr); + const uint8_t epnum = tu_edpt_number(ep->ep_addr); const uint32_t abort_mask = TU_BIT((epnum << 1) | (dir ? 0 : 1)); + // Due to Errata RP2040-E2: ABORT flag is only applicable for B2 and later (unusable for B0, B1). + // Which means we are not guaranteed to safely abort pending transfer on B0 and B1. if (rp2040_chip_version() >= 2) { usb_hw_set->abort = abort_mask; while ((usb_hw->abort_done & abort_mask) != abort_mask) {} @@ -139,8 +141,8 @@ static void hw_endpoint_abort_xfer(struct hw_endpoint* ep) { buf_ctrl |= USB_BUF_CTRL_DATA1_PID; } - io_rw_32 *buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep); - hwep_buf_ctrl_set(buf_ctrl_reg, buf_ctrl); + io_rw_32 *buf_ctrl_reg = hwbuf_ctrl_reg_device(ep); + hwbuf_ctrl_set(buf_ctrl_reg, buf_ctrl); hw_endpoint_reset_transfer(ep); if (rp2040_chip_version() >= 2) { @@ -265,15 +267,12 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { #if FORCE_VBUS_DETECT == 0 // Since we force VBUS detect On, device will always think it is connected and // couldn't distinguish between disconnect and suspend - if (status & USB_INTS_DEV_CONN_DIS_BITS) - { + if (status & USB_INTS_DEV_CONN_DIS_BITS) { handled |= USB_INTS_DEV_CONN_DIS_BITS; - if ( usb_hw->sie_status & USB_SIE_STATUS_CONNECTED_BITS ) - { + if (usb_hw->sie_status & USB_SIE_STATUS_CONNECTED_BITS) { // Connected: nothing to do - }else - { + } else { // Disconnected dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true); } @@ -295,8 +294,10 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { #if TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX // Only run enumeration workaround if pull up is enabled - if (usb_hw->sie_ctrl & USB_SIE_CTRL_PULLUP_EN_BITS) rp2040_usb_device_enumeration_fix(); -#endif + if (usb_hw->sie_ctrl & USB_SIE_CTRL_PULLUP_EN_BITS) { + rp2040_usb_device_enumeration_fix(); + } + #endif } /* Note from pico datasheet 4.1.2.6.4 (v1.2) @@ -458,7 +459,6 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* req bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { (void) rhport; const uint8_t xfer_type = desc_edpt->bmAttributes.xfer; - TU_VERIFY(xfer_type != TUSB_XFER_ISOCHRONOUS); hw_endpoint_open(desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt), xfer_type); return true; } @@ -485,13 +485,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *ep_desc) } ep->wMaxPacketSize = ep_desc->wMaxPacketSize; - // Set control register to enable endpoint - io_rw_32 *ctrl_reg = hwep_ctrl_reg_device(ep); - if (ctrl_reg != NULL) { - const uint32_t ctrl_value = EP_CTRL_ENABLE_BITS | ((uint32_t)TUSB_XFER_ISOCHRONOUS << EP_CTRL_BUFFER_TYPE_LSB) | - hw_data_offset(ep->hw_data_buf); - *ctrl_reg = ctrl_value; - } + hw_endpoint_enable(ep, TUSB_XFER_ISOCHRONOUS); return true; } @@ -522,8 +516,8 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { } // stall and clear current pending buffer, may need to use EP_ABORT - io_rw_32 *buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep); - hwep_buf_ctrl_set(buf_ctrl_reg, USB_BUF_CTRL_STALL); + io_rw_32 *buf_ctrl_reg = hwbuf_ctrl_reg_device(ep); + hwbuf_ctrl_set(buf_ctrl_reg, USB_BUF_CTRL_STALL); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { @@ -534,8 +528,8 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { // clear stall also reset toggle to DATA0, ready for next transfer ep->next_pid = 0; - io_rw_32 *buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep); - hwep_buf_ctrl_clear_mask(buf_ctrl_reg, USB_BUF_CTRL_STALL); + io_rw_32 *buf_ctrl_reg = hwbuf_ctrl_reg_device(ep); + hwbuf_ctrl_clear_mask(buf_ctrl_reg, USB_BUF_CTRL_STALL); } } diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 2e5f0fe1f..c4eba0d5f 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -62,22 +62,23 @@ enum { USB_SIE_CTRL_PULLDOWN_EN_BITS | USB_SIE_CTRL_EP0_INT_1BUF_BITS }; -static struct hw_endpoint *get_dev_ep(uint8_t dev_addr, uint8_t ep_addr) -{ +static struct hw_endpoint *get_dev_ep(uint8_t dev_addr, uint8_t ep_addr) { uint8_t num = tu_edpt_number(ep_addr); - if ( num == 0 ) return &epx; + if (num == 0) { + return &epx; + } - for ( uint32_t i = 1; i < TU_ARRAY_SIZE(ep_pool); i++ ) - { + for (uint32_t i = 1; i < TU_ARRAY_SIZE(ep_pool); i++) { struct hw_endpoint *ep = &ep_pool[i]; - if ( ep->configured && (ep->dev_addr == dev_addr) && (ep->ep_addr == ep_addr) ) return ep; + if (ep->configured && (ep->dev_addr == dev_addr) && (ep->ep_addr == ep_addr)) { + return ep; + } } return NULL; } -TU_ATTR_ALWAYS_INLINE static inline uint8_t dev_speed(void) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t dev_speed(void) { return (usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS) >> USB_SIE_STATUS_SPEED_LSB; } @@ -98,8 +99,7 @@ static void __tusb_irq_path_func(hw_xfer_complete)(struct hw_endpoint *ep, xfer_ hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, xfer_result, true); } -static void __tusb_irq_path_func(_handle_buff_status_bit)(uint bit, struct hw_endpoint *ep) -{ +static void __tusb_irq_path_func(_handle_buff_status_bit)(uint bit, struct hw_endpoint *ep) { usb_hw_clear->buf_status = bit; // EP may have been stalled? assert(ep->active); @@ -357,8 +357,7 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t // Finally, enable interrupt that endpoint usb_hw_set->int_ep_ctrl = 1 << (ep->interrupt_num + 1); - // If it's an interrupt endpoint we need to set up the buffer control - // register + // If it's an interrupt endpoint we need to set up the buffer control register } } @@ -456,8 +455,8 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { // reset epx if it is currently active with unplugged device if (epx.configured && epx.active && epx.dev_addr == dev_addr) { epx.configured = false; - *hwep_ctrl_reg_host(&epx) = 0; - *hwep_buf_ctrl_reg_host(&epx) = 0; + *hwep_ctrl_reg_host(&epx) = 0; + *hwbuf_ctrl_reg_host(&epx) = 0; hw_endpoint_reset_transfer(&epx); } @@ -472,8 +471,8 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { // unconfigure the endpoint ep->configured = false; - *hwep_ctrl_reg_host(ep) = 0; - *hwep_buf_ctrl_reg_host(ep) = 0; + *hwep_ctrl_reg_host(ep) = 0; + *hwbuf_ctrl_reg_host(ep) = 0; hw_endpoint_reset_transfer(ep); } } diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 5258b9705..798129e0c 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -88,7 +88,7 @@ void __tusb_irq_path_func(hw_endpoint_reset_transfer)(struct hw_endpoint* ep) { ep->user_buf = 0; } -void __tusb_irq_path_func(hwep_buf_ctrl_update)(io_rw_32 *buf_ctrl_reg, uint32_t and_mask, uint32_t or_mask) { +void __tusb_irq_path_func(hwbuf_ctrl_update)(io_rw_32 *buf_ctrl_reg, uint32_t and_mask, uint32_t or_mask) { const bool is_host = rp2usb_is_host_mode(); uint32_t value = 0; uint32_t buf_ctrl = *buf_ctrl_reg; @@ -101,7 +101,7 @@ void __tusb_irq_path_func(hwep_buf_ctrl_update)(io_rw_32 *buf_ctrl_reg, uint32_t value |= or_mask; if (or_mask & USB_BUF_CTRL_AVAIL) { if (buf_ctrl & USB_BUF_CTRL_AVAIL) { - panic("buf_ctrl @%lX already available", (uintptr_t)buf_ctrl_reg); + panic("buf_ctrl @ 0x%lX already available", (uintptr_t)buf_ctrl_reg); } *buf_ctrl_reg = value & ~USB_BUF_CTRL_AVAIL; @@ -162,15 +162,15 @@ void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint* ep) #if CFG_TUH_ENABLED const bool is_host = rp2usb_is_host_mode(); if (is_host) { - buf_ctrl_reg = hwep_buf_ctrl_reg_host(ep); - ep_ctrl_reg = hwep_ctrl_reg_host(ep); - is_rx = (dir == TUSB_DIR_IN); + buf_ctrl_reg = hwbuf_ctrl_reg_host(ep); + ep_ctrl_reg = hwep_ctrl_reg_host(ep); + is_rx = (dir == TUSB_DIR_IN); } else #endif { - buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep); - ep_ctrl_reg = hwep_ctrl_reg_device(ep); - is_rx = (dir == TUSB_DIR_OUT); + buf_ctrl_reg = hwbuf_ctrl_reg_device(ep); + ep_ctrl_reg = hwep_ctrl_reg_device(ep); + is_rx = (dir == TUSB_DIR_OUT); } // always compute and start with buffer 0 @@ -209,7 +209,7 @@ void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint* ep) // Finally, write to buffer_control which will trigger the transfer // the next time the controller polls this dpram address - hwep_buf_ctrl_set(buf_ctrl_reg, buf_ctrl); + hwbuf_ctrl_set(buf_ctrl_reg, buf_ctrl); } void hw_endpoint_xfer_start(struct hw_endpoint* ep, uint8_t* buffer, uint16_t total_len) { @@ -287,13 +287,13 @@ static void __tusb_irq_path_func(hwep_xfer_sync)(hw_endpoint_t *ep) { #if CFG_TUH_ENABLED const bool is_host = rp2usb_is_host_mode(); if (is_host) { - buf_ctrl_reg = hwep_buf_ctrl_reg_host(ep); + buf_ctrl_reg = hwbuf_ctrl_reg_host(ep); ep_ctrl_reg = hwep_ctrl_reg_host(ep); is_rx = (dir == TUSB_DIR_IN); } else #endif { - buf_ctrl_reg = hwep_buf_ctrl_reg_device(ep); + buf_ctrl_reg = hwbuf_ctrl_reg_device(ep); ep_ctrl_reg = hwep_ctrl_reg_device(ep); is_rx = (dir == TUSB_DIR_OUT); } @@ -327,8 +327,8 @@ static void __tusb_irq_path_func(hwep_xfer_sync)(hw_endpoint_t *ep) { ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER); ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER; - io_rw_32 *buf_ctrl_reg = is_host ? hwep_buf_ctrl_reg_host(ep) : hwep_buf_ctrl_reg_device(ep); - hwep_buf_ctrl_set(buf_ctrl_reg, 0); + io_rw_32 *buf_ctrl_reg = is_host ? hwbuf_ctrl_reg_host(ep) : hwbuf_ctrl_reg_device(ep); + hwbuf_ctrl_set(buf_ctrl_reg, 0); usb_hw->abort &= ~TU_BIT(ep_id); diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.h b/src/portable/raspberrypi/rp2040/rp2040_usb.h index e9fed73de..368bb6509 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.h +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.h @@ -1,10 +1,6 @@ #ifndef RP2040_COMMON_H_ #define RP2040_COMMON_H_ -#if defined(RP2040_USB_HOST_MODE) && defined(RP2040_USB_DEVICE_MODE) -#error TinyUSB device and host mode not supported at the same time -#endif - #include "common/tusb_common.h" #include "pico.h" @@ -13,6 +9,10 @@ #include "hardware/resets.h" #include "hardware/timer.h" +#if defined(RP2040_USB_HOST_MODE) && defined(RP2040_USB_DEVICE_MODE) + #error TinyUSB device and host mode not supported at the same time +#endif + #if defined(PICO_RP2040_USB_DEVICE_ENUMERATION_FIX) && !defined(TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX) #define TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX PICO_RP2040_USB_DEVICE_ENUMERATION_FIX #endif @@ -36,6 +36,9 @@ #define __tusb_irq_path_func(x) x #endif +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ #define usb_hw_set ((usb_hw_t *) hw_set_alias_untyped(usb_hw)) #define usb_hw_clear ((usb_hw_t *) hw_clear_alias_untyped(usb_hw)) @@ -56,9 +59,9 @@ typedef struct hw_endpoint uint16_t wMaxPacketSize; uint8_t *hw_data_buf; // Buffer pointer in usb dpram - uint8_t *user_buf; // User buffer in main memory // Current transfer information + uint8_t *user_buf; // User buffer in main memory uint16_t remaining_len; uint16_t xferred_len; @@ -108,7 +111,7 @@ TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_ctrl_reg_device(struct hw_end return (dir == TUSB_DIR_IN) ? &usb_dpram->ep_ctrl[epnum - 1].in : &usb_dpram->ep_ctrl[epnum - 1].out; } -TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_buf_ctrl_reg_device(struct hw_endpoint *ep) { +TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwbuf_ctrl_reg_device(struct hw_endpoint *ep) { const uint8_t epnum = tu_edpt_number(ep->ep_addr); const uint8_t dir = (uint8_t)tu_edpt_dir(ep->ep_addr); return (dir == TUSB_DIR_IN) ? &usb_dpram->ep_buf_ctrl[epnum].in : &usb_dpram->ep_buf_ctrl[epnum].out; @@ -123,30 +126,29 @@ TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_ctrl_reg_host(struct hw_endpo return &usbh_dpram->int_ep_ctrl[ep->interrupt_num].ctrl; } -TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_buf_ctrl_reg_host(struct hw_endpoint *ep) { - if (ep->transfer_type == TUSB_XFER_CONTROL) { +TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwbuf_ctrl_reg_host(struct hw_endpoint *ep) { + if (tu_edpt_number(ep->ep_addr) == 0) { return &usbh_dpram->epx_buf_ctrl; } return &usbh_dpram->int_ep_buffer_ctrl[ep->interrupt_num].ctrl; } #endif - //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ -void hwep_buf_ctrl_update(io_rw_32 *buf_ctrl_reg, uint32_t and_mask, uint32_t or_mask); +void hwbuf_ctrl_update(io_rw_32 *buf_ctrl_reg, uint32_t and_mask, uint32_t or_mask); -TU_ATTR_ALWAYS_INLINE static inline void hwep_buf_ctrl_set(io_rw_32 *buf_ctrl_reg, uint32_t value) { - hwep_buf_ctrl_update(buf_ctrl_reg, 0, value); +TU_ATTR_ALWAYS_INLINE static inline void hwbuf_ctrl_set(io_rw_32 *buf_ctrl_reg, uint32_t value) { + hwbuf_ctrl_update(buf_ctrl_reg, 0, value); } -TU_ATTR_ALWAYS_INLINE static inline void hwep_buf_ctrl_set_mask(io_rw_32 *buf_ctrl_reg, uint32_t value) { - hwep_buf_ctrl_update(buf_ctrl_reg, ~value, value); +TU_ATTR_ALWAYS_INLINE static inline void hwbuf_ctrl_set_mask(io_rw_32 *buf_ctrl_reg, uint32_t value) { + hwbuf_ctrl_update(buf_ctrl_reg, ~value, value); } -TU_ATTR_ALWAYS_INLINE static inline void hwep_buf_ctrl_clear_mask(io_rw_32 *buf_ctrl_reg, uint32_t value) { - hwep_buf_ctrl_update(buf_ctrl_reg, ~value, 0); +TU_ATTR_ALWAYS_INLINE static inline void hwbuf_ctrl_clear_mask(io_rw_32 *buf_ctrl_reg, uint32_t value) { + hwbuf_ctrl_update(buf_ctrl_reg, ~value, 0); } static inline uintptr_t hw_data_offset(uint8_t *buf) { -- cgit v1.3.1 From d7e715d5c238e9b05ef711a1a73d54c40b37729e Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 8 Jan 2026 15:42:08 +0700 Subject: fix hcd force_single mistake by refactor --- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 42 +++++++++------------------- src/portable/raspberrypi/rp2040/rp2040_usb.c | 5 ++-- 2 files changed, 16 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index c4eba0d5f..db3a81c87 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -110,35 +110,24 @@ static void __tusb_irq_path_func(_handle_buff_status_bit)(uint bit, struct hw_en } } -static void __tusb_irq_path_func(hw_handle_buff_status)(void) -{ +static void __tusb_irq_path_func(handle_hwbuf_status)(void) { uint32_t remaining_buffers = usb_hw->buf_status; pico_trace("buf_status 0x%08lx\n", remaining_buffers); // Check EPX first uint bit = 0b1; - if ( remaining_buffers & bit ) - { + if (remaining_buffers & bit) { remaining_buffers &= ~bit; struct hw_endpoint * ep = &epx; - uint32_t ep_ctrl = *hwep_ctrl_reg_host(ep); - if ( ep_ctrl & EP_CTRL_DOUBLE_BUFFERED_BITS ) - { - TU_LOG(3, "Double Buffered: "); - } - else - { - TU_LOG(3, "Single Buffered: "); - } - TU_LOG_HEX(3, ep_ctrl); + // uint32_t ep_ctrl = *hwep_ctrl_reg_host(ep); + // TU_LOG_HEX(3, ep_ctrl); _handle_buff_status_bit(bit, ep); } // Check "interrupt" (asynchronous) endpoints for both IN and OUT - for ( uint i = 1; i <= USB_HOST_INTERRUPT_ENDPOINTS && remaining_buffers; i++ ) - { + for (uint i = 1; i <= USB_HOST_INTERRUPT_ENDPOINTS && remaining_buffers; i++) { // EPX is bit 0 & 1 // IEP1 IN is bit 2 // IEP1 OUT is bit 3 @@ -147,19 +136,16 @@ static void __tusb_irq_path_func(hw_handle_buff_status)(void) // IEP3 IN is bit 6 // IEP3 OUT is bit 7 // etc - for ( uint j = 0; j < 2; j++ ) - { + for (uint j = 0; j < 2; j++) { bit = 1 << (i * 2 + j); - if ( remaining_buffers & bit ) - { + if (remaining_buffers & bit) { remaining_buffers &= ~bit; _handle_buff_status_bit(bit, &ep_pool[i]); } } } - if ( remaining_buffers ) - { + if (remaining_buffers) { panic("Unhandled buffer %d\n", remaining_buffers); } } @@ -220,7 +206,7 @@ static void __tusb_irq_path_func(hcd_rp2040_irq)(void) { handled |= USB_INTS_BUFF_STATUS_BITS; TU_LOG(2, "Buffer complete\r\n"); - hw_handle_buff_status(); + handle_hwbuf_status(); } if ( status & USB_INTS_TRANS_COMPLETE_BITS ) @@ -240,8 +226,8 @@ static void __tusb_irq_path_func(hcd_rp2040_irq)(void) if ( status & USB_INTS_ERROR_DATA_SEQ_BITS ) { usb_hw_clear->sie_status = USB_SIE_STATUS_DATA_SEQ_ERROR_BITS; - TU_LOG(3, " Seq Error: [0] = 0x%04u [1] = 0x%04x\r\n", tu_u32_low16(*hw_endpoint_get_buf_ctrl(&epx)), - tu_u32_high16(*hw_endpoint_get_buf_ctrl(&epx))); + TU_LOG(3, " Seq Error: [0] = 0x%04u [1] = 0x%04x\r\n", tu_u32_low16(*hwbuf_ctrl_reg_host(&epx)), + tu_u32_high16(*hwbuf_ctrl_reg_host(&epx))); panic("Data Seq Error \n"); } @@ -322,10 +308,8 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t assert(!(dpram_offset & 0b111111)); // Fill in endpoint control register with buffer offset - uint32_t ep_reg = EP_CTRL_ENABLE_BITS - | EP_CTRL_INTERRUPT_PER_BUFFER - | (ep->transfer_type << EP_CTRL_BUFFER_TYPE_LSB) - | dpram_offset; + uint32_t ep_reg = EP_CTRL_ENABLE_BITS | EP_CTRL_INTERRUPT_PER_BUFFER | + ((uint)transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset; if ( bmInterval ) { ep_reg |= (uint32_t) ((bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB); diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 798129e0c..9c9255518 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -156,11 +156,12 @@ void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint* ep) const tusb_dir_t dir = tu_edpt_dir(ep->ep_addr); bool is_rx; + bool is_host = false; io_rw_32 *ep_ctrl_reg; io_rw_32 *buf_ctrl_reg; #if CFG_TUH_ENABLED - const bool is_host = rp2usb_is_host_mode(); + is_host = rp2usb_is_host_mode(); if (is_host) { buf_ctrl_reg = hwbuf_ctrl_reg_host(ep); ep_ctrl_reg = hwep_ctrl_reg_host(ep); @@ -185,7 +186,7 @@ void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint* ep) // NOTE: this could happen to Host mode IN endpoint Also, Host mode "interrupt" endpoint hardware is only single // buffered, // NOTE2: Currently Host bulk is implemented using "interrupt" endpoint - const bool force_single = is_rx; + const bool force_single = (!is_host && is_rx) || (is_host && tu_edpt_number(ep->ep_addr) != 0); if (ep->remaining_len && !force_single) { // Use buffer 1 (double buffered) if there is still data -- cgit v1.3.1 From 0b970e6a6633f703acb0f40b52b741cf492ff166 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 9 Jan 2026 00:08:43 +0700 Subject: only apply errata E5 and E15 for rp2040. rp2350 already fixes these --- hw/bsp/rp2040/family.cmake | 6 +- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 14 ++-- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 119 ++++++++++----------------- src/portable/raspberrypi/rp2040/rp2040_usb.c | 25 +++--- src/portable/raspberrypi/rp2040/rp2040_usb.h | 67 +++++++++------ 5 files changed, 109 insertions(+), 122 deletions(-) (limited to 'src') diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 1602e35eb..9dc28fc70 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -126,7 +126,7 @@ target_compile_definitions(tinyusb_host_base INTERFACE #------------------------------------ # Host MAX3421 -#------------------------------------ +#------------------------------------1 add_library(tinyusb_host_max3421 INTERFACE) target_sources(tinyusb_host_max3421 INTERFACE ${TOP}/src/portable/analog/max3421/hcd_max3421.c @@ -157,10 +157,12 @@ target_link_libraries(tinyusb_bsp INTERFACE # tinyusb_additions will hold our extra settings for examples add_library(tinyusb_additions INTERFACE) +if (PICO_PLATFORM STREQUAL rp2040) target_compile_definitions(tinyusb_additions INTERFACE PICO_RP2040_USB_DEVICE_ENUMERATION_FIX=1 PICO_RP2040_USB_DEVICE_UFRAME_FIX=1 -) + ) +endif () if(LOGGER STREQUAL "RTT" OR LOGGER STREQUAL "rtt") target_compile_definitions(tinyusb_additions INTERFACE diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 952245cb1..bdd0d1728 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -92,6 +92,12 @@ static void hw_endpoint_init(hw_endpoint_t *ep, uint8_t ep_addr, uint16_t wMaxPa // double buffered Bulk endpoint if (transfer_type == TUSB_XFER_BULK) { size *= 2u; + + #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX + if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { + ep->e15_bulk_in = true; + } + #endif } // assign buffer @@ -221,17 +227,14 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { struct hw_endpoint *ep = hw_endpoint_get(i, TUSB_DIR_IN); // Active Bulk IN endpoint requires SOF - if ((ep->transfer_type == TUSB_XFER_BULK) && ep->active) { + if (ep->e15_bulk_in && ep->active) { keep_sof_alive = true; hw_endpoint_lock_update(ep, 1); - - // Deferred enable? if (ep->pending) { ep->pending = 0; hw_endpoint_start_next_buffer(ep); } - hw_endpoint_lock_update(ep, -1); } } @@ -292,7 +295,7 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); usb_hw_clear->sie_status = USB_SIE_STATUS_BUS_RESET_BITS; -#if TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX + #if TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX // Only run enumeration workaround if pull up is enabled if (usb_hw->sie_ctrl & USB_SIE_CTRL_PULLUP_EN_BITS) { rp2040_usb_device_enumeration_fix(); @@ -491,7 +494,6 @@ bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *ep_desc) void dcd_edpt_close_all(uint8_t rhport) { (void) rhport; - // may need to use EP Abort reset_non_control_endpoints(); } diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index db3a81c87..1193009ef 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -82,15 +82,13 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t dev_speed(void) { return (usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS) >> USB_SIE_STATUS_SPEED_LSB; } -TU_ATTR_ALWAYS_INLINE static inline bool need_pre(uint8_t dev_addr) -{ +TU_ATTR_ALWAYS_INLINE static inline bool need_pre(uint8_t dev_addr) { // If this device is different to the speed of the root device // (i.e. is a low speed device on a full speed hub) then need pre return hcd_port_speed_get(0) != tuh_speed_get(dev_addr); } -static void __tusb_irq_path_func(hw_xfer_complete)(struct hw_endpoint *ep, xfer_result_t xfer_result) -{ +static void __tusb_irq_path_func(hw_xfer_complete)(struct hw_endpoint *ep, xfer_result_t xfer_result) { // Mark transfer as done before we tell the tinyusb stack uint8_t dev_addr = ep->dev_addr; uint8_t ep_addr = ep->ep_addr; @@ -99,35 +97,28 @@ static void __tusb_irq_path_func(hw_xfer_complete)(struct hw_endpoint *ep, xfer_ hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, xfer_result, true); } -static void __tusb_irq_path_func(_handle_buff_status_bit)(uint bit, struct hw_endpoint *ep) { +static void __tusb_irq_path_func(handle_hhwbuf_status_bit)(uint bit, struct hw_endpoint *ep) { usb_hw_clear->buf_status = bit; - // EP may have been stalled? - assert(ep->active); - bool done = hw_endpoint_xfer_continue(ep); - if ( done ) - { + const bool done = hw_endpoint_xfer_continue(ep); + if (done) { hw_xfer_complete(ep, XFER_RESULT_SUCCESS); } } static void __tusb_irq_path_func(handle_hwbuf_status)(void) { - uint32_t remaining_buffers = usb_hw->buf_status; - pico_trace("buf_status 0x%08lx\n", remaining_buffers); + uint32_t buf_status = usb_hw->buf_status; + pico_trace("buf_status 0x%08lx\n", buf_status); // Check EPX first uint bit = 0b1; - if (remaining_buffers & bit) { - remaining_buffers &= ~bit; + if (buf_status & bit) { + buf_status &= ~bit; struct hw_endpoint * ep = &epx; - - // uint32_t ep_ctrl = *hwep_ctrl_reg_host(ep); - // TU_LOG_HEX(3, ep_ctrl); - - _handle_buff_status_bit(bit, ep); + handle_hhwbuf_status_bit(bit, ep); } // Check "interrupt" (asynchronous) endpoints for both IN and OUT - for (uint i = 1; i <= USB_HOST_INTERRUPT_ENDPOINTS && remaining_buffers; i++) { + for (uint i = 1; i <= USB_HOST_INTERRUPT_ENDPOINTS && buf_status; i++) { // EPX is bit 0 & 1 // IEP1 IN is bit 2 // IEP1 OUT is bit 3 @@ -138,15 +129,15 @@ static void __tusb_irq_path_func(handle_hwbuf_status)(void) { // etc for (uint j = 0; j < 2; j++) { bit = 1 << (i * 2 + j); - if (remaining_buffers & bit) { - remaining_buffers &= ~bit; - _handle_buff_status_bit(bit, &ep_pool[i]); + if (buf_status & bit) { + buf_status &= ~bit; + handle_hhwbuf_status_bit(bit, &ep_pool[i]); } } } - if (remaining_buffers) { - panic("Unhandled buffer %d\n", remaining_buffers); + if (buf_status) { + panic("Unhandled buffer %d\n", buf_status); } } @@ -251,7 +242,7 @@ static struct hw_endpoint *_next_free_interrupt_ep(void) ep = &ep_pool[i]; if ( !ep->configured ) { - // Will be configured by _hw_endpoint_init / _hw_endpoint_allocate + // Will be configured by hw_endpoint_init / hw_endpoint_allocate ep->interrupt_num = (uint8_t) (i - 1); return ep; } @@ -259,12 +250,13 @@ static struct hw_endpoint *_next_free_interrupt_ep(void) return ep; } -static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type) -{ - struct hw_endpoint * ep = NULL; +static hw_endpoint_t *hw_endpoint_allocate(uint8_t transfer_type) { + hw_endpoint_t *ep = NULL; - if ( transfer_type != TUSB_XFER_CONTROL ) - { + if (transfer_type == TUSB_XFER_CONTROL) { + ep = &epx; + ep->hw_data_buf = &usbh_dpram->epx_data[0]; + } else { // Note: even though datasheet name these "Interrupt" endpoints. These are actually // "Asynchronous" endpoints and can be used for other type such as: Bulk (ISO need confirmation) ep = _next_free_interrupt_ep(); @@ -276,17 +268,12 @@ static struct hw_endpoint *_hw_endpoint_allocate(uint8_t transfer_type) // etc ep->hw_data_buf = &usbh_dpram->epx_data[64 * (ep->interrupt_num + 2)]; } - else - { - ep = &epx; - ep->hw_data_buf = &usbh_dpram->epx_data[0]; - } return ep; } -static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type, uint8_t bmInterval) -{ +static void hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t ep_addr, uint16_t wMaxPacketSize, + uint8_t transfer_type, uint8_t bmInterval) { // Already has data buffer, endpoint control, and buffer control allocated at this point assert(ep->hw_data_buf); @@ -299,7 +286,6 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t // Response to a setup packet on EP0 starts with pid of 1 ep->next_pid = (num == 0 ? 1u : 0u); ep->wMaxPacketSize = wMaxPacketSize; - ep->transfer_type = transfer_type; pico_trace("hw_endpoint_init dev %d ep %02X xfer %d\n", ep->dev_addr, ep->ep_addr, ep->transfer_type); pico_trace("dev %d ep %02X setup buffer @ 0x%p\n", ep->dev_addr, ep->ep_addr, ep->hw_data_buf); @@ -463,46 +449,33 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { } } -uint32_t hcd_frame_number(uint8_t rhport) -{ - (void) rhport; +uint32_t hcd_frame_number(uint8_t rhport) { + (void)rhport; return usb_hw->sof_rd; } -void hcd_int_enable(uint8_t rhport) -{ - (void) rhport; - assert(rhport == 0); +void hcd_int_enable(uint8_t rhport) { + (void)rhport; irq_set_enabled(USBCTRL_IRQ, true); } -void hcd_int_disable(uint8_t rhport) -{ - (void) rhport; +void hcd_int_disable(uint8_t rhport) { + (void)rhport; // todo we should check this is disabling from the correct core; note currently this is never called - assert(rhport == 0); irq_set_enabled(USBCTRL_IRQ, false); } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ -bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) -{ - (void) rhport; - +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_endpoint_t *ep_desc) { + (void)rhport; pico_trace("hcd_edpt_open dev_addr %d, ep_addr %d\n", dev_addr, ep_desc->bEndpointAddress); - - // Allocated differently based on if it's an interrupt endpoint or not - struct hw_endpoint *ep = _hw_endpoint_allocate(ep_desc->bmAttributes.xfer); + hw_endpoint_t *ep = hw_endpoint_allocate(ep_desc->bmAttributes.xfer); TU_ASSERT(ep); - _hw_endpoint_init(ep, - dev_addr, - ep_desc->bEndpointAddress, - tu_edpt_packet_size(ep_desc), - ep_desc->bmAttributes.xfer, - ep_desc->bInterval); + hw_endpoint_init(ep, dev_addr, ep_desc->bEndpointAddress, tu_edpt_packet_size(ep_desc), ep_desc->bmAttributes.xfer, + ep_desc->bInterval); return true; } @@ -512,13 +485,12 @@ bool hcd_edpt_close(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) { return false; // TODO not implemented yet } -bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) -{ +bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) { (void) rhport; pico_trace("hcd_edpt_xfer dev_addr %d, ep_addr 0x%x, len %d\n", dev_addr, ep_addr, buflen); - uint8_t const ep_num = tu_edpt_number(ep_addr); + const uint8_t ep_num = tu_edpt_number(ep_addr); tusb_dir_t const ep_dir = tu_edpt_dir(ep_addr); // Get appropriate ep. Either EPX or interrupt endpoint @@ -530,19 +502,17 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * assert(!ep->active); // Control endpoint can change direction 0x00 <-> 0x80 - if ( ep_addr != ep->ep_addr ) - { + if (ep_addr != ep->ep_addr) { assert(ep_num == 0); // Direction has flipped on endpoint control so re init it but with same properties - _hw_endpoint_init(ep, dev_addr, ep_addr, ep->wMaxPacketSize, ep->transfer_type, 0); + hw_endpoint_init(ep, dev_addr, ep_addr, ep->wMaxPacketSize, TUSB_XFER_CONTROL, 0); } // If a normal transfer (non-interrupt) then initiate using // sie ctrl registers. Otherwise, interrupt ep registers should // already be configured - if ( ep == &epx ) - { + if (ep == &epx) { hw_endpoint_xfer_start(ep, buffer, buflen); // That has set up buffer control, endpoint control etc @@ -558,8 +528,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * usb_hw->sie_ctrl = flags & ~USB_SIE_CTRL_START_TRANS_BITS; busy_wait_at_least_cycles(12); usb_hw->sie_ctrl = flags; - }else - { + } else { hw_endpoint_xfer_start(ep, buffer, buflen); } @@ -584,14 +553,14 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet } // Configure EP0 struct with setup info for the trans complete - struct hw_endpoint * ep = _hw_endpoint_allocate( (uint8_t) TUSB_XFER_CONTROL); + hw_endpoint_t *ep = hw_endpoint_allocate((uint8_t)TUSB_XFER_CONTROL); TU_ASSERT(ep); // EPX should be inactive assert(!ep->active); // EP0 out - _hw_endpoint_init(ep, dev_addr, 0x00, ep->wMaxPacketSize, 0, 0); + hw_endpoint_init(ep, dev_addr, 0x00, ep->wMaxPacketSize, 0, 0); assert(ep->configured); ep->remaining_len = 8; diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 9c9255518..8f91ecf22 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -38,10 +38,8 @@ static void hwep_xfer_sync(hw_endpoint_t *ep); #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX -static bool e15_is_bulkin_ep(struct hw_endpoint *ep); static bool e15_is_critical_frame_period(struct hw_endpoint *ep); #else - #define e15_is_bulkin_ep(x) (false) #define e15_is_critical_frame_period(x) (false) #endif @@ -228,13 +226,16 @@ void hw_endpoint_xfer_start(struct hw_endpoint* ep, uint8_t* buffer, uint16_t to ep->active = true; ep->user_buf = buffer; - if (e15_is_bulkin_ep(ep)) { + #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX + if (ep->e15_bulk_in) { usb_hw_set->inte = USB_INTS_DEV_SOF_BITS; } if (e15_is_critical_frame_period(ep)) { - ep->pending = 1; - } else { + ep->pending = 1; // skip transfer if we are in critical frame period + } else + #endif + { hw_endpoint_start_next_buffer(ep); } @@ -360,9 +361,12 @@ bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint* ep) { hw_endpoint_lock_update(ep, -1); return true; } else { + #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX if (e15_is_critical_frame_period(ep)) { ep->pending = 1; - } else { + } else + #endif + { hw_endpoint_start_next_buffer(ep); } } @@ -397,15 +401,12 @@ bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint* ep) { volatile uint32_t e15_last_sof = 0; -// check if Errata 15 is needed for this endpoint i.e device bulk-in -static bool __tusb_irq_path_func(e15_is_bulkin_ep)(struct hw_endpoint *ep) { - return (!rp2usb_is_host_mode() && tu_edpt_dir(ep->ep_addr) == TUSB_DIR_IN && ep->transfer_type == TUSB_XFER_BULK); -} - // check if we need to apply Errata 15 workaround : i.e // Endpoint is BULK IN and is currently in critical frame period i.e 20% of last usb frame static bool __tusb_irq_path_func(e15_is_critical_frame_period)(struct hw_endpoint* ep) { - TU_VERIFY(e15_is_bulkin_ep(ep)); + if (!ep->e15_bulk_in) { + return false; + } /* Avoid the last 200us (uframe 6.5-7) of a frame, up to the EOF2 point. * The device state machine cannot recover from receiving an incorrect PID diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.h b/src/portable/raspberrypi/rp2040/rp2040_usb.h index 368bb6509..944d604bc 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.h +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.h @@ -13,17 +13,30 @@ #error TinyUSB device and host mode not supported at the same time #endif -#if defined(PICO_RP2040_USB_DEVICE_ENUMERATION_FIX) && !defined(TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX) -#define TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX PICO_RP2040_USB_DEVICE_ENUMERATION_FIX +// E5 and E15 only apply to RP2040 +#if defined(PICO_RP2040) && PICO_RP2040 == 1 + // RP2040 E5: USB device fails to exit RESET state on busy USB bus. + #if defined(PICO_RP2040_USB_DEVICE_ENUMERATION_FIX) && !defined(TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX) + #define TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX PICO_RP2040_USB_DEVICE_ENUMERATION_FIX + #endif + + // RP2040 E15: USB Device controller will hang if certain bus errors occur during an IN transfer. + #if defined(PICO_RP2040_USB_DEVICE_UFRAME_FIX) && !defined(TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX) + #define TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX PICO_RP2040_USB_DEVICE_UFRAME_FIX + #endif #endif -#if defined(PICO_RP2040_USB_DEVICE_UFRAME_FIX) && !defined(TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX) -#define TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX PICO_RP2040_USB_DEVICE_UFRAME_FIX +#ifndef TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX + #define TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX 0 +#endif + +#ifndef TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX + #define TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX 0 #endif #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX -#undef PICO_RP2040_USB_FAST_IRQ -#define PICO_RP2040_USB_FAST_IRQ 1 + #undef PICO_RP2040_USB_FAST_IRQ + #define PICO_RP2040_USB_FAST_IRQ 1 #endif #ifndef PICO_RP2040_USB_FAST_IRQ @@ -46,36 +59,36 @@ #define pico_trace(...) TU_LOG(3, __VA_ARGS__) // Hardware information per endpoint -typedef struct hw_endpoint -{ - uint8_t ep_addr; - uint8_t next_pid; - // Interrupt, bulk, etc - uint8_t transfer_type; +typedef struct hw_endpoint { + uint8_t ep_addr; + uint8_t next_pid; + uint8_t transfer_type; - bool active; // Endpoint is in use - uint8_t pending; // Transfer scheduled but not active + bool active; // transferring data - uint16_t wMaxPacketSize; +#if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX + bool e15_bulk_in; // Errata15 device bulk in + uint8_t pending; // Transfer scheduled but not active +#endif - uint8_t *hw_data_buf; // Buffer pointer in usb dpram + uint16_t wMaxPacketSize; + uint8_t *hw_data_buf; // Buffer pointer in usb dpram - // Current transfer information - uint8_t *user_buf; // User buffer in main memory - uint16_t remaining_len; - uint16_t xferred_len; + // Current transfer information + uint8_t *user_buf; // User buffer in main memory + uint16_t remaining_len; + uint16_t xferred_len; #if CFG_TUH_ENABLED - // Is this a valid struct - bool configured; + // Is this a valid struct + bool configured; - // Only needed for host - uint8_t dev_addr; + // Only needed for host + uint8_t dev_addr; - // If interrupt endpoint - uint8_t interrupt_num; + // If interrupt endpoint + uint8_t interrupt_num; #endif - } hw_endpoint_t; #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX -- cgit v1.3.1 From 39901ac89c92ba9c2cb5890cd898659bc0f13f53 Mon Sep 17 00:00:00 2001 From: Cédric Berger Date: Thu, 8 Jan 2026 18:36:31 +0100 Subject: Fix tipo in tusb_option.h --- src/tusb_option.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tusb_option.h b/src/tusb_option.h index 08a0ba2ef..a64ea27be 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -742,7 +742,7 @@ #define CFG_TUH_CDC_PL2303 0 #endif -#ifndef CFG_TUH_CDC_PL2303_VID_PID_QUIRKS_LIST +#ifndef CFG_TUH_CDC_PL2303_VID_PID_LIST // List of product IDs that can use the PL2303 CDC driver #define CFG_TUH_CDC_PL2303_VID_PID_LIST \ { 0x067b, 0x2303 }, /* initial 2303 */ \ -- cgit v1.3.1 From e69494d94a680c7b5aa5310338c206921d57640b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 9 Jan 2026 10:47:50 +0700 Subject: fix pre-commit, clean up tusb_mcu.h, add at32f45x to ci build --- .github/workflows/ci_set_matrix.py | 3 ++- hw/bsp/at32f45x/at32f45x_clock.c | 2 +- hw/bsp/at32f45x/at32f45x_clock.h | 1 - hw/bsp/at32f45x/at32f45x_int.c | 1 - hw/bsp/at32f45x/at32f45x_int.h | 1 - src/common/tusb_mcu.h | 22 +--------------------- 6 files changed, 4 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index c276d5253..237a34b9f 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -15,7 +15,8 @@ toolchain_list = [ # family: [supported toolchain] family_list = { - "at32f402_405 at32f403a_407 at32f413 at32f415 at32f423 at32f425 at32f435_437 broadcom_32bit da1469x": ["arm-gcc"], + "at32f45x at32f402_405 at32f403a_407 at32f413 at32f415 at32f423 at32f425 at32f435_437 broadcom_32bit da1469x": [ + "arm-gcc"], "broadcom_64bit": ["aarch64-gcc"], "ch32v10x ch32v20x ch32v30x fomu gd32vf103 hpmicro": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], diff --git a/hw/bsp/at32f45x/at32f45x_clock.c b/hw/bsp/at32f45x/at32f45x_clock.c index 12003cf5a..a6724e23f 100644 --- a/hw/bsp/at32f45x/at32f45x_clock.c +++ b/hw/bsp/at32f45x/at32f45x_clock.c @@ -55,7 +55,7 @@ void system_clock_config(void) /* enable pwc periph clock */ crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE); - + /* config ldo voltage */ pwc_ldo_output_voltage_set(PWC_LDO_OUTPUT_1V3); diff --git a/hw/bsp/at32f45x/at32f45x_clock.h b/hw/bsp/at32f45x/at32f45x_clock.h index 1fd2035aa..a372a605b 100644 --- a/hw/bsp/at32f45x/at32f45x_clock.h +++ b/hw/bsp/at32f45x/at32f45x_clock.h @@ -42,4 +42,3 @@ void system_clock_config(void); #endif #endif - diff --git a/hw/bsp/at32f45x/at32f45x_int.c b/hw/bsp/at32f45x/at32f45x_int.c index 15798e381..15ff90c64 100644 --- a/hw/bsp/at32f45x/at32f45x_int.c +++ b/hw/bsp/at32f45x/at32f45x_int.c @@ -98,4 +98,3 @@ void DebugMon_Handler(void) /** * @} */ - diff --git a/hw/bsp/at32f45x/at32f45x_int.h b/hw/bsp/at32f45x/at32f45x_int.h index 64930f29e..3a2667e9d 100644 --- a/hw/bsp/at32f45x/at32f45x_int.h +++ b/hw/bsp/at32f45x/at32f45x_int.h @@ -57,4 +57,3 @@ void OTGFS1_WKUP_IRQHandler(void); #endif #endif - diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index cbdcd2dfc..5b9497b9a 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -635,17 +635,7 @@ #define TUP_USBIP_DWC2_AT32 #define TUP_DCD_ENDPOINT_MAX 4 -#elif TU_CHECK_MCU(OPT_MCU_AT32F435_437) - #define TUP_USBIP_DWC2 - #define TUP_USBIP_DWC2_AT32 - #define TUP_DCD_ENDPOINT_MAX 8 - -#elif TU_CHECK_MCU(OPT_MCU_AT32F423) - #define TUP_USBIP_DWC2 - #define TUP_USBIP_DWC2_AT32 - #define TUP_DCD_ENDPOINT_MAX 8 - -#elif TU_CHECK_MCU(OPT_MCU_AT32F402_405) +#elif TU_CHECK_MCU(OPT_MCU_AT32F402_405, OPT_MCU_AT32F423, OPT_MCU_AT32F425, OPT_MCU_AT32F435_437, OPT_MCU_AT32F45X) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_AT32 #define TUP_DCD_ENDPOINT_MAX 8 @@ -657,16 +647,6 @@ #define TUP_RHPORT_HIGHSPEED 1 // Port0: FS, Port1: HS #endif -#elif TU_CHECK_MCU(OPT_MCU_AT32F425) - #define TUP_USBIP_DWC2 - #define TUP_USBIP_DWC2_AT32 - #define TUP_DCD_ENDPOINT_MAX 8 - -#elif TU_CHECK_MCU(OPT_MCU_AT32F45X) - #define TUP_USBIP_DWC2 - #define TUP_USBIP_DWC2_AT32 - #define TUP_DCD_ENDPOINT_MAX 8 - //--------------------------------------------------------------------+ // HPMicro //--------------------------------------------------------------------+ -- cgit v1.3.1 From 8452dfe3055c876a1c8cb1f52c7bceeae6678452 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 9 Jan 2026 10:28:27 +0700 Subject: clean up --- .idea/debugServers/mcxa153.xml | 13 ++++++++++ .idea/debugServers/ra6m1.xml | 13 ++++++++++ .idea/debugServers/ra6m5.xml | 13 ++++++++++ .idea/debugServers/rt1011.xml | 13 ++++++++++ .idea/debugServers/rt1170.xml | 13 ++++++++++ .idea/debugServers/stm32f072.xml | 13 ++++++++++ .idea/debugServers/stm32f303.xml | 13 ++++++++++ .idea/debugServers/stm32l053.xml | 13 ++++++++++ hw/bsp/rp2040/family.cmake | 2 +- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 4 ++-- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 36 +++++++++++++--------------- src/tusb_option.h | 2 +- 12 files changed, 125 insertions(+), 23 deletions(-) create mode 100644 .idea/debugServers/mcxa153.xml create mode 100644 .idea/debugServers/ra6m1.xml create mode 100644 .idea/debugServers/ra6m5.xml create mode 100644 .idea/debugServers/rt1011.xml create mode 100644 .idea/debugServers/rt1170.xml create mode 100644 .idea/debugServers/stm32f072.xml create mode 100644 .idea/debugServers/stm32f303.xml create mode 100644 .idea/debugServers/stm32l053.xml (limited to 'src') diff --git a/.idea/debugServers/mcxa153.xml b/.idea/debugServers/mcxa153.xml new file mode 100644 index 000000000..0e493cbd5 --- /dev/null +++ b/.idea/debugServers/mcxa153.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/debugServers/ra6m1.xml b/.idea/debugServers/ra6m1.xml new file mode 100644 index 000000000..17c902ec4 --- /dev/null +++ b/.idea/debugServers/ra6m1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/debugServers/ra6m5.xml b/.idea/debugServers/ra6m5.xml new file mode 100644 index 000000000..d8dfbdeeb --- /dev/null +++ b/.idea/debugServers/ra6m5.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/debugServers/rt1011.xml b/.idea/debugServers/rt1011.xml new file mode 100644 index 000000000..b4be501bd --- /dev/null +++ b/.idea/debugServers/rt1011.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/debugServers/rt1170.xml b/.idea/debugServers/rt1170.xml new file mode 100644 index 000000000..9a564ed57 --- /dev/null +++ b/.idea/debugServers/rt1170.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/debugServers/stm32f072.xml b/.idea/debugServers/stm32f072.xml new file mode 100644 index 000000000..c56f5a8fb --- /dev/null +++ b/.idea/debugServers/stm32f072.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/debugServers/stm32f303.xml b/.idea/debugServers/stm32f303.xml new file mode 100644 index 000000000..84aafc1e3 --- /dev/null +++ b/.idea/debugServers/stm32f303.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/debugServers/stm32l053.xml b/.idea/debugServers/stm32l053.xml new file mode 100644 index 000000000..5365189cc --- /dev/null +++ b/.idea/debugServers/stm32l053.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 9dc28fc70..40eee082d 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -126,7 +126,7 @@ target_compile_definitions(tinyusb_host_base INTERFACE #------------------------------------ # Host MAX3421 -#------------------------------------1 +#------------------------------------ add_library(tinyusb_host_max3421 INTERFACE) target_sources(tinyusb_host_max3421 INTERFACE ${TOP}/src/portable/analog/max3421/hcd_max3421.c diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index bdd0d1728..71d5cf19c 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -39,9 +39,9 @@ #include "device/dcd.h" // Current implementation force vbus detection as always present, causing device think it is always plugged into host. -// Therefore it cannot detect disconnect event, mistaken it as suspend. +// Therefore, it cannot detect disconnect event, mistaken it as suspend. // Note: won't work if change to 0 (for now) -#define FORCE_VBUS_DETECT 1 + #define FORCE_VBUS_DETECT 1 #define USB_INTS_ERROR_BITS \ (USB_INTS_ERROR_DATA_SEQ_BITS | USB_INTS_ERROR_BIT_STUFF_BITS | USB_INTS_ERROR_CRC_BITS | \ diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 1193009ef..7bf247ced 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -97,7 +97,7 @@ static void __tusb_irq_path_func(hw_xfer_complete)(struct hw_endpoint *ep, xfer_ hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, xfer_result, true); } -static void __tusb_irq_path_func(handle_hhwbuf_status_bit)(uint bit, struct hw_endpoint *ep) { +static void __tusb_irq_path_func(handle_hwbuf_status_bit)(uint bit, struct hw_endpoint *ep) { usb_hw_clear->buf_status = bit; const bool done = hw_endpoint_xfer_continue(ep); if (done) { @@ -110,11 +110,11 @@ static void __tusb_irq_path_func(handle_hwbuf_status)(void) { pico_trace("buf_status 0x%08lx\n", buf_status); // Check EPX first - uint bit = 0b1; + uint32_t bit = 1u; if (buf_status & bit) { buf_status &= ~bit; struct hw_endpoint * ep = &epx; - handle_hhwbuf_status_bit(bit, ep); + handle_hwbuf_status_bit(bit, ep); } // Check "interrupt" (asynchronous) endpoints for both IN and OUT @@ -131,7 +131,7 @@ static void __tusb_irq_path_func(handle_hwbuf_status)(void) { bit = 1 << (i * 2 + j); if (buf_status & bit) { buf_status &= ~bit; - handle_hhwbuf_status_bit(bit, &ep_pool[i]); + handle_hwbuf_status_bit(bit, &ep_pool[i]); } } } @@ -287,39 +287,37 @@ static void hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t e ep->next_pid = (num == 0 ? 1u : 0u); ep->wMaxPacketSize = wMaxPacketSize; - pico_trace("hw_endpoint_init dev %d ep %02X xfer %d\n", ep->dev_addr, ep->ep_addr, ep->transfer_type); + pico_trace("hw_endpoint_init dev %d ep %02X xfer %d\n", ep->dev_addr, ep->ep_addr, transfer_type); pico_trace("dev %d ep %02X setup buffer @ 0x%p\n", ep->dev_addr, ep->ep_addr, ep->hw_data_buf); uint dpram_offset = hw_data_offset(ep->hw_data_buf); // Bits 0-5 should be 0 assert(!(dpram_offset & 0b111111)); // Fill in endpoint control register with buffer offset - uint32_t ep_reg = EP_CTRL_ENABLE_BITS | EP_CTRL_INTERRUPT_PER_BUFFER | - ((uint)transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset; - if ( bmInterval ) - { - ep_reg |= (uint32_t) ((bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB); + uint32_t ctrl_value = EP_CTRL_ENABLE_BITS | EP_CTRL_INTERRUPT_PER_BUFFER | + ((uint32_t)transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset; + if (bmInterval) { + ctrl_value |= (uint32_t)((bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB); } - *hwep_ctrl_reg_host(ep) = ep_reg; - // pico_trace("endpoint control (0x%p) <- 0x%lx\n", ep->endpoint_control, ep_reg); + + io_rw_32 *ctrl_reg = hwep_ctrl_reg_host(ep); + *ctrl_reg = ctrl_value; + pico_trace("endpoint control (0x%p) <- 0x%lx\n", ctrl_reg, ctrl_value); ep->configured = true; - if ( ep != &epx ) - { + if (ep != &epx) { // Endpoint has its own addr_endp and interrupt bits to be setup! // This is an interrupt/async endpoint. so need to set up ADDR_ENDP register with: // - device address // - endpoint number / direction // - preamble - uint32_t reg = (uint32_t) (dev_addr | (num << USB_ADDR_ENDP1_ENDPOINT_LSB)); + uint32_t reg = (uint32_t)(dev_addr | (num << USB_ADDR_ENDP1_ENDPOINT_LSB)); - if ( dir == TUSB_DIR_OUT ) - { + if (dir == TUSB_DIR_OUT) { reg |= USB_ADDR_ENDP1_INTEP_DIR_BITS; } - if ( need_pre(dev_addr) ) - { + if (need_pre(dev_addr)) { reg |= USB_ADDR_ENDP1_INTEP_PREAMBLE_BITS; } usb_hw->int_ep_addr_ctrl[ep->interrupt_num] = reg; diff --git a/src/tusb_option.h b/src/tusb_option.h index 08a0ba2ef..9b0da3ac7 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -335,7 +335,7 @@ #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 #endif -//------------- pio-usb -------------// +//------------- Raspberry Pi -------------// // Enable PIO-USB software host controller #ifndef CFG_TUH_RPI_PIO_USB #define CFG_TUH_RPI_PIO_USB 0 -- cgit v1.3.1 From 4c86cbdc822ccf0f71a67c5f2d627e18ecbad46f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 9 Jan 2026 18:40:55 +0700 Subject: enable dedicated hwfifo for rp2 --- src/common/tusb_fifo.c | 76 +++++++++++++++++++------- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 10 +++- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 4 +- src/portable/raspberrypi/rp2040/rp2040_usb.c | 55 +++++++++++++------ src/portable/raspberrypi/rp2040/rp2040_usb.h | 35 ++++++------ src/tusb_option.h | 79 +++++++++++++++------------- 6 files changed, 169 insertions(+), 90 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index a92435912..9f188f296 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -33,7 +33,7 @@ // Suppress IAR warning // Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement #if defined(__ICCARM__) -#pragma diag_suppress = Pa082 + #pragma diag_suppress = Pa082 #endif #if OSAL_MUTEX_REQUIRED @@ -110,8 +110,9 @@ void tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) { } //--------------------------------------------------------------------+ -// Pull & Push -// copy data to/from fifo without updating read/write pointers +// Hardware FIFO API +// Support different data access width and address increment scheme +// Can support multiple i.e both 16 and 32-bit data access if needed //--------------------------------------------------------------------+ #if CFG_TUSB_FIFO_HWFIFO_API #if CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE @@ -122,18 +123,31 @@ void tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) { #define HWFIFO_ADDR_NEXT(_hwfifo, _const) HWFIFO_ADDR_NEXT_N(_hwfifo, _const, CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE) +//------------- Write -------------// #ifndef CFG_TUSB_FIFO_HWFIFO_CUSTOM_WRITE -static inline void stride_write(volatile void *hwfifo, const void *src, uint8_t data_stride) { +TU_ATTR_ALWAYS_INLINE static inline void stride_write(volatile void *hwfifo, const void *src, uint8_t data_stride) { + (void)data_stride; // possible unused #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE & 4 - if (data_stride == 4) { + #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE != 4 + if (data_stride == 4) + #endif + { *((volatile uint32_t *)hwfifo) = tu_unaligned_read32(src); } - #endif - #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE & 2 - if (data_stride == 2) { + #endif + + #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE & 2 + #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE != 2 + if (data_stride == 2) + #endif + { *((volatile uint16_t *)hwfifo) = tu_unaligned_read16(src); } - #endif + #endif + + #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE == 1 + *((volatile uint8_t *)hwfifo) = *(const uint8_t *)src; + #endif } // Copy from fifo to fixed address buffer (usually a tx register) with TU_FIFO_FIXED_ADDR_RW32 mode @@ -147,7 +161,8 @@ void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, co HWFIFO_ADDR_NEXT(hwfifo, ); } - #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS + #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE > 1 + #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS // 16-bit access is allowed for odd bytes if (len >= 2) { *((volatile uint16_t *)hwfifo) = tu_unaligned_read16(src); @@ -155,16 +170,16 @@ void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, co len -= 2; HWFIFO_ADDR_NEXT_N(hwfifo, , 2); } - #endif + #endif - #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS + #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS // 8-bit access is allowed for odd bytes while (len > 0) { *((volatile uint8_t *)hwfifo) = *src++; len--; HWFIFO_ADDR_NEXT_N(hwfifo, , 1); } - #else + #else // Write odd bytes i.e 1 byte for 16 bit or 1-3 bytes for 32 bit if (len > 0) { @@ -173,13 +188,16 @@ void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, co stride_write(hwfifo, &tmp, data_stride); HWFIFO_ADDR_NEXT(hwfifo, ); } + #endif #endif } #endif +//------------- Read -------------// #ifndef CFG_TUSB_FIFO_HWFIFO_CUSTOM_READ -static inline void stride_read(const volatile void *hwfifo, void *dest, uint8_t data_stride) { +TU_ATTR_ALWAYS_INLINE static inline void stride_read(const volatile void *hwfifo, void *dest, uint8_t data_stride) { (void)data_stride; // possible unused + #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE & 4 #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE != 4 if (data_stride == 4) @@ -197,6 +215,10 @@ static inline void stride_read(const volatile void *hwfifo, void *dest, uint8_t tu_unaligned_write16(dest, *((const volatile uint16_t *)hwfifo)); } #endif + + #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE == 1 + *(uint8_t *)dest = *((const volatile uint8_t *)hwfifo); + #endif } void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, const tu_hwfifo_access_t *access_mode) { @@ -209,7 +231,8 @@ void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, co HWFIFO_ADDR_NEXT(hwfifo, const); } - #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS + #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE > 1 + #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS // 16-bit access is allowed for odd bytes if (len >= 2) { tu_unaligned_write16(dest, *((const volatile uint16_t *)hwfifo)); @@ -235,6 +258,7 @@ void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, co HWFIFO_ADDR_NEXT(hwfifo, const); } #endif + #endif } #endif @@ -251,7 +275,11 @@ static void hwff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uin tu_hwfifo_read(hwfifo, ff_buf, n, access_mode); } else { // Wrap around case - + #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE == 1 + tu_hwfifo_read(hwfifo, ff_buf, lin_bytes, access_mode); // linear part + HWFIFO_ADDR_NEXT_N(hwfifo, const, lin_bytes); + tu_hwfifo_read(hwfifo, f->buffer, wrap_bytes, access_mode); // wrapped part + #else // Write full words to linear part of buffer const uint8_t data_stride = access_mode->data_stride; const uint32_t odd_mask = data_stride - 1; @@ -286,6 +314,7 @@ static void hwff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uin if (wrap_bytes > 0) { tu_hwfifo_read(hwfifo, ff_buf, wrap_bytes, access_mode); } + #endif } } @@ -303,11 +332,15 @@ static void hwff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t tu_hwfifo_write(hwfifo, ff_buf, n, access_mode); } else { // Wrap around case - + #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE == 1 + tu_hwfifo_write(hwfifo, ff_buf, lin_bytes, access_mode); // linear part + HWFIFO_ADDR_NEXT_N(hwfifo, , lin_bytes); + tu_hwfifo_write(hwfifo, f->buffer, wrap_bytes, access_mode); // wrapped part + #else // Read full words from linear part const uint8_t data_stride = access_mode->data_stride; const uint32_t odd_mask = data_stride - 1; - uint16_t lin_even = lin_bytes & ~odd_mask; + uint16_t lin_even = lin_bytes & ~odd_mask; tu_hwfifo_write(hwfifo, ff_buf, lin_even, access_mode); HWFIFO_ADDR_NEXT_N(hwfifo, , lin_even); ff_buf += lin_even; @@ -338,10 +371,15 @@ static void hwff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t if (wrap_bytes > 0) { tu_hwfifo_write(hwfifo, ff_buf, wrap_bytes, access_mode); } + #endif } } #endif +//--------------------------------------------------------------------+ +// Pull & Push +// copy data to/from fifo without updating read/write pointers +//--------------------------------------------------------------------+ // send n items to fifo WITHOUT updating write pointer static void ff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uint16_t wr_ptr) { uint16_t lin_bytes = f->depth - wr_ptr; @@ -787,6 +825,6 @@ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) { } else { info->linear.len = f->depth - wr_ptr; info->wrapped.len = remain - info->linear.len; // Remaining length - n already was limited to remain or FIFO depth - info->wrapped.ptr = f->buffer; // Always start of buffer + info->wrapped.ptr = f->buffer; // Always start of buffer } } diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 71d5cf19c..f25d808d4 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -502,7 +502,15 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to (void)rhport; (void)is_isr; hw_endpoint_t *ep = hw_endpoint_get_by_addr(ep_addr); - hw_endpoint_xfer_start(ep, buffer, total_bytes); + hw_endpoint_xfer_start(ep, buffer, NULL, total_bytes); + return true; +} + +bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes, bool is_isr) { + (void)rhport; + (void)is_isr; + hw_endpoint_t *ep = hw_endpoint_get_by_addr(ep_addr); + hw_endpoint_xfer_start(ep, NULL, ff, total_bytes); return true; } diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 7bf247ced..06c0ce340 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -511,7 +511,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *b // sie ctrl registers. Otherwise, interrupt ep registers should // already be configured if (ep == &epx) { - hw_endpoint_xfer_start(ep, buffer, buflen); + hw_endpoint_xfer_start(ep, buffer, NULL, buflen); // That has set up buffer control, endpoint control etc // for host we have to initiate the transfer @@ -527,7 +527,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *b busy_wait_at_least_cycles(12); usb_hw->sie_ctrl = flags; } else { - hw_endpoint_xfer_start(ep, buffer, buflen); + hw_endpoint_xfer_start(ep, buffer, NULL, buflen); } return true; diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 8f91ecf22..bde45db1b 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -35,7 +35,7 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPE //--------------------------------------------------------------------+ -static void hwep_xfer_sync(hw_endpoint_t *ep); +static void sync_xfer(hw_endpoint_t *ep); #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX static bool e15_is_critical_frame_period(struct hw_endpoint *ep); @@ -55,6 +55,16 @@ static void unaligned_memcpy(void *dst, const void *src, size_t n) { } } +void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, const tu_hwfifo_access_t *access_mode) { + (void)access_mode; + unaligned_memcpy((void *)(uintptr_t)hwfifo, src, len); +} + +void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, const tu_hwfifo_access_t *access_mode) { + (void)access_mode; + unaligned_memcpy(dest, (const void *)(uintptr_t)hwfifo, len); +} + void rp2usb_init(void) { // Reset usb controller reset_block(RESETS_RESET_USBCTRL_BITS); @@ -127,9 +137,16 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint *ep, ep->next_pid ^= 1u; if (!is_rx) { - // Copy data from user buffer to hw buffer - unaligned_memcpy(ep->hw_data_buf + buf_id * 64, ep->user_buf, buflen); - ep->user_buf += buflen; + if (buflen) { + // Copy data from user buffer/fifo to hw buffer + uint8_t *hw_buf = ep->hw_data_buf + buf_id * 64; + if (ep->is_xfer_fifo) { + tu_hwfifo_write_from_fifo(hw_buf, ep->user_fifo, buflen, NULL); + } else { + unaligned_memcpy(hw_buf, ep->user_buf, buflen); + ep->user_buf += buflen; + } + } // Mark as full buf_ctrl |= USB_BUF_CTRL_FULL; @@ -152,7 +169,6 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint *ep, // Prepare buffer control register value void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint* ep) { const tusb_dir_t dir = tu_edpt_dir(ep->ep_addr); - bool is_rx; bool is_host = false; io_rw_32 *ep_ctrl_reg; @@ -211,7 +227,7 @@ void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint* ep) hwbuf_ctrl_set(buf_ctrl_reg, buf_ctrl); } -void hw_endpoint_xfer_start(struct hw_endpoint* ep, uint8_t* buffer, uint16_t total_len) { +void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, tu_fifo_t *ff, uint16_t total_len) { hw_endpoint_lock_update(ep, 1); if (ep->active) { @@ -224,7 +240,14 @@ void hw_endpoint_xfer_start(struct hw_endpoint* ep, uint8_t* buffer, uint16_t to ep->remaining_len = total_len; ep->xferred_len = 0; ep->active = true; - ep->user_buf = buffer; + + if (ff != NULL) { + ep->user_fifo = ff; + ep->is_xfer_fifo = true; + } else { + ep->user_buf = buffer; + ep->is_xfer_fifo = false; + } #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX if (ep->e15_bulk_in) { @@ -256,17 +279,20 @@ static uint16_t __tusb_irq_path_func(sync_ep_buffer)(hw_endpoint_t *ep, io_rw_32 // We are continuing a transfer here. If we are TX, we have successfully // sent some data can increase the length we have sent assert(!(buf_ctrl & USB_BUF_CTRL_FULL)); - - ep->xferred_len = (uint16_t) (ep->xferred_len + xferred_bytes); } else { // If we have received some data, so can increase the length // we have received AFTER we have copied it to the user buffer at the appropriate offset assert(buf_ctrl & USB_BUF_CTRL_FULL); - unaligned_memcpy(ep->user_buf, ep->hw_data_buf + buf_id * 64, xferred_bytes); - ep->xferred_len = (uint16_t) (ep->xferred_len + xferred_bytes); - ep->user_buf += xferred_bytes; + uint8_t *hw_buf = ep->hw_data_buf + buf_id * 64; + if (ep->is_xfer_fifo) { + tu_hwfifo_read_to_fifo(hw_buf, ep->user_fifo, xferred_bytes, NULL); + } else { + unaligned_memcpy(ep->user_buf, hw_buf, xferred_bytes); + ep->user_buf += xferred_bytes; + } } + ep->xferred_len += xferred_bytes; // Short packet if (xferred_bytes < ep->wMaxPacketSize) { @@ -278,7 +304,7 @@ static uint16_t __tusb_irq_path_func(sync_ep_buffer)(hw_endpoint_t *ep, io_rw_32 } // Update hw endpoint struct with info from hardware after a buff status interrupt -static void __tusb_irq_path_func(hwep_xfer_sync)(hw_endpoint_t *ep) { +static void __tusb_irq_path_func(sync_xfer)(hw_endpoint_t *ep) { // const uint8_t ep_num = tu_edpt_number(ep->ep_addr); const tusb_dir_t dir = tu_edpt_dir(ep->ep_addr); @@ -350,8 +376,7 @@ bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint* ep) { panic("Can't continue xfer on inactive ep %02X", ep->ep_addr); } - // Update EP struct from hardware state - hwep_xfer_sync(ep); + sync_xfer(ep); // Update EP struct from hardware state // Now we have synced our state with the hardware. Is there more data to transfer? // If we are done then notify tinyusb diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.h b/src/portable/raspberrypi/rp2040/rp2040_usb.h index 944d604bc..cce868540 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.h +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.h @@ -1,14 +1,16 @@ #ifndef RP2040_COMMON_H_ #define RP2040_COMMON_H_ -#include "common/tusb_common.h" - #include "pico.h" #include "hardware/structs/usb.h" #include "hardware/irq.h" #include "hardware/resets.h" #include "hardware/timer.h" +#include "common/tusb_common.h" +#include "osal/osal.h" +#include "common/tusb_fifo.h" + #if defined(RP2040_USB_HOST_MODE) && defined(RP2040_USB_DEVICE_MODE) #error TinyUSB device and host mode not supported at the same time #endif @@ -63,32 +65,31 @@ typedef struct hw_endpoint { uint8_t ep_addr; uint8_t next_pid; uint8_t transfer_type; - - bool active; // transferring data + bool active; // transferring data + bool is_xfer_fifo; // transfer using fifo #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX bool e15_bulk_in; // Errata15 device bulk in uint8_t pending; // Transfer scheduled but not active #endif +#if CFG_TUH_ENABLED + bool configured; // Is this a valid struct + uint8_t dev_addr; + uint8_t interrupt_num; // for host interrupt endpoints +#endif + uint16_t wMaxPacketSize; uint8_t *hw_data_buf; // Buffer pointer in usb dpram - // Current transfer information - uint8_t *user_buf; // User buffer in main memory + // transfer info + union { + uint8_t *user_buf; // User buffer in main memory + tu_fifo_t *user_fifo; + }; uint16_t remaining_len; uint16_t xferred_len; -#if CFG_TUH_ENABLED - // Is this a valid struct - bool configured; - - // Only needed for host - uint8_t dev_addr; - - // If interrupt endpoint - uint8_t interrupt_num; -#endif } hw_endpoint_t; #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX @@ -102,7 +103,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool rp2usb_is_host_mode(void) { return (usb_hw->main_ctrl & USB_MAIN_CTRL_HOST_NDEVICE_BITS) ? true : false; } -void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, uint16_t total_len); +void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, tu_fifo_t *ff, uint16_t total_len); bool hw_endpoint_xfer_continue(struct hw_endpoint *ep); void hw_endpoint_reset_transfer(struct hw_endpoint *ep); void hw_endpoint_start_next_buffer(struct hw_endpoint *ep); diff --git a/src/tusb_option.h b/src/tusb_option.h index e0a52593f..abf5e0608 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -272,6 +272,25 @@ // USBIP //--------------------------------------------------------------------+ +//------------- ChipIdea -------------// +// Enable CI_HS VBUS Charge. Set this to 1 if the USB_VBUS pin is not connected to 5V VBUS (note: 3.3V is +// insufficient). +#ifndef CFG_TUD_CI_HS_VBUS_CHARGE + #ifndef CFG_TUD_CI_HS_VBUS_CHARGE_DEFAULT + #define CFG_TUD_CI_HS_VBUS_CHARGE_DEFAULT 0 + #endif + #define CFG_TUD_CI_HS_VBUS_CHARGE CFG_TUD_CI_HS_VBUS_CHARGE_DEFAULT +#endif + +// CI_HS support FIFO transfer if endpoint buffer is 4k aligned and size is multiple of 4k, also DCACHE is disabled +#ifndef CFG_TUD_CI_HS_EPBUF_4K_ALIGNED + #define CFG_TUD_CI_HS_EPBUF_4K_ALIGNED 0 +#endif + +#if CFG_TUD_CI_HS_EPBUF_4K_ALIGNED && !CFG_TUD_MEM_DCACHE_ENABLE + #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 +#endif + //------------- DWC2 -------------// // DMA mode for device #ifndef CFG_TUD_DWC2_DMA_ENABLE @@ -317,41 +336,6 @@ #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 0 // fixed hwfifo address #endif -//------------- ChipIdea -------------// -// Enable CI_HS VBUS Charge. Set this to 1 if the USB_VBUS pin is not connected to 5V VBUS (note: 3.3V is -// insufficient). -#ifndef CFG_TUD_CI_HS_VBUS_CHARGE - #ifndef CFG_TUD_CI_HS_VBUS_CHARGE_DEFAULT - #define CFG_TUD_CI_HS_VBUS_CHARGE_DEFAULT 0 - #endif - #define CFG_TUD_CI_HS_VBUS_CHARGE CFG_TUD_CI_HS_VBUS_CHARGE_DEFAULT -#endif - -// CI_HS support FIFO transfer if endpoint buffer is 4k aligned and size is multiple of 4k, also DCACHE is disabled -#ifndef CFG_TUD_CI_HS_EPBUF_4K_ALIGNED - #define CFG_TUD_CI_HS_EPBUF_4K_ALIGNED 0 -#endif - -#if CFG_TUD_CI_HS_EPBUF_4K_ALIGNED && !CFG_TUD_MEM_DCACHE_ENABLE - #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 -#endif - -//------------- Raspberry Pi -------------// -// Enable PIO-USB software host controller -#ifndef CFG_TUH_RPI_PIO_USB - #define CFG_TUH_RPI_PIO_USB 0 -#endif - -#ifndef CFG_TUD_RPI_PIO_USB - #define CFG_TUD_RPI_PIO_USB 0 -#endif - -//------------ MAX3421 -------------// -// Enable MAX3421 USB host controller -#ifndef CFG_TUH_MAX3421 - #define CFG_TUH_MAX3421 0 -#endif - //------------ FSDEV --------------// #if defined(TUP_USBIP_FSDEV) #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 @@ -368,6 +352,12 @@ #endif #endif +//------------ MAX3421 -------------// +// Enable MAX3421 USB host controller +#ifndef CFG_TUH_MAX3421 + #define CFG_TUH_MAX3421 0 +#endif + //------------ MUSB --------------// #if defined(TUP_USBIP_MUSB) #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 @@ -375,13 +365,30 @@ #define CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS // allow odd 16bit access #define CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS // allow odd 8bit access #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 0 // fixed hwfifo +#endif + +//------------- Raspberry Pi -------------// +// Enable PIO-USB software host controller +#ifndef CFG_TUH_RPI_PIO_USB + #define CFG_TUH_RPI_PIO_USB 0 +#endif + +#ifndef CFG_TUD_RPI_PIO_USB + #define CFG_TUD_RPI_PIO_USB 0 +#endif +#if (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUD_RPI_PIO_USB + #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 + #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 1 + #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 1 + #define CFG_TUSB_FIFO_HWFIFO_CUSTOM_WRITE + #define CFG_TUSB_FIFO_HWFIFO_CUSTOM_READ #endif //------------ RUSB2 --------------// #if defined(TUP_USBIP_RUSB2) #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 - #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE (2 | (TUD_OPT_HIGH_SPEED ? 4 : 0)) // 16 bit and 32 bit data if highspeed + #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE (2 | (TUD_OPT_HIGH_SPEED ? 4 : 0)) // 16 bit and 32 bit if highspeed #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 0 #define CFG_TUSB_FIFO_HWFIFO_CUSTOM_WRITE // custom write since rusb2 can change access width 32 -> 16 and can write // odd byte with byte access -- cgit v1.3.1 From 09b8f4008450e55caea2f8ee559a3d0abcd87a36 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 9 Jan 2026 23:34:00 +0700 Subject: remove transfer_type from hw_endpoint --- hw/bsp/rp2040/family.cmake | 1 + src/portable/raspberrypi/rp2040/dcd_rp2040.c | 1 - src/portable/raspberrypi/rp2040/rp2040_usb.c | 12 ++++++------ src/portable/raspberrypi/rp2040/rp2040_usb.h | 1 - 4 files changed, 7 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 40eee082d..e617ab3ca 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -251,6 +251,7 @@ function(family_configure_target TARGET RTOS) family_flash_jlink(${TARGET}) # Generate linkermap target and post build. LINKERMAP_OPTION can be set with -D to change default options + family_add_bloaty(${TARGET}) family_add_linkermap(${TARGET}) endfunction() diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index f25d808d4..240e6c727 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -74,7 +74,6 @@ static void hw_endpoint_init(hw_endpoint_t *ep, uint8_t ep_addr, uint16_t wMaxPa ep->ep_addr = ep_addr; ep->next_pid = 0u; ep->wMaxPacketSize = wMaxPacketSize; - ep->transfer_type = transfer_type; // Clear existing buffer control state io_rw_32 *buf_ctrl_reg = hwbuf_ctrl_reg_device(ep); diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index bde45db1b..3b65f57a4 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -47,22 +47,20 @@ static bool e15_is_critical_frame_period(struct hw_endpoint *ep); // Implementation //--------------------------------------------------------------------+ // Provide own byte by byte memcpy as not all copies are aligned -static void unaligned_memcpy(void *dst, const void *src, size_t n) { - uint8_t *dst_byte = (uint8_t*)dst; - const uint8_t *src_byte = (const uint8_t*)src; +static void unaligned_memcpy(uint8_t *dst, const uint8_t *src, size_t n) { while (n--) { - *dst_byte++ = *src_byte++; + *dst++ = *src++; } } void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, const tu_hwfifo_access_t *access_mode) { (void)access_mode; - unaligned_memcpy((void *)(uintptr_t)hwfifo, src, len); + unaligned_memcpy((uint8_t *)(uintptr_t)hwfifo, src, len); } void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, const tu_hwfifo_access_t *access_mode) { (void)access_mode; - unaligned_memcpy(dest, (const void *)(uintptr_t)hwfifo, len); + unaligned_memcpy(dest, (const uint8_t *)(uintptr_t)hwfifo, len); } void rp2usb_init(void) { @@ -141,6 +139,7 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint *ep, // Copy data from user buffer/fifo to hw buffer uint8_t *hw_buf = ep->hw_data_buf + buf_id * 64; if (ep->is_xfer_fifo) { + // not in sram, may mess up timing with E15 workaround tu_hwfifo_write_from_fifo(hw_buf, ep->user_fifo, buflen, NULL); } else { unaligned_memcpy(hw_buf, ep->user_buf, buflen); @@ -286,6 +285,7 @@ static uint16_t __tusb_irq_path_func(sync_ep_buffer)(hw_endpoint_t *ep, io_rw_32 uint8_t *hw_buf = ep->hw_data_buf + buf_id * 64; if (ep->is_xfer_fifo) { + // not in sram, may mess up timing with E15 workaround tu_hwfifo_read_to_fifo(hw_buf, ep->user_fifo, xferred_bytes, NULL); } else { unaligned_memcpy(ep->user_buf, hw_buf, xferred_bytes); diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.h b/src/portable/raspberrypi/rp2040/rp2040_usb.h index cce868540..c03dc34b2 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.h +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.h @@ -64,7 +64,6 @@ typedef struct hw_endpoint { uint8_t ep_addr; uint8_t next_pid; - uint8_t transfer_type; bool active; // transferring data bool is_xfer_fifo; // transfer using fifo -- cgit v1.3.1 From d5362220f3bf1d9e05cc66d76708a3cbb41dffdf Mon Sep 17 00:00:00 2001 From: Gabriel Chouinard Date: Mon, 12 Jan 2026 15:15:08 -0500 Subject: Fix compiler warning --- src/common/tusb_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index d473e53e6..7d26ac74e 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -554,7 +554,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_number(uint8_t addr) { } TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t dir) { - return (uint8_t) (num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0u)); + return (uint8_t) (num | (dir == (uint8_t)TUSB_DIR_IN ? (uint8_t)TUSB_DIR_IN_MASK : 0u)); } TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) { -- cgit v1.3.1 From 8cde9b69c3ea2eb94758641c0a7bd057a33ccabc Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 13 Jan 2026 15:17:23 +0700 Subject: minor clean up separate tud_mtp_data_send() and tud_mtp_data_receive() --- src/class/mtp/mtp_device.c | 73 +++++++++++++++++++++++----------------------- test/hil/hil_test.py | 16 +++++----- 2 files changed, 45 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/class/mtp/mtp_device.c b/src/class/mtp/mtp_device.c index 13f868d14..59096e476 100644 --- a/src/class/mtp/mtp_device.c +++ b/src/class/mtp/mtp_device.c @@ -92,6 +92,7 @@ typedef struct { uint8_t itf_num; uint8_t ep_in; uint8_t ep_out; + uint8_t ep_event; uint8_t ep_sz_fs; // Bulk Only Transfer (BOT) Protocol @@ -194,50 +195,47 @@ static bool prepare_new_command(mtpd_interface_t* p_mtp) { return usbd_edpt_xfer(p_mtp->rhport, p_mtp->ep_out, _mtpd_epbuf.buf, CFG_TUD_MTP_EP_BUFSIZE, false); } -static bool mtpd_data_xfer(mtp_container_info_t* p_container, uint8_t ep_addr) { - mtpd_interface_t* p_mtp = &_mtpd_itf; +bool tud_mtp_data_send(mtp_container_info_t *p_container) { + mtpd_interface_t *p_mtp = &_mtpd_itf; if (p_mtp->phase == MTP_PHASE_COMMAND) { // 1st data block: header + payload p_mtp->phase = MTP_PHASE_DATA; p_mtp->xferred_len = 0; + p_mtp->total_len = p_container->header->len; - if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { - p_mtp->total_len = p_container->header->len; - p_container->header->type = MTP_CONTAINER_TYPE_DATA_BLOCK; - p_container->header->transaction_id = p_mtp->command.header.transaction_id; - p_mtp->io_header = *p_container->header; // save header for subsequent data - } else { - p_mtp->total_len = p_container->header->len; - } - } else { - // subsequent data block: payload only - TU_ASSERT(p_mtp->phase == MTP_PHASE_DATA); + p_container->header->type = MTP_CONTAINER_TYPE_DATA_BLOCK; + p_container->header->transaction_id = p_mtp->command.header.transaction_id; + p_mtp->io_header = *p_container->header; // save header for subsequent data } - uint16_t xact_len = 0; - if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { - xact_len = (uint16_t) tu_min32(p_mtp->total_len - p_mtp->xferred_len, CFG_TUD_MTP_EP_BUFSIZE); - } else { - // Use fixed transfer length to make ZLP handling easier - xact_len = CFG_TUD_MTP_EP_BUFSIZE; - } + const uint16_t xact_len = (uint16_t)tu_min32(p_mtp->total_len - p_mtp->xferred_len, CFG_TUD_MTP_EP_BUFSIZE); - TU_LOG_DRV(" MTP Data Xfer %s: xferred_len/total_len=%lu/%lu, xact_len=%u\r\n", - (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) ? "IN" : "OUT", - p_mtp->xferred_len, p_mtp->total_len, xact_len); + TU_LOG_DRV(" MTP Data IN: xferred_len/total_len=%lu/%lu, xact_len=%u\r\n", p_mtp->xferred_len, p_mtp->total_len, + xact_len); if (xact_len) { - TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, ep_addr)); - TU_ASSERT(usbd_edpt_xfer(p_mtp->rhport, ep_addr, _mtpd_epbuf.buf, xact_len, false)); + TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, p_mtp->ep_in)); + TU_ASSERT(usbd_edpt_xfer(p_mtp->rhport, p_mtp->ep_in, _mtpd_epbuf.buf, xact_len, false)); } return true; } -bool tud_mtp_data_send(mtp_container_info_t* p_container) { - return mtpd_data_xfer(p_container, _mtpd_itf.ep_in); -} +bool tud_mtp_data_receive(mtp_container_info_t *p_container) { + mtpd_interface_t *p_mtp = &_mtpd_itf; + if (p_mtp->phase == MTP_PHASE_COMMAND) { + // 1st data block: header + payload + p_mtp->phase = MTP_PHASE_DATA; + p_mtp->xferred_len = 0; + p_mtp->total_len = p_container->header->len; + } -bool tud_mtp_data_receive(mtp_container_info_t* p_container) { - return mtpd_data_xfer(p_container, _mtpd_itf.ep_out); + // up to buffer size since 1st packet (with header) may also contain payload + const uint16_t xact_len = CFG_TUD_MTP_EP_BUFSIZE; + + TU_LOG_DRV(" MTP Data OUT: xferred_len/total_len=%lu/%lu, xact_len=%u\r\n", p_mtp->xferred_len, p_mtp->total_len, + xact_len); + TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, p_mtp->ep_out)); + TU_ASSERT(usbd_edpt_xfer(p_mtp->rhport, p_mtp->ep_out, _mtpd_epbuf.buf, xact_len, false)); + return true; } bool tud_mtp_response_send(mtp_container_info_t* p_container) { @@ -434,22 +432,25 @@ bool mtpd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t cb_data.total_xferred_bytes = p_mtp->xferred_len; const bool is_data_in = (ep_addr == p_mtp->ep_in); - const uint16_t bulk_mps = (tud_speed_get() == TUSB_SPEED_HIGH) ? 512 : p_mtp->ep_sz_fs; // For IN endpoint, threshold is bulk max packet size // For OUT endpoint, threshold is endpoint buffer size, since we always queue fixed size - const uint16_t threshold = is_data_in ? bulk_mps : CFG_TUD_MTP_EP_BUFSIZE; + uint16_t threshold; + if (is_data_in) { + threshold = (p_mtp->ep_sz_fs > 0) ? p_mtp->ep_sz_fs : 512; // full speed bulk if set + } else { + threshold = CFG_TUD_MTP_EP_BUFSIZE; + } // Check completion: ZLP, short packet, or total length reached - bool is_complete = (xferred_bytes == 0 || - xferred_bytes < threshold || - p_mtp->xferred_len >= p_mtp->total_len); + const bool is_complete = + (xferred_bytes == 0 || xferred_bytes < threshold || p_mtp->xferred_len >= p_mtp->total_len); TU_LOG_DRV(" MTP Data %s CB: xferred_bytes=%lu, xferred_len/total_len=%lu/%lu, is_complete=%d\r\n", is_data_in ? "IN" : "OUT", xferred_bytes, p_mtp->xferred_len, p_mtp->total_len, is_complete ? 1 : 0); // Send/queue ZLP if packet is full-sized but transfer is complete if (is_complete && xferred_bytes > 0 && !(xferred_bytes & (threshold - 1))) { - TU_LOG_DRV(" QUEUE ZLP\r\n"); + TU_LOG_DRV(" queue ZLP\r\n"); TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, ep_addr)); TU_ASSERT(usbd_edpt_xfer(p_mtp->rhport, ep_addr, NULL, 0, false)); return true; diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index b2e883119..dfea9612f 100755 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -151,7 +151,7 @@ def read_disk_file(uid, lun, fname): def open_mtp_dev(uid): mtp = MTP() # MTP seems to take a while to enumerate - timeout = 2*ENUM_TIMEOUT + timeout = 2 * ENUM_TIMEOUT while timeout > 0: # run_cmd(f"gio mount -u mtp://TinyUsb_TinyUsb_Device_{uid}/") for raw in mtp.detect_devices(): @@ -617,13 +617,13 @@ def test_device_mtp(board): # device tests # note don't test 2 examples with cdc or 2 msc next to each other device_tests = [ - 'device/cdc_dual_ports', - 'device/dfu', - 'device/cdc_msc', - 'device/dfu_runtime', - 'device/cdc_msc_freertos', - 'device/hid_boot_interface', - # 'device/mtp' + # 'device/cdc_dual_ports', + # 'device/dfu', + # 'device/cdc_msc', + # 'device/dfu_runtime', + # 'device/cdc_msc_freertos', + # 'device/hid_boot_interface', + 'device/mtp' ] dual_tests = [ -- cgit v1.3.1 From 104d3f2545e460ead95dc8482fcadcf98c3749e1 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 14 Jan 2026 00:18:26 +0100 Subject: bsp: add TI EK-TM4C1294XL Signed-off-by: HiFiPhile --- docs/reference/boards.rst | 1 + examples/device/dfu/skip.txt | 2 +- hw/bsp/BoardPresets.json | 44 ++++++++++++++ hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h | 8 ++- hw/bsp/tm4c/boards/ek_tm4c123gxl/board.h | 6 ++ hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld | 2 +- hw/bsp/tm4c/boards/ek_tm4c1294xl/TM4C1294NC.icf | 28 +++++++++ hw/bsp/tm4c/boards/ek_tm4c1294xl/board.cmake | 13 +++++ hw/bsp/tm4c/boards/ek_tm4c1294xl/board.h | 75 ++++++++++++++++++++++++ hw/bsp/tm4c/boards/ek_tm4c1294xl/board.mk | 16 ++++++ hw/bsp/tm4c/boards/ek_tm4c1294xl/tm4c1294nc.ld | 66 +++++++++++++++++++++ hw/bsp/tm4c/family.c | 76 ++++++++++++++++++++----- hw/bsp/tm4c/family.cmake | 14 ++--- hw/bsp/tm4c/family.mk | 6 +- src/portable/mentor/musb/musb_ti.h | 5 +- src/portable/mentor/musb/musb_type.h | 2 +- 16 files changed, 333 insertions(+), 31 deletions(-) create mode 100644 hw/bsp/tm4c/boards/ek_tm4c1294xl/TM4C1294NC.icf create mode 100644 hw/bsp/tm4c/boards/ek_tm4c1294xl/board.cmake create mode 100644 hw/bsp/tm4c/boards/ek_tm4c1294xl/board.h create mode 100644 hw/bsp/tm4c/boards/ek_tm4c1294xl/board.mk create mode 100644 hw/bsp/tm4c/boards/ek_tm4c1294xl/tm4c1294nc.ld (limited to 'src') diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index cacf52e1a..09c90e08f 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -333,6 +333,7 @@ Board Name Family URL msp_exp430f5529lp MSP430F5529 LaunchPad msp430 https://www.ti.com/tool/MSP-EXP430F5529LP msp_exp432e401y MSP432E401Y LaunchPad msp432e4 https://www.ti.com/tool/MSP-EXP432E401Y ek_tm4c123gxl TM4C123G LaunchPad tm4c https://www.ti.com/tool/EK-TM4C123GXL +ek_tm4c1294xl TM4C1294 LaunchPad tm4c https://www.ti.com/tool/EK-TM4C1294XL ================= ===================== ======== ========================================= ====== Tomu diff --git a/examples/device/dfu/skip.txt b/examples/device/dfu/skip.txt index 9dde06c30..79d3da9d2 100644 --- a/examples/device/dfu/skip.txt +++ b/examples/device/dfu/skip.txt @@ -1,3 +1,3 @@ -mcu:TM4C123 +mcu:TM4C mcu:BCM2835 family:espressif diff --git a/hw/bsp/BoardPresets.json b/hw/bsp/BoardPresets.json index 440ef8733..fabbeed93 100644 --- a/hw/bsp/BoardPresets.json +++ b/hw/bsp/BoardPresets.json @@ -174,6 +174,10 @@ "name": "ek_tm4c123gxl", "inherits": "default" }, + { + "name": "ek_tm4c1294xl", + "inherits": "default" + }, { "name": "f1c100s", "inherits": "default" @@ -718,6 +722,10 @@ "name": "stm32h745disco", "inherits": "default" }, + { + "name": "stm32h747disco", + "inherits": "default" + }, { "name": "stm32h750_weact", "inherits": "default" @@ -1108,6 +1116,11 @@ "description": "Build preset for the ek_tm4c123gxl board", "configurePreset": "ek_tm4c123gxl" }, + { + "name": "ek_tm4c1294xl", + "description": "Build preset for the ek_tm4c1294xl board", + "configurePreset": "ek_tm4c1294xl" + }, { "name": "espressif_addax_1", "description": "Build preset for the espressif_addax_1 board", @@ -1833,6 +1846,11 @@ "description": "Build preset for the stm32h745disco board", "configurePreset": "stm32h745disco" }, + { + "name": "stm32h747disco", + "description": "Build preset for the stm32h747disco board", + "configurePreset": "stm32h747disco" + }, { "name": "stm32h750_weact", "description": "Build preset for the stm32h750_weact board", @@ -2542,6 +2560,19 @@ } ] }, + { + "name": "ek_tm4c1294xl", + "steps": [ + { + "type": "configure", + "name": "ek_tm4c1294xl" + }, + { + "type": "build", + "name": "ek_tm4c1294xl" + } + ] + }, { "name": "espressif_addax_1", "steps": [ @@ -4427,6 +4458,19 @@ } ] }, + { + "name": "stm32h747disco", + "steps": [ + { + "type": "configure", + "name": "stm32h747disco" + }, + { + "type": "build", + "name": "stm32h747disco" + } + ] + }, { "name": "stm32h750_weact", "steps": [ diff --git a/hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h index 454b085e9..b4423e269 100644 --- a/hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h @@ -44,7 +44,13 @@ // skip if included from IAR assembler #ifndef __IASMARM__ - #include "TM4C123.h" + #ifdef TM4C123GH6PM + #include "TM4C123.h" + #elif TM4C1294NCPDT + #include "TM4C129.h" + #else + #error "Unknown TM4C device" + #endif #endif /* Cortex M23/M33 port configuration. */ diff --git a/hw/bsp/tm4c/boards/ek_tm4c123gxl/board.h b/hw/bsp/tm4c/boards/ek_tm4c123gxl/board.h index c0ceb4cd8..fc0ab4c60 100644 --- a/hw/bsp/tm4c/boards/ek_tm4c123gxl/board.h +++ b/hw/bsp/tm4c/boards/ek_tm4c123gxl/board.h @@ -36,20 +36,26 @@ extern "C" { #endif +#include "TM4C123.h" + #define BOARD_UART UART0 #define BOARD_UART_PORT GPIOA +#define BTN_PORT_CLK 5 #define BOARD_BTN_PORT GPIOF #define BOARD_BTN 4 #define BOARD_BTN_Msk (1u<<4) #define BUTTON_STATE_ACTIVE 0 +#define LED_PORT_CLK 5 #define LED_PORT GPIOF #define LED_PIN_RED 1 #define LED_PIN_BLUE 2 #define LED_PIN_GREEN 3 #define LED_STATE_ON 1 +#define BOARD_LED_PIN LED_PIN_BLUE + #ifdef __cplusplus } #endif diff --git a/hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld b/hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld index 11e9608cc..3f06d8f03 100644 --- a/hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld +++ b/hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld @@ -17,7 +17,7 @@ SECTIONS .text : { . = ALIGN(4) ; - *(.vectors) + KEEP(*(.vectors)) *(.text) *(.text.*) *(.init) diff --git a/hw/bsp/tm4c/boards/ek_tm4c1294xl/TM4C1294NC.icf b/hw/bsp/tm4c/boards/ek_tm4c1294xl/TM4C1294NC.icf new file mode 100644 index 000000000..2dba41866 --- /dev/null +++ b/hw/bsp/tm4c/boards/ek_tm4c1294xl/TM4C1294NC.icf @@ -0,0 +1,28 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x000FFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2003FFFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x8000; +define symbol __ICFEDIT_size_heap__ = 0x10000; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; diff --git a/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.cmake b/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.cmake new file mode 100644 index 000000000..3e03b3f72 --- /dev/null +++ b/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.cmake @@ -0,0 +1,13 @@ +set(MCU_SUB_VARIANT 129) + +set(JLINK_DEVICE TM4C1294NCPDT) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/tm4c1294nc.ld) +set(LD_FILE_IAR ${CMAKE_CURRENT_LIST_DIR}/TM4C1294NC.icf) + +set(OPENOCD_OPTION "-f board/ti_ek-tm4c1294xl.cfg") + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + TM4C1294NCPDT + ) +endfunction() diff --git a/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.h b/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.h new file mode 100644 index 000000000..4530e9430 --- /dev/null +++ b/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.h @@ -0,0 +1,75 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/* metadata: + name: TM4C1294 LaunchPad + url: https://www.ti.com/tool/EK-TM4C1294XL +*/ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "TM4C129.h" + +#define BOARD_UART UART0 +#define BOARD_UART_PORT GPIOA + +#define BTN_PORT_CLK 8 +#define BOARD_BTN_PORT GPIOJ +#define BOARD_BTN 0 +#define BOARD_BTN_Msk (1u<<0) +#define BUTTON_STATE_ACTIVE 0 + +#define LED_PORT_CLK 12 +#define LED_PORT GPION +#define LED_PIN_1 1 +#define LED_PIN_2 0 +#define LED_STATE_ON 1 + +#define BOARD_LED_PIN LED_PIN_2 + +#define GPIOA GPIOA_AHB +#define GPIOB GPIOB_AHB +#define GPIOC GPIOC_AHB +#define GPIOD GPIOD_AHB +#define GPIOE GPIOE_AHB +#define GPIOF GPIOF_AHB +#define GPIOG GPIOG_AHB +#define GPIOH GPIOH_AHB +#define GPIOI GPIOI_AHB +#define GPIOJ GPIOJ_AHB + +#define GPIOA_Type GPIOA_AHB_Type + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.mk b/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.mk new file mode 100644 index 000000000..b01977674 --- /dev/null +++ b/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.mk @@ -0,0 +1,16 @@ +MCU_SUB_VARIANT = 129 + +CFLAGS += -DTM4C1294NCPDT + +LD_FILE_GCC = $(BOARD_PATH)/tm4c1294nc.ld +LD_FILE_IAR = $(BOARD_PATH)/TM4C1294NC.icf + +# For flash-jlink target +JLINK_DEVICE = TM4C1294NCPDT + +# flash using openocd +OPENOCD_OPTION = -f board/ti_ek-tm4c1294xl.cfg + +UNIFLASH_OPTION = -c ${TOP}/${BOARD_PATH}/${BOARD}.ccxml -r 1 + +flash: flash-openocd diff --git a/hw/bsp/tm4c/boards/ek_tm4c1294xl/tm4c1294nc.ld b/hw/bsp/tm4c/boards/ek_tm4c1294xl/tm4c1294nc.ld new file mode 100644 index 000000000..fa4ea4dc5 --- /dev/null +++ b/hw/bsp/tm4c/boards/ek_tm4c1294xl/tm4c1294nc.ld @@ -0,0 +1,66 @@ +ENTRY(Reset_Handler) + +_estack = 0x20008000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000 + SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 +} + +SECTIONS +{ + .text : + { + . = ALIGN(4) ; + _text = . ; + KEEP(*(.isr_vector)) + *(.text) + *(.text.*) + *(.init) + *(.fini) + *(.rodata) + *(.rodata.*) + *(.ARM.exidx*) + _etext = . ; + . = ALIGN(4) ; + } >FLASH + + .data : AT(ADDR(.text) + SIZEOF(.text)) + { + _data = .; + . = ALIGN(4); + _ldata = LOADADDR (.data); + *(.data) + *(.data.*) + _edata = .; + . = ALIGN(4); + + } >SRAM + + .bss : + { + . = ALIGN(4) ; + _bss = .; + *(.bss) + *(.bss.*) + *(.COMMON) + _ebss = .; + . = ALIGN(4); + }>SRAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >SRAM +} diff --git a/hw/bsp/tm4c/family.c b/hw/bsp/tm4c/family.c index ee1fa2a3c..ae7f22f00 100644 --- a/hw/bsp/tm4c/family.c +++ b/hw/bsp/tm4c/family.c @@ -2,7 +2,6 @@ manufacturer: Texas Instruments */ -#include "TM4C123.h" #include "bsp/board_api.h" #include "board.h" @@ -27,6 +26,9 @@ static void board_uart_init(void) { SYSCTL->RCGCUART |= (1 << 0); // Enable the clock to UART0 SYSCTL->RCGCGPIO |= (1 << 0); // Enable the clock to GPIOA + while (!(SYSCTL->PRGPIO & (1 << 0))) {} // Wait for the GPIOA clock to stabilize + while (!(SYSCTL->PRUART & (1 << 0))) {} // Wait for the UART0 clock to stabilize + GPIOA->AFSEL |= (1 << 1) | (1 << 0); // Enable the alternate function on pin PA0 & PA1 GPIOA->PCTL |= (1 << 0) | (1 << 4); // Configure the GPIOPCTL register to select UART0 in PA0 and PA1 GPIOA->DEN |= (1 << 0) | (1 << 1); // Enable the digital functionality in PA0 and PA1 @@ -44,12 +46,26 @@ static void board_uart_init(void) { UART0->CTL = (1 << 0) | (1 << 8) | (1 << 9); // UART0 Enable, Transmit Enable, Receive Enable } -static void initialize_board_led(GPIOA_Type* port, uint8_t PinMsk, uint8_t dirmsk) { - /* Enable PortF Clock */ - SYSCTL->RCGCGPIO |= (1 << 5); +static void board_button_init(GPIOA_Type* port, uint8_t PinMsk) { + /* Enable Port Clock */ + SYSCTL->RCGCGPIO |= (1 << BTN_PORT_CLK); + + /* Let the clock stabilize */ + while (!((SYSCTL->PRGPIO) & (1 << BTN_PORT_CLK))) {} + + /* Port Digital Enable */ + port->DEN |= PinMsk; + + /* Set direction */ + port->DIR &= ~PinMsk; +} + +static void board_led_init(GPIOA_Type* port, uint8_t PinMsk, uint8_t dirmsk) { + /* Enable Port Clock */ + SYSCTL->RCGCGPIO |= (1 << LED_PORT_CLK); /* Let the clock stabilize */ - while (!((SYSCTL->PRGPIO) & (1 << 5))) {} + while (!((SYSCTL->PRGPIO) & (1 << LED_PORT_CLK))) {} /* Port Digital Enable */ port->DEN |= PinMsk; @@ -71,7 +87,9 @@ static uint32_t ReadGPIOPin(GPIOA_Type* port, uint8_t pinMsk) { } void board_init(void) { +#ifdef TM4C123_H SystemCoreClockUpdate(); +#endif #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer @@ -83,6 +101,7 @@ void board_init(void) { NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif +#ifdef TM4C123_H /* Reset USB */ SYSCTL->SRCR2 |= (1u << 16); @@ -99,7 +118,7 @@ void board_init(void) { /* USB IO Initialization */ SYSCTL->RCGCGPIO |= (1u << 3); - /* Let the clock stabilize */ + /* Let the clock stabilize */ while (!(SYSCTL->PRGPIO & (1u << 3))) {} /* USB IOs to Analog Mode */ @@ -107,16 +126,43 @@ void board_init(void) { GPIOD->DEN &= ~((1u << 4) | (1u << 5)); GPIOD->AMSEL |= ((1u << 4) | (1u << 5)); - uint8_t leds = (1 << LED_PIN_RED) | (1 << LED_PIN_BLUE) | (1 << LED_PIN_GREEN); - uint8_t dirmsk = (1 << LED_PIN_RED) | (1 << LED_PIN_BLUE) | (1 << LED_PIN_GREEN); +#else // TM4C129 + /* Reset USB */ + SYSCTL->SRUSB = 1; - /* Configure GPIO for board LED */ - initialize_board_led(LED_PORT, leds, dirmsk); + for (volatile uint8_t i = 0; i < 20; i++) {} + + SYSCTL->SRUSB = 0; - /* Configure GPIO for board switch */ - GPIOF->DIR &= ~(1 << BOARD_BTN); - GPIOF->PUR |= (1 << BOARD_BTN); - GPIOF->DEN |= (1 << BOARD_BTN); + /* Open the USB clock gate */ + SYSCTL->RCGCUSB = 1; + + /* Let the clock stabilize */ + while(!(SYSCTL->PRUSB & 1)) {} + + /* USB IO Initialization */ + SYSCTL->RCGCGPIO |= (1u << 10); + + /* Let the clock stabilize */ + while (!(SYSCTL->PRGPIO & (1u << 10))) {} + + /* USB IOs to Analog Mode */ + GPIOL->AFSEL &= ~((1u << 6) | (1u << 7)); + GPIOL->DEN &= ~((1u << 6) | (1u << 7)); + GPIOL->AMSEL |= ((1u << 6) | (1u << 7)); + + /* USB Clock Configuration */ + USB0->CC = 0x207; +#endif + + uint8_t leds = 1 << BOARD_LED_PIN; + uint8_t dirmsk = 1 << BOARD_LED_PIN; + + /* Configure GPIO for board button */ + board_button_init(BOARD_BTN_PORT, BOARD_BTN_Msk); + + /* Configure GPIO for board LED */ + board_led_init(LED_PORT, leds, dirmsk); /* Initialize board UART */ board_uart_init(); @@ -125,7 +171,7 @@ void board_init(void) { } void board_led_write(bool state) { - WriteGPIOPin(LED_PORT, (1 << LED_PIN_BLUE), state); + WriteGPIOPin(LED_PORT, (1 << BOARD_LED_PIN), state); } uint32_t board_button_read(void) { diff --git a/hw/bsp/tm4c/family.cmake b/hw/bsp/tm4c/family.cmake index 12f0448a3..9cef96b9d 100644 --- a/hw/bsp/tm4c/family.cmake +++ b/hw/bsp/tm4c/family.cmake @@ -5,14 +5,14 @@ include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) set(MCU_VARIANT tm4c${MCU_SUB_VARIANT}) set(MCU_VARIANT_UPPER TM4C${MCU_SUB_VARIANT}) -set(SDK_DIR ${TOP}/hw/mcu/ti/${MCU_VARIANT}xx) +set(SDK_DIR ${TOP}/hw/mcu/ti/tm4c) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) -set(FAMILY_MCUS TM4C123 CACHE INTERNAL "") +set(FAMILY_MCUS TM4C CACHE INTERNAL "") #------------------------------------ # Startup & Linker script @@ -20,7 +20,7 @@ set(FAMILY_MCUS TM4C123 CACHE INTERNAL "") set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_GNU ${SDK_DIR}/Source/GCC/${MCU_VARIANT}_startup.c) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - +set(STARTUP_FILE_IAR ${SDK_DIR}/Source/IAR/${MCU_VARIANT}_startup.c) #------------------------------------ # Board Target #------------------------------------ @@ -29,7 +29,7 @@ function(family_add_board BOARD_TARGET) ${SDK_DIR}/Source/system_${MCU_VARIANT_UPPER}.c ) target_include_directories(${BOARD_TARGET} PUBLIC - ${SDK_DIR}/Include/${MCU_VARIANT_UPPER} + ${SDK_DIR}/Include ${CMSIS_DIR}/CMSIS/Core/Include ) @@ -41,7 +41,7 @@ endfunction() #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) - family_add_tinyusb(${TARGET} OPT_MCU_TM4C123) + family_add_tinyusb(${TARGET} OPT_MCU_TM4C${MCU_SUB_VARIANT}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c @@ -72,12 +72,10 @@ function(family_configure_example TARGET RTOS) if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () - set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES - SKIP_LINTING ON - COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) + family_flash_jlink(${TARGET}) family_flash_openocd(${TARGET}) family_flash_uniflash(${TARGET}) endfunction() diff --git a/hw/bsp/tm4c/family.mk b/hw/bsp/tm4c/family.mk index 76ae785b2..bc966d98e 100644 --- a/hw/bsp/tm4c/family.mk +++ b/hw/bsp/tm4c/family.mk @@ -4,11 +4,11 @@ CPU_CORE ?= cortex-m4 MCU_VARIANT = tm4c${MCU_SUB_VARIANT} MCU_VARIANT_UPPER = TM4C${MCU_SUB_VARIANT} -SDK_DIR = hw/mcu/ti/${MCU_VARIANT}xx +SDK_DIR = hw/mcu/ti/tm4c CFLAGS += \ -flto \ - -DCFG_TUSB_MCU=OPT_MCU_TM4C123 \ + -DCFG_TUSB_MCU=OPT_MCU_TM4C${MCU_SUB_VARIANT} \ -uvectors \ # mcu driver cause following warnings @@ -18,7 +18,7 @@ LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs INC += \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ - $(TOP)/$(SDK_DIR)/Include/${MCU_VARIANT_UPPER} \ + $(TOP)/$(SDK_DIR)/Include \ $(TOP)/$(BOARD_PATH) SRC_C += \ diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index d17e836ee..68e89d77d 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -35,7 +35,10 @@ #include "TM4C123.h" #define FIFO0_WORD FIFO0 #define FIFO1_WORD FIFO1 -//#elif CFG_TUSB_MCU == OPT_MCU_TM4C129 +#elif CFG_TUSB_MCU == OPT_MCU_TM4C129 + #include "TM4C129.h" + #define FIFO0_WORD FIFOA + #define FIFO1_WORD FIFOB #elif CFG_TUSB_MCU == OPT_MCU_MSP432E4 #include "msp.h" #else diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index 4e448c0ed..b2f6492fa 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -147,7 +147,7 @@ typedef struct TU_ATTR_PACKED { TU_VERIFY_STATIC(sizeof(musb_ep_csr_t) == 16, "size is not correct"); -typedef struct TU_ATTR_PACKED { +typedef struct { //------------- Common -------------// __IO uint8_t faddr; // 0x00: FADDR union { -- cgit v1.3.1 From c1a506793b0617f91ec2317af6ea6ed53192bccc Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 14 Jan 2026 00:19:18 +0100 Subject: dcd/musb: fix IAR build Signed-off-by: HiFiPhile --- src/portable/mentor/musb/dcd_musb.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 3827be318..f0c5aa722 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -175,9 +175,8 @@ static void process_setup_packet(uint8_t rhport) { // Read setup packet uint32_t *p = (void*)&_dcd.setup_packet; - volatile uint32_t *fifo_ptr = &musb_regs->fifo[0]; - p[0] = *fifo_ptr; - p[1] = *fifo_ptr; + p[0] = musb_regs->fifo[0]; + p[1] = musb_regs->fifo[0]; _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; @@ -218,7 +217,7 @@ static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) tu_hwfifo_write_from_fifo(fifo_ptr, (tu_fifo_t *)buf, len, NULL); } else { tu_hwfifo_write(fifo_ptr, buf, len, NULL); - pipe->buf = buf + len; + pipe->buf = (uint8_t*)buf + len; } pipe->remaining = rem - len; } @@ -249,7 +248,7 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) tu_hwfifo_read_to_fifo(fifo_ptr, (tu_fifo_t *)buf, len, NULL); } else { tu_hwfifo_read(fifo_ptr, buf, len, NULL); - pipe->buf = buf + len; + pipe->buf = (uint8_t*)buf + len; } pipe->remaining = rem - len; } -- cgit v1.3.1 From 86ca8fe717f379879298f6a723cafa897bae04de Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Jan 2026 10:46:59 +0700 Subject: remove no-fifo mode in edpt stream API update vendor_device.c for direct usbd xfer when either RX/TX BUFSIZE is 0 i.e CFG_TUD_VENDOR_TXRX_BUFFERED = 0 --- src/class/vendor/vendor_device.c | 262 +++++++++++++++++++++++---------------- src/class/vendor/vendor_device.h | 44 ++++--- src/common/tusb_private.h | 8 -- src/tusb.c | 103 +++++---------- 4 files changed, 206 insertions(+), 211 deletions(-) (limited to 'src') diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index b8e6fec6f..b917c8dc7 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -40,36 +40,33 @@ typedef struct { uint8_t rhport; uint8_t itf_num; + #if CFG_TUD_VENDOR_TXRX_BUFFERED /*------------- From this point, data is not cleared by bus reset -------------*/ - struct { - tu_edpt_stream_t tx; - tu_edpt_stream_t rx; - - #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 - uint8_t tx_ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; - #endif - - #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - uint8_t rx_ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; + tu_edpt_stream_t tx_stream; + tu_edpt_stream_t rx_stream; + uint8_t tx_ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; + uint8_t rx_ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; + #else + uint8_t ep_in; + uint8_t ep_out; + uint16_t ep_in_mps; + uint16_t ep_out_mps; #endif - } stream; } vendord_interface_t; -#define ITF_MEM_RESET_SIZE (offsetof(vendord_interface_t, itf_num) + sizeof(((vendord_interface_t *)0)->itf_num)) + #if CFG_TUD_VENDOR_TXRX_BUFFERED + #define ITF_MEM_RESET_SIZE (offsetof(vendord_interface_t, itf_num) + TU_FIELD_SIZE(vendord_interface_t, itf_num)) + #else + #define ITF_MEM_RESET_SIZE sizeof(vendord_interface_t) + #endif static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR]; -#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 || CFG_TUD_VENDOR_RX_BUFSIZE == 0 + // Skip local EP buffer if dedicated hw FIFO is supported or no fifo mode + #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 || !CFG_TUD_VENDOR_TXRX_BUFFERED typedef struct { - // Skip local EP buffer if dedicated hw FIFO is supported - #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 || CFG_TUD_VENDOR_RX_BUFSIZE == 0 TUD_EPBUF_DEF(epout, CFG_TUD_VENDOR_EPSIZE); - #endif - - // Skip local EP buffer if dedicated hw FIFO is supported - #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 TUD_EPBUF_DEF(epin, CFG_TUD_VENDOR_EPSIZE); - #endif } vendord_epbuf_t; CFG_TUD_MEM_SECTION static vendord_epbuf_t _vendord_epbuf[CFG_TUD_VENDOR]; @@ -78,7 +75,6 @@ CFG_TUD_MEM_SECTION static vendord_epbuf_t _vendord_epbuf[CFG_TUD_VENDOR]; //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ - TU_ATTR_WEAK void tud_vendor_rx_cb(uint8_t idx, const uint8_t *buffer, uint32_t bufsize) { (void)idx; (void)buffer; @@ -93,40 +89,44 @@ TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t idx, uint32_t sent_bytes) { //-------------------------------------------------------------------- // Application API //-------------------------------------------------------------------- - bool tud_vendor_n_mounted(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR); vendord_interface_t *p_itf = &_vendord_itf[idx]; - return p_itf->stream.rx.ep_addr || p_itf->stream.tx.ep_addr; + + #if CFG_TUD_VENDOR_TXRX_BUFFERED + return (p_itf->rx_stream.ep_addr != 0) || (p_itf->tx_stream.ep_addr != 0); + #else + return (p_itf->ep_out != 0) || (p_itf->ep_in != 0); + #endif } //--------------------------------------------------------------------+ // Read API //--------------------------------------------------------------------+ -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 + #if CFG_TUD_VENDOR_TXRX_BUFFERED uint32_t tud_vendor_n_available(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_itf = &_vendord_itf[idx]; - return tu_edpt_stream_read_available(&p_itf->stream.rx); + return tu_edpt_stream_read_available(&p_itf->rx_stream); } bool tud_vendor_n_peek(uint8_t idx, uint8_t *u8) { TU_VERIFY(idx < CFG_TUD_VENDOR); vendord_interface_t *p_itf = &_vendord_itf[idx]; - return tu_edpt_stream_peek(&p_itf->stream.rx, u8); + return tu_edpt_stream_peek(&p_itf->rx_stream, u8); } uint32_t tud_vendor_n_read(uint8_t idx, void *buffer, uint32_t bufsize) { TU_VERIFY(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_itf = &_vendord_itf[idx]; - return tu_edpt_stream_read(&p_itf->stream.rx, buffer, bufsize); + return tu_edpt_stream_read(&p_itf->rx_stream, buffer, bufsize); } void tud_vendor_n_read_flush(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR, ); vendord_interface_t *p_itf = &_vendord_itf[idx]; - tu_edpt_stream_clear(&p_itf->stream.rx); - tu_edpt_stream_read_xfer(&p_itf->stream.rx); + tu_edpt_stream_clear(&p_itf->rx_stream); + tu_edpt_stream_read_xfer(&p_itf->rx_stream); } #endif @@ -134,9 +134,17 @@ void tud_vendor_n_read_flush(uint8_t idx) { bool tud_vendor_n_read_xfer(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR); vendord_interface_t *p_itf = &_vendord_itf[idx]; - return tu_edpt_stream_read_xfer(&p_itf->stream.rx); + + #if CFG_TUD_VENDOR_TXRX_BUFFERED + return tu_edpt_stream_read_xfer(&p_itf->rx_stream); + + #else + // Non-FIFO mode + TU_VERIFY(usbd_edpt_claim(p_itf->rhport, p_itf->ep_out)); + return usbd_edpt_xfer(p_itf->rhport, p_itf->ep_out, _vendord_epbuf[idx].epout, CFG_TUD_VENDOR_EPSIZE, false); + #endif } -#endif + #endif //--------------------------------------------------------------------+ @@ -145,26 +153,45 @@ bool tud_vendor_n_read_xfer(uint8_t idx) { uint32_t tud_vendor_n_write(uint8_t idx, const void *buffer, uint32_t bufsize) { TU_VERIFY(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_itf = &_vendord_itf[idx]; - return tu_edpt_stream_write(&p_itf->stream.tx, buffer, (uint16_t)bufsize); + + #if CFG_TUD_VENDOR_TXRX_BUFFERED + return tu_edpt_stream_write(&p_itf->tx_stream, buffer, (uint16_t)bufsize); + + #else + // non-fifo mode: direct transfer + TU_VERIFY(usbd_edpt_claim(p_itf->rhport, p_itf->ep_in), 0); + const uint32_t xact_len = tu_min32(bufsize, CFG_TUD_VENDOR_EPSIZE); + memcpy(_vendord_epbuf[idx].epin, buffer, xact_len); + TU_ASSERT(usbd_edpt_xfer(p_itf->rhport, p_itf->ep_in, _vendord_epbuf[idx].epin, (uint16_t)xact_len, false), 0); + return xact_len; + #endif } -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 -uint32_t tud_vendor_n_write_flush(uint8_t idx) { +uint32_t tud_vendor_n_write_available(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_itf = &_vendord_itf[idx]; - return tu_edpt_stream_write_xfer(&p_itf->stream.tx); + + #if CFG_TUD_VENDOR_TXRX_BUFFERED + return tu_edpt_stream_write_available(&p_itf->tx_stream); + + #else + // Non-FIFO mode + TU_VERIFY(p_itf->ep_in > 0, 0); // must be opened + return usbd_edpt_busy(p_itf->rhport, p_itf->ep_in) ? 0 : CFG_TUD_VENDOR_EPSIZE; + #endif } -uint32_t tud_vendor_n_write_available(uint8_t idx) { + #if CFG_TUD_VENDOR_TXRX_BUFFERED +uint32_t tud_vendor_n_write_flush(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_itf = &_vendord_itf[idx]; - return tu_edpt_stream_write_available(&p_itf->stream.tx); + return tu_edpt_stream_write_xfer(&p_itf->tx_stream); } bool tud_vendor_n_write_clear(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_itf = &_vendord_itf[idx]; - tu_edpt_stream_clear(&p_itf->stream.tx); + tu_edpt_stream_clear(&p_itf->tx_stream); return true; } #endif @@ -175,48 +202,37 @@ bool tud_vendor_n_write_clear(uint8_t idx) { void vendord_init(void) { tu_memclr(_vendord_itf, sizeof(_vendord_itf)); - for(uint8_t i=0; i 0 - uint8_t *rx_ff_buf = p_itf->stream.rx_ff_buf; - #else - uint8_t *rx_ff_buf = NULL; - #endif + #endif - tu_edpt_stream_init(&p_itf->stream.rx, false, false, false, rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, epout_buf, + uint8_t *rx_ff_buf = p_itf->rx_ff_buf; + tu_edpt_stream_init(&p_itf->rx_stream, false, false, false, rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, epout_buf, CFG_TUD_VENDOR_EPSIZE); - #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 - uint8_t *tx_ff_buf = p_itf->stream.tx_ff_buf; - #else - uint8_t *tx_ff_buf = NULL; - #endif - - tu_edpt_stream_init(&p_itf->stream.tx, false, true, false, tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, epin_buf, + uint8_t *tx_ff_buf = p_itf->tx_ff_buf; + tu_edpt_stream_init(&p_itf->tx_stream, false, true, false, tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, epin_buf, CFG_TUD_VENDOR_EPSIZE); } + #endif } bool vendord_deinit(void) { - for(uint8_t i=0; istream.rx); - tu_edpt_stream_deinit(&p_itf->stream.tx); + #if CFG_TUD_VENDOR_TXRX_BUFFERED + for (uint8_t i = 0; i < CFG_TUD_VENDOR; i++) { + vendord_interface_t *p_itf = &_vendord_itf[i]; + tu_edpt_stream_deinit(&p_itf->rx_stream); + tu_edpt_stream_deinit(&p_itf->tx_stream); } + #endif return true; } @@ -227,11 +243,12 @@ void vendord_reset(uint8_t rhport) { vendord_interface_t* p_itf = &_vendord_itf[i]; tu_memclr(p_itf, ITF_MEM_RESET_SIZE); - tu_edpt_stream_clear(&p_itf->stream.rx); - tu_edpt_stream_close(&p_itf->stream.rx); - - tu_edpt_stream_clear(&p_itf->stream.tx); - tu_edpt_stream_close(&p_itf->stream.tx); + #if CFG_TUD_VENDOR_TXRX_BUFFERED + tu_edpt_stream_clear(&p_itf->rx_stream); + tu_edpt_stream_close(&p_itf->rx_stream); + tu_edpt_stream_clear(&p_itf->tx_stream); + tu_edpt_stream_close(&p_itf->tx_stream); + #endif } } @@ -241,13 +258,25 @@ static uint8_t find_vendor_itf(uint8_t ep_addr) { const vendord_interface_t *p_vendor = &_vendord_itf[idx]; if (ep_addr == 0) { // find unused: require both ep == 0 - if (p_vendor->stream.rx.ep_addr == 0 && p_vendor->stream.tx.ep_addr == 0) { + #if CFG_TUD_VENDOR_TXRX_BUFFERED + if (p_vendor->rx_stream.ep_addr == 0 && p_vendor->tx_stream.ep_addr == 0) { return idx; } - } else if (ep_addr == p_vendor->stream.rx.ep_addr || ep_addr == p_vendor->stream.tx.ep_addr) { - return idx; + #else + if (p_vendor->ep_out == 0 && p_vendor->ep_in == 0) { + return idx; + } + #endif } else { - // nothing to do + #if CFG_TUD_VENDOR_TXRX_BUFFERED + if (ep_addr == p_vendor->rx_stream.ep_addr || ep_addr == p_vendor->tx_stream.ep_addr) { + return idx; + } + #else + if (ep_addr == p_vendor->ep_out || ep_addr == p_vendor->ep_in) { + return idx; + } + #endif } } return 0xff; @@ -273,28 +302,39 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uin const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); - // open endpoint stream, skip if already opened (multiple IN/OUT endpoints) + #if CFG_TUD_VENDOR_TXRX_BUFFERED + // open endpoint stream if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { - tu_edpt_stream_t *stream_tx = &p_vendor->stream.tx; - if (stream_tx->ep_addr == 0) { - tu_edpt_stream_open(stream_tx, rhport, desc_ep); - tu_edpt_stream_write_xfer(stream_tx); // flush pending data - } + tu_edpt_stream_t *tx_stream = &p_vendor->tx_stream; + tu_edpt_stream_open(tx_stream, rhport, desc_ep); + tu_edpt_stream_write_xfer(tx_stream); // flush pending data } else { - tu_edpt_stream_t *stream_rx = &p_vendor->stream.rx; - if (stream_rx->ep_addr == 0) { - tu_edpt_stream_open(stream_rx, rhport, desc_ep); - #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 - TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); // prepare for incoming data - #endif - } + tu_edpt_stream_t *rx_stream = &p_vendor->rx_stream; + tu_edpt_stream_open(rx_stream, rhport, desc_ep); + #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 + TU_ASSERT(tu_edpt_stream_read_xfer(rx_stream) > 0, 0); // prepare for incoming data + #endif + } + #else + // Non-FIFO mode: store endpoint info + if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { + p_vendor->ep_in = desc_ep->bEndpointAddress; + p_vendor->ep_in_mps = tu_edpt_packet_size(desc_ep); + } else { + p_vendor->ep_out = desc_ep->bEndpointAddress; + p_vendor->ep_out_mps = tu_edpt_packet_size(desc_ep); + #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 + // Prepare for incoming data + TU_ASSERT(usbd_edpt_xfer(rhport, p_vendor->ep_out, _vendord_epbuf[idx].epout, CFG_TUD_VENDOR_EPSIZE, false), 0); + #endif } + #endif } p_desc = tu_desc_next(p_desc); } - return (uint16_t) ((uintptr_t) p_desc - (uintptr_t) desc_itf); + return (uint16_t)((uintptr_t)p_desc - (uintptr_t)desc_itf); } bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { @@ -304,34 +344,36 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint TU_VERIFY(idx < CFG_TUD_VENDOR); vendord_interface_t *p_vendor = &_vendord_itf[idx]; - if (ep_addr == p_vendor->stream.rx.ep_addr) { - #if CFG_TUD_VENDOR_RX_BUFSIZE - // Received new data: put into stream's fifo - tu_edpt_stream_read_xfer_complete(&p_vendor->stream.rx, xferred_bytes); - #endif - - // invoke callback - #if CFG_TUD_VENDOR_RX_BUFSIZE == 0 - tud_vendor_rx_cb(idx, p_vendor->stream.rx.ep_buf, xferred_bytes); - #else +#if CFG_TUD_VENDOR_TXRX_BUFFERED + if (ep_addr == p_vendor->rx_stream.ep_addr) { + // Put received data to FIFO + tu_edpt_stream_read_xfer_complete(&p_vendor->rx_stream, xferred_bytes); tud_vendor_rx_cb(idx, NULL, 0); - #endif - - #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 - tu_edpt_stream_read_xfer(&p_vendor->stream.rx); // prepare next data - #endif - } else if (ep_addr == p_vendor->stream.tx.ep_addr) { + #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 + tu_edpt_stream_read_xfer(&p_vendor->rx_stream); // prepare next data + #endif + } else if (ep_addr == p_vendor->tx_stream.ep_addr) { // Send complete tud_vendor_tx_cb(idx, (uint16_t)xferred_bytes); - #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 // try to send more if possible - if (0 == tu_edpt_stream_write_xfer(&p_vendor->stream.tx)) { + if (0 == tu_edpt_stream_write_xfer(&p_vendor->tx_stream)) { // If there is no data left, a ZLP should be sent if xferred_bytes is multiple of EP Packet size and not zero - tu_edpt_stream_write_zlp_if_needed(&p_vendor->stream.tx, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(&p_vendor->tx_stream, xferred_bytes); } - #endif } + #else + if (ep_addr == p_vendor->ep_out) { + // Non-FIFO mode: invoke callback with buffer + tud_vendor_rx_cb(idx, _vendord_epbuf[idx].epout, xferred_bytes); + #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 + usbd_edpt_xfer(rhport, p_vendor->ep_out, _vendord_epbuf[idx].epout, CFG_TUD_VENDOR_EPSIZE, false); + #endif + } else if (ep_addr == p_vendor->ep_in) { + // Send complete + tud_vendor_tx_cb(idx, (uint16_t)xferred_bytes); + } + #endif return true; } diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index c3de4c49d..101765bb1 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -50,8 +50,14 @@ extern "C" { #define CFG_TUD_VENDOR_TX_BUFSIZE 64 #endif +// Vendor is buffered (FIFO mode) if both TX and RX buffers are configured +// If either is 0, vendor operates in non-buffered (direct transfer) mode +#ifndef CFG_TUD_VENDOR_TXRX_BUFFERED + #define CFG_TUD_VENDOR_TXRX_BUFFERED ((CFG_TUD_VENDOR_RX_BUFSIZE > 0) && (CFG_TUD_VENDOR_TX_BUFSIZE > 0)) +#endif + // Application will manually schedule RX transfer. This can be useful when using with non-fifo (buffered) mode -// i.e. CFG_TUD_VENDOR_RX_BUFSIZE = 0 +// i.e. CFG_TUD_VENDOR_TXRX_BUFFERED = 0 #ifndef CFG_TUD_VENDOR_RX_MANUAL_XFER #define CFG_TUD_VENDOR_RX_MANUAL_XFER 0 #endif @@ -63,7 +69,8 @@ extern "C" { // Return whether the vendor interface is mounted bool tud_vendor_n_mounted(uint8_t idx); -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 +//------------- RX -------------// +#if CFG_TUD_VENDOR_TXRX_BUFFERED // Return number of available bytes for reading uint32_t tud_vendor_n_available(uint8_t idx); @@ -82,16 +89,17 @@ void tud_vendor_n_read_flush(uint8_t idx); bool tud_vendor_n_read_xfer(uint8_t idx); #endif +//------------- TX -------------// // Write to TX FIFO. This can be buffered and not sent immediately unless buffered bytes >= USB endpoint size uint32_t tud_vendor_n_write(uint8_t idx, const void *buffer, uint32_t bufsize); -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 +// Return number of bytes available for writing in TX FIFO (or endpoint if non-buffered) +uint32_t tud_vendor_n_write_available(uint8_t idx); + +#if CFG_TUD_VENDOR_TXRX_BUFFERED // Force sending buffered data, return number of bytes sent uint32_t tud_vendor_n_write_flush(uint8_t idx); -// Return number of bytes available for writing in TX FIFO -uint32_t tud_vendor_n_write_available(uint8_t idx); - // Clear the transmit FIFO bool tud_vendor_n_write_clear(uint8_t idx); #endif @@ -111,7 +119,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool tud_vendor_mounted(void) { return tud_vendor_n_mounted(0); } -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 +#if CFG_TUD_VENDOR_TXRX_BUFFERED TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_available(void) { return tud_vendor_n_available(0); } @@ -127,6 +135,14 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_read(void *buffer, uint3 TU_ATTR_ALWAYS_INLINE static inline void tud_vendor_read_flush(void) { tud_vendor_n_read_flush(0); } + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_flush(void) { + return tud_vendor_n_write_flush(0); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_vendor_write_clear(void) { + return tud_vendor_n_write_clear(0); +} #endif #if CFG_TUD_VENDOR_RX_MANUAL_XFER @@ -143,20 +159,10 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_str(const char *st return tud_vendor_n_write_str(0, str); } -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 -TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_flush(void) { - return tud_vendor_n_write_flush(0); -} - TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_available(void) { return tud_vendor_n_write_available(0); } -TU_ATTR_ALWAYS_INLINE static inline bool tud_vendor_write_clear(void) { - return tud_vendor_n_write_clear(0); -} -#endif - // backward compatible #define tud_vendor_flush() tud_vendor_write_flush() @@ -165,8 +171,8 @@ TU_ATTR_ALWAYS_INLINE static inline bool tud_vendor_write_clear(void) { //--------------------------------------------------------------------+ // Invoked when received new data. -// - CFG_TUD_VENDOR_RX_BUFSIZE > 0; buffer and bufsize must not be used (both NULL,0) since data is in RX FIFO -// - CFG_TUD_VENDOR_RX_BUFSIZE = 0: Buffer and bufsize are valid +// - CFG_TUD_VENDOR_TXRX_BUFFERED = 1: buffer and bufsize must not be used (both NULL,0) since data is in RX FIFO +// - CFG_TUD_VENDOR_TXRX_BUFFERED = 0: Buffer and bufsize are valid void tud_vendor_rx_cb(uint8_t idx, const uint8_t *buffer, uint32_t bufsize); // Invoked when tx transfer is finished diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 10e12c2af..43ce7a1df 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -37,14 +37,6 @@ // Configuration //--------------------------------------------------------------------+ -#if CFG_TUD_ENABLED && CFG_TUD_VENDOR && (CFG_TUD_VENDOR_TX_BUFSIZE == 0 || CFG_TUD_VENDOR_RX_BUFSIZE == 0) - #define CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED 1 -#endif - -#ifndef CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED - #define CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED 0 -#endif - #define TUP_USBIP_CONTROLLER_NUM 2 extern tusb_role_t _tusb_rhport_role[TUP_USBIP_CONTROLLER_NUM]; diff --git a/src/tusb.c b/src/tusb.c index 256aa832f..bf82cdbe9 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -309,11 +309,9 @@ bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool ove uint16_t ff_bufsize, uint8_t *ep_buf, uint16_t ep_bufsize) { (void) is_tx; - #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED == 0 // FIFO is required if (ff_buf == NULL || ff_bufsize == 0) { return false; } - #endif s->is_host = is_host; tu_fifo_config(&s->ff, ff_buf, ff_bufsize, overwritable); @@ -411,88 +409,45 @@ uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t *s) { } uint32_t tu_edpt_stream_write(tu_edpt_stream_t *s, const void *buffer, uint32_t bufsize) { - #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED - if (0 == tu_fifo_depth(&s->ff)) { - // non-fifo mode: TX need ep buffer - TU_VERIFY(s->ep_buf != NULL, 0); - TU_VERIFY(stream_claim(s), 0); - uint32_t xact_len = tu_min32(bufsize, s->ep_bufsize); - memcpy(s->ep_buf, buffer, xact_len); - TU_ASSERT(stream_xfer(s, (uint16_t) xact_len), 0); - return xact_len; - } else - #endif - { - TU_VERIFY(bufsize > 0); - const uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); - - // flush if fifo has more than packet size or - // in rare case: fifo depth is configured too small (which never reach packet size) - if ((tu_fifo_count(&s->ff) >= s->mps) || (tu_fifo_depth(&s->ff) < s->mps)) { - tu_edpt_stream_write_xfer(s); - } - return ret; + TU_VERIFY(bufsize > 0); + const uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); + + // flush if fifo has more than packet size or + // in rare case: fifo depth is configured too small (which never reach packet size) + if ((tu_fifo_count(&s->ff) >= s->mps) || (tu_fifo_depth(&s->ff) < s->mps)) { + tu_edpt_stream_write_xfer(s); } + return ret; } uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t *s) { - #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED - if (0 == tu_fifo_depth(&s->ff)) { - // non-fifo mode - TU_VERIFY(s->ep_addr > 0); // must be opened - bool is_busy = true; - if (s->is_host) { - #if CFG_TUH_ENABLED - is_busy = usbh_edpt_busy(s->hwid, s->ep_addr); - #endif - } else { - #if CFG_TUD_ENABLED - is_busy = usbd_edpt_busy(s->hwid, s->ep_addr); - #endif - } - return is_busy ? 0 : s->ep_bufsize; - } else - #endif - { - return (uint32_t)tu_fifo_remaining(&s->ff); - } + return (uint32_t)tu_fifo_remaining(&s->ff); } //--------------------------------------------------------------------+ // Stream Read //--------------------------------------------------------------------+ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t *s) { - #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED - if (0 == tu_fifo_depth(&s->ff)) { - // non-fifo mode: RX need ep buffer - TU_VERIFY(s->ep_buf != NULL, 0); - TU_VERIFY(stream_claim(s), 0); - TU_ASSERT(stream_xfer(s, s->ep_bufsize), 0); - return s->ep_bufsize; - } else - #endif - { - uint16_t available = tu_fifo_remaining(&s->ff); - - // Prepare for incoming data but only allow what we can store in the ring buffer. - // TODO Actually we can still carry out the transfer, keeping count of received bytes - // and slowly move it to the FIFO when read(). - // This pre-check reduces endpoint claiming - TU_VERIFY(available >= s->mps); - TU_VERIFY(stream_claim(s), 0); - available = tu_fifo_remaining(&s->ff); // re-get available since fifo can be changed - - if (available >= s->mps) { - // multiple of packet size limit by ep bufsize - uint16_t count = (uint16_t) (available & ~(s->mps - 1)); - count = tu_min16(count, s->ep_bufsize); - TU_ASSERT(stream_xfer(s, count), 0); - return count; - } else { - // Release endpoint since we don't make any transfer - stream_release(s); - return 0; - } + uint16_t available = tu_fifo_remaining(&s->ff); + + // Prepare for incoming data but only allow what we can store in the ring buffer. + // TODO Actually we can still carry out the transfer, keeping count of received bytes + // and slowly move it to the FIFO when read(). + // This pre-check reduces endpoint claiming + TU_VERIFY(available >= s->mps); + TU_VERIFY(stream_claim(s), 0); + available = tu_fifo_remaining(&s->ff); // re-get available since fifo can be changed + + if (available >= s->mps) { + // multiple of packet size limit by ep bufsize + uint16_t count = (uint16_t) (available & ~(s->mps - 1)); + count = tu_min16(count, s->ep_bufsize); + TU_ASSERT(stream_xfer(s, count), 0); + return count; + } else { + // Release endpoint since we don't make any transfer + stream_release(s); + return 0; } } -- cgit v1.3.1 From dbfbfcf48b45ccc1e6534c454f7b2807b9ae88bd Mon Sep 17 00:00:00 2001 From: Rémi Berthoz Date: Wed, 14 Jan 2026 19:58:47 +0100 Subject: update printer_device.c accounting for upstream changes --- src/class/printer/printer_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/class/printer/printer_device.c b/src/class/printer/printer_device.c index 76151949b..aaea4c988 100644 --- a/src/class/printer/printer_device.c +++ b/src/class/printer/printer_device.c @@ -147,8 +147,8 @@ void printerd_init(void) { for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { printer_interface_t *p_printer = &_printer_itf[i]; - tu_fifo_config(&p_printer->rx_ff, p_printer->rx_ff_buf, TU_ARRAY_SIZE(p_printer->rx_ff_buf), 1, false); - tu_fifo_config(&p_printer->tx_ff, p_printer->tx_ff_buf, TU_ARRAY_SIZE(p_printer->tx_ff_buf), 1, true); + tu_fifo_config(&p_printer->rx_ff, p_printer->rx_ff_buf, TU_ARRAY_SIZE(p_printer->rx_ff_buf), false); + tu_fifo_config(&p_printer->tx_ff, p_printer->tx_ff_buf, TU_ARRAY_SIZE(p_printer->tx_ff_buf), true); #if OSAL_MUTEX_REQUIRED osal_mutex_t mutex_rd = osal_mutex_create(&p_printer->rx_ff_mutex); -- cgit v1.3.1 From b03a87731cb38d7f1fbf82f07886e071f0a48bbf Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 15 Jan 2026 19:13:02 +0100 Subject: dcd/musb: fix unaligned cast Signed-off-by: HiFiPhile --- src/portable/mentor/musb/dcd_musb.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index f0c5aa722..06f62b0d3 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -32,12 +32,6 @@ #define MUSB_DEBUG 2 #define MUSB_REGS(rhport) ((musb_regs_t*) MUSB_BASES[rhport]) -#if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) -/* GCC warns that an address may be unaligned, even though - * the target CPU has the capability for unaligned memory access. */ -_Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); -#endif - #include "musb_type.h" #include "device/dcd.h" @@ -73,7 +67,10 @@ typedef struct TU_ATTR_PACKED typedef struct { - tusb_control_request_t setup_packet; + union { + tusb_control_request_t setup_packet; + uint32_t setup_buffer[2]; + }; uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ int8_t status_out; pipe_state_t pipe0; @@ -174,9 +171,8 @@ static void process_setup_packet(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); // Read setup packet - uint32_t *p = (void*)&_dcd.setup_packet; - p[0] = musb_regs->fifo[0]; - p[1] = musb_regs->fifo[0]; + _dcd.setup_buffer[0] = musb_regs->fifo[0]; + _dcd.setup_buffer[1] = musb_regs->fifo[0]; _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; -- cgit v1.3.1 From 8ef8ee1946f3c0f600500eb49b2b0c1352f8dcb8 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 15 Jan 2026 19:13:18 +0100 Subject: dcd/musb: fix zlp IN Signed-off-by: HiFiPhile --- src/portable/mentor/musb/dcd_musb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 06f62b0d3..9e6ee6f5d 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -189,14 +189,14 @@ static void process_setup_packet(uint8_t rhport) { } } -static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) +static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr, bool is_zlp) { unsigned epnum = tu_edpt_number(ep_addr); unsigned epnum_minus1 = epnum - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; const unsigned rem = pipe->remaining; - if (!rem) { + if (!rem && !is_zlp) { pipe->buf = NULL; return true; } @@ -268,7 +268,7 @@ static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16 pipe->remaining = total_bytes; if (dir_in) { - handle_xfer_in(rhport, ep_addr); + handle_xfer_in(rhport, ep_addr, total_bytes == 0); } else { musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum); @@ -445,7 +445,7 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) ep_csr->tx_csrl &= ~(MUSB_TXCSRL1_STALLED | MUSB_TXCSRL1_UNDRN); return; } - completed = handle_xfer_in(rhport, ep_addr); + completed = handle_xfer_in(rhport, ep_addr, false); } else { // TU_LOG1(" RX CSRL%d = %x\r\n", epn, ep_csr->rx_csrl); if (ep_csr->rx_csrl & MUSB_RXCSRL1_STALLED) { -- cgit v1.3.1 From 042ebc04b325f95d593d337317709adc74e7b435 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 16 Jan 2026 16:17:05 +0100 Subject: fix stream write racing Signed-off-by: HiFiPhile --- src/tusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tusb.c b/src/tusb.c index bf82cdbe9..6075e9db4 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -392,7 +392,7 @@ uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t *s) { // Pull data from FIFO -> EP buf uint16_t count; if (s->ep_buf == NULL) { - count = ff_count; + count = tu_fifo_count(&s->ff); // re-get count since fifo can be changed } else { count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); } -- cgit v1.3.1 From d89a5812c3b3d1d88911f9c6307f343c9d3756bd Mon Sep 17 00:00:00 2001 From: Mitsumine Suzu <60875431+verylowfreq@users.noreply.github.com> Date: Sat, 24 Jan 2026 17:08:55 +0900 Subject: Fix macro directive for FSDEV of CH32V20x --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 22a9e4af8..a6abc6244 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -833,7 +833,7 @@ void dcd_int_disable(uint8_t rhport) { fsdev_int_disable(rhport); } - #if defined(USB_BCDR_DPPU) || defined(SYSCFG_PMC_USB_PU) + #if defined(USB_BCDR_DPPU) || defined(SYSCFG_PMC_USB_PU) || defined(EXTEN_USBD_PU_EN) void dcd_connect(uint8_t rhport) { fsdev_connect(rhport); } -- cgit v1.3.1 From 697f6b313e82cb59d034664d2c8f258f087a1269 Mon Sep 17 00:00:00 2001 From: Zixun LI Date: Mon, 26 Jan 2026 16:11:24 +0100 Subject: device/msc: skip command stage if EP out is stalled Signed-off-by: Zixun LI --- src/class/msc/msc_device.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 15bfafc35..be40c37e7 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -121,7 +121,12 @@ TU_ATTR_ALWAYS_INLINE static inline bool send_csw(mscd_interface_t* p_msc) { TU_ATTR_ALWAYS_INLINE static inline bool prepare_cbw(mscd_interface_t* p_msc) { uint8_t rhport = p_msc->rhport; p_msc->stage = MSC_STAGE_CMD; - return usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_epbuf.buf, sizeof(msc_cbw_t), false); + // Skip command stage until Clear Stall request if endpoint is stalled + if (!usbd_edpt_stalled(rhport, p_msc->ep_out)) { + return usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_epbuf.buf, sizeof(msc_cbw_t), false); + } else { + return true; + } } static void fail_scsi_op(mscd_interface_t* p_msc, uint8_t status) { -- cgit v1.3.1 From 31dfd673ec7549006474a03786bfd3a01508b68c Mon Sep 17 00:00:00 2001 From: Zixun LI Date: Mon, 26 Jan 2026 17:15:23 +0100 Subject: fix stm32u0 data stride Signed-off-by: Zixun LI --- src/portable/st/stm32_fsdev/fsdev_common.h | 4 ++-- src/tusb_option.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index c53e345b0..442e738ae 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -71,11 +71,11 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b // 1x16 bit / word access scheme #define FSDEV_PMA_STRIDE 2 #define pma_access_scheme TU_ATTR_ALIGNED(4) -#elif CFG_TUSB_FSDEV_PMA_SIZE == 1024 +#elif CFG_TUSB_FSDEV_PMA_SIZE == 1024 && CFG_TUSB_MCU != OPT_MCU_STM32U0 // 2x16 bit / word access scheme #define FSDEV_PMA_STRIDE 1 #define pma_access_scheme -#elif CFG_TUSB_FSDEV_PMA_SIZE == 2048 +#elif CFG_TUSB_FSDEV_PMA_SIZE == 2048 || CFG_TUSB_MCU == OPT_MCU_STM32U0 // 32 bit access scheme #define FSDEV_BUS_32BIT #define FSDEV_PMA_STRIDE 1 diff --git a/src/tusb_option.h b/src/tusb_option.h index abf5e0608..1b65cc5aa 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -343,10 +343,10 @@ #if CFG_TUSB_FSDEV_PMA_SIZE == 512 #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 2 // 16-bit data #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 4 // 32-bit address increase - #elif CFG_TUSB_FSDEV_PMA_SIZE == 1024 + #elif CFG_TUSB_FSDEV_PMA_SIZE == 1024 && CFG_TUSB_MCU != OPT_MCU_STM32U0 #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 2 // 16-bit data #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 2 // 16-bit address increase - #elif CFG_TUSB_FSDEV_PMA_SIZE == 2048 + #elif CFG_TUSB_FSDEV_PMA_SIZE == 2048 || CFG_TUSB_MCU == OPT_MCU_STM32U0 #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4 // 32-bit data #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 4 // 32-bit address increase #endif -- cgit v1.3.1 From 78411bbefa2187bee3b9b99561a34aa75c2d562b Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 30 Jan 2026 14:09:26 +0100 Subject: dcd/dwc2: Fix SEDET unable to be cleared on stm32u5 Signed-off-by: HiFiPhile --- src/portable/synopsys/dwc2/dcd_dwc2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 44f7137f9..f73c36d2f 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -780,7 +780,7 @@ static void handle_bus_reset(uint8_t rhport) { dwc2->epout[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); } - dwc2->gintmsk |= GINTMSK_OEPINT | GINTMSK_IEPINT | GINTMSK_IISOIXFRM; + dwc2->gintmsk |= GINTMSK_OTGINT | GINTMSK_OEPINT | GINTMSK_IEPINT | GINTMSK_IISOIXFRM; } static void handle_enum_done(uint8_t rhport) { @@ -1180,6 +1180,7 @@ void dcd_int_handler(uint8_t rhport) { const uint32_t otg_int = dwc2->gotgint; if (otg_int & GOTGINT_SEDET) { + dwc2->gintmsk &= ~GINTMSK_OTGINT; dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); } -- cgit v1.3.1 From fd369937279594eb8c48a81eabebb7f66bd8306a Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 30 Jan 2026 19:24:12 +0100 Subject: dwc2: add vbus sense config Signed-off-by: HiFiPhile --- src/device/usbd.h | 1 + src/portable/synopsys/dwc2/dcd_dwc2.c | 12 +-- src/portable/synopsys/dwc2/dwc2_stm32.h | 130 ++++++++++++++++++++++++++++++++ src/portable/synopsys/dwc2/dwc2_type.h | 45 ++++++----- src/portable/synopsys/dwc2/hcd_dwc2.c | 4 + 5 files changed, 169 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/device/usbd.h b/src/device/usbd.h index bd5a3c395..f923b1c56 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -41,6 +41,7 @@ enum { typedef struct { uint16_t bm_double_buffered; // bitmap of IN endpoints to be double buffered, only effective for bulk endpoints + bool vbus_sensing; // Vbus pin is used for device connection detection, mandatory for tud_umount_cb() } tud_configure_dwc2_t; typedef union { diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index f73c36d2f..36cb763aa 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -78,7 +78,8 @@ CFG_TUD_MEM_SECTION static struct { } _dcd_usbbuf; static tud_configure_dwc2_t _tud_cfg = { - .bm_double_buffered = 0 + .bm_double_buffered = 0, + .vbus_sensing = false }; TU_ATTR_ALWAYS_INLINE static inline uint8_t dwc2_ep_count(const dwc2_regs_t* dwc2) { @@ -472,12 +473,11 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { // Force device mode dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_FHMOD) | GUSBCFG_FDMOD; - // Clear A override, force B Valid - dwc2->gotgctl = (dwc2->gotgctl & ~GOTGCTL_AVALOEN) | GOTGCTL_BVALOEN | GOTGCTL_BVALOVAL; + // Clear A override, force B Valid if Vbus sensing is not used + dwc2->gotgctl = (dwc2->gotgctl & ~GOTGCTL_AVALOEN) | (_tud_cfg.vbus_sensing ? 0 : GOTGCTL_BVALOEN | GOTGCTL_BVALOVAL); -#if CFG_TUSB_MCU == OPT_MCU_STM32N6 - // No hardware detection of Vbus B-session is available on the STM32N6 - dwc2->stm32_gccfg |= STM32_GCCFG_VBVALOVAL; +#ifdef TUP_USBIP_DWC2_STM32 + dwc2_stm32_gccfg_cfg(dwc2, _tud_cfg.vbus_sensing, false); #endif // Enable required interrupts diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 516eb021b..a87eef068 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -300,6 +300,136 @@ static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { } } +//------------- GCCFG configuration -------------// +static inline void dwc2_stm32_gccfg_cfg(dwc2_regs_t* dwc2, bool vbus_sensing, bool is_host) { + if (is_host) { + vbus_sensing = false; + } +#if CFG_TUSB_MCU == OPT_MCU_STM32F1 + // F1: Basic FS-only core, no VBUS sensing support + // Only PWRDWN bit is used (set in dwc2_phy_init) + (void) vbus_sensing; + +#elif CFG_TUSB_MCU == OPT_MCU_STM32F2 || CFG_TUSB_MCU == OPT_MCU_STM32F4 + // F2/F4: Dual FS/HS with VBUSBSEN/VBUSASEN/NOVBUSSENS bits + if (is_host) { + dwc2->stm32_gccfg &= ~(STM32_GCCFG_NOVBUSSENS | STM32_GCCFG_VBUSBSEN | STM32_GCCFG_VBUSASEN); + } else { + if (vbus_sensing) { + dwc2->stm32_gccfg &= ~STM32_GCCFG_NOVBUSSENS; + dwc2->stm32_gccfg |= STM32_GCCFG_VBUSBSEN; + } else { + dwc2->stm32_gccfg |= STM32_GCCFG_NOVBUSSENS; + dwc2->stm32_gccfg &= ~STM32_GCCFG_VBUSBSEN; + dwc2->stm32_gccfg &= ~STM32_GCCFG_VBUSASEN; + } + } +#elif CFG_TUSB_MCU == OPT_MCU_STM32F7 + // F7: Enhanced FS/HS with battery charging detection + if (vbus_sensing) { + dwc2->stm32_gccfg |= STM32_GCCFG_VBDEN; + } else { + dwc2->stm32_gccfg &= ~STM32_GCCFG_VBDEN; + } + +#elif CFG_TUSB_MCU == OPT_MCU_STM32H7 + if (vbus_sensing) { + dwc2->stm32_gccfg |= STM32_GCCFG_VBDEN; + } else { + dwc2->stm32_gccfg &= ~STM32_GCCFG_VBDEN; + } + +#elif CFG_TUSB_MCU == OPT_MCU_STM32H7RS + // H7FS: Port0: Basic FS-only core; Port1: femtoPHY + if ((uintptr_t)dwc2 == _dwc2_controller[0].reg_base) { + if (vbus_sensing) { + dwc2->stm32_gccfg |= STM32_GCCFG_VBDEN; + } else { + dwc2->stm32_gccfg &= ~STM32_GCCFG_VBDEN; + } + return; + } else { + // Uses VBVALEXTOEN and VBVALOVAL for external VBUS sensing override + if (is_host) { + dwc2->stm32_gccfg |= STM32_GCCFG_PULLDOWNEN; + dwc2->stm32_gccfg &= ~(STM32_GCCFG_VBDEN | STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL); + } else { + dwc2->stm32_gccfg &= ~STM32_GCCFG_PULLDOWNEN; + if (vbus_sensing) { + dwc2->stm32_gccfg |= STM32_GCCFG_VBDEN; + dwc2->stm32_gccfg &= ~(STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL); + } else { + dwc2->stm32_gccfg &= ~STM32_GCCFG_VBDEN; + dwc2->stm32_gccfg |= STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL; + } + } + } + +#elif CFG_TUSB_MCU == OPT_MCU_STM32N6 + // N6: femtoPHY + // In this device, the software override is always active + (void) vbus_sensing; + if (is_host) { + dwc2->stm32_gccfg |= STM32_GCCFG_PULLDOWNEN; + dwc2->stm32_gccfg &= ~(STM32_GCCFG_VBVALOVAL); + } else { + dwc2->stm32_gccfg &= ~STM32_GCCFG_PULLDOWNEN; + dwc2->stm32_gccfg |= STM32_GCCFG_VBVALOVAL; + } + +#elif CFG_TUSB_MCU == OPT_MCU_STM32L4 + // L4: Low-power FS-only with VBUS detection + if (vbus_sensing) { + dwc2->stm32_gccfg |= STM32_GCCFG_VBDEN; + } else { + dwc2->stm32_gccfg &= ~STM32_GCCFG_VBDEN; + } + +#elif CFG_TUSB_MCU == OPT_MCU_STM32U5 + #ifdef USB_OTG_FS + // U5: FS PHY (U575/585 have FS only) + if (vbus_sensing) { + dwc2->stm32_gccfg |= STM32_GCCFG_VBDEN; + } else { + dwc2->stm32_gccfg &= ~STM32_GCCFG_VBDEN; + } + #else + // U5: femtoPHY (U59x/5Ax/5Fx/5Gx have HS) + // Uses VBVALEXTOEN and VBVALOVAL for external VBUS sensing override + if (is_host) { + dwc2->stm32_gccfg |= STM32_GCCFG_PULLDOWNEN; + dwc2->stm32_gccfg &= ~(STM32_GCCFG_VBDEN | STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL); + } else { + dwc2->stm32_gccfg &= ~STM32_GCCFG_PULLDOWNEN; + if (vbus_sensing) { + dwc2->stm32_gccfg |= STM32_GCCFG_VBDEN; + dwc2->stm32_gccfg &= ~(STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL); + } else { + dwc2->stm32_gccfg &= ~STM32_GCCFG_VBDEN; + dwc2->stm32_gccfg |= STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL; + } + } + #endif +#elif CFG_TUSB_MCU == OPT_MCU_STM32WBA + // WBA: femtoPHY + // In this device, the software override is always active + if (is_host) { + dwc2->stm32_gccfg |= STM32_GCCFG_PULLDOWNEN; + dwc2->stm32_gccfg &= ~(STM32_GCCFG_VBVALOVAL); + } else { + dwc2->stm32_gccfg &= ~STM32_GCCFG_PULLDOWNEN; + if (vbus_sensing) { + dwc2->stm32_gccfg &= ~(STM32_GCCFG_VBVALOVAL); + } else { + dwc2->stm32_gccfg |= STM32_GCCFG_VBVALOVAL; + } + } + +#else + #error "Unsupported MCU family" +#endif +} + //------------- DCache -------------// #if CFG_TUD_MEM_DCACHE_ENABLE || CFG_TUH_MEM_DCACHE_ENABLE diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index 7693ce02a..2dd73c184 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -1650,23 +1650,34 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define STM32_GCCFG_PHYHSEN_Msk (0x1UL << STM32_GCCFG_PHYHSEN_Pos) // 0x00800000 #define STM32_GCCFG_PHYHSEN STM32_GCCFG_PHYHSEN_Msk // HS PHY enable -// TODO stm32u5a5 SDEN is 22nd bit, conflict with 20th bit above -//#define STM32_GCCFG_SDEN_Pos (22U) -//#define STM32_GCCFG_SDEN_Msk (0x1U << STM32_GCCFG_SDEN_Pos) // 0x00400000 -//#define STM32_GCCFG_SDEN STM32_GCCFG_SDEN_Msk // Secondary detection (PD) mode enable - -// TODO stm32u5a5 VBVALOVA is 23rd bit, conflict with PHYHSEN bit above -#define STM32_GCCFG_VBVALOVAL_Pos (23U) -#define STM32_GCCFG_VBVALOVAL_Msk (0x1U << STM32_GCCFG_VBVALOVAL_Pos) // 0x00800000 -#define STM32_GCCFG_VBVALOVAL STM32_GCCFG_VBVALOVAL_Msk // Value of VBUSVLDEXT0 femtoPHY input - -#define STM32_GCCFG_VBVALEXTOEN_Pos (24U) -#define STM32_GCCFG_VBVALEXTOEN_Msk (0x1U << STM32_GCCFG_VBVALEXTOEN_Pos) // 0x01000000 -#define STM32_GCCFG_VBVALEXTOEN STM32_GCCFG_VBVALEXTOEN_Msk // Enables of VBUSVLDEXT0 femtoPHY input override - -#define STM32_GCCFG_PULLDOWNEN_Pos (25U) -#define STM32_GCCFG_PULLDOWNEN_Msk (0x1U << STM32_GCCFG_PULLDOWNEN_Pos) // 0x02000000 -#define STM32_GCCFG_PULLDOWNEN STM32_GCCFG_PULLDOWNEN_Msk // Enables of femtoPHY pulldown resistors, used when ID PAD is disabled +// stm32f2/stm32f4 +#define STM32_GCCFG_VBUSASEN_Pos (18U) +#define STM32_GCCFG_VBUSASEN_Msk (0x1UL << STM32_GCCFG_VBUSASEN_Pos) // 0x00040000 +#define STM32_GCCFG_VBUSASEN STM32_GCCFG_VBUSASEN_Msk // Enable A-device (host) VBUS sensing +#define STM32_GCCFG_VBUSBSEN_Pos (19U) +#define STM32_GCCFG_VBUSBSEN_Msk (0x1UL << STM32_GCCFG_VBUSBSEN_Pos) // 0x00080000 +#define STM32_GCCFG_VBUSBSEN STM32_GCCFG_VBUSBSEN_Msk // Enable B-device (peripheral) VBUS sensing +#define STM32_GCCFG_NOVBUSSENS_Pos (21U) +#define STM32_GCCFG_NOVBUSSENS_Msk (0x1UL << STM32_GCCFG_NOVBUSSENS_Pos) // 0x00200000 +#define STM32_GCCFG_NOVBUSSENS STM32_GCCFG_NOVBUSSENS_Msk // VBUS sensing disable option + +// TODO: stm32u5a5 SDEN is 22nd bit, conflict with 20th bit above +// #define STM32_GCCFG_SDEN_Pos (22U) +// #define STM32_GCCFG_SDEN_Msk (0x1U << STM32_GCCFG_SDEN_Pos) // 0x00400000 +// #define STM32_GCCFG_SDEN STM32_GCCFG_SDEN_Msk // Secondary detection (PD) mode enable + +// stm32u5a5 VBVALOVA is 23rd bit, conflict with PHYHSEN bit above +#define STM32_GCCFG_VBVALOVAL_Pos (23U) +#define STM32_GCCFG_VBVALOVAL_Msk (0x1U << STM32_GCCFG_VBVALOVAL_Pos) // 0x00800000 +#define STM32_GCCFG_VBVALOVAL STM32_GCCFG_VBVALOVAL_Msk // Value of VBUSVLDEXT0 femtoPHY input + +#define STM32_GCCFG_VBVALEXTOEN_Pos (24U) +#define STM32_GCCFG_VBVALEXTOEN_Msk (0x1U << STM32_GCCFG_VBVALEXTOEN_Pos) // 0x01000000 +#define STM32_GCCFG_VBVALEXTOEN STM32_GCCFG_VBVALEXTOEN_Msk // Enables of VBUSVLDEXT0 femtoPHY input override + +#define STM32_GCCFG_PULLDOWNEN_Pos (25U) +#define STM32_GCCFG_PULLDOWNEN_Msk (0x1U << STM32_GCCFG_PULLDOWNEN_Pos) // 0x02000000 +#define STM32_GCCFG_PULLDOWNEN STM32_GCCFG_PULLDOWNEN_Msk // Enables of femtoPHY pulldown resistors, used when ID PAD is disabled /******************** Bit definition for DEACHINTMSK register ********************/ diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index c40703b09..8182fd6cc 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -428,6 +428,10 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { #endif while ((dwc2->gintsts & GINTSTS_CMOD) != GINTSTS_CMODE_HOST) {} +#ifdef TUP_USBIP_DWC2_STM32 + dwc2_stm32_gccfg_cfg(dwc2, false, true); +#endif + // configure fixed-allocated fifo scheme dfifo_host_init(rhport); -- cgit v1.3.1 From c57d355af63080ab425143d1ce7a4579100b626f Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 31 Jan 2026 16:32:58 +0100 Subject: dwc2: add stm32n6 DMA regions Signed-off-by: HiFiPhile --- src/portable/synopsys/dwc2/dwc2_stm32.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index a87eef068..3da78b893 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -85,8 +85,11 @@ extern "C" { #define EP_MAX_HS 9 #define EP_FIFO_SIZE_HS 4096 - #define USB_OTG_HS_PERIPH_BASE USB1_OTG_HS_BASE - #define OTG_HS_IRQn USB1_OTG_HS_IRQn + #define USB_OTG_FS_PERIPH_BASE USB1_OTG_HS_BASE + #define OTG_FS_IRQn USB1_OTG_HS_IRQn + + #define USB_OTG_HS_PERIPH_BASE USB2_OTG_HS_BASE + #define OTG_HS_IRQn USB2_OTG_HS_IRQn #elif CFG_TUSB_MCU == OPT_MCU_STM32F7 #include "stm32f7xx.h" @@ -451,8 +454,13 @@ static mem_region_t uncached_regions[] = { // DTCM (although USB DMA can't transfer to/from DTCM) {.start = 0x20000000, .end = 0x2002FFFF}, #elif CFG_TUSB_MCU == OPT_MCU_STM32F7 - // DTCM + // DTCM {.start = 0x20000000, .end = 0x2000FFFF}, +#elif CFG_TUSB_MCU == OPT_MCU_STM32N6 + // DTCM NS + {.start = 0x20000000, .end = 0x2003FFFF}, + // DTCM S + {.start = 0x30000000, .end = 0x3003FFFF}, #else #error "Cache maintenance is not supported yet" #endif -- cgit v1.3.1 From b73df6c22e4743f9232f7922fe2cf0fbd05a3a2e Mon Sep 17 00:00:00 2001 From: Cédric Berger Date: Sun, 1 Feb 2026 21:08:03 +0100 Subject: Limit events processed by tud_task_ext() / tuh_task_ext() --- src/device/usbd.c | 9 +++++++-- src/host/usbh.c | 9 +++++++-- src/tusb_option.h | 10 ++++++++++ 3 files changed, 24 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index 1e21c667a..8f3a7a226 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -666,8 +666,13 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { return; } - // Loop until there is no more events in the queue - while (1) { + // Loop until there are no more events in the queue or CFG_TUD_TASK_EVENTS_PER_RUN is reached + for (unsigned epr = 0;; epr++) { +#if CFG_TUD_TASK_EVENTS_PER_RUN > 0 + if (epr >= CFG_TUD_TASK_EVENTS_PER_RUN) { + TU_LOG_USBD("USBD event limit (" TU_XSTRING(CFG_TUD_TASK_EVENTS_PER_RUN) ") reached\r\n"); + } +#endif dcd_event_t event; if (!osal_queue_receive(_usbd_q, &event, timeout_ms)) { return; diff --git a/src/host/usbh.c b/src/host/usbh.c index a725b7c8b..cc99c0a53 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -599,8 +599,13 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { return; } - // Loop until there is no more events in the queue - while (1) { + // Loop until there are no more events in the queue or CFG_TUH_TASK_EVENTS_PER_RUN is reached + for (unsigned epr = 0;; epr++) { +#if CFG_TUH_TASK_EVENTS_PER_RUN > 0 + if (epr >= CFG_TUH_TASK_EVENTS_PER_RUN) { + TU_LOG_USBH("USBH event limit (" TU_XSTRING(CFG_TUH_TASK_EVENTS_PER_RUN) ") reached\r\n"); + } +#endif hcd_event_t event; if (!osal_queue_receive(_usbh_q, &event, timeout_ms)) { return; } diff --git a/src/tusb_option.h b/src/tusb_option.h index abf5e0608..d34f2b710 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -560,6 +560,11 @@ #define CFG_TUD_INTERFACE_MAX 16 #endif +// max events processed in one tud_task_ext() call, 0 for unlimited +#ifndef CFG_TUD_TASK_EVENTS_PER_RUN + #define CFG_TUD_TASK_EVENTS_PER_RUN 16 +#endif + // default to max hardware endpoint, but can be smaller to save RAM #ifndef CFG_TUD_ENDPPOINT_MAX #define CFG_TUD_ENDPPOINT_MAX TUP_DCD_ENDPOINT_MAX @@ -679,6 +684,11 @@ #define CFG_TUH_MEM_DCACHE_LINE_SIZE CFG_TUSB_MEM_DCACHE_LINE_SIZE #endif +// max events processed in one tuh_task_ext() call, 0 for unlimited +#ifndef CFG_TUH_TASK_EVENTS_PER_RUN + #define CFG_TUH_TASK_EVENTS_PER_RUN 16 +#endif + //------------- CLASS -------------// #ifndef CFG_TUH_HUB -- cgit v1.3.1 From d2f1b1899d4dbdab2a5bfd822c3bbe5fc0ee8deb Mon Sep 17 00:00:00 2001 From: Cédric Berger Date: Sun, 1 Feb 2026 22:29:52 +0100 Subject: Actually exit the loop in addition to logging. ENOTENOUGHCOFFEE --- src/device/usbd.c | 1 + src/host/usbh.c | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index 8f3a7a226..cca4169d7 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -671,6 +671,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { #if CFG_TUD_TASK_EVENTS_PER_RUN > 0 if (epr >= CFG_TUD_TASK_EVENTS_PER_RUN) { TU_LOG_USBD("USBD event limit (" TU_XSTRING(CFG_TUD_TASK_EVENTS_PER_RUN) ") reached\r\n"); + break; } #endif dcd_event_t event; diff --git a/src/host/usbh.c b/src/host/usbh.c index cc99c0a53..41f41dcfb 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -604,6 +604,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { #if CFG_TUH_TASK_EVENTS_PER_RUN > 0 if (epr >= CFG_TUH_TASK_EVENTS_PER_RUN) { TU_LOG_USBH("USBH event limit (" TU_XSTRING(CFG_TUH_TASK_EVENTS_PER_RUN) ") reached\r\n"); + break; } #endif hcd_event_t event; -- cgit v1.3.1 From fa2e076d723c50bb8f361b491126393cf33f2508 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 3 Feb 2026 08:20:18 +0000 Subject: Fix DFU descriptor version from 1.0.1 (0x0101) to 1.1.0 (0x0110) Co-authored-by: hathach <249515+hathach@users.noreply.github.com> --- hw/mcu/raspberry_pi/Pico-PIO-USB | 1 + hw/mcu/st/cmsis_device_f4 | 1 + hw/mcu/st/stm32f4xx_hal_driver | 1 + lib/CMSIS_5 | 1 + lib/FreeRTOS-Kernel | 1 + lib/lwip | 1 + src/device/usbd.h | 4 ++-- tools/linkermap | 1 + tools/uf2 | 1 + 9 files changed, 10 insertions(+), 2 deletions(-) create mode 160000 hw/mcu/raspberry_pi/Pico-PIO-USB create mode 160000 hw/mcu/st/cmsis_device_f4 create mode 160000 hw/mcu/st/stm32f4xx_hal_driver create mode 160000 lib/CMSIS_5 create mode 160000 lib/FreeRTOS-Kernel create mode 160000 lib/lwip create mode 160000 tools/linkermap create mode 160000 tools/uf2 (limited to 'src') diff --git a/hw/mcu/raspberry_pi/Pico-PIO-USB b/hw/mcu/raspberry_pi/Pico-PIO-USB new file mode 160000 index 000000000..675543bcc --- /dev/null +++ b/hw/mcu/raspberry_pi/Pico-PIO-USB @@ -0,0 +1 @@ +Subproject commit 675543bcc9baa8170f868ab7ba316d418dbcf41f diff --git a/hw/mcu/st/cmsis_device_f4 b/hw/mcu/st/cmsis_device_f4 new file mode 160000 index 000000000..3c77349ce --- /dev/null +++ b/hw/mcu/st/cmsis_device_f4 @@ -0,0 +1 @@ +Subproject commit 3c77349ce04c8af401454cc51f85ea9a50e34fc1 diff --git a/hw/mcu/st/stm32f4xx_hal_driver b/hw/mcu/st/stm32f4xx_hal_driver new file mode 160000 index 000000000..b6f0ed382 --- /dev/null +++ b/hw/mcu/st/stm32f4xx_hal_driver @@ -0,0 +1 @@ +Subproject commit b6f0ed3829f3829eb358a2e7417d80bba1a42db7 diff --git a/lib/CMSIS_5 b/lib/CMSIS_5 new file mode 160000 index 000000000..2b7495b85 --- /dev/null +++ b/lib/CMSIS_5 @@ -0,0 +1 @@ +Subproject commit 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c diff --git a/lib/FreeRTOS-Kernel b/lib/FreeRTOS-Kernel new file mode 160000 index 000000000..cc0e0707c --- /dev/null +++ b/lib/FreeRTOS-Kernel @@ -0,0 +1 @@ +Subproject commit cc0e0707c0c748713485b870bb980852b210877f diff --git a/lib/lwip b/lib/lwip new file mode 160000 index 000000000..159e31b68 --- /dev/null +++ b/lib/lwip @@ -0,0 +1 @@ +Subproject commit 159e31b689577dbf69cf0683bbaffbd71fa5ee10 diff --git a/src/device/usbd.h b/src/device/usbd.h index bd5a3c395..4016a45a4 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -819,7 +819,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ /* Interface */ \ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_RT, _stridx, \ /* Function */ \ - 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101) + 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0110) //--------------------------------------------------------------------+ // DFU Descriptor Templates @@ -833,7 +833,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ #define TUD_DFU_DESCRIPTOR(_itfnum, _alt_count, _stridx, _attr, _timeout, _xfer_size) \ TU_XSTRCAT(TUD_DFU_ALT_,_alt_count)(_itfnum, 0, _stridx), \ /* Function */ \ - 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101) + 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0110) #define TUD_DFU_ALT(_itfnum, _alt, _stridx) \ /* Interface */ \ diff --git a/tools/linkermap b/tools/linkermap new file mode 160000 index 000000000..8e1f440fa --- /dev/null +++ b/tools/linkermap @@ -0,0 +1 @@ +Subproject commit 8e1f440fa15c567aceb5aa0d14f6d18c329cc67f diff --git a/tools/uf2 b/tools/uf2 new file mode 160000 index 000000000..c594542b2 --- /dev/null +++ b/tools/uf2 @@ -0,0 +1 @@ +Subproject commit c594542b2faa01cc33a2b97c9fbebc38549df80a -- cgit v1.3.1 From 26ca4e232b44023cb470457bf1a889c8df4508db Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 5 Feb 2026 14:22:00 +0700 Subject: reverse pma size check to reduce duplication --- .idea/cmake.xml | 1 + src/portable/st/stm32_fsdev/fsdev_common.h | 22 ++++++++++------------ src/tusb_option.h | 10 +++++----- 3 files changed, 16 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/.idea/cmake.xml b/.idea/cmake.xml index cc73ca8fc..5f9e1acd2 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -131,6 +131,7 @@ + diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 442e738ae..b749a92ff 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -63,23 +63,21 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b // CFG_TUSB_FSDEV_PMA_SIZE is PMA buffer size in bytes. // - 512-byte devices, access with a stride of two words (use every other 16-bit address) -// - 1024-byte devices, access with a stride of one word (use every 16-bit address) +// - 1024-byte devices, access with a stride of one word (use every 16-bit address) or 32-bit address // - 2048-byte devices, access with 32-bit address - -// For purposes of accessing the packet -#if CFG_TUSB_FSDEV_PMA_SIZE == 512 - // 1x16 bit / word access scheme - #define FSDEV_PMA_STRIDE 2 - #define pma_access_scheme TU_ATTR_ALIGNED(4) -#elif CFG_TUSB_FSDEV_PMA_SIZE == 1024 && CFG_TUSB_MCU != OPT_MCU_STM32U0 - // 2x16 bit / word access scheme - #define FSDEV_PMA_STRIDE 1 - #define pma_access_scheme -#elif CFG_TUSB_FSDEV_PMA_SIZE == 2048 || CFG_TUSB_MCU == OPT_MCU_STM32U0 +#if CFG_TUSB_FSDEV_PMA_SIZE == 2048 || TU_CHECK_MCU(OPT_MCU_STM32U0) // 32 bit access scheme #define FSDEV_BUS_32BIT #define FSDEV_PMA_STRIDE 1 #define pma_access_scheme +#elif CFG_TUSB_FSDEV_PMA_SIZE == 1024 + // 2x16 bit / word access scheme + #define FSDEV_PMA_STRIDE 1 + #define pma_access_scheme +#elif CFG_TUSB_FSDEV_PMA_SIZE == 512 + // 1x16 bit / word access scheme + #define FSDEV_PMA_STRIDE 2 + #define pma_access_scheme TU_ATTR_ALIGNED(4) #endif // The fsdev_bus_t type can be used for both register and PMA access necessities diff --git a/src/tusb_option.h b/src/tusb_option.h index 1b65cc5aa..bbef13344 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -340,14 +340,14 @@ #if defined(TUP_USBIP_FSDEV) #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 - #if CFG_TUSB_FSDEV_PMA_SIZE == 512 - #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 2 // 16-bit data + #if CFG_TUSB_FSDEV_PMA_SIZE == 2048 || TU_CHECK_MCU(OPT_MCU_STM32U0) + #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4 // 32-bit data #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 4 // 32-bit address increase - #elif CFG_TUSB_FSDEV_PMA_SIZE == 1024 && CFG_TUSB_MCU != OPT_MCU_STM32U0 + #elif CFG_TUSB_FSDEV_PMA_SIZE == 1024 #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 2 // 16-bit data #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 2 // 16-bit address increase - #elif CFG_TUSB_FSDEV_PMA_SIZE == 2048 || CFG_TUSB_MCU == OPT_MCU_STM32U0 - #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4 // 32-bit data + #elif CFG_TUSB_FSDEV_PMA_SIZE == 512 + #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 2 // 16-bit data #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 4 // 32-bit address increase #endif #endif -- cgit v1.3.1 From 9f1d86c2e30b318eb78cb8c0c976793a7812cd34 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 6 Feb 2026 23:56:30 +0700 Subject: adjust handle_xfer_in logic to simplify ZLP handling --- src/portable/mentor/musb/dcd_musb.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 9e6ee6f5d..d329285e9 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -189,14 +189,13 @@ static void process_setup_packet(uint8_t rhport) { } } -static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr, bool is_zlp) -{ +static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) { unsigned epnum = tu_edpt_number(ep_addr); unsigned epnum_minus1 = epnum - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; const unsigned rem = pipe->remaining; - if (!rem && !is_zlp) { + if (rem == 0 && pipe->length > 0) { pipe->buf = NULL; return true; } @@ -268,7 +267,7 @@ static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16 pipe->remaining = total_bytes; if (dir_in) { - handle_xfer_in(rhport, ep_addr, total_bytes == 0); + handle_xfer_in(rhport, ep_addr); } else { musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum); @@ -445,7 +444,7 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) ep_csr->tx_csrl &= ~(MUSB_TXCSRL1_STALLED | MUSB_TXCSRL1_UNDRN); return; } - completed = handle_xfer_in(rhport, ep_addr, false); + completed = handle_xfer_in(rhport, ep_addr); } else { // TU_LOG1(" RX CSRL%d = %x\r\n", epn, ep_csr->rx_csrl); if (ep_csr->rx_csrl & MUSB_RXCSRL1_STALLED) { -- cgit v1.3.1 From 25de49f8f6e8590eb548d4016e030d19166b9fb3 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 7 Feb 2026 18:01:23 +0700 Subject: minor update --- src/class/mtp/mtp_device.h | 2 +- src/class/video/video_device.h | 3 +-- tools/codespell/ignore-words.txt | 21 +++++++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/class/mtp/mtp_device.h b/src/class/mtp/mtp_device.h index a33f1dc08..6cce7efbb 100644 --- a/src/class/mtp/mtp_device.h +++ b/src/class/mtp/mtp_device.h @@ -18,7 +18,7 @@ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN0 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * This file is part of the TinyUSB stack. diff --git a/src/class/video/video_device.h b/src/class/video/video_device.h index f14555e4f..2750bb2fb 100644 --- a/src/class/video/video_device.h +++ b/src/class/video/video_device.h @@ -99,8 +99,7 @@ int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, * @param[in] stm_idx Destination streaming interface index * @param[out] payload_buf Payload storage buffer (target buffer for requested data) * @param[in] payload_size Size of payload_buf (requested data size) - * @param[in] offset Current byte offset relative to given bufsize from tud_video_n_frame_xfer (framesize) - * @return video_error_code_t */ + * @param[in] offset Current byte offset relative to given bufsize from tud_video_n_frame_xfer (framesize) */ void tud_video_prepare_payload_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, tud_video_payload_request_t* request); //--------------------------------------------------------------------+ diff --git a/tools/codespell/ignore-words.txt b/tools/codespell/ignore-words.txt index 957cbd86b..5b6e2e98b 100644 --- a/tools/codespell/ignore-words.txt +++ b/tools/codespell/ignore-words.txt @@ -1,14 +1,15 @@ -synopsys -sie -tre -thre -hsi -fro -dout -mot -te attch +busses +dout endianess +fro +hsi +inout +mot pris -busses ser +sie +synopsys +te +thre +tre -- cgit v1.3.1 From ebc9edfb7a512c8dd6816a40698c62c364bd78da Mon Sep 17 00:00:00 2001 From: Aleksei Musin Date: Mon, 9 Feb 2026 12:20:43 +0400 Subject: clean --- src/osal/osal_threadx.h | 48 ++++++++++++++---------------------------------- 1 file changed, 14 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/osal/osal_threadx.h b/src/osal/osal_threadx.h index 681aff772..4f05ef535 100644 --- a/src/osal/osal_threadx.h +++ b/src/osal/osal_threadx.h @@ -34,19 +34,6 @@ extern "C" { #endif -/* -typedef struct -{ - uint16_t depth; - uint16_t item_sz; - void* buf; - char const* name; - TX_QUEUE *queue; - -} osal_queue_def_t; - -typedef TX_QUEUE * osal_queue_t; -*/ //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ @@ -87,38 +74,38 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) { } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) { -// if (!in_isr) { -// ctx->interrupt_set(false); -// } + if (!in_isr) { + ctx->interrupt_set(false); + } } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) { -// if (!in_isr) { -// ctx->interrupt_set(true); -// } + if (!in_isr) { + ctx->interrupt_set(true); + } } //--------------------------------------------------------------------+ -// Binary Semaphore API +// Binary Semaphore API (act) //--------------------------------------------------------------------+ +// Note: semaphores are not used in tinyusb for now, and their API has not been tested + typedef TX_SEMAPHORE osal_semaphore_def_t, * osal_semaphore_t; -/* TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t *semdef) { tx_semaphore_create(semdef->semaphore, semdef->name, 0); return semdef; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { - (void) semd_hdl; - return true; // nothing to do +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t sem_hdl) { + (void) sem_hdl; + return TX_SUCCESS == tx_semaphore_delete(sem_hdl); } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; - tx_semaphore_put(sem_hdl); - return true; + return TX_SUCCESS == tx_semaphore_put(sem_hdl); } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { @@ -127,7 +114,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t se TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { } -*/ + //--------------------------------------------------------------------+ // MUTEX API //--------------------------------------------------------------------+ @@ -171,13 +158,6 @@ osal_queue_def_t _name = { \ .tx_queue_start = _name##_buf } -// Event queue: usbd_int_set() is used as mutex in OS NONE config -/* -OSAL_QUEUE_DEF(usbd_int_set, _usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t); -static osal_queue_t _usbd_q; -*/ - - TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { return TX_SUCCESS == tx_queue_create(qdef, qdef->tx_queue_name, qdef->tx_queue_message_size, qdef->tx_queue_start, qdef->tx_queue_capacity * qdef->tx_queue_message_size * 4) -- cgit v1.3.1 From 2f1b6296c6ea5506d8a8ff837a1cf8fbf8b1f9e0 Mon Sep 17 00:00:00 2001 From: Cédric Berger Date: Wed, 11 Feb 2026 15:04:04 +0100 Subject: Split functions calling tusb_time_delay_ms_api() --- src/host/usbh.c | 188 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 117 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/host/usbh.c b/src/host/usbh.c index 41f41dcfb..c61001dff 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -169,6 +169,9 @@ static OSAL_SPINLOCK_DEF(_usbh_spin, usbh_int_set); OSAL_QUEUE_DEF(usbh_int_set, _usbh_qdef, CFG_TUH_TASK_QUEUE_SZ, hcd_event_t); static osal_queue_t _usbh_q; +// Callback after waiting +typedef void (*usbh_wait_delay_cb)(void); + // Control transfers: since most controllers do not support multiple control transfers // on multiple devices concurrently and control transfers are not used much except for // enumeration, we will only execute control transfers one at a time. @@ -187,8 +190,10 @@ typedef struct { uint8_t controller_id; // controller ID uint8_t enumerating_daddr; // device address of the device being enumerated uint8_t attach_debouncing_bm; // bitmask for roothub port attach debouncing + uint8_t enum_failed_count; // see process_enumeration() tuh_bus_info_t dev0_bus; // bus info for dev0 in enumeration usbh_ctrl_xfer_info_t ctrl_xfer_info; // control transfer + tuh_xfer_t enum_xfer_retry; // enumeration transfer to retry } usbh_data_t; static usbh_data_t _usbh_data = { @@ -311,7 +316,7 @@ TU_ATTR_ALWAYS_INLINE static inline usbh_class_driver_t const *get_driver(uint8_ //--------------------------------------------------------------------+ // Function Inline and Prototypes //--------------------------------------------------------------------+ -static bool enum_new_device(hcd_event_t* event); +static void enum_new_device(hcd_event_t* event); static void process_remove_event(hcd_event_t *event); static void remove_device_tree(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port); static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size); @@ -349,6 +354,12 @@ TU_ATTR_ALWAYS_INLINE static inline bool usbh_setup_send(uint8_t daddr, const ui return ret; } +TU_ATTR_ALWAYS_INLINE static inline void usbh_wait_delay_ms(uint32_t delay_ms, usbh_wait_delay_cb complete_cb) +{ + tusb_time_delay_ms_api(delay_ms); + complete_cb(); +} + TU_ATTR_ALWAYS_INLINE static inline void usbh_device_close(uint8_t rhport, uint8_t daddr) { hcd_device_close(rhport, daddr); @@ -1449,16 +1460,29 @@ static bool enum_parse_configuration_desc (uint8_t dev_addr, tusb_desc_configura static void enum_full_complete(bool success); static void process_enumeration(tuh_xfer_t* xfer); +// continuation functions after waiting +static void enum_after_attempt_delay(void); +static void enum_after_debouncing_delay(void); +static void enum_after_reset_root_delay(void); +static void enum_after_reset_root_post_delay(void); +static void enum_after_reset_recovery_delay(void); +static void enum_after_set_address_recovery_delay(void); +#if CFG_TUH_HUB +static void enum_after_reset_hub_delay(void); +#endif + // start a new enumeration process -static bool enum_new_device(hcd_event_t* event) { +static void enum_new_device(hcd_event_t* event) { tuh_bus_info_t* dev0_bus = &_usbh_data.dev0_bus; dev0_bus->rhport = event->rhport; dev0_bus->hub_addr = event->connection.hub_addr; dev0_bus->hub_port = event->connection.hub_port; - // wait until device connection is stable TODO non blocking - tusb_time_delay_ms_api(ENUM_DEBOUNCING_DELAY_MS); + usbh_wait_delay_ms(ENUM_DEBOUNCING_DELAY_MS, enum_after_debouncing_delay); +} +static void enum_after_debouncing_delay(void) { + tuh_bus_info_t* dev0_bus = &_usbh_data.dev0_bus; if (dev0_bus->hub_addr == 0) { // connected directly to roothub // USB bus not active and frame number is not available yet. @@ -1469,68 +1493,72 @@ static bool enum_new_device(hcd_event_t* event) { if (!hcd_port_connect_status(dev0_bus->rhport)) { TU_LOG_USBH("Device unplugged while debouncing\r\n"); enum_full_complete(false); - return true; + return; } // reset device hcd_port_reset(dev0_bus->rhport); - tusb_time_delay_ms_api(ENUM_RESET_ROOT_DELAY_MS); - hcd_port_reset_end(dev0_bus->rhport); - tusb_time_delay_ms_api(ENUM_RESET_ROOT_POST_DELAY_MS); - - if (!hcd_port_connect_status(dev0_bus->rhport)) { - // device unplugged while delaying - enum_full_complete(false); - return true; - } - - dev0_bus->speed = hcd_port_speed_get(dev0_bus->rhport); - TU_LOG_USBH("%s Speed\r\n", tu_str_speed[dev0_bus->speed]); - - // fake transfer to kick-off the enumeration process - tuh_xfer_t xfer; - xfer.daddr = 0; - xfer.result = XFER_RESULT_SUCCESS; - xfer.user_data = ENUM_ADDR0_DEVICE_DESC; - process_enumeration(&xfer); + usbh_wait_delay_ms(ENUM_RESET_ROOT_DELAY_MS, enum_after_reset_root_delay); } #if CFG_TUH_HUB else { // connected via hub - TU_VERIFY(dev0_bus->hub_port != 0); + TU_VERIFY(dev0_bus->hub_port != 0,); TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, NULL, - process_enumeration, ENUM_HUB_RERSET)); + process_enumeration, ENUM_HUB_RERSET),); } #endif // hub +} - return true; +static void enum_after_reset_root_delay(void) { + tuh_bus_info_t* dev0_bus = &_usbh_data.dev0_bus; + hcd_port_reset_end(dev0_bus->rhport); + return usbh_wait_delay_ms(ENUM_RESET_ROOT_POST_DELAY_MS, enum_after_reset_root_post_delay); } +static void enum_after_reset_root_post_delay(void) { + tuh_bus_info_t* dev0_bus = &_usbh_data.dev0_bus; + if (!hcd_port_connect_status(dev0_bus->rhport)) { + // device unplugged while delaying + enum_full_complete(false); + return; + } + + dev0_bus->speed = hcd_port_speed_get(dev0_bus->rhport); + TU_LOG_USBH("%s Speed\r\n", tu_str_speed[dev0_bus->speed]); + + // fake transfer to kick-off the enumeration process + tuh_xfer_t xfer; + xfer.daddr = 0; + xfer.result = XFER_RESULT_SUCCESS; + xfer.user_data = ENUM_ADDR0_DEVICE_DESC; + process_enumeration(&xfer); +} + +enum { + ATTEMPT_COUNT_MAX = 3, + ATTEMPT_DELAY_MS = 100 +}; + // process device enumeration static void process_enumeration(tuh_xfer_t* xfer) { // Retry a few times while enumerating since device can be unstable when starting up - static uint8_t failed_count = 0; + _usbh_data.enum_failed_count = 0; if (XFER_RESULT_FAILED == xfer->result) { - enum { - ATTEMPT_COUNT_MAX = 3, - ATTEMPT_DELAY_MS = 100 - }; // retry if not reaching max attempt - failed_count++; - bool retry = (_usbh_data.enumerating_daddr != TUSB_INDEX_INVALID_8) && (failed_count < ATTEMPT_COUNT_MAX); + _usbh_data.enum_failed_count++; + bool retry = (_usbh_data.enumerating_daddr != TUSB_INDEX_INVALID_8) && (_usbh_data.enum_failed_count < ATTEMPT_COUNT_MAX); if (retry) { - tusb_time_delay_ms_api(ATTEMPT_DELAY_MS); // delay a bit - TU_LOG_USBH("Enumeration attempt %u/%u\r\n", failed_count+1, ATTEMPT_COUNT_MAX); - retry = tuh_control_xfer(xfer); - } - - if (!retry) { + // save transfer for later + _usbh_data.enum_xfer_retry = *xfer; + usbh_wait_delay_ms(ATTEMPT_DELAY_MS, enum_after_attempt_delay); // wait for reset to take effect + } else { enum_full_complete(false); // complete as failed } return; } - failed_count = 0; + _usbh_data.enum_failed_count = 0; uint8_t const daddr = xfer->daddr; uintptr_t const state = xfer->user_data; @@ -1558,10 +1586,7 @@ static void process_enumeration(tuh_xfer_t* xfer) { } case ENUM_HUB_GET_STATUS_AFTER_RESET: { - tusb_time_delay_ms_api(ENUM_RESET_HUB_DELAY_MS); // wait for reset to take effect - - // get status to check for reset change - TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, NULL, process_enumeration, ENUM_HUB_CLEAR_RESET),); + usbh_wait_delay_ms(ENUM_RESET_HUB_DELAY_MS, enum_after_reset_hub_delay); // wait for reset to take effect break; } @@ -1598,20 +1623,7 @@ static void process_enumeration(tuh_xfer_t* xfer) { #endif case ENUM_ADDR0_DEVICE_DESC: { - tusb_time_delay_ms_api(ENUM_RESET_RECOVERY_DELAY_MS); // reset recovery - - // TODO probably doesn't need to open/close each enumeration - uint8_t const addr0 = 0; - if (!usbh_edpt_control_open(addr0, 8)) { - // Stop enumeration gracefully - enum_full_complete(false); - TU_ASSERT(false,); - } - - // Get first 8 bytes of device descriptor for control endpoint size - TU_LOG_USBH("Get 8 byte of Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_epbuf.ctrl, 8, - process_enumeration, ENUM_SET_ADDR),); + usbh_wait_delay_ms(ENUM_RESET_RECOVERY_DELAY_MS, enum_after_reset_recovery_delay); break; } @@ -1630,8 +1642,6 @@ static void process_enumeration(tuh_xfer_t* xfer) { } case ENUM_GET_DEVICE_DESC: { - tusb_time_delay_ms_api(ENUM_SET_ADDRESS_RECOVERY_DELAY_MS); // set address recovery - const uint8_t new_addr = (uint8_t) tu_le16toh(xfer->setup->wValue); usbh_device_t* new_dev = get_device(new_addr); TU_ASSERT(new_dev,); @@ -1640,16 +1650,7 @@ static void process_enumeration(tuh_xfer_t* xfer) { usbh_device_close(dev0_bus->rhport, 0); // close dev0 - if (!usbh_edpt_control_open(new_addr, new_dev->bMaxPacketSize0)) { // open new control endpoint - // Stop enumeration gracefully - clear_device(new_dev); - enum_full_complete(false); - TU_ASSERT(false,); - } - - TU_LOG_USBH("Get Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_epbuf.ctrl, sizeof(tusb_desc_device_t), - process_enumeration, ENUM_GET_STRING_LANGUAGE_ID_LEN),); + usbh_wait_delay_ms(ENUM_SET_ADDRESS_RECOVERY_DELAY_MS, enum_after_set_address_recovery_delay); break; } @@ -1823,6 +1824,51 @@ static void process_enumeration(tuh_xfer_t* xfer) { } } +static void enum_after_attempt_delay(void) { + TU_LOG_USBH("Enumeration attempt %u/%u\r\n", _usbh_data.enum_failed_count+1, ATTEMPT_COUNT_MAX); + if (!tuh_control_xfer(&_usbh_data.enum_xfer_retry)) + enum_full_complete(false); // complete as failed +} + +static void enum_after_set_address_recovery_delay(void) { + const uint8_t new_addr =_usbh_data.enumerating_daddr; + usbh_device_t* new_dev = get_device(new_addr); + TU_ASSERT(new_dev,); + if (!usbh_edpt_control_open(new_addr, new_dev->bMaxPacketSize0)) { // open new control endpoint + // Stop enumeration gracefully + clear_device(new_dev); + enum_full_complete(false); + TU_ASSERT(false,); + } + + TU_LOG_USBH("Get Device Descriptor\r\n"); + TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_epbuf.ctrl, sizeof(tusb_desc_device_t), + process_enumeration, ENUM_GET_STRING_LANGUAGE_ID_LEN),); +} + +static void enum_after_reset_recovery_delay(void) { + // TODO probably doesn't need to open/close each enumeration + uint8_t const addr0 = 0; + if (!usbh_edpt_control_open(addr0, 8)) { + // Stop enumeration gracefully + enum_full_complete(false); + TU_ASSERT(false,); + } + + // Get first 8 bytes of device descriptor for control endpoint size + TU_LOG_USBH("Get 8 byte of Device Descriptor\r\n"); + TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_epbuf.ctrl, 8, + process_enumeration, ENUM_SET_ADDR),); +} + +#if CFG_TUH_HUB +static void enum_after_reset_hub_delay(void) { + tuh_bus_info_t* dev0_bus = &_usbh_data.dev0_bus; + // get status to check for reset change + TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, NULL, process_enumeration, ENUM_HUB_CLEAR_RESET),); +} +#endif + static uint8_t enum_get_new_address(bool is_hub) { uint8_t start; uint8_t end; -- cgit v1.3.1 From 2808b65a0eedf934b7c759b7de6f21636d377d14 Mon Sep 17 00:00:00 2001 From: Cédric Berger Date: Wed, 11 Feb 2026 15:05:25 +0100 Subject: Call continuation functions asynchronously --- src/host/usbh.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++------ src/tusb_option.h | 11 ++++++++++ 2 files changed, 67 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/host/usbh.c b/src/host/usbh.c index c61001dff..1b4963d3e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -193,7 +193,11 @@ typedef struct { uint8_t enum_failed_count; // see process_enumeration() tuh_bus_info_t dev0_bus; // bus info for dev0 in enumeration usbh_ctrl_xfer_info_t ctrl_xfer_info; // control transfer +#if CFG_TUH_TASK_USE_TIME_MILLIS_API tuh_xfer_t enum_xfer_retry; // enumeration transfer to retry + usbh_wait_delay_cb enum_wait_delay_cb; // continuation function after waiting + uint32_t enum_wait_deadline; // ticks when the timer expires +#endif } usbh_data_t; static usbh_data_t _usbh_data = { @@ -321,6 +325,7 @@ static void process_remove_event(hcd_event_t *event); static void remove_device_tree(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port); static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size); static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); +static void usbh_task_mq(uint32_t timeout_ms, bool in_isr); TU_ATTR_ALWAYS_INLINE static inline usbh_device_t* get_device(uint8_t dev_addr) { TU_VERIFY(dev_addr > 0 && dev_addr <= TOTAL_DEVICES, NULL); @@ -356,8 +361,15 @@ TU_ATTR_ALWAYS_INLINE static inline bool usbh_setup_send(uint8_t daddr, const ui TU_ATTR_ALWAYS_INLINE static inline void usbh_wait_delay_ms(uint32_t delay_ms, usbh_wait_delay_cb complete_cb) { +#if CFG_TUH_TASK_USE_TIME_MILLIS_API + TU_LOG_USBH("USBH start timer for %u ms\r\n", (unsigned int)delay_ms); + _usbh_data.enum_wait_deadline = tusb_time_millis_api() + delay_ms; + _usbh_data.enum_wait_delay_cb = complete_cb; +#else + TU_LOG_USBH("USBH sleep for %u ms\r\n", (unsigned int)delay_ms); tusb_time_delay_ms_api(delay_ms); complete_cb(); +#endif } TU_ATTR_ALWAYS_INLINE static inline void usbh_device_close(uint8_t rhport, uint8_t daddr) { @@ -371,6 +383,9 @@ TU_ATTR_ALWAYS_INLINE static inline void usbh_device_close(uint8_t rhport, uint8 // invalidate if enumerating if (daddr == _usbh_data.enumerating_daddr) { _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8; +#if CFG_TUH_TASK_USE_TIME_MILLIS_API + _usbh_data.enum_wait_delay_cb = NULL; +#endif } } @@ -519,6 +534,9 @@ bool tuh_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { _usbh_data.controller_id = TUSB_INDEX_INVALID_8; _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8; +#if CFG_TUH_TASK_USE_TIME_MILLIS_API + _usbh_data.enum_wait_delay_cb = NULL; +#endif for (uint8_t i = 0; i < TOTAL_DEVICES; i++) { clear_device(&_usbh_devices[i]); @@ -603,13 +621,35 @@ bool tuh_task_event_ready(void) { @endcode */ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { - (void) in_isr; // not implemented yet - // Skip if stack is not initialized if (!tuh_inited()) { return; } +#if CFG_TUH_TASK_USE_TIME_MILLIS_API + // Process continuation function if timer is expired + usbh_wait_delay_cb delay_cb = _usbh_data.enum_wait_delay_cb; + if (delay_cb) { + int32_t ms = (int32_t)(_usbh_data.enum_wait_deadline - tusb_time_millis_api()); + if (ms <= 0) { + // delay expired, run callback now + TU_LOG_USBH("USBH run timer callback\r\n"); + _usbh_data.enum_wait_delay_cb = NULL; + delay_cb(); + } else if (timeout_ms > (uint32_t)ms) { + // reduce timeout accordingly + timeout_ms = (uint32_t)ms; + } + } +#endif + + // Process the message queue + usbh_task_mq(timeout_ms, in_isr); +} + +static void usbh_task_mq(uint32_t timeout_ms, bool in_isr) { + (void) in_isr; // not implemented yet + // Loop until there are no more events in the queue or CFG_TUH_TASK_EVENTS_PER_RUN is reached for (unsigned epr = 0;; epr++) { #if CFG_TUH_TASK_EVENTS_PER_RUN > 0 @@ -781,10 +821,8 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) { while (result == XFER_RESULT_INVALID) { // Note: this can be called within an callback ie. part of tuh_task() - // therefore event with RTOS tuh_task() still need to be invoked - if (tuh_task_event_ready()) { - tuh_task(); - } + // therefore even with RTOS usbh_task_mq() still need to be invoked + usbh_task_mq(0, false); // TODO probably some timeout to prevent hanged } @@ -1461,7 +1499,9 @@ static void enum_full_complete(bool success); static void process_enumeration(tuh_xfer_t* xfer); // continuation functions after waiting +#if CFG_TUH_TASK_USE_TIME_MILLIS_API static void enum_after_attempt_delay(void); +#endif static void enum_after_debouncing_delay(void); static void enum_after_reset_root_delay(void); static void enum_after_reset_root_post_delay(void); @@ -1550,9 +1590,14 @@ static void process_enumeration(tuh_xfer_t* xfer) { _usbh_data.enum_failed_count++; bool retry = (_usbh_data.enumerating_daddr != TUSB_INDEX_INVALID_8) && (_usbh_data.enum_failed_count < ATTEMPT_COUNT_MAX); if (retry) { +#if CFG_TUH_TASK_USE_TIME_MILLIS_API // save transfer for later _usbh_data.enum_xfer_retry = *xfer; usbh_wait_delay_ms(ATTEMPT_DELAY_MS, enum_after_attempt_delay); // wait for reset to take effect +#else + if (!tuh_control_xfer(xfer)) + enum_full_complete(false); // complete as failed +#endif } else { enum_full_complete(false); // complete as failed } @@ -1824,11 +1869,13 @@ static void process_enumeration(tuh_xfer_t* xfer) { } } +#if CFG_TUH_TASK_USE_TIME_MILLIS_API static void enum_after_attempt_delay(void) { TU_LOG_USBH("Enumeration attempt %u/%u\r\n", _usbh_data.enum_failed_count+1, ATTEMPT_COUNT_MAX); if (!tuh_control_xfer(&_usbh_data.enum_xfer_retry)) enum_full_complete(false); // complete as failed } +#endif static void enum_after_set_address_recovery_delay(void) { const uint8_t new_addr =_usbh_data.enumerating_daddr; @@ -1982,6 +2029,9 @@ static void enum_full_complete(bool success) { (void)success; // mark enumeration as complete _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8; +#if CFG_TUH_TASK_USE_TIME_MILLIS_API + _usbh_data.enum_wait_delay_cb = NULL; +#endif #if CFG_TUH_HUB // Hub status is already requested in case of successful enumeration diff --git a/src/tusb_option.h b/src/tusb_option.h index 8e270e5f2..4717846c6 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -689,6 +689,17 @@ #define CFG_TUH_TASK_EVENTS_PER_RUN 16 #endif +// use tusb_time_millis_api() instead of tusb_time_delay_ms_api() in tuh_task() +// tuh_task_ext() will be asynchronous and never sleep in tusb_time_delay_ms_api() +#ifndef CFG_TUH_TASK_USE_TIME_MILLIS_API + #if CFG_TUSB_OS == OPT_OS_RTX4 || CFG_TUSB_OS == OPT_OS_PICO || defined(ESP_PLATFORM) + // these boards/os do not implements the required tusb_time_millis_api() + #define CFG_TUH_TASK_USE_TIME_MILLIS_API 0 + #else + #define CFG_TUH_TASK_USE_TIME_MILLIS_API 1 + #endif +#endif + //------------- CLASS -------------// #ifndef CFG_TUH_HUB -- cgit v1.3.1 From 90d0514630d9b0f6d50881aabd82dcd613141f6b Mon Sep 17 00:00:00 2001 From: Cédric Berger Date: Wed, 11 Feb 2026 15:06:27 +0100 Subject: Put deferred attachments in a separate queue --- src/host/usbh.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/host/usbh.c b/src/host/usbh.c index 1b4963d3e..ae337d867 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -169,6 +169,12 @@ static OSAL_SPINLOCK_DEF(_usbh_spin, usbh_int_set); OSAL_QUEUE_DEF(usbh_int_set, _usbh_qdef, CFG_TUH_TASK_QUEUE_SZ, hcd_event_t); static osal_queue_t _usbh_q; +#if CFG_TUH_HUB +// Deferred attachment queue +OSAL_QUEUE_DEF(usbh_int_set, _usbh_daqdef, TOTAL_DEVICES, hcd_event_t); +static osal_queue_t _usbh_daq; +#endif + // Callback after waiting typedef void (*usbh_wait_delay_cb)(void); @@ -519,6 +525,12 @@ bool tuh_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { _usbh_q = osal_queue_create(&_usbh_qdef); TU_ASSERT(_usbh_q != NULL); +#if CFG_TUH_HUB + // Deferred attachment queue + _usbh_daq = osal_queue_create(&_usbh_daqdef); + TU_ASSERT(_usbh_daq != NULL); +#endif + #if OSAL_MUTEX_REQUIRED // Init mutex _usbh_mutex = osal_mutex_create(&_usbh_mutexdef); @@ -587,11 +599,16 @@ bool tuh_deinit(uint8_t rhport) { osal_queue_delete(_usbh_q); _usbh_q = NULL; - #if OSAL_MUTEX_REQUIRED +#if CFG_TUH_HUB + osal_queue_delete(_usbh_daq); + _usbh_daq = NULL; +#endif + +#if OSAL_MUTEX_REQUIRED // TODO make sure there is no task waiting on this mutex osal_mutex_delete(_usbh_mutex); _usbh_mutex = NULL; - #endif +#endif } return true; @@ -643,6 +660,19 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { } #endif +#if CFG_TUH_HUB + // Process deferred device attachments + if (_usbh_data.enumerating_daddr == TUSB_INDEX_INVALID_8) { + hcd_event_t event; + if (osal_queue_receive(_usbh_daq, &event, 0)) { + // We are ready to process a new attachment + TU_LOG_USBH("[%u:] USBH Deferred Device Attach\r\n", event.rhport); + _usbh_data.enumerating_daddr = 0; // enumerate new device with address 0 + enum_new_device(&event); + } + } +#endif + // Process the message queue usbh_task_mq(timeout_ms, in_isr); } @@ -669,20 +699,17 @@ static void usbh_task_mq(uint32_t timeout_ms, bool in_isr) { process_remove_event(&event); // due to the shared control buffer, we must fully complete enumerating one device first. - // TODO better to have an separated queue for newly attached devices if (_usbh_data.enumerating_daddr == TUSB_INDEX_INVALID_8) { // New device attached and we are ready TU_LOG_USBH("[%u:] USBH Device Attach\r\n", event.rhport); _usbh_data.enumerating_daddr = 0; // enumerate new device with address 0 enum_new_device(&event); +#if CFG_TUH_HUB } else { // currently enumerating another device TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport); - const bool is_empty = osal_queue_empty(_usbh_q); - queue_event(&event, in_isr); - if (is_empty) { - return; // Exit if this is the only event in the queue, otherwise we loop forever - } + TU_ASSERT(osal_queue_send(_usbh_daq, &event, in_isr),); +#endif } break; -- cgit v1.3.1 From 1586e80ffe7e3610f999208ddf25a6803b58e22e Mon Sep 17 00:00:00 2001 From: Cédric Berger Date: Wed, 11 Feb 2026 15:25:48 +0100 Subject: Introduce CFG_TUSB_DEBUG_BREAKPOINT hook --- src/common/tusb_verify.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index c9e06361c..931a53be7 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -73,8 +73,12 @@ #define TU_MESS_FAILED() do {} while (0) #endif + // Custom defined application function +#ifdef CFG_TUSB_DEBUG_BREAKPOINT +#define TU_BREAKPOINT() do { void CFG_TUSB_DEBUG_BREAKPOINT(void); CFG_TUSB_DEBUG_BREAKPOINT(); } while (0) + // Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7, M33. M55 -#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__) || \ +#elif defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__) || \ defined(__ARM7M__) || defined (__ARM7EM__) || defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) #define TU_BREAKPOINT() do { \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ -- cgit v1.3.1 From 75adb35f35acb6084fc053b468725070f5c662ec Mon Sep 17 00:00:00 2001 From: Cédric Berger Date: Wed, 11 Feb 2026 16:23:11 +0100 Subject: Update tusb_verify.h --- src/common/tusb_verify.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index 931a53be7..bd00b9d11 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -73,9 +73,10 @@ #define TU_MESS_FAILED() do {} while (0) #endif - // Custom defined application function +// Custom defined application function #ifdef CFG_TUSB_DEBUG_BREAKPOINT -#define TU_BREAKPOINT() do { void CFG_TUSB_DEBUG_BREAKPOINT(void); CFG_TUSB_DEBUG_BREAKPOINT(); } while (0) + extern void CFG_TUSB_DEBUG_BREAKPOINT(void); + #define TU_BREAKPOINT() CFG_TUSB_DEBUG_BREAKPOINT() // Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7, M33. M55 #elif defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__) || \ -- cgit v1.3.1 From b5c84aa140773009926fce97e207075fb11682ed Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 11 Feb 2026 23:44:39 +0700 Subject: device/msc: only defer prepare_cbw() from STATUS_SENT when EP OUT stalled --- src/class/msc/msc_device.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index be40c37e7..3766e3a25 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -121,12 +121,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool send_csw(mscd_interface_t* p_msc) { TU_ATTR_ALWAYS_INLINE static inline bool prepare_cbw(mscd_interface_t* p_msc) { uint8_t rhport = p_msc->rhport; p_msc->stage = MSC_STAGE_CMD; - // Skip command stage until Clear Stall request if endpoint is stalled - if (!usbd_edpt_stalled(rhport, p_msc->ep_out)) { - return usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_epbuf.buf, sizeof(msc_cbw_t), false); - } else { - return true; - } + return usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_epbuf.buf, sizeof(msc_cbw_t), false); } static void fail_scsi_op(mscd_interface_t* p_msc, uint8_t status) { @@ -651,7 +646,11 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t break; } - TU_ASSERT(prepare_cbw(p_msc)); + if (!usbd_edpt_stalled(rhport, p_msc->ep_out)) { + TU_ASSERT(prepare_cbw(p_msc)); + } else { + p_msc->stage = MSC_STAGE_CMD; + } } else { // Any xfer ended here is considered unknown error, ignore it TU_LOG1(" Warning expect SCSI Status but received unknown data\r\n"); -- cgit v1.3.1 From 8f14cf4bfa061690084c7c32b3f8b70301f5e0ff Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 Feb 2026 19:45:09 +0700 Subject: add CFG_TUD_VBUS_SENSE, that could allow to skip tud_configure() for fixed vbus sensing simplify dwc2_stm32_gccfg_cfg() using guid value --- .../stm32h7rs/boards/stm32h7s3nucleo/board.cmake | 2 + hw/bsp/stm32h7rs/family.cmake | 2 +- src/device/usbd.h | 2 + src/portable/synopsys/dwc2/dcd_dwc2.c | 15 ++- src/portable/synopsys/dwc2/dwc2_info.md | 116 ++++++++-------- src/portable/synopsys/dwc2/dwc2_info.py | 10 +- src/portable/synopsys/dwc2/dwc2_stm32.h | 146 ++++++--------------- src/portable/synopsys/dwc2/dwc2_type.h | 9 +- src/tusb_option.h | 11 +- 9 files changed, 131 insertions(+), 182 deletions(-) (limited to 'src') diff --git a/hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/board.cmake b/hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/board.cmake index 7b3456585..189c175dd 100644 --- a/hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/board.cmake +++ b/hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/board.cmake @@ -2,6 +2,8 @@ set(MCU_VARIANT stm32h7s3xx) set(JLINK_DEVICE stm32h7s3l8) set(LD_FILE_Clang ${LD_FILE_GNU}) +set(RHPORT_DEVICE 1) +set(RHPORT_HOST 1) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC diff --git a/hw/bsp/stm32h7rs/family.cmake b/hw/bsp/stm32h7rs/family.cmake index 1fd1cb057..3b9dbf5cf 100644 --- a/hw/bsp/stm32h7rs/family.cmake +++ b/hw/bsp/stm32h7rs/family.cmake @@ -24,7 +24,7 @@ if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 1) endif () if (NOT DEFINED RHPORT_HOST) - set(RHPORT_HOST 1) + set(RHPORT_HOST 0) endif () if (NOT DEFINED RHPORT_SPEED) diff --git a/src/device/usbd.h b/src/device/usbd.h index 7d7604c81..eaf07b81e 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -44,6 +44,8 @@ typedef struct { bool vbus_sensing; // Vbus pin is used for device connection detection, mandatory for tud_umount_cb() } tud_configure_dwc2_t; +#define TUD_CONFIGURE_DWC2_DEFAULT { .bm_double_buffered = 0, .vbus_sensing = CFG_TUD_VBUS_SENSE } + typedef union { tud_configure_dwc2_t dwc2; } tud_configure_param_t; diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 36cb763aa..a6a598dbf 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -77,10 +77,7 @@ CFG_TUD_MEM_SECTION static struct { TUD_EPBUF_DEF(setup_packet, 8); } _dcd_usbbuf; -static tud_configure_dwc2_t _tud_cfg = { - .bm_double_buffered = 0, - .vbus_sensing = false -}; +static tud_configure_dwc2_t _tud_cfg = TUD_CONFIGURE_DWC2_DEFAULT; TU_ATTR_ALWAYS_INLINE static inline uint8_t dwc2_ep_count(const dwc2_regs_t* dwc2) { #if TU_CHECK_MCU(OPT_MCU_GD32VF103) @@ -473,10 +470,14 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { // Force device mode dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_FHMOD) | GUSBCFG_FDMOD; - // Clear A override, force B Valid if Vbus sensing is not used - dwc2->gotgctl = (dwc2->gotgctl & ~GOTGCTL_AVALOEN) | (_tud_cfg.vbus_sensing ? 0 : GOTGCTL_BVALOEN | GOTGCTL_BVALOVAL); + // OTG Ctrl + uint32_t gotgctl = dwc2->gotgctl & ~GOTGCTL_AVALOEN; // Clear A-override + if (!_tud_cfg.vbus_sensing) { + gotgctl |= GOTGCTL_BVALOEN | GOTGCTL_BVALOVAL; // force B Valid if not sensing VBus + } + dwc2->gotgctl = gotgctl; -#ifdef TUP_USBIP_DWC2_STM32 + #ifdef TUP_USBIP_DWC2_STM32 dwc2_stm32_gccfg_cfg(dwc2, _tud_cfg.vbus_sensing, false); #endif diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md index f655e4dba..f83007b8c 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.md +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -1,58 +1,58 @@ -| | AT32 F405 FS | AT32 F405 HS | AT32 F415 | BCM2711 (Pi4) | EFM32GG | ESP32-S2/S3 | ESP32-P4 | nRF54 | ST F207/F407/411/429 FS | ST F407/429 HS | ST F412/76x FS | ST F723/L4P5 FS | ST F723 HS | ST F76x HS | ST H743/H750 | ST L476 FS | ST U5A5/H7RS/N6 HS | XMC4500 | GD32VF103 | -|:---------------------------|:---------------|:---------------|:------------|:----------------|:-------------|:--------------|:-------------|:-------------|:--------------------------|:-----------------|:-----------------|:------------------|:-------------|:-------------|:---------------|:-------------|:---------------------|:-------------|:------------| -| GUID | 0x00002000 | 0x00000000 | 0x00001000 | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00AEC000 | 0x00001000 | -| GSNPSID | 0x4F54400A | 0x4F54400A | 0x4F54400A | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54430A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x4F54292A | 0x00000000 | -| - specs version | 4.00a | 4.00a | 4.00a | 2.80a | 3.30a | 4.00a | 4.00a | 4.30a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 2.92a | 0.00W | -| GHWCFG1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0xAA555000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | -| GHWCFG2 | 0x228FDD00 | 0x229FDDD0 | 0x228DCD00 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x228BFC72 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x228F5930 | 0x00000000 | -| - op_mode | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | -| - arch | Slave only | DMA internal | Slave only | DMA internal | DMA internal | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | Slave only | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | DMA internal | Slave only | -| - single_point | hub | hub | hub | hub | hub | n/a | hub | n/a | n/a | hub | n/a | n/a | hub | hub | hub | n/a | hub | n/a | hub | -| - hs_phy_type | n/a | UTMI+/ULPI | n/a | UTMI+ | n/a | n/a | UTMI+/ULPI | UTMI+ | n/a | ULPI | n/a | n/a | UTMI+/ULPI | ULPI | ULPI | n/a | UTMI+ | n/a | n/a | -| - fs_phy_type | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Shared ULPI | n/a | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | n/a | Dedicated | n/a | -| - num_dev_ep | 7 | 7 | 3 | 7 | 6 | 6 | 15 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 6 | 0 | -| - num_host_ch | 15 | 15 | 7 | 7 | 13 | 7 | 15 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 15 | 11 | 15 | 13 | 0 | -| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - mul_proc_intrpt | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - nptx_q_depth | 8 | 8 | 8 | 8 | 8 | 4 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | -| - ptx_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | -| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | -| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| GHWCFG3 | 0x020004E8 | 0x03F006E8 | 0x020004E8 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x0BEAC0E8 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x027A01E5 | 0x00000000 | -| - xfer_size_width | 8 | 8 | 8 | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 5 | 0 | -| - packet_size_width | 6 | 6 | 6 | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | -| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - i2c_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | -| - vendor_ctrl_itf | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | -| - optional_feature_removed | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | -| - dfifo_depth | 512 | 1008 | 512 | 4080 | 498 | 200 | 896 | 3050 | 512 | 1012 | 512 | 512 | 1006 | 1006 | 952 | 512 | 952 | 634 | 0 | -| GHWCFG4 | 0x1FF0A020 | 0x1FF0A020 | 0x0000000F | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x1E10AA60 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0xDBF08030 | 0x00000000 | -| - num_dev_period_in_ep | 0 | 0 | 15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - partial_powerdown | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - ahb_freq_min | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - enhanced_lpm_support | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - phy_data_width | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8 bit | 8/16 bit | 8 bit | 8/16 bit | 8 bit | -| - ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - iddg_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - vbus_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | -| - a_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | -| - b_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | -| - session_end_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | -| - dedicated_fifos | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - num_dev_in_eps | 7 | 7 | 0 | 7 | 6 | 4 | 7 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 6 | 0 | -| - dma_desc_enable | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | -| - dma_desc_dynamic | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | +| | AT32 F405 FS | AT32 F405 HS | AT32 F415 | BCM2711 (Pi4) | EFM32GG | ESP32-S2/S3 | ESP32-P4 | nRF54 | ST F407/429 HS | ST F207/F407/411/429 FS | ST L476 FS | ST F412/76x FS | ST F76x HS | ST H743/H750 | ST F723/L4P5 FS | ST F723 HS | ST H7RS FS | ST U5A5/H7RS/N6 HS | XMC4500 | GD32VF103 | +|:---------------------------|:---------------|:---------------|:------------|:----------------|:-------------|:--------------|:-------------|:-------------|:-----------------|:--------------------------|:-------------|:-----------------|:-------------|:---------------|:------------------|:-------------|:-------------|:---------------------|:-------------|:------------| +| GUID | 0x00002000 | 0x00000000 | 0x00001000 | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001100 | 0x00001200 | 0x00002000 | 0x00002000 | 0x00002100 | 0x00002300 | 0x00003000 | 0x00003100 | 0x00004000 | 0x00005000 | 0x00AEC000 | 0x00001000 | +| GSNPSID | 0x4F54400A | 0x4F54400A | 0x4F54400A | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54430A | 0x4F54281A | 0x4F54281A | 0x4F54310A | 0x4F54320A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54330A | 0x4F54411A | 0x4F54411A | 0x4F54292A | 0x00000000 | +| - specs version | 4.00a | 4.00a | 4.00a | 2.80a | 3.30a | 4.00a | 4.00a | 4.30a | 2.81a | 2.81a | 3.10a | 3.20a | 3.20a | 3.30a | 3.30a | 3.30a | 4.11a | 4.11a | 2.92a | 0.00W | +| GHWCFG1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0xAA555000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| GHWCFG2 | 0x228FDD00 | 0x229FDDD0 | 0x228DCD00 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x228BFC72 | 0x229ED590 | 0x229DCD20 | 0x229ED520 | 0x229ED520 | 0x229FE190 | 0x229FE190 | 0x229ED520 | 0x229FE1D0 | 0x229ED522 | 0x228FE052 | 0x228F5930 | 0x00000000 | +| - op_mode | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | noHNP noSRP | HNP SRP | HNP SRP | +| - arch | Slave only | DMA internal | Slave only | DMA internal | DMA internal | DMA internal | DMA internal | DMA internal | DMA internal | Slave only | Slave only | Slave only | DMA internal | DMA internal | Slave only | DMA internal | Slave only | DMA internal | DMA internal | Slave only | +| - single_point | hub | hub | hub | hub | hub | n/a | hub | n/a | hub | n/a | n/a | n/a | hub | hub | n/a | hub | n/a | hub | n/a | hub | +| - hs_phy_type | n/a | UTMI+/ULPI | n/a | UTMI+ | n/a | n/a | UTMI+/ULPI | UTMI+ | ULPI | n/a | n/a | n/a | ULPI | ULPI | n/a | UTMI+/ULPI | n/a | UTMI+ | n/a | n/a | +| - fs_phy_type | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Shared ULPI | n/a | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | n/a | Dedicated | n/a | +| - num_dev_ep | 7 | 7 | 3 | 7 | 6 | 6 | 15 | 15 | 5 | 3 | 5 | 5 | 8 | 8 | 5 | 8 | 5 | 8 | 6 | 0 | +| - num_host_ch | 15 | 15 | 7 | 7 | 13 | 7 | 15 | 15 | 11 | 7 | 11 | 11 | 15 | 15 | 11 | 15 | 11 | 15 | 13 | 0 | +| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - mul_proc_intrpt | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - nptx_q_depth | 8 | 8 | 8 | 8 | 8 | 4 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | +| - ptx_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | +| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | +| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| GHWCFG3 | 0x020004E8 | 0x03F006E8 | 0x020004E8 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x0BEAC0E8 | 0x03F403E8 | 0x020001E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03EED2E8 | 0x020081E8 | 0x03B882E8 | 0x027A01E5 | 0x00000000 | +| - xfer_size_width | 8 | 8 | 8 | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 5 | 0 | +| - packet_size_width | 6 | 6 | 6 | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | +| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - i2c_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | +| - vendor_ctrl_itf | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | +| - optional_feature_removed | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | +| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | +| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | +| - dfifo_depth | 512 | 1008 | 512 | 4080 | 498 | 200 | 896 | 3050 | 1012 | 512 | 512 | 512 | 1006 | 952 | 512 | 1006 | 512 | 952 | 634 | 0 | +| GHWCFG4 | 0x1FF0A020 | 0x1FF0A020 | 0x0000000F | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x1E10AA60 | 0x17F00030 | 0x0FF08030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0x23F00030 | 0x1610B230 | 0xE2103E30 | 0xDBF08030 | 0x00000000 | +| - num_dev_period_in_ep | 0 | 0 | 15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - partial_powerdown | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - ahb_freq_min | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | +| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | +| - enhanced_lpm_support | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | +| - phy_data_width | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8/16 bit | 8 bit | 8/16 bit | 8 bit | 8/16 bit | 8 bit | +| - ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - iddg_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - vbus_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | +| - a_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | +| - b_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | +| - session_end_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | +| - dedicated_fifos | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - num_dev_in_eps | 7 | 7 | 0 | 7 | 6 | 4 | 7 | 7 | 5 | 3 | 5 | 5 | 8 | 8 | 5 | 8 | 5 | 8 | 6 | 0 | +| - dma_desc_enable | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | +| - dma_desc_dynamic | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py index 8fbbc00a0..e6601f482 100755 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -16,14 +16,16 @@ dwc2_reg_value = { 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0x0C804B5, 0xD3F0A030], 'ESP32-P4': [0, 0x4F54400A, 0, 0x215FFFD0, 0x03805EB5, 0xDFF1A030], 'nRF54': [0, 0x4F54430A, 0xAA555000, 0x228BFC72, 0x0BEAC0E8, 0x1E10AA60], - 'ST F207/F407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x020001E8, 0x0FF08030], + # ST sort by GUID 'ST F407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x03F403E8, 0x17F00030], + 'ST F207/F407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x020001E8, 0x0FF08030], + 'ST L476 FS': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030], 'ST F412/76x FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030], - 'ST F723/L4P5 FS': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030], - 'ST F723 HS': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x03EED2E8, 0x23F00030], 'ST F76x HS': [0x2100, 0x4F54320A, 0, 0x229FE190, 0x03EED2E8, 0x23F00030], 'ST H743/H750': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x03B8D2E8, 0xE3F00030], - 'ST L476 FS': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030], + 'ST F723/L4P5 FS': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030], + 'ST F723 HS': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x03EED2E8, 0x23F00030], + 'ST H7RS FS': [0x4000, 0x4F54411A, 0, 0x229ED522, 0x20081E8, 0x1610B230], 'ST U5A5/H7RS/N6 HS': [0x5000, 0x4F54411A, 0, 0x228FE052, 0x03B882E8, 0xE2103E30], 'XMC4500': [0xAEC000, 0x4F54292A, 0, 0x228F5930, 0x027A01E5, 0xDBF08030], 'GD32VF103': [0x1000, 0, 0, 0, 0, 0], diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 3da78b893..753917a20 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -308,129 +308,59 @@ static inline void dwc2_stm32_gccfg_cfg(dwc2_regs_t* dwc2, bool vbus_sensing, bo if (is_host) { vbus_sensing = false; } -#if CFG_TUSB_MCU == OPT_MCU_STM32F1 - // F1: Basic FS-only core, no VBUS sensing support - // Only PWRDWN bit is used (set in dwc2_phy_init) - (void) vbus_sensing; - -#elif CFG_TUSB_MCU == OPT_MCU_STM32F2 || CFG_TUSB_MCU == OPT_MCU_STM32F4 - // F2/F4: Dual FS/HS with VBUSBSEN/VBUSASEN/NOVBUSSENS bits - if (is_host) { - dwc2->stm32_gccfg &= ~(STM32_GCCFG_NOVBUSSENS | STM32_GCCFG_VBUSBSEN | STM32_GCCFG_VBUSASEN); - } else { - if (vbus_sensing) { - dwc2->stm32_gccfg &= ~STM32_GCCFG_NOVBUSSENS; - dwc2->stm32_gccfg |= STM32_GCCFG_VBUSBSEN; - } else { - dwc2->stm32_gccfg |= STM32_GCCFG_NOVBUSSENS; - dwc2->stm32_gccfg &= ~STM32_GCCFG_VBUSBSEN; - dwc2->stm32_gccfg &= ~STM32_GCCFG_VBUSASEN; - } - } -#elif CFG_TUSB_MCU == OPT_MCU_STM32F7 - // F7: Enhanced FS/HS with battery charging detection - if (vbus_sensing) { - dwc2->stm32_gccfg |= STM32_GCCFG_VBDEN; - } else { - dwc2->stm32_gccfg &= ~STM32_GCCFG_VBDEN; - } -#elif CFG_TUSB_MCU == OPT_MCU_STM32H7 - if (vbus_sensing) { - dwc2->stm32_gccfg |= STM32_GCCFG_VBDEN; - } else { - dwc2->stm32_gccfg &= ~STM32_GCCFG_VBDEN; - } - -#elif CFG_TUSB_MCU == OPT_MCU_STM32H7RS - // H7FS: Port0: Basic FS-only core; Port1: femtoPHY - if ((uintptr_t)dwc2 == _dwc2_controller[0].reg_base) { - if (vbus_sensing) { - dwc2->stm32_gccfg |= STM32_GCCFG_VBDEN; - } else { - dwc2->stm32_gccfg &= ~STM32_GCCFG_VBDEN; - } - return; - } else { - // Uses VBVALEXTOEN and VBVALOVAL for external VBUS sensing override + uint32_t gccfg = dwc2->stm32_gccfg; + if (dwc2->guid < 0x2000) { + // use VBUSASEN/VBUSBSEN/NOVBUSSENS bits if (is_host) { - dwc2->stm32_gccfg |= STM32_GCCFG_PULLDOWNEN; - dwc2->stm32_gccfg &= ~(STM32_GCCFG_VBDEN | STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL); + gccfg &= ~(STM32_GCCFG_NOVBUSSENS | STM32_GCCFG_VBUSBSEN | STM32_GCCFG_VBUSASEN); } else { - dwc2->stm32_gccfg &= ~STM32_GCCFG_PULLDOWNEN; if (vbus_sensing) { - dwc2->stm32_gccfg |= STM32_GCCFG_VBDEN; - dwc2->stm32_gccfg &= ~(STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL); + gccfg &= ~STM32_GCCFG_NOVBUSSENS; + gccfg |= STM32_GCCFG_VBUSBSEN; } else { - dwc2->stm32_gccfg &= ~STM32_GCCFG_VBDEN; - dwc2->stm32_gccfg |= STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL; + gccfg |= STM32_GCCFG_NOVBUSSENS; + gccfg &= ~(STM32_GCCFG_VBUSBSEN | STM32_GCCFG_VBUSASEN); } } - } - -#elif CFG_TUSB_MCU == OPT_MCU_STM32N6 - // N6: femtoPHY - // In this device, the software override is always active - (void) vbus_sensing; - if (is_host) { - dwc2->stm32_gccfg |= STM32_GCCFG_PULLDOWNEN; - dwc2->stm32_gccfg &= ~(STM32_GCCFG_VBVALOVAL); - } else { - dwc2->stm32_gccfg &= ~STM32_GCCFG_PULLDOWNEN; - dwc2->stm32_gccfg |= STM32_GCCFG_VBVALOVAL; - } - -#elif CFG_TUSB_MCU == OPT_MCU_STM32L4 - // L4: Low-power FS-only with VBUS detection - if (vbus_sensing) { - dwc2->stm32_gccfg |= STM32_GCCFG_VBDEN; - } else { - dwc2->stm32_gccfg &= ~STM32_GCCFG_VBDEN; - } - -#elif CFG_TUSB_MCU == OPT_MCU_STM32U5 - #ifdef USB_OTG_FS - // U5: FS PHY (U575/585 have FS only) - if (vbus_sensing) { - dwc2->stm32_gccfg |= STM32_GCCFG_VBDEN; - } else { - dwc2->stm32_gccfg &= ~STM32_GCCFG_VBDEN; - } - #else - // U5: femtoPHY (U59x/5Ax/5Fx/5Gx have HS) - // Uses VBVALEXTOEN and VBVALOVAL for external VBUS sensing override - if (is_host) { - dwc2->stm32_gccfg |= STM32_GCCFG_PULLDOWNEN; - dwc2->stm32_gccfg &= ~(STM32_GCCFG_VBDEN | STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL); - } else { - dwc2->stm32_gccfg &= ~STM32_GCCFG_PULLDOWNEN; + } else if (dwc2->guid < 0x5000) { + // the later version uses VBDEN with battery charging detection if (vbus_sensing) { - dwc2->stm32_gccfg |= STM32_GCCFG_VBDEN; - dwc2->stm32_gccfg &= ~(STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL); + gccfg |= STM32_GCCFG_VBDEN; } else { - dwc2->stm32_gccfg &= ~STM32_GCCFG_VBDEN; - dwc2->stm32_gccfg |= STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL; + gccfg &= ~STM32_GCCFG_VBDEN; } - } - #endif -#elif CFG_TUSB_MCU == OPT_MCU_STM32WBA - // WBA: femtoPHY - // In this device, the software override is always active - if (is_host) { - dwc2->stm32_gccfg |= STM32_GCCFG_PULLDOWNEN; - dwc2->stm32_gccfg &= ~(STM32_GCCFG_VBVALOVAL); } else { - dwc2->stm32_gccfg &= ~STM32_GCCFG_PULLDOWNEN; - if (vbus_sensing) { - dwc2->stm32_gccfg &= ~(STM32_GCCFG_VBVALOVAL); + // from 0x5000 ST seems to use femtoPHY for UTMI+ HS PHY. Which use VBVALEXTOEN and VBVALOVAL for software override + // external VBUS sensing + // Note: N6 does not support hardware VBUS sensing, so the software override is always active. Therefore, VBDEN and + // VBVALEXTOEN are not available +#if CFG_TUSB_MCU == OPT_MCU_STM32N6 + if (is_host) { + gccfg |= STM32_GCCFG_PULLDOWNEN; + gccfg &= ~(STM32_GCCFG_VBVALOVAL); } else { - dwc2->stm32_gccfg |= STM32_GCCFG_VBVALOVAL; + gccfg &= ~STM32_GCCFG_PULLDOWNEN; + gccfg |= STM32_GCCFG_VBVALOVAL; } - } - #else - #error "Unsupported MCU family" + if (is_host) { + gccfg |= STM32_GCCFG_PULLDOWNEN; + gccfg &= ~(STM32_GCCFG_VBDEN | STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL); + } else { + gccfg &= ~STM32_GCCFG_PULLDOWNEN; + if (vbus_sensing) { + gccfg |= STM32_GCCFG_VBDEN; + gccfg &= ~(STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL); + } else { + gccfg &= ~STM32_GCCFG_VBDEN; + gccfg |= STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL; + } + } #endif + } + + dwc2->stm32_gccfg = gccfg; } //------------- DCache -------------// diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index 2dd73c184..596bd0b34 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -1650,23 +1650,26 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define STM32_GCCFG_PHYHSEN_Msk (0x1UL << STM32_GCCFG_PHYHSEN_Pos) // 0x00800000 #define STM32_GCCFG_PHYHSEN STM32_GCCFG_PHYHSEN_Msk // HS PHY enable -// stm32f2/stm32f4 +// GUID < 0x2000: VBUSASEN, VBUSBSEN, NOVBUSSENS bits #define STM32_GCCFG_VBUSASEN_Pos (18U) #define STM32_GCCFG_VBUSASEN_Msk (0x1UL << STM32_GCCFG_VBUSASEN_Pos) // 0x00040000 #define STM32_GCCFG_VBUSASEN STM32_GCCFG_VBUSASEN_Msk // Enable A-device (host) VBUS sensing + #define STM32_GCCFG_VBUSBSEN_Pos (19U) #define STM32_GCCFG_VBUSBSEN_Msk (0x1UL << STM32_GCCFG_VBUSBSEN_Pos) // 0x00080000 #define STM32_GCCFG_VBUSBSEN STM32_GCCFG_VBUSBSEN_Msk // Enable B-device (peripheral) VBUS sensing + #define STM32_GCCFG_NOVBUSSENS_Pos (21U) #define STM32_GCCFG_NOVBUSSENS_Msk (0x1UL << STM32_GCCFG_NOVBUSSENS_Pos) // 0x00200000 #define STM32_GCCFG_NOVBUSSENS STM32_GCCFG_NOVBUSSENS_Msk // VBUS sensing disable option +// GUID < 0x2000: end // TODO: stm32u5a5 SDEN is 22nd bit, conflict with 20th bit above // #define STM32_GCCFG_SDEN_Pos (22U) // #define STM32_GCCFG_SDEN_Msk (0x1U << STM32_GCCFG_SDEN_Pos) // 0x00400000 // #define STM32_GCCFG_SDEN STM32_GCCFG_SDEN_Msk // Secondary detection (PD) mode enable -// stm32u5a5 VBVALOVA is 23rd bit, conflict with PHYHSEN bit above +// GUID >= 0x5000 use femtoPHY: VBVALOVA, VBVALEXTOEN, PULLDOWNEN #define STM32_GCCFG_VBVALOVAL_Pos (23U) #define STM32_GCCFG_VBVALOVAL_Msk (0x1U << STM32_GCCFG_VBVALOVAL_Pos) // 0x00800000 #define STM32_GCCFG_VBVALOVAL STM32_GCCFG_VBVALOVAL_Msk // Value of VBUSVLDEXT0 femtoPHY input @@ -1678,7 +1681,7 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define STM32_GCCFG_PULLDOWNEN_Pos (25U) #define STM32_GCCFG_PULLDOWNEN_Msk (0x1U << STM32_GCCFG_PULLDOWNEN_Pos) // 0x02000000 #define STM32_GCCFG_PULLDOWNEN STM32_GCCFG_PULLDOWNEN_Msk // Enables of femtoPHY pulldown resistors, used when ID PAD is disabled - +// GUID >= 0x5000: end /******************** Bit definition for DEACHINTMSK register ********************/ #define DEACHINTMSK_IEP1INTM_Pos (1U) diff --git a/src/tusb_option.h b/src/tusb_option.h index 8e270e5f2..ebf366e17 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -579,9 +579,18 @@ #define CFG_TUD_TEST_MODE 0 #endif +#ifndef CFG_TUD_VBUS_SENSE_DEFAULT + #define CFG_TUD_VBUS_SENSE_DEFAULT 0 +#endif + +// Enable VBUS Sensing +#ifndef CFG_TUD_VBUS_SENSE + #define CFG_TUD_VBUS_SENSE CFG_TUD_VBUS_SENSE_DEFAULT +#endif + //------------- Device Class Driver -------------// #ifndef CFG_TUD_BTH - #define CFG_TUD_BTH 0 + #define CFG_TUD_BTH 0 #endif #if CFG_TUD_BTH && !defined(CFG_TUD_BTH_ISO_ALT_COUNT) -- cgit v1.3.1 From f0b44ec6154237a4bd65a5a9d8f8bf944669af64 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 Feb 2026 22:29:14 +0700 Subject: use CFG_TUD_CONFIGURE_DWC2_DEFAULT to make it easier to add more value --- hw/bsp/stm32f2/family.c | 6 ++---- hw/bsp/stm32f4/family.c | 6 ++---- hw/bsp/stm32f7/family.c | 12 ++++-------- hw/bsp/stm32h7/family.c | 12 ++++-------- hw/bsp/stm32h7rs/family.c | 12 ++++-------- hw/bsp/stm32l4/family.c | 6 ++---- hw/bsp/stm32u5/family.c | 12 ++++-------- src/device/usbd.h | 4 +++- src/portable/synopsys/dwc2/dcd_dwc2.c | 2 +- src/tusb_option.h | 10 +++++----- 10 files changed, 31 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/hw/bsp/stm32f2/family.c b/hw/bsp/stm32f2/family.c index f863a59f0..f95128040 100644 --- a/hw/bsp/stm32f2/family.c +++ b/hw/bsp/stm32f2/family.c @@ -106,10 +106,8 @@ void board_init(void) { #if CFG_TUD_ENABLED // Enable VBUS sense (B device) via pin PA9 - tud_configure_dwc2_t cfg = { - .bm_double_buffered = 0, - .vbus_sensing = true - }; + tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; + cfg.vbus_sensing = true; tud_configure(0, TUD_CFGID_DWC2, &cfg); #endif } diff --git a/hw/bsp/stm32f4/family.c b/hw/bsp/stm32f4/family.c index 2170faca7..f0e9620f2 100644 --- a/hw/bsp/stm32f4/family.c +++ b/hw/bsp/stm32f4/family.c @@ -180,10 +180,8 @@ void board_init(void) { #endif #if CFG_TUD_ENABLED - tud_configure_dwc2_t cfg = { - .bm_double_buffered = 0, - .vbus_sensing = VBUS_SENSE_EN - }; + tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; + cfg.vbus_sensing = VBUS_SENSE_EN; tud_configure(BOARD_TUD_RHPORT, TUD_CFGID_DWC2, &cfg); board_vbus_set(BOARD_TUD_RHPORT, false); #endif diff --git a/hw/bsp/stm32f7/family.c b/hw/bsp/stm32f7/family.c index fc1c0bd13..d8f0da201 100644 --- a/hw/bsp/stm32f7/family.c +++ b/hw/bsp/stm32f7/family.c @@ -157,10 +157,8 @@ void board_init(void) { #endif // vbus sense #if CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 0 - tud_configure_dwc2_t cfg = { - .bm_double_buffered = 0, - .vbus_sensing = OTG_FS_VBUS_SENSE - }; + tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; + cfg.vbus_sensing = OTG_FS_VBUS_SENSE; tud_configure(0, TUD_CFGID_DWC2, &cfg); #endif @@ -239,10 +237,8 @@ void board_init(void) { __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); #if CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 1 - tud_configure_dwc2_t cfg = { - .bm_double_buffered = 0, - .vbus_sensing = OTG_HS_VBUS_SENSE - }; + tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; + cfg.vbus_sensing = OTG_HS_VBUS_SENSE; tud_configure(1, TUD_CFGID_DWC2, &cfg); #endif diff --git a/hw/bsp/stm32h7/family.c b/hw/bsp/stm32h7/family.c index 920f222d7..a320a7e72 100644 --- a/hw/bsp/stm32h7/family.c +++ b/hw/bsp/stm32h7/family.c @@ -183,10 +183,8 @@ void board_init(void) { #endif // vbus sense #if CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 0 - tud_configure_dwc2_t cfg = { - .bm_double_buffered = 0, - .vbus_sensing = OTG_FS_VBUS_SENSE - }; + tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; + cfg.vbus_sensing = OTG_FS_VBUS_SENSE; tud_configure(0, TUD_CFGID_DWC2, &cfg); #endif @@ -215,10 +213,8 @@ void board_init(void) { __HAL_RCC_USB1_OTG_HS_CLK_ENABLE(); #if CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 1 - tud_configure_dwc2_t cfg = { - .bm_double_buffered = 0, - .vbus_sensing = OTG_HS_VBUS_SENSE - }; + tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; + cfg.vbus_sensing = OTG_HS_VBUS_SENSE; tud_configure(1, TUD_CFGID_DWC2, &cfg); #endif #endif diff --git a/hw/bsp/stm32h7rs/family.c b/hw/bsp/stm32h7rs/family.c index b1980f2ed..2cc39b7ac 100644 --- a/hw/bsp/stm32h7rs/family.c +++ b/hw/bsp/stm32h7rs/family.c @@ -359,10 +359,8 @@ void board_init(void) { #endif // vbus sense #if CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 0 - tud_configure_dwc2_t cfg = { - .bm_double_buffered = 0, - .vbus_sensing = OTG_FS_VBUS_SENSE - }; + tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; + cfg.vbus_sensing = OTG_FS_VBUS_SENSE; tud_configure(0, TUD_CFGID_DWC2, &cfg); #endif @@ -390,10 +388,8 @@ void board_init(void) { #endif #if CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 1 - tud_configure_dwc2_t cfg = { - .bm_double_buffered = 0, - .vbus_sensing = OTG_HS_VBUS_SENSE - }; + tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; + cfg.vbus_sensing = OTG_HS_VBUS_SENSE; tud_configure(1, TUD_CFGID_DWC2, &cfg); #endif diff --git a/hw/bsp/stm32l4/family.c b/hw/bsp/stm32l4/family.c index b51a9fc8f..65f6b9ab3 100644 --- a/hw/bsp/stm32l4/family.c +++ b/hw/bsp/stm32l4/family.c @@ -176,10 +176,8 @@ void board_init(void) { #if CFG_TUD_ENABLED /* Set Vbus sense */ - tud_configure_dwc2_t cfg = { - .bm_double_buffered = 0, - .vbus_sensing = VBUS_SENSE_EN - }; + tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; + cfg.vbus_sensing = VBUS_SENSE_EN; tud_configure(0, TUD_CFGID_DWC2, &cfg); #endif #else diff --git a/hw/bsp/stm32u5/family.c b/hw/bsp/stm32u5/family.c index c2ea270df..dfcf5c537 100644 --- a/hw/bsp/stm32u5/family.c +++ b/hw/bsp/stm32u5/family.c @@ -182,10 +182,8 @@ void board_init(void) { #endif // vbus sense #if CFG_TUD_ENABLED - tud_configure_dwc2_t cfg = { - .bm_double_buffered = 0, - .vbus_sensing = VBUS_SENSE_EN - }; + tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; + cfg.vbus_sensing = VBUS_SENSE_EN; tud_configure(0, TUD_CFGID_DWC2, &cfg); #endif @@ -217,10 +215,8 @@ void board_init(void) { HAL_SYSCFG_EnableOTGPHY(SYSCFG_OTG_HS_PHY_ENABLE); #if CFG_TUD_ENABLED - tud_configure_dwc2_t cfg = { - .bm_double_buffered = 0, - .vbus_sensing = VBUS_SENSE_EN - }; + tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; + cfg.vbus_sensing = VBUS_SENSE_EN; tud_configure(0, TUD_CFGID_DWC2, &cfg); #endif #endif // USB_OTG_FS diff --git a/src/device/usbd.h b/src/device/usbd.h index eaf07b81e..825fdba90 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -44,7 +44,9 @@ typedef struct { bool vbus_sensing; // Vbus pin is used for device connection detection, mandatory for tud_umount_cb() } tud_configure_dwc2_t; -#define TUD_CONFIGURE_DWC2_DEFAULT { .bm_double_buffered = 0, .vbus_sensing = CFG_TUD_VBUS_SENSE } + #ifndef CFG_TUD_CONFIGURE_DWC2_DEFAULT + #define CFG_TUD_CONFIGURE_DWC2_DEFAULT {.bm_double_buffered = 0, .vbus_sensing = CFG_TUD_VBUS_DETECT_HW} + #endif typedef union { tud_configure_dwc2_t dwc2; diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index a6a598dbf..97e83f4e1 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -77,7 +77,7 @@ CFG_TUD_MEM_SECTION static struct { TUD_EPBUF_DEF(setup_packet, 8); } _dcd_usbbuf; -static tud_configure_dwc2_t _tud_cfg = TUD_CONFIGURE_DWC2_DEFAULT; +static tud_configure_dwc2_t _tud_cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; TU_ATTR_ALWAYS_INLINE static inline uint8_t dwc2_ep_count(const dwc2_regs_t* dwc2) { #if TU_CHECK_MCU(OPT_MCU_GD32VF103) diff --git a/src/tusb_option.h b/src/tusb_option.h index ebf366e17..d87c2dc8b 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -579,13 +579,13 @@ #define CFG_TUD_TEST_MODE 0 #endif -#ifndef CFG_TUD_VBUS_SENSE_DEFAULT - #define CFG_TUD_VBUS_SENSE_DEFAULT 0 +#ifndef CFG_TUD_VBUS_DETECT_HW_DEFAULT + #define CFG_TUD_VBUS_DETECT_HW_DEFAULT 0 #endif -// Enable VBUS Sensing -#ifndef CFG_TUD_VBUS_SENSE - #define CFG_TUD_VBUS_SENSE CFG_TUD_VBUS_SENSE_DEFAULT +// Enable VBUS Detect hardware, usually via functional GPIO +#ifndef CFG_TUD_VBUS_DETECT_HW + #define CFG_TUD_VBUS_DETECT_HW CFG_TUD_VBUS_DETECT_HW_DEFAULT #endif //------------- Device Class Driver -------------// -- cgit v1.3.1 From 59feef3208b84da0414c5159a9edba7653a82324 Mon Sep 17 00:00:00 2001 From: Roman Leonov Date: Sat, 14 Feb 2026 11:52:52 +0100 Subject: add(usbh.c): LOG1 debug message when no address available for hub --- src/host/usbh.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/host/usbh.c b/src/host/usbh.c index 41f41dcfb..d702e9186 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1841,6 +1841,12 @@ static uint8_t enum_get_new_address(bool is_hub) { } } +#if CFG_TUH_HUB + if ( is_hub ) { + TU_LOG1("All addresses are occupied, try to increase CFG_TUH_HUB value.\r\n"); + } +#endif // CFG_TUH_HUB + return 0; // invalid address } -- cgit v1.3.1 From db1ff5d1692a4407496284b6684438256e1988db Mon Sep 17 00:00:00 2001 From: Cédric Berger Date: Thu, 19 Feb 2026 23:00:27 +0100 Subject: Better variable/function names --- src/portable/synopsys/dwc2/dcd_dwc2.c | 6 +++--- src/portable/synopsys/dwc2/dwc2_common.c | 6 +++--- src/portable/synopsys/dwc2/dwc2_common.h | 4 ++-- src/portable/synopsys/dwc2/hcd_dwc2.c | 10 +++++----- 4 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 97e83f4e1..558065134 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -442,14 +442,14 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { tu_memclr(&_dcd_data, sizeof(_dcd_data)); // Core Initialization - const bool is_highspeed = dwc2_core_is_highspeed(dwc2, TUSB_ROLE_DEVICE); + const bool highspeed_phy = dwc2_core_is_highspeed_phy(dwc2, TUSB_ROLE_DEVICE); const bool is_dma = dma_device_enabled(dwc2); - TU_ASSERT(dwc2_core_init(rhport, is_highspeed, is_dma)); + TU_ASSERT(dwc2_core_init(rhport, highspeed_phy, is_dma)); //------------- 7.1 Device Initialization -------------// // Set device max speed uint32_t dcfg = dwc2->dcfg & ~DCFG_DSPD_Msk; - if (is_highspeed) { + if (highspeed_phy) { // dcfg Highspeed's mask is 0 // XCVRDLY: transceiver delay between xcvr_sel and txvalid during device chirp is required diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index a7e6188df..5429af440 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -179,7 +179,7 @@ static bool check_dwc2(dwc2_regs_t* dwc2) { //-------------------------------------------------------------------- // //-------------------------------------------------------------------- -bool dwc2_core_is_highspeed(dwc2_regs_t* dwc2, tusb_role_t role) { +bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, tusb_role_t role) { (void)dwc2; #if CFG_TUD_ENABLED if (role == TUSB_ROLE_DEVICE && !TUD_OPT_HIGH_SPEED) { @@ -204,7 +204,7 @@ bool dwc2_core_is_highspeed(dwc2_regs_t* dwc2, tusb_role_t role) { * In addition, UTMI+/ULPI can be shared to run at fullspeed mode with 48Mhz * */ -bool dwc2_core_init(uint8_t rhport, bool is_highspeed, bool is_dma) { +bool dwc2_core_init(uint8_t rhport, bool highspeed_phy, bool is_dma) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Check Synopsys ID register, failed if controller clock/power is not enabled @@ -213,7 +213,7 @@ bool dwc2_core_init(uint8_t rhport, bool is_highspeed, bool is_dma) { // disable global interrupt dwc2->gahbcfg &= ~GAHBCFG_GINT; - if (is_highspeed) { + if (highspeed_phy) { phy_hs_init(dwc2); } else { phy_fs_init(dwc2); diff --git a/src/portable/synopsys/dwc2/dwc2_common.h b/src/portable/synopsys/dwc2/dwc2_common.h index 428304ba9..b03fecad9 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.h +++ b/src/portable/synopsys/dwc2/dwc2_common.h @@ -84,8 +84,8 @@ TU_ATTR_ALWAYS_INLINE static inline dwc2_regs_t* DWC2_REG(uint8_t rhport) { return (dwc2_regs_t*)_dwc2_controller[rhport].reg_base; } -bool dwc2_core_is_highspeed(dwc2_regs_t* dwc2, tusb_role_t role); -bool dwc2_core_init(uint8_t rhport, bool is_highspeed, bool is_dma); +bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, tusb_role_t role); +bool dwc2_core_init(uint8_t rhport, bool highspeed_phy, bool is_dma); void dwc2_core_handle_common_irq(uint8_t rhport, bool in_isr); //--------------------------------------------------------------------+ diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index 8182fd6cc..2d667eb43 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -364,9 +364,9 @@ static void dfifo_host_init(uint8_t rhport) { // fixed allocation for now, improve later: // - ptx_largest is limited to 256 for FS since most FS core only has 1024 bytes total - bool is_highspeed = dwc2_core_is_highspeed(dwc2, TUSB_ROLE_HOST); - uint32_t nptx_largest = is_highspeed ? TUSB_EPSIZE_BULK_HS/4 : TUSB_EPSIZE_BULK_FS/4; - uint32_t ptx_largest = is_highspeed ? TUSB_EPSIZE_ISO_HS_MAX/4 : 256/4; + bool highspeed_phy = dwc2_core_is_highspeed_phy(dwc2, TUSB_ROLE_HOST); + uint32_t nptx_largest = highspeed_phy ? TUSB_EPSIZE_BULK_HS/4 : TUSB_EPSIZE_BULK_FS/4; + uint32_t ptx_largest = highspeed_phy ? TUSB_EPSIZE_ISO_HS_MAX/4 : 256/4; uint16_t nptxfsiz = 2 * nptx_largest; uint16_t rxfsiz = 2 * (ptx_largest + 2) + ghwcfg2.num_host_ch; @@ -406,9 +406,9 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { tu_memclr(&_hcd_data, sizeof(_hcd_data)); // Core Initialization - const bool is_highspeed = dwc2_core_is_highspeed(dwc2, TUSB_ROLE_HOST); + const bool highspeed_phy = dwc2_core_is_highspeed_phy(dwc2, TUSB_ROLE_HOST); const bool is_dma = dma_host_enabled(dwc2); - TU_ASSERT(dwc2_core_init(rhport, is_highspeed, is_dma)); + TU_ASSERT(dwc2_core_init(rhport, highspeed_phy, is_dma)); //------------- 3.1 Host Initialization -------------// -- cgit v1.3.1 From c8265a3709ebe6b5f77aa3b5bb148740c5818f00 Mon Sep 17 00:00:00 2001 From: Cédric Berger Date: Thu, 19 Feb 2026 23:03:32 +0100 Subject: Introduce TUH_CFGID_PHY_SPEED configure option --- src/host/usbh.h | 1 + src/portable/synopsys/dwc2/dwc2_common.c | 9 +++++++-- src/portable/synopsys/dwc2/dwc2_common.h | 3 +++ src/portable/synopsys/dwc2/hcd_dwc2.c | 18 +++++++++++------- 4 files changed, 22 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/host/usbh.h b/src/host/usbh.h index d86efbcb2..03577ba3f 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -93,6 +93,7 @@ typedef struct { // ConfigID for tuh_configure() enum { TUH_CFGID_INVALID = 0, + TUH_CFGID_PHY_SPEED = 10, // cfg_param: tusb_speed_t TUH_CFGID_RPI_PIO_USB_CONFIGURATION = 100, // cfg_param: pio_usb_configuration_t TUH_CFGID_MAX3421 = 200, TUH_CFGID_FSDEV = 300, diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index 5429af440..429c56123 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -187,8 +187,13 @@ bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, tusb_role_t role) { } #endif #if CFG_TUH_ENABLED - if (role == TUSB_ROLE_HOST && !TUH_OPT_HIGH_SPEED) { - return false; + if (role == TUSB_ROLE_HOST) { + if (_hcd_cfg_phy_speed == TUSB_SPEED_HIGH) + return true; + if (_hcd_cfg_phy_speed < TUSB_SPEED_HIGH) + return false; + if (!TUH_OPT_HIGH_SPEED) + return false; } #endif diff --git a/src/portable/synopsys/dwc2/dwc2_common.h b/src/portable/synopsys/dwc2/dwc2_common.h index b03fecad9..16a18c673 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.h +++ b/src/portable/synopsys/dwc2/dwc2_common.h @@ -76,6 +76,9 @@ enum { //--------------------------------------------------------------------+ // Core/Controller //--------------------------------------------------------------------+ + +extern tusb_speed_t _hcd_cfg_phy_speed; + TU_ATTR_ALWAYS_INLINE static inline dwc2_regs_t* DWC2_REG(uint8_t rhport) { if (rhport >= DWC2_CONTROLLER_COUNT) { // user mis-configured, ignore and use first controller diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index 2d667eb43..99be779ef 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -112,6 +112,7 @@ typedef struct { } hcd_data_t; hcd_data_t _hcd_data; +tusb_speed_t _hcd_cfg_phy_speed = TUSB_SPEED_AUTO; //-------------------------------------------------------------------- // @@ -392,15 +393,13 @@ static void dfifo_host_init(uint8_t rhport) { // optional hcd configuration, called by tuh_configure() bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { (void) rhport; - (void) cfg_id; - (void) cfg_param; - + TU_VERIFY(cfg_id == TUH_CFGID_PHY_SPEED && cfg_param != NULL); + _hcd_cfg_phy_speed = *(const tusb_speed_t *)cfg_param; return true; } // Initialize controller to host mode bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { - (void) rh_init; dwc2_regs_t* dwc2 = DWC2_REG(rhport); tu_memclr(&_hcd_data, sizeof(_hcd_data)); @@ -412,9 +411,6 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { //------------- 3.1 Host Initialization -------------// - // work at max supported speed - dwc2->hcfg &= ~HCFG_FSLS_ONLY; - // Enable HFIR reload if (dwc2->gsnpsid >= DWC2_CORE_REV_2_92a) { dwc2->hfir |= HFIR_RELOAD_CTRL; @@ -432,6 +428,14 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { dwc2_stm32_gccfg_cfg(dwc2, false, true); #endif + if (highspeed_phy && rh_init->speed < TUSB_SPEED_HIGH) { + // disable high speed mode + dwc2->hcfg |= HCFG_FSLS_ONLY; + } else { + // work at max supported speed + dwc2->hcfg &= ~HCFG_FSLS_ONLY; + } + // configure fixed-allocated fifo scheme dfifo_host_init(rhport); -- cgit v1.3.1 From 7e6177097166073579418ce1ff98aa2185f48396 Mon Sep 17 00:00:00 2001 From: Cédric Berger Date: Thu, 19 Feb 2026 23:30:25 +0100 Subject: Fix a couple indentations --- src/portable/synopsys/dwc2/dwc2_common.c | 12 ++++++------ src/portable/synopsys/dwc2/hcd_dwc2.c | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index 429c56123..8c2324283 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -188,12 +188,12 @@ bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, tusb_role_t role) { #endif #if CFG_TUH_ENABLED if (role == TUSB_ROLE_HOST) { - if (_hcd_cfg_phy_speed == TUSB_SPEED_HIGH) - return true; - if (_hcd_cfg_phy_speed < TUSB_SPEED_HIGH) - return false; - if (!TUH_OPT_HIGH_SPEED) - return false; + if (_hcd_cfg_phy_speed == TUSB_SPEED_HIGH) + return true; + if (_hcd_cfg_phy_speed < TUSB_SPEED_HIGH) + return false; + if (!TUH_OPT_HIGH_SPEED) + return false; } #endif diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index 99be779ef..9f8133196 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -429,11 +429,11 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { #endif if (highspeed_phy && rh_init->speed < TUSB_SPEED_HIGH) { - // disable high speed mode - dwc2->hcfg |= HCFG_FSLS_ONLY; + // disable high speed mode + dwc2->hcfg |= HCFG_FSLS_ONLY; } else { - // work at max supported speed - dwc2->hcfg &= ~HCFG_FSLS_ONLY; + // work at max supported speed + dwc2->hcfg &= ~HCFG_FSLS_ONLY; } // configure fixed-allocated fifo scheme -- cgit v1.3.1 From c5ec572396d3f5bae05d4f0baa2c026598604f48 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 20 Feb 2026 13:57:34 +0100 Subject: refactor config option Signed-off-by: HiFiPhile --- src/host/usbh.h | 7 ++++++- src/portable/synopsys/dwc2/dwc2_common.c | 9 ++------- src/portable/synopsys/dwc2/dwc2_common.h | 3 --- src/portable/synopsys/dwc2/hcd_dwc2.c | 13 +++++++------ 4 files changed, 15 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/host/usbh.h b/src/host/usbh.h index 03577ba3f..2f332b442 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -93,10 +93,10 @@ typedef struct { // ConfigID for tuh_configure() enum { TUH_CFGID_INVALID = 0, - TUH_CFGID_PHY_SPEED = 10, // cfg_param: tusb_speed_t TUH_CFGID_RPI_PIO_USB_CONFIGURATION = 100, // cfg_param: pio_usb_configuration_t TUH_CFGID_MAX3421 = 200, TUH_CFGID_FSDEV = 300, + TUH_CFGID_DWC2 = 400 }; typedef struct { @@ -109,10 +109,15 @@ typedef struct { uint8_t max_nak; // max NAK per endpoint per frame to save CPU usage (0=unlimited) } tuh_configure_fsdev_t; +typedef struct { + bool use_hs_phy; // Always use high-speed ULPI/UTMI phy even working at full-speed +} tuh_configure_dwc2_t; + typedef union { // For TUH_CFGID_RPI_PIO_USB_CONFIGURATION use pio_usb_configuration_t tuh_configure_max3421_t max3421; tuh_configure_fsdev_t fsdev; + tuh_configure_dwc2_t dwc2; } tuh_configure_param_t; //--------------------------------------------------------------------+ diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index 8c2324283..5429af440 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -187,13 +187,8 @@ bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, tusb_role_t role) { } #endif #if CFG_TUH_ENABLED - if (role == TUSB_ROLE_HOST) { - if (_hcd_cfg_phy_speed == TUSB_SPEED_HIGH) - return true; - if (_hcd_cfg_phy_speed < TUSB_SPEED_HIGH) - return false; - if (!TUH_OPT_HIGH_SPEED) - return false; + if (role == TUSB_ROLE_HOST && !TUH_OPT_HIGH_SPEED) { + return false; } #endif diff --git a/src/portable/synopsys/dwc2/dwc2_common.h b/src/portable/synopsys/dwc2/dwc2_common.h index 16a18c673..b03fecad9 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.h +++ b/src/portable/synopsys/dwc2/dwc2_common.h @@ -76,9 +76,6 @@ enum { //--------------------------------------------------------------------+ // Core/Controller //--------------------------------------------------------------------+ - -extern tusb_speed_t _hcd_cfg_phy_speed; - TU_ATTR_ALWAYS_INLINE static inline dwc2_regs_t* DWC2_REG(uint8_t rhport) { if (rhport >= DWC2_CONTROLLER_COUNT) { // user mis-configured, ignore and use first controller diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index 9f8133196..0fbb55191 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -111,8 +111,9 @@ typedef struct { hcd_endpoint_t edpt[CFG_TUH_DWC2_ENDPOINT_MAX]; } hcd_data_t; -hcd_data_t _hcd_data; -tusb_speed_t _hcd_cfg_phy_speed = TUSB_SPEED_AUTO; +static hcd_data_t _hcd_data; + +static tuh_configure_dwc2_t _tuh_cfg = {.use_hs_phy = TUH_OPT_HIGH_SPEED}; //-------------------------------------------------------------------- // @@ -393,8 +394,8 @@ static void dfifo_host_init(uint8_t rhport) { // optional hcd configuration, called by tuh_configure() bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { (void) rhport; - TU_VERIFY(cfg_id == TUH_CFGID_PHY_SPEED && cfg_param != NULL); - _hcd_cfg_phy_speed = *(const tusb_speed_t *)cfg_param; + TU_VERIFY(cfg_id == TUH_CFGID_DWC2 && cfg_param != NULL); + _tuh_cfg = *(const tuh_configure_dwc2_t *)cfg_param; return true; } @@ -405,7 +406,7 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { tu_memclr(&_hcd_data, sizeof(_hcd_data)); // Core Initialization - const bool highspeed_phy = dwc2_core_is_highspeed_phy(dwc2, TUSB_ROLE_HOST); + const bool highspeed_phy = dwc2_core_is_highspeed_phy(dwc2, TUSB_ROLE_HOST) || _tuh_cfg.use_hs_phy; const bool is_dma = dma_host_enabled(dwc2); TU_ASSERT(dwc2_core_init(rhport, highspeed_phy, is_dma)); @@ -428,7 +429,7 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { dwc2_stm32_gccfg_cfg(dwc2, false, true); #endif - if (highspeed_phy && rh_init->speed < TUSB_SPEED_HIGH) { + if (rh_init->speed < TUSB_SPEED_HIGH || !TUH_OPT_HIGH_SPEED) { // disable high speed mode dwc2->hcfg |= HCFG_FSLS_ONLY; } else { -- cgit v1.3.1 From 167a50714636261b72ed6fc3f7c6682c209c0d7f Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 21 Feb 2026 17:03:06 +0100 Subject: fix ci Signed-off-by: HiFiPhile --- src/portable/synopsys/dwc2/hcd_dwc2.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index 0fbb55191..f7dc93ae1 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -432,10 +432,13 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { if (rh_init->speed < TUSB_SPEED_HIGH || !TUH_OPT_HIGH_SPEED) { // disable high speed mode dwc2->hcfg |= HCFG_FSLS_ONLY; - } else { + } +#if TUH_OPT_HIGH_SPEED + else { // work at max supported speed dwc2->hcfg &= ~HCFG_FSLS_ONLY; } +#endif // configure fixed-allocated fifo scheme dfifo_host_init(rhport); -- cgit v1.3.1 From dafb0d2bf4b99531fe632acb621861cb64c80e66 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 21 Feb 2026 17:34:11 +0100 Subject: check femtoPHY speed Signed-off-by: HiFiPhile --- src/portable/synopsys/dwc2/dwc2_common.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index 5429af440..70e38b9f7 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -180,7 +180,13 @@ static bool check_dwc2(dwc2_regs_t* dwc2) { // //-------------------------------------------------------------------- bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, tusb_role_t role) { - (void)dwc2; +#ifdef TUP_USBIP_DWC2_STM32 + if (dwc2->guid >= 0x5000) { + // femtoPHY UTMI+ PHY + return true; + } +#endif + #if CFG_TUD_ENABLED if (role == TUSB_ROLE_DEVICE && !TUD_OPT_HIGH_SPEED) { return false; -- cgit v1.3.1 From b585df168a3489845cda3cb732560d4fe260e609 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 21 Feb 2026 17:44:17 +0100 Subject: refactor speed check Signed-off-by: HiFiPhile --- src/portable/synopsys/dwc2/dcd_dwc2.c | 2 +- src/portable/synopsys/dwc2/dwc2_common.c | 11 ++--------- src/portable/synopsys/dwc2/dwc2_common.h | 2 +- src/portable/synopsys/dwc2/hcd_dwc2.c | 4 ++-- 4 files changed, 6 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 558065134..dec2db5f2 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -442,7 +442,7 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { tu_memclr(&_dcd_data, sizeof(_dcd_data)); // Core Initialization - const bool highspeed_phy = dwc2_core_is_highspeed_phy(dwc2, TUSB_ROLE_DEVICE); + const bool highspeed_phy = dwc2_core_is_highspeed_phy(dwc2, TUD_OPT_HIGH_SPEED); const bool is_dma = dma_device_enabled(dwc2); TU_ASSERT(dwc2_core_init(rhport, highspeed_phy, is_dma)); diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index 70e38b9f7..d26e2daca 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -179,7 +179,7 @@ static bool check_dwc2(dwc2_regs_t* dwc2) { //-------------------------------------------------------------------- // //-------------------------------------------------------------------- -bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, tusb_role_t role) { +bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, bool prefer_hs_phy) { #ifdef TUP_USBIP_DWC2_STM32 if (dwc2->guid >= 0x5000) { // femtoPHY UTMI+ PHY @@ -187,16 +187,9 @@ bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, tusb_role_t role) { } #endif -#if CFG_TUD_ENABLED - if (role == TUSB_ROLE_DEVICE && !TUD_OPT_HIGH_SPEED) { + if (!prefer_hs_phy) { return false; } -#endif -#if CFG_TUH_ENABLED - if (role == TUSB_ROLE_HOST && !TUH_OPT_HIGH_SPEED) { - return false; - } -#endif const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; return ghwcfg2.hs_phy_type != GHWCFG2_HSPHY_NOT_SUPPORTED; diff --git a/src/portable/synopsys/dwc2/dwc2_common.h b/src/portable/synopsys/dwc2/dwc2_common.h index b03fecad9..aacb62536 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.h +++ b/src/portable/synopsys/dwc2/dwc2_common.h @@ -84,7 +84,7 @@ TU_ATTR_ALWAYS_INLINE static inline dwc2_regs_t* DWC2_REG(uint8_t rhport) { return (dwc2_regs_t*)_dwc2_controller[rhport].reg_base; } -bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, tusb_role_t role); +bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, bool prefer_hs_phy); bool dwc2_core_init(uint8_t rhport, bool highspeed_phy, bool is_dma); void dwc2_core_handle_common_irq(uint8_t rhport, bool in_isr); diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index f7dc93ae1..c9ea144c8 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -366,7 +366,7 @@ static void dfifo_host_init(uint8_t rhport) { // fixed allocation for now, improve later: // - ptx_largest is limited to 256 for FS since most FS core only has 1024 bytes total - bool highspeed_phy = dwc2_core_is_highspeed_phy(dwc2, TUSB_ROLE_HOST); + bool highspeed_phy = dwc2_core_is_highspeed_phy(dwc2, _tuh_cfg.use_hs_phy); uint32_t nptx_largest = highspeed_phy ? TUSB_EPSIZE_BULK_HS/4 : TUSB_EPSIZE_BULK_FS/4; uint32_t ptx_largest = highspeed_phy ? TUSB_EPSIZE_ISO_HS_MAX/4 : 256/4; @@ -406,7 +406,7 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { tu_memclr(&_hcd_data, sizeof(_hcd_data)); // Core Initialization - const bool highspeed_phy = dwc2_core_is_highspeed_phy(dwc2, TUSB_ROLE_HOST) || _tuh_cfg.use_hs_phy; + const bool highspeed_phy = dwc2_core_is_highspeed_phy(dwc2, _tuh_cfg.use_hs_phy); const bool is_dma = dma_host_enabled(dwc2); TU_ASSERT(dwc2_core_init(rhport, highspeed_phy, is_dma)); -- cgit v1.3.1 From e947af26c62fe8717f754e072a18e9e24f33ca96 Mon Sep 17 00:00:00 2001 From: Zixun LI Date: Sun, 22 Feb 2026 13:33:29 +0100 Subject: Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/host/usbh.h | 2 +- src/portable/synopsys/dwc2/hcd_dwc2.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/host/usbh.h b/src/host/usbh.h index 2f332b442..143d36f8c 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -110,7 +110,7 @@ typedef struct { } tuh_configure_fsdev_t; typedef struct { - bool use_hs_phy; // Always use high-speed ULPI/UTMI phy even working at full-speed + bool use_hs_phy; // Always use high-speed ULPI/UTMI phy even when working at full-speed } tuh_configure_dwc2_t; typedef union { diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index c9ea144c8..ac6fcceb1 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -395,7 +395,8 @@ static void dfifo_host_init(uint8_t rhport) { bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { (void) rhport; TU_VERIFY(cfg_id == TUH_CFGID_DWC2 && cfg_param != NULL); - _tuh_cfg = *(const tuh_configure_dwc2_t *)cfg_param; + tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param; + _tuh_cfg = cfg->dwc2; return true; } -- cgit v1.3.1 From 1eef6f4f4f7a26a5be3c4b774992aadcc8660820 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 23 Feb 2026 15:34:59 +0700 Subject: refactor: improve high-speed PHY handling and FIFO configuration in DWC2 driver --- src/portable/synopsys/dwc2/dcd_dwc2.c | 6 ++--- src/portable/synopsys/dwc2/dwc2_common.c | 4 ++-- src/portable/synopsys/dwc2/dwc2_common.h | 2 +- src/portable/synopsys/dwc2/hcd_dwc2.c | 39 +++++++++++++++----------------- 4 files changed, 24 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index dec2db5f2..d1d4b080e 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -442,14 +442,14 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { tu_memclr(&_dcd_data, sizeof(_dcd_data)); // Core Initialization - const bool highspeed_phy = dwc2_core_is_highspeed_phy(dwc2, TUD_OPT_HIGH_SPEED); + const bool is_hs_phy = dwc2_core_is_highspeed_phy(dwc2, TUD_OPT_HIGH_SPEED); const bool is_dma = dma_device_enabled(dwc2); - TU_ASSERT(dwc2_core_init(rhport, highspeed_phy, is_dma)); + TU_ASSERT(dwc2_core_init(rhport, is_hs_phy, is_dma)); //------------- 7.1 Device Initialization -------------// // Set device max speed uint32_t dcfg = dwc2->dcfg & ~DCFG_DSPD_Msk; - if (highspeed_phy) { + if (is_hs_phy) { // dcfg Highspeed's mask is 0 // XCVRDLY: transceiver delay between xcvr_sel and txvalid during device chirp is required diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index d26e2daca..98ef22d03 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -203,7 +203,7 @@ bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, bool prefer_hs_phy) { * In addition, UTMI+/ULPI can be shared to run at fullspeed mode with 48Mhz * */ -bool dwc2_core_init(uint8_t rhport, bool highspeed_phy, bool is_dma) { +bool dwc2_core_init(uint8_t rhport, bool is_hs_phy, bool is_dma) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Check Synopsys ID register, failed if controller clock/power is not enabled @@ -212,7 +212,7 @@ bool dwc2_core_init(uint8_t rhport, bool highspeed_phy, bool is_dma) { // disable global interrupt dwc2->gahbcfg &= ~GAHBCFG_GINT; - if (highspeed_phy) { + if (is_hs_phy) { phy_hs_init(dwc2); } else { phy_fs_init(dwc2); diff --git a/src/portable/synopsys/dwc2/dwc2_common.h b/src/portable/synopsys/dwc2/dwc2_common.h index aacb62536..6ee351ab5 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.h +++ b/src/portable/synopsys/dwc2/dwc2_common.h @@ -85,7 +85,7 @@ TU_ATTR_ALWAYS_INLINE static inline dwc2_regs_t* DWC2_REG(uint8_t rhport) { } bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, bool prefer_hs_phy); -bool dwc2_core_init(uint8_t rhport, bool highspeed_phy, bool is_dma); +bool dwc2_core_init(uint8_t rhport, bool is_hs_phy, bool is_dma); void dwc2_core_handle_common_irq(uint8_t rhport, bool in_isr); //--------------------------------------------------------------------+ diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index ac6fcceb1..cc11c82d7 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -112,7 +112,6 @@ typedef struct { } hcd_data_t; static hcd_data_t _hcd_data; - static tuh_configure_dwc2_t _tuh_cfg = {.use_hs_phy = TUH_OPT_HIGH_SPEED}; //-------------------------------------------------------------------- @@ -352,7 +351,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t cal_next_pid(uint8_t pid, uint8_t pa * TX periodic (PTX) * - At least largest-EPsize*MulCount/4 (MulCount up to 3 for high-bandwidth ISO/interrupt) */ -static void dfifo_host_init(uint8_t rhport) { +static void dfifo_host_init(uint8_t rhport, bool is_highspeed) { const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; dwc2_regs_t* dwc2 = DWC2_REG(rhport); const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; @@ -365,10 +364,9 @@ static void dfifo_host_init(uint8_t rhport) { } // fixed allocation for now, improve later: - // - ptx_largest is limited to 256 for FS since most FS core only has 1024 bytes total - bool highspeed_phy = dwc2_core_is_highspeed_phy(dwc2, _tuh_cfg.use_hs_phy); - uint32_t nptx_largest = highspeed_phy ? TUSB_EPSIZE_BULK_HS/4 : TUSB_EPSIZE_BULK_FS/4; - uint32_t ptx_largest = highspeed_phy ? TUSB_EPSIZE_ISO_HS_MAX/4 : 256/4; + // - ptx_largest is limited to 256 for FS since most FS core only has 1024 bytes total + uint32_t nptx_largest = is_highspeed ? TUSB_EPSIZE_BULK_HS / 4 : TUSB_EPSIZE_BULK_FS / 4; + uint32_t ptx_largest = is_highspeed ? TUSB_EPSIZE_ISO_HS_MAX / 4 : 256 / 4; uint16_t nptxfsiz = 2 * nptx_largest; uint16_t rxfsiz = 2 * (ptx_largest + 2) + ghwcfg2.num_host_ch; @@ -403,16 +401,14 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { // Initialize controller to host mode bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); - tu_memclr(&_hcd_data, sizeof(_hcd_data)); // Core Initialization - const bool highspeed_phy = dwc2_core_is_highspeed_phy(dwc2, _tuh_cfg.use_hs_phy); + const bool is_hs_phy = dwc2_core_is_highspeed_phy(dwc2, _tuh_cfg.use_hs_phy); const bool is_dma = dma_host_enabled(dwc2); - TU_ASSERT(dwc2_core_init(rhport, highspeed_phy, is_dma)); + TU_ASSERT(dwc2_core_init(rhport, is_hs_phy, is_dma)); //------------- 3.1 Host Initialization -------------// - // Enable HFIR reload if (dwc2->gsnpsid >= DWC2_CORE_REV_2_92a) { dwc2->hfir |= HFIR_RELOAD_CTRL; @@ -426,23 +422,24 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { #endif while ((dwc2->gintsts & GINTSTS_CMOD) != GINTSTS_CMODE_HOST) {} -#ifdef TUP_USBIP_DWC2_STM32 + #ifdef TUP_USBIP_DWC2_STM32 dwc2_stm32_gccfg_cfg(dwc2, false, true); -#endif + #endif - if (rh_init->speed < TUSB_SPEED_HIGH || !TUH_OPT_HIGH_SPEED) { - // disable high speed mode - dwc2->hcfg |= HCFG_FSLS_ONLY; + bool is_highspeed; + if (!TUH_OPT_HIGH_SPEED || rh_init->speed < TUSB_SPEED_HIGH) { + dwc2->hcfg |= HCFG_FSLS_ONLY; // disable high speed mode + is_highspeed = false; } -#if TUH_OPT_HIGH_SPEED + #if TUH_OPT_HIGH_SPEED else { - // work at max supported speed - dwc2->hcfg &= ~HCFG_FSLS_ONLY; + dwc2->hcfg &= ~HCFG_FSLS_ONLY; // work at max supported speed + is_highspeed = true; } -#endif + #endif - // configure fixed-allocated fifo scheme - dfifo_host_init(rhport); + // configure a fixed-allocated fifo scheme + dfifo_host_init(rhport, is_highspeed); dwc2->hprt = HPRT_W1_MASK; // clear all write-1-clear bits dwc2->hprt = HPRT_POWER; // turn on VBUS -- cgit v1.3.1 From f179b2957dbe00ad937eb50ada42dc32233a7a93 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 23 Feb 2026 19:33:29 +0700 Subject: refactor: streamline high-speed PHY detection and configuration in DWC2 driver --- AGENTS.md | 10 +++++++-- src/portable/synopsys/dwc2/dcd_dwc2.c | 2 +- src/portable/synopsys/dwc2/dwc2_common.c | 35 +++++++++++++++----------------- src/portable/synopsys/dwc2/dwc2_common.h | 1 + src/portable/synopsys/dwc2/hcd_dwc2.c | 27 ++++++++++-------------- 5 files changed, 37 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/AGENTS.md b/AGENTS.md index 73bf1f599..ef8baec5a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -101,9 +101,15 @@ make BOARD=raspberry_pi_pico all ## Hardware-in-the-Loop (HIL) Testing +- `-B examples` means `examples` is the parent folder that contains multi-board build outputs such as `examples/cmake-build-BOARD_NAME/...` +- Select config file before running HIL tests: + - if GitHub Actions self-hosted runner service is running, use `tinyusb.json` + - otherwise use `local.json` + - example: + `HIL_CONFIG=$( (systemctl list-units --type=service --state=running 2>/dev/null; systemctl --user list-units --type=service --state=running 2>/dev/null) | grep -q 'actions\.runner' && echo tinyusb.json || echo local.json )` - Run tests on actual hardware, one of following ways: - - test a specific board `python test/hil/hil_test.py -b BOARD_NAME -B examples local.json` - - test all boards in config `python test/hil/hil_test.py -B examples local.json` + - test a specific board `python test/hil/hil_test.py -b BOARD_NAME -B examples $HIL_CONFIG` + - test all boards in config `python test/hil/hil_test.py -B examples $HIL_CONFIG` - In case of error, enabled verbose mode with `-v` flag for detailed logs. Also try to observe script output, and try to modify hil_test.py (temporarily) to add more debug prints to pinpoint the issue. - Requires pre-built (all) examples for target boards (see Build Examples section 2) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index d1d4b080e..2e2b050bc 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -479,7 +479,7 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { #ifdef TUP_USBIP_DWC2_STM32 dwc2_stm32_gccfg_cfg(dwc2, _tud_cfg.vbus_sensing, false); -#endif + #endif // Enable required interrupts dwc2->gintmsk |= GINTMSK_OTGINT | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM; diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index 98ef22d03..27dda44ee 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -60,6 +60,7 @@ static void reset_core(dwc2_regs_t* dwc2) { while (!(dwc2->grstctl & GRSTCTL_AHBIDL)) {} // wait for AHB master IDLE } +// Dedicated FS PHY is internal with a clock 48Mhz. static void phy_fs_init(dwc2_regs_t* dwc2) { TU_LOG(DWC2_COMMON_DEBUG, "Fullspeed PHY init\r\n"); @@ -86,6 +87,13 @@ static void phy_fs_init(dwc2_regs_t* dwc2) { dwc2_phy_update(dwc2, GHWCFG2_HSPHY_NOT_SUPPORTED); } +/* dwc2 has 2 highspeed PHYs options + * - UTMI+ is internal highspeed PHY, can be clocked at 30/60 Mhz for fullspeed or 60 Mhz for highspeed. Can be either + * 8 or 16-bit interface. + * - ULPI is external highspeed PHY, clocked at 60Mhz with 8-bit interface. + * + * In addition, UTMI+/ULPI can be shared to run at fullspeed mode with 48Mhz + */ static void phy_hs_init(dwc2_regs_t* dwc2) { uint32_t gusbcfg = dwc2->gusbcfg; const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; @@ -180,29 +188,18 @@ static bool check_dwc2(dwc2_regs_t* dwc2) { // //-------------------------------------------------------------------- bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, bool prefer_hs_phy) { -#ifdef TUP_USBIP_DWC2_STM32 - if (dwc2->guid >= 0x5000) { - // femtoPHY UTMI+ PHY - return true; - } -#endif + const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; + const bool has_hs_phy = (ghwcfg2.hs_phy_type != GHWCFG2_HSPHY_NOT_SUPPORTED); - if (!prefer_hs_phy) { - return false; + if (prefer_hs_phy) { + return has_hs_phy; + } else { + const bool has_fs_phy = (ghwcfg2.fs_phy_type != GHWCFG2_FSPHY_NOT_SUPPORTED); + // false if has fs phy, otherwise true since hs phy is the only available phy + return !has_fs_phy && has_hs_phy; } - - const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; - return ghwcfg2.hs_phy_type != GHWCFG2_HSPHY_NOT_SUPPORTED; } -/* dwc2 has several PHYs option - * - UTMI+ is internal highspeed PHY, clock can be 30 Mhz (8-bit) or 60 Mhz (16-bit) - * - ULPI is external highspeed PHY, clock is 60Mhz with only 8-bit interface - * - Dedicated FS PHY is internal with clock 48Mhz. - * - * In addition, UTMI+/ULPI can be shared to run at fullspeed mode with 48Mhz - * -*/ bool dwc2_core_init(uint8_t rhport, bool is_hs_phy, bool is_dma) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); diff --git a/src/portable/synopsys/dwc2/dwc2_common.h b/src/portable/synopsys/dwc2/dwc2_common.h index 6ee351ab5..1947173b2 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.h +++ b/src/portable/synopsys/dwc2/dwc2_common.h @@ -84,6 +84,7 @@ TU_ATTR_ALWAYS_INLINE static inline dwc2_regs_t* DWC2_REG(uint8_t rhport) { return (dwc2_regs_t*)_dwc2_controller[rhport].reg_base; } +// check if highspeed phy should be used bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, bool prefer_hs_phy); bool dwc2_core_init(uint8_t rhport, bool is_hs_phy, bool is_dma); void dwc2_core_handle_common_irq(uint8_t rhport, bool in_isr); diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index cc11c82d7..0fd60b35d 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -351,7 +351,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t cal_next_pid(uint8_t pid, uint8_t pa * TX periodic (PTX) * - At least largest-EPsize*MulCount/4 (MulCount up to 3 for high-bandwidth ISO/interrupt) */ -static void dfifo_host_init(uint8_t rhport, bool is_highspeed) { +static void dfifo_host_init(uint8_t rhport, bool is_hs_phy) { const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; dwc2_regs_t* dwc2 = DWC2_REG(rhport); const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; @@ -365,8 +365,8 @@ static void dfifo_host_init(uint8_t rhport, bool is_highspeed) { // fixed allocation for now, improve later: // - ptx_largest is limited to 256 for FS since most FS core only has 1024 bytes total - uint32_t nptx_largest = is_highspeed ? TUSB_EPSIZE_BULK_HS / 4 : TUSB_EPSIZE_BULK_FS / 4; - uint32_t ptx_largest = is_highspeed ? TUSB_EPSIZE_ISO_HS_MAX / 4 : 256 / 4; + uint32_t nptx_largest = is_hs_phy ? TUSB_EPSIZE_BULK_HS / 4 : TUSB_EPSIZE_BULK_FS / 4; + uint32_t ptx_largest = is_hs_phy ? TUSB_EPSIZE_ISO_HS_MAX / 4 : 256 / 4; uint16_t nptxfsiz = 2 * nptx_largest; uint16_t rxfsiz = 2 * (ptx_largest + 2) + ghwcfg2.num_host_ch; @@ -416,30 +416,25 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { // force host mode and wait for mode switch dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_FDMOD) | GUSBCFG_FHMOD; -#if CFG_TUSB_MCU == OPT_MCU_STM32N6 + #if CFG_TUSB_MCU == OPT_MCU_STM32N6 // No hardware detection of Vbus B-session is available on the STM32N6 dwc2->stm32_gccfg &= ~STM32_GCCFG_VBVALOVAL; -#endif + #endif + while ((dwc2->gintsts & GINTSTS_CMOD) != GINTSTS_CMODE_HOST) {} #ifdef TUP_USBIP_DWC2_STM32 dwc2_stm32_gccfg_cfg(dwc2, false, true); #endif - bool is_highspeed; - if (!TUH_OPT_HIGH_SPEED || rh_init->speed < TUSB_SPEED_HIGH) { - dwc2->hcfg |= HCFG_FSLS_ONLY; // disable high speed mode - is_highspeed = false; - } - #if TUH_OPT_HIGH_SPEED - else { - dwc2->hcfg &= ~HCFG_FSLS_ONLY; // work at max supported speed - is_highspeed = true; + if (is_hs_phy && (rh_init->speed == TUSB_SPEED_HIGH || rh_init->speed == TUSB_SPEED_AUTO)) { + dwc2->hcfg &= ~HCFG_FSLS_ONLY; // max speed + } else { + dwc2->hcfg |= HCFG_FSLS_ONLY; // disable high speed mode } - #endif // configure a fixed-allocated fifo scheme - dfifo_host_init(rhport, is_highspeed); + dfifo_host_init(rhport, is_hs_phy); dwc2->hprt = HPRT_W1_MASK; // clear all write-1-clear bits dwc2->hprt = HPRT_POWER; // turn on VBUS -- cgit v1.3.1 From da21dab358a06106188e2bb06fa71ccd5390fa1a Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 24 Feb 2026 23:37:07 +0700 Subject: fix CDC host FTDI multiple channel loop fix typos for ftdi_process_set_config() add J-Link GDB + RTT logging instructions --- AGENTS.md | 16 +++++ src/class/cdc/cdc_host.c | 171 ++++++++++++++++++++++++----------------------- 2 files changed, 103 insertions(+), 84 deletions(-) (limited to 'src') diff --git a/AGENTS.md b/AGENTS.md index ef8baec5a..a5159aa4a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -91,6 +91,22 @@ make BOARD=raspberry_pi_pico all - Make: `make BOARD=raspberry_pi_pico all uf2` - **List all targets** (CMake/Ninja): `ninja -t targets` +## J-Link GDB Server + RTT Logging + +- Build with RTT logging enabled (example): + `cd examples/device/cdc_msc && make BOARD=stm32h743eval LOG=2 LOGGER=rtt all` +- Flash with J-Link: + `cd examples/device/cdc_msc && make BOARD=stm32h743eval LOG=2 LOGGER=rtt flash-jlink` +- Launch GDB server (keep this running in terminal 1): + `JLinkGDBServer -device stm32h743xi -if SWD -speed 4000 -port 2331 -swoport 2332 -telnetport 2333 -RTTTelnetPort 19021 -nogui` +- Read RTT output (terminal 2): + `JLinkRTTClient` +- Capture RTT to file (optional): + `JLinkRTTClient | tee rtt.log` +- For non-interactive capture: + `timeout 20s JLinkRTTClient > rtt.log` +- Use the board-specific `JLINK_DEVICE` from `hw/bsp/*/boards/*/board.mk` if you are not using `stm32h743eval`. + ## Unit Testing - Install Ceedling: `sudo gem install ceedling` diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index f19c4a327..8f6dd7200 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -127,7 +127,7 @@ static bool acm_set_control_line_state(cdch_interface_t *p_cdc, tuh_xfer_cb_ static uint16_t const ftdi_vid_pid_list[][2] = {CFG_TUH_CDC_FTDI_VID_PID_LIST}; static uint16_t ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); -static bool ftdi_proccess_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); +static bool ftdi_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); static void ftdi_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); static bool ftdi_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool ftdi_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); @@ -216,82 +216,84 @@ typedef struct { #define DRIVER_NAME_DECLARE(_str) #endif +// clang-format off // Note driver list must be in the same order as SERIAL_DRIVER enum static const cdch_serial_driver_t serial_drivers[] = { { - .vid_pid_list = NULL, - .vid_pid_count = 0, - .open = acm_open, - .process_set_config = acm_process_set_config, - .request_complete = acm_internal_control_complete, - .set_control_line_state = acm_set_control_line_state, - .set_baudrate = acm_set_line_coding, - .set_data_format = acm_set_line_coding, - .set_line_coding = acm_set_line_coding, - DRIVER_NAME_DECLARE("ACM") + .vid_pid_list = NULL, + .vid_pid_count = 0, + .open = acm_open, + .process_set_config = acm_process_set_config, + .request_complete = acm_internal_control_complete, + .set_control_line_state = acm_set_control_line_state, + .set_baudrate = acm_set_line_coding, + .set_data_format = acm_set_line_coding, + .set_line_coding = acm_set_line_coding, + DRIVER_NAME_DECLARE("ACM") }, #if CFG_TUH_CDC_FTDI { - .vid_pid_list = ftdi_vid_pid_list, - .vid_pid_count = TU_ARRAY_SIZE(ftdi_vid_pid_list), - .open = ftdi_open, - .process_set_config = ftdi_proccess_set_config, - .request_complete = ftdi_internal_control_complete, - .set_control_line_state = ftdi_set_modem_ctrl, - .set_baudrate = ftdi_set_baudrate, - .set_data_format = ftdi_set_data_format, - .set_line_coding = NULL, // 2 stage set line coding - DRIVER_NAME_DECLARE("FTDI") + .vid_pid_list = ftdi_vid_pid_list, + .vid_pid_count = TU_ARRAY_SIZE(ftdi_vid_pid_list), + .open = ftdi_open, + .process_set_config = ftdi_process_set_config, + .request_complete = ftdi_internal_control_complete, + .set_control_line_state = ftdi_set_modem_ctrl, + .set_baudrate = ftdi_set_baudrate, + .set_data_format = ftdi_set_data_format, + .set_line_coding = NULL, // 2 stage set line coding + DRIVER_NAME_DECLARE("FTDI") }, #endif #if CFG_TUH_CDC_CP210X { - .vid_pid_list = cp210x_vid_pid_list, - .vid_pid_count = TU_ARRAY_SIZE(cp210x_vid_pid_list), - .open = cp210x_open, - .process_set_config = cp210x_process_set_config, - .request_complete = cp210x_internal_control_complete, - .set_control_line_state = cp210x_set_modem_ctrl, - .set_baudrate = cp210x_set_baudrate, - .set_data_format = cp210x_set_data_format, - .set_line_coding = NULL, // 2 stage set line coding - DRIVER_NAME_DECLARE("CP210x") + .vid_pid_list = cp210x_vid_pid_list, + .vid_pid_count = TU_ARRAY_SIZE(cp210x_vid_pid_list), + .open = cp210x_open, + .process_set_config = cp210x_process_set_config, + .request_complete = cp210x_internal_control_complete, + .set_control_line_state = cp210x_set_modem_ctrl, + .set_baudrate = cp210x_set_baudrate, + .set_data_format = cp210x_set_data_format, + .set_line_coding = NULL, // 2 stage set line coding + DRIVER_NAME_DECLARE("CP210x") }, #endif #if CFG_TUH_CDC_CH34X { - .vid_pid_list = ch34x_vid_pid_list, - .vid_pid_count = TU_ARRAY_SIZE(ch34x_vid_pid_list), - .open = ch34x_open, - .process_set_config = ch34x_process_set_config, - .request_complete = ch34x_internal_control_complete, - - .set_control_line_state = ch34x_set_modem_ctrl, - .set_baudrate = ch34x_set_baudrate, - .set_data_format = ch34x_set_data_format, - .set_line_coding = NULL, // 2 stage set line coding - DRIVER_NAME_DECLARE("CH34x") + .vid_pid_list = ch34x_vid_pid_list, + .vid_pid_count = TU_ARRAY_SIZE(ch34x_vid_pid_list), + .open = ch34x_open, + .process_set_config = ch34x_process_set_config, + .request_complete = ch34x_internal_control_complete, + + .set_control_line_state = ch34x_set_modem_ctrl, + .set_baudrate = ch34x_set_baudrate, + .set_data_format = ch34x_set_data_format, + .set_line_coding = NULL, // 2 stage set line coding + DRIVER_NAME_DECLARE("CH34x") }, #endif #if CFG_TUH_CDC_PL2303 { - .vid_pid_list = pl2303_vid_pid_list, - .vid_pid_count = TU_ARRAY_SIZE(pl2303_vid_pid_list), - .open = pl2303_open, - .process_set_config = pl2303_process_set_config, - .request_complete = pl2303_internal_control_complete, - .set_control_line_state = pl2303_set_modem_ctrl, - .set_baudrate = pl2303_set_line_coding, - .set_data_format = pl2303_set_line_coding, - .set_line_coding = pl2303_set_line_coding, - DRIVER_NAME_DECLARE("PL2303") + .vid_pid_list = pl2303_vid_pid_list, + .vid_pid_count = TU_ARRAY_SIZE(pl2303_vid_pid_list), + .open = pl2303_open, + .process_set_config = pl2303_process_set_config, + .request_complete = pl2303_internal_control_complete, + .set_control_line_state = pl2303_set_modem_ctrl, + .set_baudrate = pl2303_set_line_coding, + .set_data_format = pl2303_set_line_coding, + .set_line_coding = pl2303_set_line_coding, + DRIVER_NAME_DECLARE("PL2303") } #endif }; +// clang-format on TU_VERIFY_STATIC(TU_ARRAY_SIZE(serial_drivers) == SERIAL_DRIVER_COUNT, "Serial driver count mismatch"); @@ -761,7 +763,8 @@ uint16_t cdch_open(uint8_t rhport, uint8_t daddr, const tusb_desc_interface_t *i for (size_t i = 0; i < driver->vid_pid_count; i++) { if (driver->vid_pid_list[i][0] == vid && driver->vid_pid_list[i][1] == pid) { const uint16_t drv_len = driver->open(daddr, itf_desc, max_len); - TU_LOG_DRV("[:%u:%u] CDCh %s open %s\r\n", daddr, itf_desc->bInterfaceNumber, driver->name, drv_len > 0 ? "OK" : "FAILED"); + TU_LOG_DRV("[:%u:%u] CDCh %s open %s\r\n", daddr, itf_desc->bInterfaceNumber, driver->name, + drv_len > 0 ? "OK" : "FAILED"); return drv_len; } } @@ -773,35 +776,16 @@ uint16_t cdch_open(uint8_t rhport, uint8_t daddr, const tusb_desc_interface_t *i return 0; } -bool cdch_set_config(uint8_t daddr, uint8_t itf_num) { - tusb_control_request_t request; - request.wIndex = tu_htole16((uint16_t) itf_num); - uint8_t const idx = tuh_cdc_itf_get_index(daddr, itf_num); - cdch_interface_t *p_cdc = get_itf(idx); - TU_ASSERT(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); - TU_LOG_CDC(p_cdc, "set config"); - - // fake transfer to kick-off process_set_config() - tuh_xfer_t xfer; - xfer.daddr = daddr; - xfer.result = XFER_RESULT_SUCCESS; - xfer.setup = &request; - xfer.user_data = 0; // initial state 0 - cdch_process_set_config(&xfer); - - return true; -} - static void set_config_complete(cdch_interface_t *p_cdc, bool success) { if (success) { const uint8_t idx = get_idx_by_ptr(p_cdc); - p_cdc->mounted = true; + p_cdc->mounted = true; tuh_cdc_mount_cb(idx); // Prepare for incoming data tu_edpt_stream_read_xfer(&p_cdc->stream.rx); } else { // clear the interface entry - p_cdc->daddr = 0; + p_cdc->daddr = 0; p_cdc->bInterfaceNumber = 0; } @@ -810,6 +794,33 @@ static void set_config_complete(cdch_interface_t *p_cdc, bool success) { usbh_driver_set_config_complete(p_cdc->daddr, p_cdc->bInterfaceNumber + itf_offset); } +bool cdch_set_config(uint8_t daddr, uint8_t itf_num) { + const uint8_t idx = tuh_cdc_itf_get_index(daddr, itf_num); + cdch_interface_t *p_cdc = get_itf(idx); + TU_ASSERT(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); + TU_LOG_CDC(p_cdc, "set config"); + + // fake transfer to kick-off process_set_config() + tusb_control_request_t request; + request.wIndex = tu_htole16((uint16_t)itf_num); + + tuh_xfer_t xfer; + xfer.daddr = daddr; + xfer.ep_addr = 0; + xfer.result = XFER_RESULT_SUCCESS; + xfer.setup = &request; + xfer.complete_cb = NULL; + xfer.buffer = NULL; + xfer.user_data = 0; // initial state 0 + + const cdch_serial_driver_t *driver = &serial_drivers[p_cdc->serial_drid]; + if (!driver->process_set_config(p_cdc, &xfer)) { + set_config_complete(p_cdc, false); + } + + return true; +} + static void cdch_process_set_config(tuh_xfer_t *xfer) { cdch_interface_t *p_cdc = get_itf_by_xfer(xfer); TU_ASSERT(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT,); @@ -1215,22 +1226,14 @@ static uint16_t ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, return drv_len; } -static bool ftdi_proccess_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { +static bool ftdi_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); const uintptr_t state = xfer->user_data; switch (state) { // from here sequence overtaken from Linux Kernel function ftdi_port_probe() case CONFIG_FTDI_DETERMINE_TYPE: // determine type - if (p_cdc->bInterfaceNumber == 0) { - TU_ASSERT(ftdi_determine_type(p_cdc)); - } else { - // other interfaces have same type as interface 0 - uint8_t const idx_itf0 = tuh_cdc_itf_get_index(xfer->daddr, 0); - cdch_interface_t const *p_cdc_itf0 = get_itf(idx_itf0); - TU_ASSERT(p_cdc_itf0); - p_cdc->ftdi.chip_type = p_cdc_itf0->ftdi.chip_type; - } + TU_ASSERT(ftdi_determine_type(p_cdc)); TU_ATTR_FALLTHROUGH; case CONFIG_FTDI_WRITE_LATENCY: -- cgit v1.3.1 From 4d402194dc506a98ed574233cd542ca7f27ff991 Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Wed, 25 Feb 2026 12:38:44 -0300 Subject: midi device: add cable-aware stream read (tud_midi_n_demux_stream_read) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing tud_midi_n_stream_read() accepts a cable_num parameter but ignores it — all cables share a single FIFO and stream parser state, so data from different virtual cables is silently mixed together. Add tud_midi_n_demux_stream_read() which returns the cable number of the data that was actually read. It peeks at each USB-MIDI event packet header before consuming it and stops when the next packet belongs to a different cable, allowing callers to dispatch per-cable without losing data. Implementation details: - Mirrors the host-side tuh_midi_stream_read() approach: tu_edpt_stream_peek for cable inspection, CIN-based byte count (USB MIDI 1.0 Table 4-1), leftover handling via existing midi_driver_stream_t - *p_cable_num initialized to 0xff sentinel so callers can detect "no data" even when return value is 0 - Cable-change check (total_read > 0 guard) covers both leftover-originated reads and freshly consumed packets - TU_VERIFY uses explicit != NULL comparisons, consistent with codebase style - Note: shares stream->buffer with tud_midi_n_stream_read(); do not mix calls on the same interface - Adds single-interface convenience wrapper tud_midi_demux_stream_read() Closes #1838 --- src/class/midi/midi_device.c | 102 +++++++++++++++++++++++++++++++++++++++++++ src/class/midi/midi_device.h | 12 +++++ 2 files changed, 114 insertions(+) (limited to 'src') diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 023a81595..a49cd725b 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -168,6 +168,108 @@ uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void *buffer, ui return total_read; } +// Note: this function shares stream->buffer with tud_midi_n_stream_read(). +// Do not mix calls to both functions on the same interface. +uint32_t tud_midi_n_demux_stream_read(uint8_t itf, uint8_t *p_cable_num, void *buffer, uint32_t bufsize) { + TU_VERIFY(p_cable_num != NULL && buffer != NULL && bufsize > 0, 0); + + midid_interface_t *p_midi = &_midid_itf[itf]; + midi_driver_stream_t *stream = &p_midi->stream_read; + tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; + + uint8_t *buf8 = (uint8_t *)buffer; + uint32_t total_read = 0; + + // Initialize to invalid cable so callers can detect "no data" even when + // the return value is 0. + *p_cable_num = 0xff; + + // If there are leftover bytes from a previous partial read, return them first + if (stream->total > 0) { + *p_cable_num = (stream->buffer[0] >> 4) & 0x0f; + const uint8_t count = (uint8_t)tu_min32((uint32_t)(stream->total - stream->index), bufsize); + TU_VERIFY(0 == tu_memcpy_s(buf8, bufsize, stream->buffer + 1 + stream->index, count)); + + total_read += count; + stream->index += count; + buf8 += count; + bufsize -= count; + + if (stream->total == stream->index) { + stream->index = 0; + stream->total = 0; + } + + if (bufsize == 0) { + return total_read; + } + } + + while (bufsize > 0) { + // Peek at next packet header to get cable number without consuming + uint8_t one_byte; + if (!tu_edpt_stream_peek(ep_str, &one_byte)) { + break; + } + + const uint8_t next_cable = (one_byte >> 4) & 0x0f; + + // Stop if cable changed (covers both leftover-originated reads and + // freshly consumed packets — total_read > 0 in either case) + if (total_read > 0 && next_cable != *p_cable_num) { + break; + } + *p_cable_num = next_cable; + + // Consume the packet + if (!tud_midi_n_packet_read(itf, stream->buffer)) { + break; + } + + const uint8_t code_index = stream->buffer[0] & 0x0f; + uint8_t msg_bytes; + + // MIDI 1.0 Table 4-1: Code Index Number Classifications + switch (code_index) { + case MIDI_CIN_MISC: + case MIDI_CIN_CABLE_EVENT: + // Reserved and unused, skip this packet + continue; + + case MIDI_CIN_SYSEX_END_1BYTE: + case MIDI_CIN_1BYTE_DATA: + msg_bytes = 1; + break; + + case MIDI_CIN_SYSCOM_2BYTE: + case MIDI_CIN_SYSEX_END_2BYTE: + case MIDI_CIN_PROGRAM_CHANGE: + case MIDI_CIN_CHANNEL_PRESSURE: + msg_bytes = 2; + break; + + default: + msg_bytes = 3; + break; + } + + const uint8_t count = (uint8_t)tu_min32((uint32_t)msg_bytes, bufsize); + TU_VERIFY(0 == tu_memcpy_s(buf8, bufsize, stream->buffer + 1, count)); + + total_read += count; + buf8 += count; + bufsize -= count; + + if (count < msg_bytes) { + // Output buffer full, save remaining for next call + stream->total = msg_bytes; + stream->index = count; + } + } + + return total_read; +} + bool tud_midi_n_packet_read(uint8_t itf, uint8_t packet[4]) { midid_interface_t *p_midi = &_midid_itf[itf]; tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index ddbc2f9f0..b80ad544a 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -66,6 +66,13 @@ uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num); // Read byte stream (legacy) uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void *buffer, uint32_t bufsize); +// Read byte stream with cable demultiplexing: returns the cable number of the +// data that was read. Reads from a single cable per call; stops when the next +// packet belongs to a different cable so the caller can dispatch per-cable. +// Note: shares internal state with tud_midi_n_stream_read(); do not mix both +// on the same interface. +uint32_t tud_midi_n_demux_stream_read(uint8_t itf, uint8_t *p_cable_num, void *buffer, uint32_t bufsize); + // Write byte Stream (legacy) uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t *buffer, uint32_t bufsize); @@ -96,6 +103,11 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_stream_read(void *buffer, return tud_midi_n_stream_read(0, 0, buffer, bufsize); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t +tud_midi_demux_stream_read(uint8_t *p_cable_num, void *buffer, uint32_t bufsize) { + return tud_midi_n_demux_stream_read(0, p_cable_num, buffer, bufsize); +} + TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_stream_write(uint8_t cable_num, const uint8_t *buffer, uint32_t bufsize) { return tud_midi_n_stream_write(0, cable_num, buffer, bufsize); -- cgit v1.3.1 From 56fca0076a3ee51ae56dd2fed52b5ac778a2b58e Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 26 Feb 2026 14:33:04 +0700 Subject: refactor, rename to schedule function with usbh_call_after_ms() to use with enumeration delay --- src/common/tusb_private.h | 12 +- src/host/usbh.c | 368 +++++++++++++++++++++------------------------- src/host/usbh_pvt.h | 1 + src/tusb_option.h | 16 +- 4 files changed, 179 insertions(+), 218 deletions(-) (limited to 'src') diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 43ce7a1df..5a51dfc37 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef TUSB_PRIVATE_H_ -#define TUSB_PRIVATE_H_ +#ifndef TUSB_PRIVATE_H +#define TUSB_PRIVATE_H // Internal Helper used by Host and Device Stack @@ -33,9 +33,11 @@ extern "C" { #endif -//--------------------------------------------------------------------+ -// Configuration -//--------------------------------------------------------------------+ +typedef void (*tusb_defer_func_t)(uintptr_t param); + + //--------------------------------------------------------------------+ + // Configuration + //--------------------------------------------------------------------+ #define TUP_USBIP_CONTROLLER_NUM 2 extern tusb_role_t _tusb_rhport_role[TUP_USBIP_CONTROLLER_NUM]; diff --git a/src/host/usbh.c b/src/host/usbh.c index f32d1336d..09f6adb15 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -175,9 +175,6 @@ OSAL_QUEUE_DEF(usbh_int_set, _usbh_daqdef, TOTAL_DEVICES, hcd_event_t); static osal_queue_t _usbh_daq; #endif -// Callback after waiting -typedef void (*usbh_wait_delay_cb)(void); - // Control transfers: since most controllers do not support multiple control transfers // on multiple devices concurrently and control transfers are not used much except for // enumeration, we will only execute control transfers one at a time. @@ -196,14 +193,16 @@ typedef struct { uint8_t controller_id; // controller ID uint8_t enumerating_daddr; // device address of the device being enumerated uint8_t attach_debouncing_bm; // bitmask for roothub port attach debouncing - uint8_t enum_failed_count; // see process_enumeration() tuh_bus_info_t dev0_bus; // bus info for dev0 in enumeration usbh_ctrl_xfer_info_t ctrl_xfer_info; // control transfer -#if CFG_TUH_TASK_USE_TIME_MILLIS_API - tuh_xfer_t enum_xfer_retry; // enumeration transfer to retry - usbh_wait_delay_cb enum_wait_delay_cb; // continuation function after waiting - uint32_t enum_wait_deadline; // ticks when the timer expires -#endif + + #if CFG_TUSB_OS_HAS_SCHEDULER == 0 // call after only needed for non-scheduler OS + struct { + tusb_defer_func_t func; + uintptr_t arg; + uint32_t at_ms; + } call_after; + #endif } usbh_data_t; static usbh_data_t _usbh_data = { @@ -365,17 +364,18 @@ TU_ATTR_ALWAYS_INLINE static inline bool usbh_setup_send(uint8_t daddr, const ui return ret; } -TU_ATTR_ALWAYS_INLINE static inline void usbh_wait_delay_ms(uint32_t delay_ms, usbh_wait_delay_cb complete_cb) -{ -#if CFG_TUH_TASK_USE_TIME_MILLIS_API - TU_LOG_USBH("USBH start timer for %u ms\r\n", (unsigned int)delay_ms); - _usbh_data.enum_wait_deadline = tusb_time_millis_api() + delay_ms; - _usbh_data.enum_wait_delay_cb = complete_cb; -#else - TU_LOG_USBH("USBH sleep for %u ms\r\n", (unsigned int)delay_ms); - tusb_time_delay_ms_api(delay_ms); - complete_cb(); -#endif +// For non-scheduler deferred callback. For scheduler OS: blocking delay then callback +static void usbh_call_after_ms(uint32_t ms, tusb_defer_func_t func, uintptr_t param) { + #if CFG_TUSB_OS_HAS_SCHEDULER + TU_LOG_USBH("USBH sleep for %u ms\r\n", (unsigned int)ms); + osal_task_delay(ms); + func(param); + #else + TU_LOG_USBH("USBH start timer for %u ms\r\n", (unsigned int)ms); + _usbh_data.call_after.func = func; + _usbh_data.call_after.arg = param; + _usbh_data.call_after.at_ms = tusb_time_millis_api() + ms; + #endif } TU_ATTR_ALWAYS_INLINE static inline void usbh_device_close(uint8_t rhport, uint8_t daddr) { @@ -389,9 +389,9 @@ TU_ATTR_ALWAYS_INLINE static inline void usbh_device_close(uint8_t rhport, uint8 // invalidate if enumerating if (daddr == _usbh_data.enumerating_daddr) { _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8; -#if CFG_TUH_TASK_USE_TIME_MILLIS_API - _usbh_data.enum_wait_delay_cb = NULL; -#endif + #if CFG_TUSB_OS_HAS_SCHEDULER == 0 + _usbh_data.call_after.func = NULL; + #endif } } @@ -546,9 +546,6 @@ bool tuh_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { _usbh_data.controller_id = TUSB_INDEX_INVALID_8; _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8; -#if CFG_TUH_TASK_USE_TIME_MILLIS_API - _usbh_data.enum_wait_delay_cb = NULL; -#endif for (uint8_t i = 0; i < TOTAL_DEVICES; i++) { clear_device(&_usbh_devices[i]); @@ -643,16 +640,16 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { return; } -#if CFG_TUH_TASK_USE_TIME_MILLIS_API +#if CFG_TUSB_OS_HAS_SCHEDULER == 0 // Process continuation function if timer is expired - usbh_wait_delay_cb delay_cb = _usbh_data.enum_wait_delay_cb; - if (delay_cb) { - int32_t ms = (int32_t)(_usbh_data.enum_wait_deadline - tusb_time_millis_api()); + tusb_defer_func_t after_cb = _usbh_data.call_after.func; + if (after_cb) { + int32_t ms = (int32_t)(_usbh_data.call_after.at_ms - tusb_time_millis_api()); if (ms <= 0) { // delay expired, run callback now TU_LOG_USBH("USBH run timer callback\r\n"); - _usbh_data.enum_wait_delay_cb = NULL; - delay_cb(); + _usbh_data.call_after.func = NULL; + after_cb(_usbh_data.call_after.arg); } else if (timeout_ms > (uint32_t)ms) { // reduce timeout accordingly timeout_ms = (uint32_t)ms; @@ -1499,10 +1496,9 @@ enum { // USB 2.0 specs 7.1.7 for timing enum { ENUM_IDLE, ENUM_HUB_RERSET, - ENUM_HUB_GET_STATUS_AFTER_RESET, + ENUM_HUB_RESET_COMPLETE, ENUM_HUB_CLEAR_RESET, ENUM_HUB_CLEAR_RESET_COMPLETE, - ENUM_ADDR0_DEVICE_DESC, ENUM_SET_ADDR, ENUM_GET_DEVICE_DESC, @@ -1521,128 +1517,146 @@ enum { }; static uint8_t enum_get_new_address(bool is_hub); -static bool enum_parse_configuration_desc (uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg); -static void enum_full_complete(bool success); -static void process_enumeration(tuh_xfer_t* xfer); +static bool enum_parse_configuration_desc(uint8_t dev_addr, const tusb_desc_configuration_t *desc_cfg); +static void enum_full_complete(bool success); +static void process_enumeration(tuh_xfer_t *xfer); -// continuation functions after waiting -#if CFG_TUH_TASK_USE_TIME_MILLIS_API -static void enum_after_attempt_delay(void); -#endif -static void enum_after_debouncing_delay(void); -static void enum_after_reset_root_delay(void); -static void enum_after_reset_root_post_delay(void); -static void enum_after_reset_recovery_delay(void); -static void enum_after_set_address_recovery_delay(void); -#if CFG_TUH_HUB -static void enum_after_reset_hub_delay(void); -#endif +enum { + ENUM_AFTER_DEBOUNCING_DELAY, + ENUM_AFTER_RESET_ROOT_DELAY, + ENUM_AFTER_RESET_ROOT_POST_DELAY, + ENUM_AFTER_RESET_HUB_DELAY, + ENUM_AFTER_RESET_RECOVERY_DELAY, + ENUM_AFTER_SET_ADDRESS_RECOVERY_DELAY, +}; -// start a new enumeration process -static void enum_new_device(hcd_event_t* event) { - tuh_bus_info_t* dev0_bus = &_usbh_data.dev0_bus; - dev0_bus->rhport = event->rhport; - dev0_bus->hub_addr = event->connection.hub_addr; - dev0_bus->hub_port = event->connection.hub_port; + // fallthrough to avoid recursive call of enum_async_delay() + #if CFG_TUSB_OS_HAS_SCHEDULER + #define ENUM_ASYNC_DELAY_OR_FALLTHROUGH(_ms, _state) \ + osal_task_delay(_ms); \ + TU_ATTR_FALLTHROUGH + #else + #define ENUM_ASYNC_DELAY_OR_FALLTHROUGH(_ms, _state) \ + usbh_call_after_ms(_ms, enum_async_delay, _state); \ + break + #endif - usbh_wait_delay_ms(ENUM_DEBOUNCING_DELAY_MS, enum_after_debouncing_delay); -} +// process async delay in enumeration +static void enum_async_delay(uintptr_t state) { + tuh_bus_info_t *dev0_bus = &_usbh_data.dev0_bus; + switch (state) { + case ENUM_AFTER_DEBOUNCING_DELAY: + if (dev0_bus->hub_addr == 0) { + // connected directly to roothub + _usbh_data.attach_debouncing_bm &= (uint8_t)~TU_BIT(dev0_bus->rhport); // clear roothub debouncing delay + if (!hcd_port_connect_status(dev0_bus->rhport)) { + TU_LOG_USBH("Device unplugged while debouncing\r\n"); + enum_full_complete(false); + return; + } + hcd_port_reset(dev0_bus->rhport); // reset port + ENUM_ASYNC_DELAY_OR_FALLTHROUGH(ENUM_RESET_ROOT_DELAY_MS, ENUM_AFTER_RESET_ROOT_DELAY); + } + #if CFG_TUH_HUB + else { + // connected via hub + TU_VERIFY(dev0_bus->hub_port != 0, ); + TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, NULL, process_enumeration, + ENUM_HUB_RERSET), ); + break; + } + #endif // hub -static void enum_after_debouncing_delay(void) { - tuh_bus_info_t* dev0_bus = &_usbh_data.dev0_bus; - if (dev0_bus->hub_addr == 0) { - // connected directly to roothub - // USB bus not active and frame number is not available yet. - // need to depend on tusb_time_millis_api() TODO non blocking + case ENUM_AFTER_RESET_ROOT_DELAY: + hcd_port_reset_end(dev0_bus->rhport); + ENUM_ASYNC_DELAY_OR_FALLTHROUGH(ENUM_RESET_ROOT_POST_DELAY_MS, ENUM_AFTER_RESET_ROOT_POST_DELAY); - _usbh_data.attach_debouncing_bm &= (uint8_t) ~TU_BIT(dev0_bus->rhport); // clear roothub debouncing delay + case ENUM_AFTER_RESET_ROOT_POST_DELAY: + if (!hcd_port_connect_status(dev0_bus->rhport)) { + // device unplugged while delaying + enum_full_complete(false); + return; + } - if (!hcd_port_connect_status(dev0_bus->rhport)) { - TU_LOG_USBH("Device unplugged while debouncing\r\n"); - enum_full_complete(false); - return; - } + dev0_bus->speed = hcd_port_speed_get(dev0_bus->rhport); + TU_LOG_USBH("%s Speed\r\n", tu_str_speed[dev0_bus->speed]); - // reset device - hcd_port_reset(dev0_bus->rhport); - usbh_wait_delay_ms(ENUM_RESET_ROOT_DELAY_MS, enum_after_reset_root_delay); - } - #if CFG_TUH_HUB - else { - // connected via hub - TU_VERIFY(dev0_bus->hub_port != 0,); - TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, NULL, - process_enumeration, ENUM_HUB_RERSET),); - } - #endif // hub -} + // fake transfer to kick-off the enumeration process + tuh_xfer_t xfer; + xfer.daddr = 0; + xfer.result = XFER_RESULT_SUCCESS; + xfer.user_data = ENUM_ADDR0_DEVICE_DESC; + process_enumeration(&xfer); + break; -static void enum_after_reset_root_delay(void) { - tuh_bus_info_t* dev0_bus = &_usbh_data.dev0_bus; - hcd_port_reset_end(dev0_bus->rhport); - return usbh_wait_delay_ms(ENUM_RESET_ROOT_POST_DELAY_MS, enum_after_reset_root_post_delay); -} + #if CFG_TUH_HUB + case ENUM_AFTER_RESET_HUB_DELAY: + // get status after reset complete to check for reset change + TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, NULL, process_enumeration, + ENUM_HUB_CLEAR_RESET), ); + break; + #endif -static void enum_after_reset_root_post_delay(void) { - tuh_bus_info_t* dev0_bus = &_usbh_data.dev0_bus; - if (!hcd_port_connect_status(dev0_bus->rhport)) { - // device unplugged while delaying - enum_full_complete(false); - return; - } + case ENUM_AFTER_RESET_RECOVERY_DELAY: + // TODO probably doesn't need to open/close each enumeration + if (!usbh_edpt_control_open(0, 8)) { + TU_LOG_USBH("Failed to open dev0's control endpoint\r\n"); + enum_full_complete(false); // Stop enumeration gracefully + return; + } + // Get first 8 bytes of device descriptor for control endpoint size + TU_LOG_USBH("Get 8 byte of Device Descriptor\r\n"); + TU_ASSERT(tuh_descriptor_get_device(0, _usbh_epbuf.ctrl, 8, process_enumeration, ENUM_SET_ADDR), ); + break; - dev0_bus->speed = hcd_port_speed_get(dev0_bus->rhport); - TU_LOG_USBH("%s Speed\r\n", tu_str_speed[dev0_bus->speed]); + case ENUM_AFTER_SET_ADDRESS_RECOVERY_DELAY: { + const uint8_t new_addr = _usbh_data.enumerating_daddr; + usbh_device_t *new_dev = get_device(new_addr); + TU_ASSERT(new_dev, ); + if (!usbh_edpt_control_open(new_addr, new_dev->bMaxPacketSize0)) { + TU_LOG_USBH("Failed to open new device's control endpoint\r\n"); + clear_device(new_dev); + enum_full_complete(false); + return; + } + TU_LOG_USBH("Get Device Descriptor\r\n"); + TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_epbuf.ctrl, sizeof(tusb_desc_device_t), process_enumeration, + ENUM_GET_STRING_LANGUAGE_ID_LEN), ); + break; + } - // fake transfer to kick-off the enumeration process - tuh_xfer_t xfer; - xfer.daddr = 0; - xfer.result = XFER_RESULT_SUCCESS; - xfer.user_data = ENUM_ADDR0_DEVICE_DESC; - process_enumeration(&xfer); + default: + break; + } } -enum { - ATTEMPT_COUNT_MAX = 3, - ATTEMPT_DELAY_MS = 100 -}; +// start a new enumeration process +static void enum_new_device(hcd_event_t *event) { + tuh_bus_info_t *dev0_bus = &_usbh_data.dev0_bus; + dev0_bus->rhport = event->rhport; + dev0_bus->hub_addr = event->connection.hub_addr; + dev0_bus->hub_port = event->connection.hub_port; + usbh_call_after_ms(ENUM_DEBOUNCING_DELAY_MS, enum_async_delay, ENUM_AFTER_DEBOUNCING_DELAY); +} // process device enumeration -static void process_enumeration(tuh_xfer_t* xfer) { - // Retry a few times while enumerating since device can be unstable when starting up - _usbh_data.enum_failed_count = 0; +static void process_enumeration(tuh_xfer_t *xfer) { if (XFER_RESULT_FAILED == xfer->result) { - - // retry if not reaching max attempt - _usbh_data.enum_failed_count++; - bool retry = (_usbh_data.enumerating_daddr != TUSB_INDEX_INVALID_8) && (_usbh_data.enum_failed_count < ATTEMPT_COUNT_MAX); - if (retry) { -#if CFG_TUH_TASK_USE_TIME_MILLIS_API - // save transfer for later - _usbh_data.enum_xfer_retry = *xfer; - usbh_wait_delay_ms(ATTEMPT_DELAY_MS, enum_after_attempt_delay); // wait for reset to take effect -#else - if (!tuh_control_xfer(xfer)) - enum_full_complete(false); // complete as failed -#endif - } else { - enum_full_complete(false); // complete as failed - } + enum_full_complete(false); // failed to enum return; } - _usbh_data.enum_failed_count = 0; - uint8_t const daddr = xfer->daddr; - uintptr_t const state = xfer->user_data; - usbh_device_t* dev = get_device(daddr); - tuh_bus_info_t* dev0_bus = &_usbh_data.dev0_bus; + const uint8_t daddr = xfer->daddr; + const uintptr_t state = xfer->user_data; + usbh_device_t *dev = get_device(daddr); + tuh_bus_info_t *dev0_bus = &_usbh_data.dev0_bus; if (daddr > 0) { TU_ASSERT(dev != NULL,); } uint16_t langid = 0x0409; // default is English switch (state) { - #if CFG_TUH_HUB + #if CFG_TUH_HUB case ENUM_HUB_RERSET: { hub_port_status_response_t port_status; hub_port_get_status_local(dev0_bus->hub_addr, dev0_bus->hub_port, &port_status); @@ -1653,14 +1667,14 @@ static void process_enumeration(tuh_xfer_t* xfer) { return; } - TU_ASSERT(hub_port_reset(dev0_bus->hub_addr, dev0_bus->hub_port, process_enumeration, ENUM_HUB_GET_STATUS_AFTER_RESET),); + TU_ASSERT(hub_port_reset(dev0_bus->hub_addr, dev0_bus->hub_port, process_enumeration, ENUM_HUB_RESET_COMPLETE), ); break; } - case ENUM_HUB_GET_STATUS_AFTER_RESET: { - usbh_wait_delay_ms(ENUM_RESET_HUB_DELAY_MS, enum_after_reset_hub_delay); // wait for reset to take effect + case ENUM_HUB_RESET_COMPLETE: + // wait for reset to take effect + usbh_call_after_ms(ENUM_RESET_HUB_DELAY_MS, enum_async_delay, ENUM_AFTER_RESET_HUB_DELAY); break; - } case ENUM_HUB_CLEAR_RESET: { hub_port_status_response_t port_status; @@ -1687,17 +1701,17 @@ static void process_enumeration(tuh_xfer_t* xfer) { return; } - dev0_bus->speed = (port_status.status.high_speed) ? TUSB_SPEED_HIGH : - (port_status.status.low_speed) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; + dev0_bus->speed = (port_status.status.high_speed) ? TUSB_SPEED_HIGH + : (port_status.status.low_speed) ? TUSB_SPEED_LOW + : TUSB_SPEED_FULL; TU_ATTR_FALLTHROUGH; } - #endif + #endif - case ENUM_ADDR0_DEVICE_DESC: { - usbh_wait_delay_ms(ENUM_RESET_RECOVERY_DELAY_MS, enum_after_reset_recovery_delay); + case ENUM_ADDR0_DEVICE_DESC: + usbh_call_after_ms(ENUM_RESET_RECOVERY_DELAY_MS, enum_async_delay, ENUM_AFTER_RESET_RECOVERY_DELAY); break; - } case ENUM_SET_ADDR: { const tusb_desc_device_t *desc_device = (const tusb_desc_device_t *) _usbh_epbuf.ctrl; @@ -1709,20 +1723,19 @@ static void process_enumeration(tuh_xfer_t* xfer) { new_dev->connected = 1; new_dev->bMaxPacketSize0 = desc_device->bMaxPacketSize0; - TU_ASSERT(tuh_address_set(0, new_addr, process_enumeration, ENUM_GET_DEVICE_DESC),); + TU_ASSERT(tuh_address_set(0, new_addr, process_enumeration, ENUM_GET_DEVICE_DESC), ); break; } case ENUM_GET_DEVICE_DESC: { - const uint8_t new_addr = (uint8_t) tu_le16toh(xfer->setup->wValue); - usbh_device_t* new_dev = get_device(new_addr); - TU_ASSERT(new_dev,); - new_dev->addressed = 1; + const uint8_t new_addr = (uint8_t)tu_le16toh(xfer->setup->wValue); + usbh_device_t *new_dev = get_device(new_addr); + TU_ASSERT(new_dev, ); + new_dev->addressed = 1; _usbh_data.enumerating_daddr = new_addr; usbh_device_close(dev0_bus->rhport, 0); // close dev0 - - usbh_wait_delay_ms(ENUM_SET_ADDRESS_RECOVERY_DELAY_MS, enum_after_set_address_recovery_delay); + usbh_call_after_ms(ENUM_SET_ADDRESS_RECOVERY_DELAY_MS, enum_async_delay, ENUM_AFTER_SET_ADDRESS_RECOVERY_DELAY); break; } @@ -1896,53 +1909,6 @@ static void process_enumeration(tuh_xfer_t* xfer) { } } -#if CFG_TUH_TASK_USE_TIME_MILLIS_API -static void enum_after_attempt_delay(void) { - TU_LOG_USBH("Enumeration attempt %u/%u\r\n", _usbh_data.enum_failed_count+1, ATTEMPT_COUNT_MAX); - if (!tuh_control_xfer(&_usbh_data.enum_xfer_retry)) - enum_full_complete(false); // complete as failed -} -#endif - -static void enum_after_set_address_recovery_delay(void) { - const uint8_t new_addr =_usbh_data.enumerating_daddr; - usbh_device_t* new_dev = get_device(new_addr); - TU_ASSERT(new_dev,); - if (!usbh_edpt_control_open(new_addr, new_dev->bMaxPacketSize0)) { // open new control endpoint - // Stop enumeration gracefully - clear_device(new_dev); - enum_full_complete(false); - TU_ASSERT(false,); - } - - TU_LOG_USBH("Get Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_epbuf.ctrl, sizeof(tusb_desc_device_t), - process_enumeration, ENUM_GET_STRING_LANGUAGE_ID_LEN),); -} - -static void enum_after_reset_recovery_delay(void) { - // TODO probably doesn't need to open/close each enumeration - uint8_t const addr0 = 0; - if (!usbh_edpt_control_open(addr0, 8)) { - // Stop enumeration gracefully - enum_full_complete(false); - TU_ASSERT(false,); - } - - // Get first 8 bytes of device descriptor for control endpoint size - TU_LOG_USBH("Get 8 byte of Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_epbuf.ctrl, 8, - process_enumeration, ENUM_SET_ADDR),); -} - -#if CFG_TUH_HUB -static void enum_after_reset_hub_delay(void) { - tuh_bus_info_t* dev0_bus = &_usbh_data.dev0_bus; - // get status to check for reset change - TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, NULL, process_enumeration, ENUM_HUB_CLEAR_RESET),); -} -#endif - static uint8_t enum_get_new_address(bool is_hub) { uint8_t start; uint8_t end; @@ -2060,13 +2026,13 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) { static void enum_full_complete(bool success) { (void)success; - // mark enumeration as complete - _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8; -#if CFG_TUH_TASK_USE_TIME_MILLIS_API - _usbh_data.enum_wait_delay_cb = NULL; -#endif -#if CFG_TUH_HUB + _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8; // mark enumeration as complete + #if CFG_TUSB_OS_HAS_SCHEDULER == 0 + _usbh_data.call_after.func = NULL; + #endif + + #if CFG_TUH_HUB // Hub status is already requested in case of successful enumeration if (_usbh_data.dev0_bus.hub_addr != 0 && !success) { hub_edpt_status_xfer(_usbh_data.dev0_bus.hub_addr); // get next hub status diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h index 57428e3c5..ecb692e9d 100644 --- a/src/host/usbh_pvt.h +++ b/src/host/usbh_pvt.h @@ -68,6 +68,7 @@ uint8_t* usbh_get_enum_buf(void); void usbh_int_set(bool enabled); +// Invoke this function later in tuh_task() by putting it into task queue void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr); void usbh_spin_lock(bool in_isr); diff --git a/src/tusb_option.h b/src/tusb_option.h index 2cac501f7..44ba8879a 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -469,7 +469,6 @@ #define TUP_MCU_STRICT_ALIGN 0 #endif - //--------------------------------------------------------------------+ // Common Options (Default) //--------------------------------------------------------------------+ @@ -514,6 +513,10 @@ #define CFG_TUSB_OS OPT_OS_NONE #endif +#ifndef CFG_TUSB_OS_HAS_SCHEDULER + #define CFG_TUSB_OS_HAS_SCHEDULER (CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO) +#endif + #ifndef CFG_TUSB_OS_INC_PATH #ifndef CFG_TUSB_OS_INC_PATH_DEFAULT #define CFG_TUSB_OS_INC_PATH_DEFAULT @@ -698,17 +701,6 @@ #define CFG_TUH_TASK_EVENTS_PER_RUN 16 #endif -// use tusb_time_millis_api() instead of tusb_time_delay_ms_api() in tuh_task() -// tuh_task_ext() will be asynchronous and never sleep in tusb_time_delay_ms_api() -#ifndef CFG_TUH_TASK_USE_TIME_MILLIS_API - #if CFG_TUSB_OS == OPT_OS_RTX4 || CFG_TUSB_OS == OPT_OS_PICO || defined(ESP_PLATFORM) - // these boards/os do not implements the required tusb_time_millis_api() - #define CFG_TUH_TASK_USE_TIME_MILLIS_API 0 - #else - #define CFG_TUH_TASK_USE_TIME_MILLIS_API 1 - #endif -#endif - //------------- CLASS -------------// #ifndef CFG_TUH_HUB -- cgit v1.3.1 From abdf3452ac5657d880d944201ef21ff18263311a Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 26 Feb 2026 16:36:40 +0700 Subject: revert usbh dedicated queue for attached event --- src/host/usbh.c | 116 +++++++++++++++++++++----------------------------------- 1 file changed, 43 insertions(+), 73 deletions(-) (limited to 'src') diff --git a/src/host/usbh.c b/src/host/usbh.c index 09f6adb15..ef2e22a16 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -169,12 +169,6 @@ static OSAL_SPINLOCK_DEF(_usbh_spin, usbh_int_set); OSAL_QUEUE_DEF(usbh_int_set, _usbh_qdef, CFG_TUH_TASK_QUEUE_SZ, hcd_event_t); static osal_queue_t _usbh_q; -#if CFG_TUH_HUB -// Deferred attachment queue -OSAL_QUEUE_DEF(usbh_int_set, _usbh_daqdef, TOTAL_DEVICES, hcd_event_t); -static osal_queue_t _usbh_daq; -#endif - // Control transfers: since most controllers do not support multiple control transfers // on multiple devices concurrently and control transfers are not used much except for // enumeration, we will only execute control transfers one at a time. @@ -189,6 +183,12 @@ typedef struct { uint8_t failed_count; } usbh_ctrl_xfer_info_t; +typedef struct { + tusb_defer_func_t func; + uintptr_t arg; + uint32_t at_ms; +} usbh_call_after_t; + typedef struct { uint8_t controller_id; // controller ID uint8_t enumerating_daddr; // device address of the device being enumerated @@ -197,11 +197,7 @@ typedef struct { usbh_ctrl_xfer_info_t ctrl_xfer_info; // control transfer #if CFG_TUSB_OS_HAS_SCHEDULER == 0 // call after only needed for non-scheduler OS - struct { - tusb_defer_func_t func; - uintptr_t arg; - uint32_t at_ms; - } call_after; + usbh_call_after_t call_after; #endif } usbh_data_t; @@ -330,7 +326,6 @@ static void process_remove_event(hcd_event_t *event); static void remove_device_tree(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port); static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size); static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); -static void usbh_task_mq(uint32_t timeout_ms, bool in_isr); TU_ATTR_ALWAYS_INLINE static inline usbh_device_t* get_device(uint8_t dev_addr) { TU_VERIFY(dev_addr > 0 && dev_addr <= TOTAL_DEVICES, NULL); @@ -365,17 +360,20 @@ TU_ATTR_ALWAYS_INLINE static inline bool usbh_setup_send(uint8_t daddr, const ui } // For non-scheduler deferred callback. For scheduler OS: blocking delay then callback -static void usbh_call_after_ms(uint32_t ms, tusb_defer_func_t func, uintptr_t param) { +static bool usbh_call_after_ms(uint32_t ms, tusb_defer_func_t func, uintptr_t param) { #if CFG_TUSB_OS_HAS_SCHEDULER TU_LOG_USBH("USBH sleep for %u ms\r\n", (unsigned int)ms); osal_task_delay(ms); func(param); #else + TU_ASSERT(_usbh_data.call_after.func == NULL); TU_LOG_USBH("USBH start timer for %u ms\r\n", (unsigned int)ms); _usbh_data.call_after.func = func; _usbh_data.call_after.arg = param; _usbh_data.call_after.at_ms = tusb_time_millis_api() + ms; #endif + + return true; } TU_ATTR_ALWAYS_INLINE static inline void usbh_device_close(uint8_t rhport, uint8_t daddr) { @@ -525,12 +523,6 @@ bool tuh_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { _usbh_q = osal_queue_create(&_usbh_qdef); TU_ASSERT(_usbh_q != NULL); -#if CFG_TUH_HUB - // Deferred attachment queue - _usbh_daq = osal_queue_create(&_usbh_daqdef); - TU_ASSERT(_usbh_daq != NULL); -#endif - #if OSAL_MUTEX_REQUIRED // Init mutex _usbh_mutex = osal_mutex_create(&_usbh_mutexdef); @@ -596,11 +588,6 @@ bool tuh_deinit(uint8_t rhport) { osal_queue_delete(_usbh_q); _usbh_q = NULL; -#if CFG_TUH_HUB - osal_queue_delete(_usbh_daq); - _usbh_daq = NULL; -#endif - #if OSAL_MUTEX_REQUIRED // TODO make sure there is no task waiting on this mutex osal_mutex_delete(_usbh_mutex); @@ -640,51 +627,30 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { return; } -#if CFG_TUSB_OS_HAS_SCHEDULER == 0 - // Process continuation function if timer is expired - tusb_defer_func_t after_cb = _usbh_data.call_after.func; - if (after_cb) { - int32_t ms = (int32_t)(_usbh_data.call_after.at_ms - tusb_time_millis_api()); - if (ms <= 0) { - // delay expired, run callback now - TU_LOG_USBH("USBH run timer callback\r\n"); - _usbh_data.call_after.func = NULL; - after_cb(_usbh_data.call_after.arg); - } else if (timeout_ms > (uint32_t)ms) { - // reduce timeout accordingly - timeout_ms = (uint32_t)ms; - } - } -#endif - -#if CFG_TUH_HUB - // Process deferred device attachments - if (_usbh_data.enumerating_daddr == TUSB_INDEX_INVALID_8) { - hcd_event_t event; - if (osal_queue_receive(_usbh_daq, &event, 0)) { - // We are ready to process a new attachment - TU_LOG_USBH("[%u:] USBH Deferred Device Attach\r\n", event.rhport); - _usbh_data.enumerating_daddr = 0; // enumerate new device with address 0 - enum_new_device(&event); - } - } -#endif - - // Process the message queue - usbh_task_mq(timeout_ms, in_isr); -} - -static void usbh_task_mq(uint32_t timeout_ms, bool in_isr) { (void) in_isr; // not implemented yet // Loop until there are no more events in the queue or CFG_TUH_TASK_EVENTS_PER_RUN is reached for (unsigned epr = 0;; epr++) { -#if CFG_TUH_TASK_EVENTS_PER_RUN > 0 + #if CFG_TUH_TASK_EVENTS_PER_RUN > 0 if (epr >= CFG_TUH_TASK_EVENTS_PER_RUN) { TU_LOG_USBH("USBH event limit (" TU_XSTRING(CFG_TUH_TASK_EVENTS_PER_RUN) ") reached\r\n"); break; } -#endif + #endif + + #if CFG_TUSB_OS_HAS_SCHEDULER == 0 + // Process call_after_ms function if ms is reached + tusb_defer_func_t after_cb = _usbh_data.call_after.func; + if (after_cb) { + uint32_t ms = tusb_time_millis_api(); + if (ms >= _usbh_data.call_after.at_ms) { + TU_LOG_USBH("USBH run timer callback\r\n"); + _usbh_data.call_after.func = NULL; + after_cb(_usbh_data.call_after.arg); + } + } + #endif + hcd_event_t event; if (!osal_queue_receive(_usbh_q, &event, timeout_ms)) { return; } @@ -701,12 +667,14 @@ static void usbh_task_mq(uint32_t timeout_ms, bool in_isr) { TU_LOG_USBH("[%u:] USBH Device Attach\r\n", event.rhport); _usbh_data.enumerating_daddr = 0; // enumerate new device with address 0 enum_new_device(&event); -#if CFG_TUH_HUB } else { // currently enumerating another device TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport); - TU_ASSERT(osal_queue_send(_usbh_daq, &event, in_isr),); -#endif + const bool is_empty = osal_queue_empty(_usbh_q); + queue_event(&event, in_isr); + if (is_empty) { + return; // Exit if this is the only event in the queue, otherwise we loop forever + } } break; @@ -784,10 +752,12 @@ static void usbh_task_mq(uint32_t timeout_ms, bool in_isr) { break; } -#if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO - // return if there is no more events, for application to run other background - if (osal_queue_empty(_usbh_q)) return; -#endif + #if CFG_TUSB_OS_HAS_SCHEDULER + // return if there are no more events, for application to run other backgrounds + if (osal_queue_empty(_usbh_q)) { + return; + } + #endif } } @@ -845,8 +815,8 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) { while (result == XFER_RESULT_INVALID) { // Note: this can be called within an callback ie. part of tuh_task() - // therefore even with RTOS usbh_task_mq() still need to be invoked - usbh_task_mq(0, false); + // therefore even with RTOS tuh_task_ext() still need to be invoked + tuh_task_ext(0, false); // TODO probably some timeout to prevent hanged } @@ -1944,10 +1914,10 @@ static bool enum_parse_configuration_desc(uint8_t dev_addr, tusb_desc_configurat TU_LOG_USBH("Parsing Configuration descriptor (wTotalLength = %u)\r\n", total_len); - // parse each interfaces + // parse all interfaces while (tu_desc_in_bounds(p_desc, desc_end)) { if (0 == tu_desc_len(p_desc)) { - // A zero length descriptor indicates that the device is off spec (e.g. wrong wTotalLength). + // A zero-length descriptor indicates that the device is off spec (e.g. wrong wTotalLength). // Parsed interfaces should still be usable TU_LOG_USBH("Encountered a zero-length descriptor after %" PRIu32 " bytes\r\n", (uint32_t)p_desc - (uint32_t)desc_cfg); break; @@ -1963,7 +1933,7 @@ static bool enum_parse_configuration_desc(uint8_t dev_addr, tusb_desc_configurat // uint16_t const drv_len = tu_desc_get_interface_total_len(desc_itf, assoc_itf_count, (uint16_t) // (desc_end-p_desc)); TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t)); - // Find driver for this interface + // Find a driver for this interface const uint16_t remaining_len = (uint16_t)(desc_end - p_desc); uint8_t drv_id; for (drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { -- cgit v1.3.1 From fd933642df6a687d4452275d277e9479870f806c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 26 Feb 2026 18:02:09 +0700 Subject: fix fallthrough --- src/host/usbh.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/host/usbh.c b/src/host/usbh.c index ef2e22a16..76269eb2f 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1516,7 +1516,16 @@ static void enum_async_delay(uintptr_t state) { tuh_bus_info_t *dev0_bus = &_usbh_data.dev0_bus; switch (state) { case ENUM_AFTER_DEBOUNCING_DELAY: - if (dev0_bus->hub_addr == 0) { + #if CFG_TUH_HUB + if (dev0_bus->hub_addr != 0) { + // connected via hub + TU_VERIFY(dev0_bus->hub_port != 0, ); + TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, NULL, process_enumeration, + ENUM_HUB_RERSET), ); + break; + } else + #endif + { // connected directly to roothub _usbh_data.attach_debouncing_bm &= (uint8_t)~TU_BIT(dev0_bus->rhport); // clear roothub debouncing delay if (!hcd_port_connect_status(dev0_bus->rhport)) { @@ -1527,15 +1536,6 @@ static void enum_async_delay(uintptr_t state) { hcd_port_reset(dev0_bus->rhport); // reset port ENUM_ASYNC_DELAY_OR_FALLTHROUGH(ENUM_RESET_ROOT_DELAY_MS, ENUM_AFTER_RESET_ROOT_DELAY); } - #if CFG_TUH_HUB - else { - // connected via hub - TU_VERIFY(dev0_bus->hub_port != 0, ); - TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, NULL, process_enumeration, - ENUM_HUB_RERSET), ); - break; - } - #endif // hub case ENUM_AFTER_RESET_ROOT_DELAY: hcd_port_reset_end(dev0_bus->rhport); -- cgit v1.3.1 From bb8845c8e89002629d8eb4f8d72eaf370b97b004 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 27 Feb 2026 10:58:01 +0100 Subject: dcd/samx7x: synchronize DMA and cache options Signed-off-by: HiFiPhile --- src/common/tusb_mcu.h | 4 + src/portable/microchip/samx7x/common_usb_regs.h | 2108 ---------------------- src/portable/microchip/samx7x/dcd_samx7x.c | 58 +- src/portable/microchip/samx7x/samx7x_common.h | 2173 +++++++++++++++++++++++ src/tusb_option.h | 18 + 5 files changed, 2218 insertions(+), 2143 deletions(-) delete mode 100644 src/portable/microchip/samx7x/common_usb_regs.h create mode 100644 src/portable/microchip/samx7x/samx7x_common.h (limited to 'src') diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 5b9497b9a..32f7eb557 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -172,6 +172,10 @@ #define TUP_RHPORT_HIGHSPEED 1 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY + // Enable dcache if DMA is enabled + #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_SAMX7X_DMA_ENABLE + #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32 + #elif TU_CHECK_MCU(OPT_MCU_PIC32MZ) #define TUP_DCD_ENDPOINT_MAX 8 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY diff --git a/src/portable/microchip/samx7x/common_usb_regs.h b/src/portable/microchip/samx7x/common_usb_regs.h deleted file mode 100644 index db4a81e0e..000000000 --- a/src/portable/microchip/samx7x/common_usb_regs.h +++ /dev/null @@ -1,2108 +0,0 @@ - /* -* The MIT License (MIT) -* -* Copyright (c) 2019 Microchip Technology Inc. -* Copyright (c) 2018, hathach (tinyusb.org) -* Copyright (c) 2021, HiFiPhile -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -* -* This file is part of the TinyUSB stack. -*/ - -#ifndef _COMMON_USB_REGS_H_ -#define _COMMON_USB_REGS_H_ - -#if CFG_TUSB_MCU == OPT_MCU_SAMX7X - -/* -------- DEVDMANXTDSC : (USBHS Offset: 0x00) (R/W 32) Device DMA Channel Next Descriptor Address Register -------- */ - -#define DEVDMANXTDSC_OFFSET (0x00) /**< (DEVDMANXTDSC) Device DMA Channel Next Descriptor Address Register Offset */ - -#define DEVDMANXTDSC_NXT_DSC_ADD_Pos 0 /**< (DEVDMANXTDSC) Next Descriptor Address Position */ -#define DEVDMANXTDSC_NXT_DSC_ADD (_U_(0xFFFFFFFF) << DEVDMANXTDSC_NXT_DSC_ADD_Pos) /**< (DEVDMANXTDSC) Next Descriptor Address Mask */ -#define DEVDMANXTDSC_Msk _U_(0xFFFFFFFF) /**< (DEVDMANXTDSC) Register Mask */ - - -/* -------- DEVDMAADDRESS : (USBHS Offset: 0x04) (R/W 32) Device DMA Channel Address Register -------- */ - -#define DEVDMAADDRESS_OFFSET (0x04) /**< (DEVDMAADDRESS) Device DMA Channel Address Register Offset */ - -#define DEVDMAADDRESS_BUFF_ADD_Pos 0 /**< (DEVDMAADDRESS) Buffer Address Position */ -#define DEVDMAADDRESS_BUFF_ADD (_U_(0xFFFFFFFF) << DEVDMAADDRESS_BUFF_ADD_Pos) /**< (DEVDMAADDRESS) Buffer Address Mask */ -#define DEVDMAADDRESS_Msk _U_(0xFFFFFFFF) /**< (DEVDMAADDRESS) Register Mask */ - - -/* -------- DEVDMACONTROL : (USBHS Offset: 0x08) (R/W 32) Device DMA Channel Control Register -------- */ - -#define DEVDMACONTROL_OFFSET (0x08) /**< (DEVDMACONTROL) Device DMA Channel Control Register Offset */ - -#define DEVDMACONTROL_CHANN_ENB_Pos 0 /**< (DEVDMACONTROL) Channel Enable Command Position */ -#define DEVDMACONTROL_CHANN_ENB (_U_(0x1) << DEVDMACONTROL_CHANN_ENB_Pos) /**< (DEVDMACONTROL) Channel Enable Command Mask */ -#define DEVDMACONTROL_LDNXT_DSC_Pos 1 /**< (DEVDMACONTROL) Load Next Channel Transfer Descriptor Enable Command Position */ -#define DEVDMACONTROL_LDNXT_DSC (_U_(0x1) << DEVDMACONTROL_LDNXT_DSC_Pos) /**< (DEVDMACONTROL) Load Next Channel Transfer Descriptor Enable Command Mask */ -#define DEVDMACONTROL_END_TR_EN_Pos 2 /**< (DEVDMACONTROL) End of Transfer Enable Control (OUT transfers only) Position */ -#define DEVDMACONTROL_END_TR_EN (_U_(0x1) << DEVDMACONTROL_END_TR_EN_Pos) /**< (DEVDMACONTROL) End of Transfer Enable Control (OUT transfers only) Mask */ -#define DEVDMACONTROL_END_B_EN_Pos 3 /**< (DEVDMACONTROL) End of Buffer Enable Control Position */ -#define DEVDMACONTROL_END_B_EN (_U_(0x1) << DEVDMACONTROL_END_B_EN_Pos) /**< (DEVDMACONTROL) End of Buffer Enable Control Mask */ -#define DEVDMACONTROL_END_TR_IT_Pos 4 /**< (DEVDMACONTROL) End of Transfer Interrupt Enable Position */ -#define DEVDMACONTROL_END_TR_IT (_U_(0x1) << DEVDMACONTROL_END_TR_IT_Pos) /**< (DEVDMACONTROL) End of Transfer Interrupt Enable Mask */ -#define DEVDMACONTROL_END_BUFFIT_Pos 5 /**< (DEVDMACONTROL) End of Buffer Interrupt Enable Position */ -#define DEVDMACONTROL_END_BUFFIT (_U_(0x1) << DEVDMACONTROL_END_BUFFIT_Pos) /**< (DEVDMACONTROL) End of Buffer Interrupt Enable Mask */ -#define DEVDMACONTROL_DESC_LD_IT_Pos 6 /**< (DEVDMACONTROL) Descriptor Loaded Interrupt Enable Position */ -#define DEVDMACONTROL_DESC_LD_IT (_U_(0x1) << DEVDMACONTROL_DESC_LD_IT_Pos) /**< (DEVDMACONTROL) Descriptor Loaded Interrupt Enable Mask */ -#define DEVDMACONTROL_BURST_LCK_Pos 7 /**< (DEVDMACONTROL) Burst Lock Enable Position */ -#define DEVDMACONTROL_BURST_LCK (_U_(0x1) << DEVDMACONTROL_BURST_LCK_Pos) /**< (DEVDMACONTROL) Burst Lock Enable Mask */ -#define DEVDMACONTROL_BUFF_LENGTH_Pos 16 /**< (DEVDMACONTROL) Buffer Byte Length (Write-only) Position */ -#define DEVDMACONTROL_BUFF_LENGTH (_U_(0xFFFF) << DEVDMACONTROL_BUFF_LENGTH_Pos) /**< (DEVDMACONTROL) Buffer Byte Length (Write-only) Mask */ -#define DEVDMACONTROL_Msk _U_(0xFFFF00FF) /**< (DEVDMACONTROL) Register Mask */ - - -/* -------- DEVDMASTATUS : (USBHS Offset: 0x0c) (R/W 32) Device DMA Channel Status Register -------- */ - -#define DEVDMASTATUS_OFFSET (0x0C) /**< (DEVDMASTATUS) Device DMA Channel Status Register Offset */ - -#define DEVDMASTATUS_CHANN_ENB_Pos 0 /**< (DEVDMASTATUS) Channel Enable Status Position */ -#define DEVDMASTATUS_CHANN_ENB (_U_(0x1) << DEVDMASTATUS_CHANN_ENB_Pos) /**< (DEVDMASTATUS) Channel Enable Status Mask */ -#define DEVDMASTATUS_CHANN_ACT_Pos 1 /**< (DEVDMASTATUS) Channel Active Status Position */ -#define DEVDMASTATUS_CHANN_ACT (_U_(0x1) << DEVDMASTATUS_CHANN_ACT_Pos) /**< (DEVDMASTATUS) Channel Active Status Mask */ -#define DEVDMASTATUS_END_TR_ST_Pos 4 /**< (DEVDMASTATUS) End of Channel Transfer Status Position */ -#define DEVDMASTATUS_END_TR_ST (_U_(0x1) << DEVDMASTATUS_END_TR_ST_Pos) /**< (DEVDMASTATUS) End of Channel Transfer Status Mask */ -#define DEVDMASTATUS_END_BF_ST_Pos 5 /**< (DEVDMASTATUS) End of Channel Buffer Status Position */ -#define DEVDMASTATUS_END_BF_ST (_U_(0x1) << DEVDMASTATUS_END_BF_ST_Pos) /**< (DEVDMASTATUS) End of Channel Buffer Status Mask */ -#define DEVDMASTATUS_DESC_LDST_Pos 6 /**< (DEVDMASTATUS) Descriptor Loaded Status Position */ -#define DEVDMASTATUS_DESC_LDST (_U_(0x1) << DEVDMASTATUS_DESC_LDST_Pos) /**< (DEVDMASTATUS) Descriptor Loaded Status Mask */ -#define DEVDMASTATUS_BUFF_COUNT_Pos 16 /**< (DEVDMASTATUS) Buffer Byte Count Position */ -#define DEVDMASTATUS_BUFF_COUNT (_U_(0xFFFF) << DEVDMASTATUS_BUFF_COUNT_Pos) /**< (DEVDMASTATUS) Buffer Byte Count Mask */ -#define DEVDMASTATUS_Msk _U_(0xFFFF0073) /**< (DEVDMASTATUS) Register Mask */ - - -/* -------- HSTDMANXTDSC : (USBHS Offset: 0x00) (R/W 32) Host DMA Channel Next Descriptor Address Register -------- */ - -#define HSTDMANXTDSC_OFFSET (0x00) /**< (HSTDMANXTDSC) Host DMA Channel Next Descriptor Address Register Offset */ - -#define HSTDMANXTDSC_NXT_DSC_ADD_Pos 0 /**< (HSTDMANXTDSC) Next Descriptor Address Position */ -#define HSTDMANXTDSC_NXT_DSC_ADD (_U_(0xFFFFFFFF) << HSTDMANXTDSC_NXT_DSC_ADD_Pos) /**< (HSTDMANXTDSC) Next Descriptor Address Mask */ -#define HSTDMANXTDSC_Msk _U_(0xFFFFFFFF) /**< (HSTDMANXTDSC) Register Mask */ - - -/* -------- HSTDMAADDRESS : (USBHS Offset: 0x04) (R/W 32) Host DMA Channel Address Register -------- */ - -#define HSTDMAADDRESS_OFFSET (0x04) /**< (HSTDMAADDRESS) Host DMA Channel Address Register Offset */ - -#define HSTDMAADDRESS_BUFF_ADD_Pos 0 /**< (HSTDMAADDRESS) Buffer Address Position */ -#define HSTDMAADDRESS_BUFF_ADD (_U_(0xFFFFFFFF) << HSTDMAADDRESS_BUFF_ADD_Pos) /**< (HSTDMAADDRESS) Buffer Address Mask */ -#define HSTDMAADDRESS_Msk _U_(0xFFFFFFFF) /**< (HSTDMAADDRESS) Register Mask */ - - -/* -------- HSTDMACONTROL : (USBHS Offset: 0x08) (R/W 32) Host DMA Channel Control Register -------- */ - -#define HSTDMACONTROL_OFFSET (0x08) /**< (HSTDMACONTROL) Host DMA Channel Control Register Offset */ - -#define HSTDMACONTROL_CHANN_ENB_Pos 0 /**< (HSTDMACONTROL) Channel Enable Command Position */ -#define HSTDMACONTROL_CHANN_ENB (_U_(0x1) << HSTDMACONTROL_CHANN_ENB_Pos) /**< (HSTDMACONTROL) Channel Enable Command Mask */ -#define HSTDMACONTROL_LDNXT_DSC_Pos 1 /**< (HSTDMACONTROL) Load Next Channel Transfer Descriptor Enable Command Position */ -#define HSTDMACONTROL_LDNXT_DSC (_U_(0x1) << HSTDMACONTROL_LDNXT_DSC_Pos) /**< (HSTDMACONTROL) Load Next Channel Transfer Descriptor Enable Command Mask */ -#define HSTDMACONTROL_END_TR_EN_Pos 2 /**< (HSTDMACONTROL) End of Transfer Enable Control (OUT transfers only) Position */ -#define HSTDMACONTROL_END_TR_EN (_U_(0x1) << HSTDMACONTROL_END_TR_EN_Pos) /**< (HSTDMACONTROL) End of Transfer Enable Control (OUT transfers only) Mask */ -#define HSTDMACONTROL_END_B_EN_Pos 3 /**< (HSTDMACONTROL) End of Buffer Enable Control Position */ -#define HSTDMACONTROL_END_B_EN (_U_(0x1) << HSTDMACONTROL_END_B_EN_Pos) /**< (HSTDMACONTROL) End of Buffer Enable Control Mask */ -#define HSTDMACONTROL_END_TR_IT_Pos 4 /**< (HSTDMACONTROL) End of Transfer Interrupt Enable Position */ -#define HSTDMACONTROL_END_TR_IT (_U_(0x1) << HSTDMACONTROL_END_TR_IT_Pos) /**< (HSTDMACONTROL) End of Transfer Interrupt Enable Mask */ -#define HSTDMACONTROL_END_BUFFIT_Pos 5 /**< (HSTDMACONTROL) End of Buffer Interrupt Enable Position */ -#define HSTDMACONTROL_END_BUFFIT (_U_(0x1) << HSTDMACONTROL_END_BUFFIT_Pos) /**< (HSTDMACONTROL) End of Buffer Interrupt Enable Mask */ -#define HSTDMACONTROL_DESC_LD_IT_Pos 6 /**< (HSTDMACONTROL) Descriptor Loaded Interrupt Enable Position */ -#define HSTDMACONTROL_DESC_LD_IT (_U_(0x1) << HSTDMACONTROL_DESC_LD_IT_Pos) /**< (HSTDMACONTROL) Descriptor Loaded Interrupt Enable Mask */ -#define HSTDMACONTROL_BURST_LCK_Pos 7 /**< (HSTDMACONTROL) Burst Lock Enable Position */ -#define HSTDMACONTROL_BURST_LCK (_U_(0x1) << HSTDMACONTROL_BURST_LCK_Pos) /**< (HSTDMACONTROL) Burst Lock Enable Mask */ -#define HSTDMACONTROL_BUFF_LENGTH_Pos 16 /**< (HSTDMACONTROL) Buffer Byte Length (Write-only) Position */ -#define HSTDMACONTROL_BUFF_LENGTH (_U_(0xFFFF) << HSTDMACONTROL_BUFF_LENGTH_Pos) /**< (HSTDMACONTROL) Buffer Byte Length (Write-only) Mask */ -#define HSTDMACONTROL_Msk _U_(0xFFFF00FF) /**< (HSTDMACONTROL) Register Mask */ - - -/* -------- HSTDMASTATUS : (USBHS Offset: 0x0c) (R/W 32) Host DMA Channel Status Register -------- */ - -#define HSTDMASTATUS_OFFSET (0x0C) /**< (HSTDMASTATUS) Host DMA Channel Status Register Offset */ - -#define HSTDMASTATUS_CHANN_ENB_Pos 0 /**< (HSTDMASTATUS) Channel Enable Status Position */ -#define HSTDMASTATUS_CHANN_ENB (_U_(0x1) << HSTDMASTATUS_CHANN_ENB_Pos) /**< (HSTDMASTATUS) Channel Enable Status Mask */ -#define HSTDMASTATUS_CHANN_ACT_Pos 1 /**< (HSTDMASTATUS) Channel Active Status Position */ -#define HSTDMASTATUS_CHANN_ACT (_U_(0x1) << HSTDMASTATUS_CHANN_ACT_Pos) /**< (HSTDMASTATUS) Channel Active Status Mask */ -#define HSTDMASTATUS_END_TR_ST_Pos 4 /**< (HSTDMASTATUS) End of Channel Transfer Status Position */ -#define HSTDMASTATUS_END_TR_ST (_U_(0x1) << HSTDMASTATUS_END_TR_ST_Pos) /**< (HSTDMASTATUS) End of Channel Transfer Status Mask */ -#define HSTDMASTATUS_END_BF_ST_Pos 5 /**< (HSTDMASTATUS) End of Channel Buffer Status Position */ -#define HSTDMASTATUS_END_BF_ST (_U_(0x1) << HSTDMASTATUS_END_BF_ST_Pos) /**< (HSTDMASTATUS) End of Channel Buffer Status Mask */ -#define HSTDMASTATUS_DESC_LDST_Pos 6 /**< (HSTDMASTATUS) Descriptor Loaded Status Position */ -#define HSTDMASTATUS_DESC_LDST (_U_(0x1) << HSTDMASTATUS_DESC_LDST_Pos) /**< (HSTDMASTATUS) Descriptor Loaded Status Mask */ -#define HSTDMASTATUS_BUFF_COUNT_Pos 16 /**< (HSTDMASTATUS) Buffer Byte Count Position */ -#define HSTDMASTATUS_BUFF_COUNT (_U_(0xFFFF) << HSTDMASTATUS_BUFF_COUNT_Pos) /**< (HSTDMASTATUS) Buffer Byte Count Mask */ -#define HSTDMASTATUS_Msk _U_(0xFFFF0073) /**< (HSTDMASTATUS) Register Mask */ - - -/* -------- DEVCTRL : (USBHS Offset: 0x00) (R/W 32) Device General Control Register -------- */ - -#define DEVCTRL_OFFSET (0x00) /**< (DEVCTRL) Device General Control Register Offset */ - -#define DEVCTRL_UADD_Pos 0 /**< (DEVCTRL) USB Address Position */ -#define DEVCTRL_UADD (_U_(0x7F) << DEVCTRL_UADD_Pos) /**< (DEVCTRL) USB Address Mask */ -#define DEVCTRL_ADDEN_Pos 7 /**< (DEVCTRL) Address Enable Position */ -#define DEVCTRL_ADDEN (_U_(0x1) << DEVCTRL_ADDEN_Pos) /**< (DEVCTRL) Address Enable Mask */ -#define DEVCTRL_DETACH_Pos 8 /**< (DEVCTRL) Detach Position */ -#define DEVCTRL_DETACH (_U_(0x1) << DEVCTRL_DETACH_Pos) /**< (DEVCTRL) Detach Mask */ -#define DEVCTRL_RMWKUP_Pos 9 /**< (DEVCTRL) Remote Wake-Up Position */ -#define DEVCTRL_RMWKUP (_U_(0x1) << DEVCTRL_RMWKUP_Pos) /**< (DEVCTRL) Remote Wake-Up Mask */ -#define DEVCTRL_SPDCONF_Pos 10 /**< (DEVCTRL) Mode Configuration Position */ -#define DEVCTRL_SPDCONF (_U_(0x3) << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) Mode Configuration Mask */ -#define DEVCTRL_SPDCONF_NORMAL_Val _U_(0x0) /**< (DEVCTRL) The peripheral starts in Full-speed mode and performs a high-speed reset to switch to High-speed mode if the host is high-speed-capable. */ -#define DEVCTRL_SPDCONF_LOW_POWER_Val _U_(0x1) /**< (DEVCTRL) For a better consumption, if high speed is not needed. */ -#define DEVCTRL_SPDCONF_HIGH_SPEED_Val _U_(0x2) /**< (DEVCTRL) Forced high speed. */ -#define DEVCTRL_SPDCONF_FORCED_FS_Val _U_(0x3) /**< (DEVCTRL) The peripheral remains in Full-speed mode whatever the host speed capability. */ -#define DEVCTRL_SPDCONF_NORMAL (DEVCTRL_SPDCONF_NORMAL_Val << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) The peripheral starts in Full-speed mode and performs a high-speed reset to switch to High-speed mode if the host is high-speed-capable. Position */ -#define DEVCTRL_SPDCONF_LOW_POWER (DEVCTRL_SPDCONF_LOW_POWER_Val << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) For a better consumption, if high speed is not needed. Position */ -#define DEVCTRL_SPDCONF_HIGH_SPEED (DEVCTRL_SPDCONF_HIGH_SPEED_Val << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) Forced high speed. Position */ -#define DEVCTRL_SPDCONF_FORCED_FS (DEVCTRL_SPDCONF_FORCED_FS_Val << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) The peripheral remains in Full-speed mode whatever the host speed capability. Position */ -#define DEVCTRL_LS_Pos 12 /**< (DEVCTRL) Low-Speed Mode Force Position */ -#define DEVCTRL_LS (_U_(0x1) << DEVCTRL_LS_Pos) /**< (DEVCTRL) Low-Speed Mode Force Mask */ -#define DEVCTRL_TSTJ_Pos 13 /**< (DEVCTRL) Test mode J Position */ -#define DEVCTRL_TSTJ (_U_(0x1) << DEVCTRL_TSTJ_Pos) /**< (DEVCTRL) Test mode J Mask */ -#define DEVCTRL_TSTK_Pos 14 /**< (DEVCTRL) Test mode K Position */ -#define DEVCTRL_TSTK (_U_(0x1) << DEVCTRL_TSTK_Pos) /**< (DEVCTRL) Test mode K Mask */ -#define DEVCTRL_TSTPCKT_Pos 15 /**< (DEVCTRL) Test packet mode Position */ -#define DEVCTRL_TSTPCKT (_U_(0x1) << DEVCTRL_TSTPCKT_Pos) /**< (DEVCTRL) Test packet mode Mask */ -#define DEVCTRL_OPMODE2_Pos 16 /**< (DEVCTRL) Specific Operational mode Position */ -#define DEVCTRL_OPMODE2 (_U_(0x1) << DEVCTRL_OPMODE2_Pos) /**< (DEVCTRL) Specific Operational mode Mask */ -#define DEVCTRL_Msk _U_(0x1FFFF) /**< (DEVCTRL) Register Mask */ - -#define DEVCTRL_OPMODE_Pos 16 /**< (DEVCTRL Position) Specific Operational mode */ -#define DEVCTRL_OPMODE (_U_(0x1) << DEVCTRL_OPMODE_Pos) /**< (DEVCTRL Mask) OPMODE */ - -/* -------- DEVISR : (USBHS Offset: 0x04) (R/ 32) Device Global Interrupt Status Register -------- */ - -#define DEVISR_OFFSET (0x04) /**< (DEVISR) Device Global Interrupt Status Register Offset */ - -#define DEVISR_SUSP_Pos 0 /**< (DEVISR) Suspend Interrupt Position */ -#define DEVISR_SUSP (_U_(0x1) << DEVISR_SUSP_Pos) /**< (DEVISR) Suspend Interrupt Mask */ -#define DEVISR_MSOF_Pos 1 /**< (DEVISR) Micro Start of Frame Interrupt Position */ -#define DEVISR_MSOF (_U_(0x1) << DEVISR_MSOF_Pos) /**< (DEVISR) Micro Start of Frame Interrupt Mask */ -#define DEVISR_SOF_Pos 2 /**< (DEVISR) Start of Frame Interrupt Position */ -#define DEVISR_SOF (_U_(0x1) << DEVISR_SOF_Pos) /**< (DEVISR) Start of Frame Interrupt Mask */ -#define DEVISR_EORST_Pos 3 /**< (DEVISR) End of Reset Interrupt Position */ -#define DEVISR_EORST (_U_(0x1) << DEVISR_EORST_Pos) /**< (DEVISR) End of Reset Interrupt Mask */ -#define DEVISR_WAKEUP_Pos 4 /**< (DEVISR) Wake-Up Interrupt Position */ -#define DEVISR_WAKEUP (_U_(0x1) << DEVISR_WAKEUP_Pos) /**< (DEVISR) Wake-Up Interrupt Mask */ -#define DEVISR_EORSM_Pos 5 /**< (DEVISR) End of Resume Interrupt Position */ -#define DEVISR_EORSM (_U_(0x1) << DEVISR_EORSM_Pos) /**< (DEVISR) End of Resume Interrupt Mask */ -#define DEVISR_UPRSM_Pos 6 /**< (DEVISR) Upstream Resume Interrupt Position */ -#define DEVISR_UPRSM (_U_(0x1) << DEVISR_UPRSM_Pos) /**< (DEVISR) Upstream Resume Interrupt Mask */ -#define DEVISR_PEP_0_Pos 12 /**< (DEVISR) Endpoint 0 Interrupt Position */ -#define DEVISR_PEP_0 (_U_(0x1) << DEVISR_PEP_0_Pos) /**< (DEVISR) Endpoint 0 Interrupt Mask */ -#define DEVISR_PEP_1_Pos 13 /**< (DEVISR) Endpoint 1 Interrupt Position */ -#define DEVISR_PEP_1 (_U_(0x1) << DEVISR_PEP_1_Pos) /**< (DEVISR) Endpoint 1 Interrupt Mask */ -#define DEVISR_PEP_2_Pos 14 /**< (DEVISR) Endpoint 2 Interrupt Position */ -#define DEVISR_PEP_2 (_U_(0x1) << DEVISR_PEP_2_Pos) /**< (DEVISR) Endpoint 2 Interrupt Mask */ -#define DEVISR_PEP_3_Pos 15 /**< (DEVISR) Endpoint 3 Interrupt Position */ -#define DEVISR_PEP_3 (_U_(0x1) << DEVISR_PEP_3_Pos) /**< (DEVISR) Endpoint 3 Interrupt Mask */ -#define DEVISR_PEP_4_Pos 16 /**< (DEVISR) Endpoint 4 Interrupt Position */ -#define DEVISR_PEP_4 (_U_(0x1) << DEVISR_PEP_4_Pos) /**< (DEVISR) Endpoint 4 Interrupt Mask */ -#define DEVISR_PEP_5_Pos 17 /**< (DEVISR) Endpoint 5 Interrupt Position */ -#define DEVISR_PEP_5 (_U_(0x1) << DEVISR_PEP_5_Pos) /**< (DEVISR) Endpoint 5 Interrupt Mask */ -#define DEVISR_PEP_6_Pos 18 /**< (DEVISR) Endpoint 6 Interrupt Position */ -#define DEVISR_PEP_6 (_U_(0x1) << DEVISR_PEP_6_Pos) /**< (DEVISR) Endpoint 6 Interrupt Mask */ -#define DEVISR_PEP_7_Pos 19 /**< (DEVISR) Endpoint 7 Interrupt Position */ -#define DEVISR_PEP_7 (_U_(0x1) << DEVISR_PEP_7_Pos) /**< (DEVISR) Endpoint 7 Interrupt Mask */ -#define DEVISR_PEP_8_Pos 20 /**< (DEVISR) Endpoint 8 Interrupt Position */ -#define DEVISR_PEP_8 (_U_(0x1) << DEVISR_PEP_8_Pos) /**< (DEVISR) Endpoint 8 Interrupt Mask */ -#define DEVISR_PEP_9_Pos 21 /**< (DEVISR) Endpoint 9 Interrupt Position */ -#define DEVISR_PEP_9 (_U_(0x1) << DEVISR_PEP_9_Pos) /**< (DEVISR) Endpoint 9 Interrupt Mask */ -#define DEVISR_DMA_1_Pos 25 /**< (DEVISR) DMA Channel 1 Interrupt Position */ -#define DEVISR_DMA_1 (_U_(0x1) << DEVISR_DMA_1_Pos) /**< (DEVISR) DMA Channel 1 Interrupt Mask */ -#define DEVISR_DMA_2_Pos 26 /**< (DEVISR) DMA Channel 2 Interrupt Position */ -#define DEVISR_DMA_2 (_U_(0x1) << DEVISR_DMA_2_Pos) /**< (DEVISR) DMA Channel 2 Interrupt Mask */ -#define DEVISR_DMA_3_Pos 27 /**< (DEVISR) DMA Channel 3 Interrupt Position */ -#define DEVISR_DMA_3 (_U_(0x1) << DEVISR_DMA_3_Pos) /**< (DEVISR) DMA Channel 3 Interrupt Mask */ -#define DEVISR_DMA_4_Pos 28 /**< (DEVISR) DMA Channel 4 Interrupt Position */ -#define DEVISR_DMA_4 (_U_(0x1) << DEVISR_DMA_4_Pos) /**< (DEVISR) DMA Channel 4 Interrupt Mask */ -#define DEVISR_DMA_5_Pos 29 /**< (DEVISR) DMA Channel 5 Interrupt Position */ -#define DEVISR_DMA_5 (_U_(0x1) << DEVISR_DMA_5_Pos) /**< (DEVISR) DMA Channel 5 Interrupt Mask */ -#define DEVISR_DMA_6_Pos 30 /**< (DEVISR) DMA Channel 6 Interrupt Position */ -#define DEVISR_DMA_6 (_U_(0x1) << DEVISR_DMA_6_Pos) /**< (DEVISR) DMA Channel 6 Interrupt Mask */ -#define DEVISR_DMA_7_Pos 31 /**< (DEVISR) DMA Channel 7 Interrupt Position */ -#define DEVISR_DMA_7 (_U_(0x1) << DEVISR_DMA_7_Pos) /**< (DEVISR) DMA Channel 7 Interrupt Mask */ -#define DEVISR_Msk _U_(0xFE3FF07F) /**< (DEVISR) Register Mask */ - -#define DEVISR_PEP__Pos 12 /**< (DEVISR Position) Endpoint x Interrupt */ -#define DEVISR_PEP_ (_U_(0x3FF) << DEVISR_PEP__Pos) /**< (DEVISR Mask) PEP_ */ -#define DEVISR_DMA__Pos 25 /**< (DEVISR Position) DMA Channel 7 Interrupt */ -#define DEVISR_DMA_ (_U_(0x7F) << DEVISR_DMA__Pos) /**< (DEVISR Mask) DMA_ */ - -/* -------- DEVICR : (USBHS Offset: 0x08) (/W 32) Device Global Interrupt Clear Register -------- */ - -#define DEVICR_OFFSET (0x08) /**< (DEVICR) Device Global Interrupt Clear Register Offset */ - -#define DEVICR_SUSPC_Pos 0 /**< (DEVICR) Suspend Interrupt Clear Position */ -#define DEVICR_SUSPC (_U_(0x1) << DEVICR_SUSPC_Pos) /**< (DEVICR) Suspend Interrupt Clear Mask */ -#define DEVICR_MSOFC_Pos 1 /**< (DEVICR) Micro Start of Frame Interrupt Clear Position */ -#define DEVICR_MSOFC (_U_(0x1) << DEVICR_MSOFC_Pos) /**< (DEVICR) Micro Start of Frame Interrupt Clear Mask */ -#define DEVICR_SOFC_Pos 2 /**< (DEVICR) Start of Frame Interrupt Clear Position */ -#define DEVICR_SOFC (_U_(0x1) << DEVICR_SOFC_Pos) /**< (DEVICR) Start of Frame Interrupt Clear Mask */ -#define DEVICR_EORSTC_Pos 3 /**< (DEVICR) End of Reset Interrupt Clear Position */ -#define DEVICR_EORSTC (_U_(0x1) << DEVICR_EORSTC_Pos) /**< (DEVICR) End of Reset Interrupt Clear Mask */ -#define DEVICR_WAKEUPC_Pos 4 /**< (DEVICR) Wake-Up Interrupt Clear Position */ -#define DEVICR_WAKEUPC (_U_(0x1) << DEVICR_WAKEUPC_Pos) /**< (DEVICR) Wake-Up Interrupt Clear Mask */ -#define DEVICR_EORSMC_Pos 5 /**< (DEVICR) End of Resume Interrupt Clear Position */ -#define DEVICR_EORSMC (_U_(0x1) << DEVICR_EORSMC_Pos) /**< (DEVICR) End of Resume Interrupt Clear Mask */ -#define DEVICR_UPRSMC_Pos 6 /**< (DEVICR) Upstream Resume Interrupt Clear Position */ -#define DEVICR_UPRSMC (_U_(0x1) << DEVICR_UPRSMC_Pos) /**< (DEVICR) Upstream Resume Interrupt Clear Mask */ -#define DEVICR_Msk _U_(0x7F) /**< (DEVICR) Register Mask */ - - -/* -------- DEVIFR : (USBHS Offset: 0x0c) (/W 32) Device Global Interrupt Set Register -------- */ - -#define DEVIFR_OFFSET (0x0C) /**< (DEVIFR) Device Global Interrupt Set Register Offset */ - -#define DEVIFR_SUSPS_Pos 0 /**< (DEVIFR) Suspend Interrupt Set Position */ -#define DEVIFR_SUSPS (_U_(0x1) << DEVIFR_SUSPS_Pos) /**< (DEVIFR) Suspend Interrupt Set Mask */ -#define DEVIFR_MSOFS_Pos 1 /**< (DEVIFR) Micro Start of Frame Interrupt Set Position */ -#define DEVIFR_MSOFS (_U_(0x1) << DEVIFR_MSOFS_Pos) /**< (DEVIFR) Micro Start of Frame Interrupt Set Mask */ -#define DEVIFR_SOFS_Pos 2 /**< (DEVIFR) Start of Frame Interrupt Set Position */ -#define DEVIFR_SOFS (_U_(0x1) << DEVIFR_SOFS_Pos) /**< (DEVIFR) Start of Frame Interrupt Set Mask */ -#define DEVIFR_EORSTS_Pos 3 /**< (DEVIFR) End of Reset Interrupt Set Position */ -#define DEVIFR_EORSTS (_U_(0x1) << DEVIFR_EORSTS_Pos) /**< (DEVIFR) End of Reset Interrupt Set Mask */ -#define DEVIFR_WAKEUPS_Pos 4 /**< (DEVIFR) Wake-Up Interrupt Set Position */ -#define DEVIFR_WAKEUPS (_U_(0x1) << DEVIFR_WAKEUPS_Pos) /**< (DEVIFR) Wake-Up Interrupt Set Mask */ -#define DEVIFR_EORSMS_Pos 5 /**< (DEVIFR) End of Resume Interrupt Set Position */ -#define DEVIFR_EORSMS (_U_(0x1) << DEVIFR_EORSMS_Pos) /**< (DEVIFR) End of Resume Interrupt Set Mask */ -#define DEVIFR_UPRSMS_Pos 6 /**< (DEVIFR) Upstream Resume Interrupt Set Position */ -#define DEVIFR_UPRSMS (_U_(0x1) << DEVIFR_UPRSMS_Pos) /**< (DEVIFR) Upstream Resume Interrupt Set Mask */ -#define DEVIFR_DMA_1_Pos 25 /**< (DEVIFR) DMA Channel 1 Interrupt Set Position */ -#define DEVIFR_DMA_1 (_U_(0x1) << DEVIFR_DMA_1_Pos) /**< (DEVIFR) DMA Channel 1 Interrupt Set Mask */ -#define DEVIFR_DMA_2_Pos 26 /**< (DEVIFR) DMA Channel 2 Interrupt Set Position */ -#define DEVIFR_DMA_2 (_U_(0x1) << DEVIFR_DMA_2_Pos) /**< (DEVIFR) DMA Channel 2 Interrupt Set Mask */ -#define DEVIFR_DMA_3_Pos 27 /**< (DEVIFR) DMA Channel 3 Interrupt Set Position */ -#define DEVIFR_DMA_3 (_U_(0x1) << DEVIFR_DMA_3_Pos) /**< (DEVIFR) DMA Channel 3 Interrupt Set Mask */ -#define DEVIFR_DMA_4_Pos 28 /**< (DEVIFR) DMA Channel 4 Interrupt Set Position */ -#define DEVIFR_DMA_4 (_U_(0x1) << DEVIFR_DMA_4_Pos) /**< (DEVIFR) DMA Channel 4 Interrupt Set Mask */ -#define DEVIFR_DMA_5_Pos 29 /**< (DEVIFR) DMA Channel 5 Interrupt Set Position */ -#define DEVIFR_DMA_5 (_U_(0x1) << DEVIFR_DMA_5_Pos) /**< (DEVIFR) DMA Channel 5 Interrupt Set Mask */ -#define DEVIFR_DMA_6_Pos 30 /**< (DEVIFR) DMA Channel 6 Interrupt Set Position */ -#define DEVIFR_DMA_6 (_U_(0x1) << DEVIFR_DMA_6_Pos) /**< (DEVIFR) DMA Channel 6 Interrupt Set Mask */ -#define DEVIFR_DMA_7_Pos 31 /**< (DEVIFR) DMA Channel 7 Interrupt Set Position */ -#define DEVIFR_DMA_7 (_U_(0x1) << DEVIFR_DMA_7_Pos) /**< (DEVIFR) DMA Channel 7 Interrupt Set Mask */ -#define DEVIFR_Msk _U_(0xFE00007F) /**< (DEVIFR) Register Mask */ - -#define DEVIFR_DMA__Pos 25 /**< (DEVIFR Position) DMA Channel 7 Interrupt Set */ -#define DEVIFR_DMA_ (_U_(0x7F) << DEVIFR_DMA__Pos) /**< (DEVIFR Mask) DMA_ */ - -/* -------- DEVIMR : (USBHS Offset: 0x10) (R/ 32) Device Global Interrupt Mask Register -------- */ - -#define DEVIMR_OFFSET (0x10) /**< (DEVIMR) Device Global Interrupt Mask Register Offset */ - -#define DEVIMR_SUSPE_Pos 0 /**< (DEVIMR) Suspend Interrupt Mask Position */ -#define DEVIMR_SUSPE (_U_(0x1) << DEVIMR_SUSPE_Pos) /**< (DEVIMR) Suspend Interrupt Mask Mask */ -#define DEVIMR_MSOFE_Pos 1 /**< (DEVIMR) Micro Start of Frame Interrupt Mask Position */ -#define DEVIMR_MSOFE (_U_(0x1) << DEVIMR_MSOFE_Pos) /**< (DEVIMR) Micro Start of Frame Interrupt Mask Mask */ -#define DEVIMR_SOFE_Pos 2 /**< (DEVIMR) Start of Frame Interrupt Mask Position */ -#define DEVIMR_SOFE (_U_(0x1) << DEVIMR_SOFE_Pos) /**< (DEVIMR) Start of Frame Interrupt Mask Mask */ -#define DEVIMR_EORSTE_Pos 3 /**< (DEVIMR) End of Reset Interrupt Mask Position */ -#define DEVIMR_EORSTE (_U_(0x1) << DEVIMR_EORSTE_Pos) /**< (DEVIMR) End of Reset Interrupt Mask Mask */ -#define DEVIMR_WAKEUPE_Pos 4 /**< (DEVIMR) Wake-Up Interrupt Mask Position */ -#define DEVIMR_WAKEUPE (_U_(0x1) << DEVIMR_WAKEUPE_Pos) /**< (DEVIMR) Wake-Up Interrupt Mask Mask */ -#define DEVIMR_EORSME_Pos 5 /**< (DEVIMR) End of Resume Interrupt Mask Position */ -#define DEVIMR_EORSME (_U_(0x1) << DEVIMR_EORSME_Pos) /**< (DEVIMR) End of Resume Interrupt Mask Mask */ -#define DEVIMR_UPRSME_Pos 6 /**< (DEVIMR) Upstream Resume Interrupt Mask Position */ -#define DEVIMR_UPRSME (_U_(0x1) << DEVIMR_UPRSME_Pos) /**< (DEVIMR) Upstream Resume Interrupt Mask Mask */ -#define DEVIMR_PEP_0_Pos 12 /**< (DEVIMR) Endpoint 0 Interrupt Mask Position */ -#define DEVIMR_PEP_0 (_U_(0x1) << DEVIMR_PEP_0_Pos) /**< (DEVIMR) Endpoint 0 Interrupt Mask Mask */ -#define DEVIMR_PEP_1_Pos 13 /**< (DEVIMR) Endpoint 1 Interrupt Mask Position */ -#define DEVIMR_PEP_1 (_U_(0x1) << DEVIMR_PEP_1_Pos) /**< (DEVIMR) Endpoint 1 Interrupt Mask Mask */ -#define DEVIMR_PEP_2_Pos 14 /**< (DEVIMR) Endpoint 2 Interrupt Mask Position */ -#define DEVIMR_PEP_2 (_U_(0x1) << DEVIMR_PEP_2_Pos) /**< (DEVIMR) Endpoint 2 Interrupt Mask Mask */ -#define DEVIMR_PEP_3_Pos 15 /**< (DEVIMR) Endpoint 3 Interrupt Mask Position */ -#define DEVIMR_PEP_3 (_U_(0x1) << DEVIMR_PEP_3_Pos) /**< (DEVIMR) Endpoint 3 Interrupt Mask Mask */ -#define DEVIMR_PEP_4_Pos 16 /**< (DEVIMR) Endpoint 4 Interrupt Mask Position */ -#define DEVIMR_PEP_4 (_U_(0x1) << DEVIMR_PEP_4_Pos) /**< (DEVIMR) Endpoint 4 Interrupt Mask Mask */ -#define DEVIMR_PEP_5_Pos 17 /**< (DEVIMR) Endpoint 5 Interrupt Mask Position */ -#define DEVIMR_PEP_5 (_U_(0x1) << DEVIMR_PEP_5_Pos) /**< (DEVIMR) Endpoint 5 Interrupt Mask Mask */ -#define DEVIMR_PEP_6_Pos 18 /**< (DEVIMR) Endpoint 6 Interrupt Mask Position */ -#define DEVIMR_PEP_6 (_U_(0x1) << DEVIMR_PEP_6_Pos) /**< (DEVIMR) Endpoint 6 Interrupt Mask Mask */ -#define DEVIMR_PEP_7_Pos 19 /**< (DEVIMR) Endpoint 7 Interrupt Mask Position */ -#define DEVIMR_PEP_7 (_U_(0x1) << DEVIMR_PEP_7_Pos) /**< (DEVIMR) Endpoint 7 Interrupt Mask Mask */ -#define DEVIMR_PEP_8_Pos 20 /**< (DEVIMR) Endpoint 8 Interrupt Mask Position */ -#define DEVIMR_PEP_8 (_U_(0x1) << DEVIMR_PEP_8_Pos) /**< (DEVIMR) Endpoint 8 Interrupt Mask Mask */ -#define DEVIMR_PEP_9_Pos 21 /**< (DEVIMR) Endpoint 9 Interrupt Mask Position */ -#define DEVIMR_PEP_9 (_U_(0x1) << DEVIMR_PEP_9_Pos) /**< (DEVIMR) Endpoint 9 Interrupt Mask Mask */ -#define DEVIMR_DMA_1_Pos 25 /**< (DEVIMR) DMA Channel 1 Interrupt Mask Position */ -#define DEVIMR_DMA_1 (_U_(0x1) << DEVIMR_DMA_1_Pos) /**< (DEVIMR) DMA Channel 1 Interrupt Mask Mask */ -#define DEVIMR_DMA_2_Pos 26 /**< (DEVIMR) DMA Channel 2 Interrupt Mask Position */ -#define DEVIMR_DMA_2 (_U_(0x1) << DEVIMR_DMA_2_Pos) /**< (DEVIMR) DMA Channel 2 Interrupt Mask Mask */ -#define DEVIMR_DMA_3_Pos 27 /**< (DEVIMR) DMA Channel 3 Interrupt Mask Position */ -#define DEVIMR_DMA_3 (_U_(0x1) << DEVIMR_DMA_3_Pos) /**< (DEVIMR) DMA Channel 3 Interrupt Mask Mask */ -#define DEVIMR_DMA_4_Pos 28 /**< (DEVIMR) DMA Channel 4 Interrupt Mask Position */ -#define DEVIMR_DMA_4 (_U_(0x1) << DEVIMR_DMA_4_Pos) /**< (DEVIMR) DMA Channel 4 Interrupt Mask Mask */ -#define DEVIMR_DMA_5_Pos 29 /**< (DEVIMR) DMA Channel 5 Interrupt Mask Position */ -#define DEVIMR_DMA_5 (_U_(0x1) << DEVIMR_DMA_5_Pos) /**< (DEVIMR) DMA Channel 5 Interrupt Mask Mask */ -#define DEVIMR_DMA_6_Pos 30 /**< (DEVIMR) DMA Channel 6 Interrupt Mask Position */ -#define DEVIMR_DMA_6 (_U_(0x1) << DEVIMR_DMA_6_Pos) /**< (DEVIMR) DMA Channel 6 Interrupt Mask Mask */ -#define DEVIMR_DMA_7_Pos 31 /**< (DEVIMR) DMA Channel 7 Interrupt Mask Position */ -#define DEVIMR_DMA_7 (_U_(0x1) << DEVIMR_DMA_7_Pos) /**< (DEVIMR) DMA Channel 7 Interrupt Mask Mask */ -#define DEVIMR_Msk _U_(0xFE3FF07F) /**< (DEVIMR) Register Mask */ - -#define DEVIMR_PEP__Pos 12 /**< (DEVIMR Position) Endpoint x Interrupt Mask */ -#define DEVIMR_PEP_ (_U_(0x3FF) << DEVIMR_PEP__Pos) /**< (DEVIMR Mask) PEP_ */ -#define DEVIMR_DMA__Pos 25 /**< (DEVIMR Position) DMA Channel 7 Interrupt Mask */ -#define DEVIMR_DMA_ (_U_(0x7F) << DEVIMR_DMA__Pos) /**< (DEVIMR Mask) DMA_ */ - -/* -------- DEVIDR : (USBHS Offset: 0x14) (/W 32) Device Global Interrupt Disable Register -------- */ - -#define DEVIDR_OFFSET (0x14) /**< (DEVIDR) Device Global Interrupt Disable Register Offset */ - -#define DEVIDR_SUSPEC_Pos 0 /**< (DEVIDR) Suspend Interrupt Disable Position */ -#define DEVIDR_SUSPEC (_U_(0x1) << DEVIDR_SUSPEC_Pos) /**< (DEVIDR) Suspend Interrupt Disable Mask */ -#define DEVIDR_MSOFEC_Pos 1 /**< (DEVIDR) Micro Start of Frame Interrupt Disable Position */ -#define DEVIDR_MSOFEC (_U_(0x1) << DEVIDR_MSOFEC_Pos) /**< (DEVIDR) Micro Start of Frame Interrupt Disable Mask */ -#define DEVIDR_SOFEC_Pos 2 /**< (DEVIDR) Start of Frame Interrupt Disable Position */ -#define DEVIDR_SOFEC (_U_(0x1) << DEVIDR_SOFEC_Pos) /**< (DEVIDR) Start of Frame Interrupt Disable Mask */ -#define DEVIDR_EORSTEC_Pos 3 /**< (DEVIDR) End of Reset Interrupt Disable Position */ -#define DEVIDR_EORSTEC (_U_(0x1) << DEVIDR_EORSTEC_Pos) /**< (DEVIDR) End of Reset Interrupt Disable Mask */ -#define DEVIDR_WAKEUPEC_Pos 4 /**< (DEVIDR) Wake-Up Interrupt Disable Position */ -#define DEVIDR_WAKEUPEC (_U_(0x1) << DEVIDR_WAKEUPEC_Pos) /**< (DEVIDR) Wake-Up Interrupt Disable Mask */ -#define DEVIDR_EORSMEC_Pos 5 /**< (DEVIDR) End of Resume Interrupt Disable Position */ -#define DEVIDR_EORSMEC (_U_(0x1) << DEVIDR_EORSMEC_Pos) /**< (DEVIDR) End of Resume Interrupt Disable Mask */ -#define DEVIDR_UPRSMEC_Pos 6 /**< (DEVIDR) Upstream Resume Interrupt Disable Position */ -#define DEVIDR_UPRSMEC (_U_(0x1) << DEVIDR_UPRSMEC_Pos) /**< (DEVIDR) Upstream Resume Interrupt Disable Mask */ -#define DEVIDR_PEP_0_Pos 12 /**< (DEVIDR) Endpoint 0 Interrupt Disable Position */ -#define DEVIDR_PEP_0 (_U_(0x1) << DEVIDR_PEP_0_Pos) /**< (DEVIDR) Endpoint 0 Interrupt Disable Mask */ -#define DEVIDR_PEP_1_Pos 13 /**< (DEVIDR) Endpoint 1 Interrupt Disable Position */ -#define DEVIDR_PEP_1 (_U_(0x1) << DEVIDR_PEP_1_Pos) /**< (DEVIDR) Endpoint 1 Interrupt Disable Mask */ -#define DEVIDR_PEP_2_Pos 14 /**< (DEVIDR) Endpoint 2 Interrupt Disable Position */ -#define DEVIDR_PEP_2 (_U_(0x1) << DEVIDR_PEP_2_Pos) /**< (DEVIDR) Endpoint 2 Interrupt Disable Mask */ -#define DEVIDR_PEP_3_Pos 15 /**< (DEVIDR) Endpoint 3 Interrupt Disable Position */ -#define DEVIDR_PEP_3 (_U_(0x1) << DEVIDR_PEP_3_Pos) /**< (DEVIDR) Endpoint 3 Interrupt Disable Mask */ -#define DEVIDR_PEP_4_Pos 16 /**< (DEVIDR) Endpoint 4 Interrupt Disable Position */ -#define DEVIDR_PEP_4 (_U_(0x1) << DEVIDR_PEP_4_Pos) /**< (DEVIDR) Endpoint 4 Interrupt Disable Mask */ -#define DEVIDR_PEP_5_Pos 17 /**< (DEVIDR) Endpoint 5 Interrupt Disable Position */ -#define DEVIDR_PEP_5 (_U_(0x1) << DEVIDR_PEP_5_Pos) /**< (DEVIDR) Endpoint 5 Interrupt Disable Mask */ -#define DEVIDR_PEP_6_Pos 18 /**< (DEVIDR) Endpoint 6 Interrupt Disable Position */ -#define DEVIDR_PEP_6 (_U_(0x1) << DEVIDR_PEP_6_Pos) /**< (DEVIDR) Endpoint 6 Interrupt Disable Mask */ -#define DEVIDR_PEP_7_Pos 19 /**< (DEVIDR) Endpoint 7 Interrupt Disable Position */ -#define DEVIDR_PEP_7 (_U_(0x1) << DEVIDR_PEP_7_Pos) /**< (DEVIDR) Endpoint 7 Interrupt Disable Mask */ -#define DEVIDR_PEP_8_Pos 20 /**< (DEVIDR) Endpoint 8 Interrupt Disable Position */ -#define DEVIDR_PEP_8 (_U_(0x1) << DEVIDR_PEP_8_Pos) /**< (DEVIDR) Endpoint 8 Interrupt Disable Mask */ -#define DEVIDR_PEP_9_Pos 21 /**< (DEVIDR) Endpoint 9 Interrupt Disable Position */ -#define DEVIDR_PEP_9 (_U_(0x1) << DEVIDR_PEP_9_Pos) /**< (DEVIDR) Endpoint 9 Interrupt Disable Mask */ -#define DEVIDR_DMA_1_Pos 25 /**< (DEVIDR) DMA Channel 1 Interrupt Disable Position */ -#define DEVIDR_DMA_1 (_U_(0x1) << DEVIDR_DMA_1_Pos) /**< (DEVIDR) DMA Channel 1 Interrupt Disable Mask */ -#define DEVIDR_DMA_2_Pos 26 /**< (DEVIDR) DMA Channel 2 Interrupt Disable Position */ -#define DEVIDR_DMA_2 (_U_(0x1) << DEVIDR_DMA_2_Pos) /**< (DEVIDR) DMA Channel 2 Interrupt Disable Mask */ -#define DEVIDR_DMA_3_Pos 27 /**< (DEVIDR) DMA Channel 3 Interrupt Disable Position */ -#define DEVIDR_DMA_3 (_U_(0x1) << DEVIDR_DMA_3_Pos) /**< (DEVIDR) DMA Channel 3 Interrupt Disable Mask */ -#define DEVIDR_DMA_4_Pos 28 /**< (DEVIDR) DMA Channel 4 Interrupt Disable Position */ -#define DEVIDR_DMA_4 (_U_(0x1) << DEVIDR_DMA_4_Pos) /**< (DEVIDR) DMA Channel 4 Interrupt Disable Mask */ -#define DEVIDR_DMA_5_Pos 29 /**< (DEVIDR) DMA Channel 5 Interrupt Disable Position */ -#define DEVIDR_DMA_5 (_U_(0x1) << DEVIDR_DMA_5_Pos) /**< (DEVIDR) DMA Channel 5 Interrupt Disable Mask */ -#define DEVIDR_DMA_6_Pos 30 /**< (DEVIDR) DMA Channel 6 Interrupt Disable Position */ -#define DEVIDR_DMA_6 (_U_(0x1) << DEVIDR_DMA_6_Pos) /**< (DEVIDR) DMA Channel 6 Interrupt Disable Mask */ -#define DEVIDR_DMA_7_Pos 31 /**< (DEVIDR) DMA Channel 7 Interrupt Disable Position */ -#define DEVIDR_DMA_7 (_U_(0x1) << DEVIDR_DMA_7_Pos) /**< (DEVIDR) DMA Channel 7 Interrupt Disable Mask */ -#define DEVIDR_Msk _U_(0xFE3FF07F) /**< (DEVIDR) Register Mask */ - -#define DEVIDR_PEP__Pos 12 /**< (DEVIDR Position) Endpoint x Interrupt Disable */ -#define DEVIDR_PEP_ (_U_(0x3FF) << DEVIDR_PEP__Pos) /**< (DEVIDR Mask) PEP_ */ -#define DEVIDR_DMA__Pos 25 /**< (DEVIDR Position) DMA Channel 7 Interrupt Disable */ -#define DEVIDR_DMA_ (_U_(0x7F) << DEVIDR_DMA__Pos) /**< (DEVIDR Mask) DMA_ */ - -/* -------- DEVIER : (USBHS Offset: 0x18) (/W 32) Device Global Interrupt Enable Register -------- */ - -#define DEVIER_OFFSET (0x18) /**< (DEVIER) Device Global Interrupt Enable Register Offset */ - -#define DEVIER_SUSPES_Pos 0 /**< (DEVIER) Suspend Interrupt Enable Position */ -#define DEVIER_SUSPES (_U_(0x1) << DEVIER_SUSPES_Pos) /**< (DEVIER) Suspend Interrupt Enable Mask */ -#define DEVIER_MSOFES_Pos 1 /**< (DEVIER) Micro Start of Frame Interrupt Enable Position */ -#define DEVIER_MSOFES (_U_(0x1) << DEVIER_MSOFES_Pos) /**< (DEVIER) Micro Start of Frame Interrupt Enable Mask */ -#define DEVIER_SOFES_Pos 2 /**< (DEVIER) Start of Frame Interrupt Enable Position */ -#define DEVIER_SOFES (_U_(0x1) << DEVIER_SOFES_Pos) /**< (DEVIER) Start of Frame Interrupt Enable Mask */ -#define DEVIER_EORSTES_Pos 3 /**< (DEVIER) End of Reset Interrupt Enable Position */ -#define DEVIER_EORSTES (_U_(0x1) << DEVIER_EORSTES_Pos) /**< (DEVIER) End of Reset Interrupt Enable Mask */ -#define DEVIER_WAKEUPES_Pos 4 /**< (DEVIER) Wake-Up Interrupt Enable Position */ -#define DEVIER_WAKEUPES (_U_(0x1) << DEVIER_WAKEUPES_Pos) /**< (DEVIER) Wake-Up Interrupt Enable Mask */ -#define DEVIER_EORSMES_Pos 5 /**< (DEVIER) End of Resume Interrupt Enable Position */ -#define DEVIER_EORSMES (_U_(0x1) << DEVIER_EORSMES_Pos) /**< (DEVIER) End of Resume Interrupt Enable Mask */ -#define DEVIER_UPRSMES_Pos 6 /**< (DEVIER) Upstream Resume Interrupt Enable Position */ -#define DEVIER_UPRSMES (_U_(0x1) << DEVIER_UPRSMES_Pos) /**< (DEVIER) Upstream Resume Interrupt Enable Mask */ -#define DEVIER_PEP_0_Pos 12 /**< (DEVIER) Endpoint 0 Interrupt Enable Position */ -#define DEVIER_PEP_0 (_U_(0x1) << DEVIER_PEP_0_Pos) /**< (DEVIER) Endpoint 0 Interrupt Enable Mask */ -#define DEVIER_PEP_1_Pos 13 /**< (DEVIER) Endpoint 1 Interrupt Enable Position */ -#define DEVIER_PEP_1 (_U_(0x1) << DEVIER_PEP_1_Pos) /**< (DEVIER) Endpoint 1 Interrupt Enable Mask */ -#define DEVIER_PEP_2_Pos 14 /**< (DEVIER) Endpoint 2 Interrupt Enable Position */ -#define DEVIER_PEP_2 (_U_(0x1) << DEVIER_PEP_2_Pos) /**< (DEVIER) Endpoint 2 Interrupt Enable Mask */ -#define DEVIER_PEP_3_Pos 15 /**< (DEVIER) Endpoint 3 Interrupt Enable Position */ -#define DEVIER_PEP_3 (_U_(0x1) << DEVIER_PEP_3_Pos) /**< (DEVIER) Endpoint 3 Interrupt Enable Mask */ -#define DEVIER_PEP_4_Pos 16 /**< (DEVIER) Endpoint 4 Interrupt Enable Position */ -#define DEVIER_PEP_4 (_U_(0x1) << DEVIER_PEP_4_Pos) /**< (DEVIER) Endpoint 4 Interrupt Enable Mask */ -#define DEVIER_PEP_5_Pos 17 /**< (DEVIER) Endpoint 5 Interrupt Enable Position */ -#define DEVIER_PEP_5 (_U_(0x1) << DEVIER_PEP_5_Pos) /**< (DEVIER) Endpoint 5 Interrupt Enable Mask */ -#define DEVIER_PEP_6_Pos 18 /**< (DEVIER) Endpoint 6 Interrupt Enable Position */ -#define DEVIER_PEP_6 (_U_(0x1) << DEVIER_PEP_6_Pos) /**< (DEVIER) Endpoint 6 Interrupt Enable Mask */ -#define DEVIER_PEP_7_Pos 19 /**< (DEVIER) Endpoint 7 Interrupt Enable Position */ -#define DEVIER_PEP_7 (_U_(0x1) << DEVIER_PEP_7_Pos) /**< (DEVIER) Endpoint 7 Interrupt Enable Mask */ -#define DEVIER_PEP_8_Pos 20 /**< (DEVIER) Endpoint 8 Interrupt Enable Position */ -#define DEVIER_PEP_8 (_U_(0x1) << DEVIER_PEP_8_Pos) /**< (DEVIER) Endpoint 8 Interrupt Enable Mask */ -#define DEVIER_PEP_9_Pos 21 /**< (DEVIER) Endpoint 9 Interrupt Enable Position */ -#define DEVIER_PEP_9 (_U_(0x1) << DEVIER_PEP_9_Pos) /**< (DEVIER) Endpoint 9 Interrupt Enable Mask */ -#define DEVIER_DMA_1_Pos 25 /**< (DEVIER) DMA Channel 1 Interrupt Enable Position */ -#define DEVIER_DMA_1 (_U_(0x1) << DEVIER_DMA_1_Pos) /**< (DEVIER) DMA Channel 1 Interrupt Enable Mask */ -#define DEVIER_DMA_2_Pos 26 /**< (DEVIER) DMA Channel 2 Interrupt Enable Position */ -#define DEVIER_DMA_2 (_U_(0x1) << DEVIER_DMA_2_Pos) /**< (DEVIER) DMA Channel 2 Interrupt Enable Mask */ -#define DEVIER_DMA_3_Pos 27 /**< (DEVIER) DMA Channel 3 Interrupt Enable Position */ -#define DEVIER_DMA_3 (_U_(0x1) << DEVIER_DMA_3_Pos) /**< (DEVIER) DMA Channel 3 Interrupt Enable Mask */ -#define DEVIER_DMA_4_Pos 28 /**< (DEVIER) DMA Channel 4 Interrupt Enable Position */ -#define DEVIER_DMA_4 (_U_(0x1) << DEVIER_DMA_4_Pos) /**< (DEVIER) DMA Channel 4 Interrupt Enable Mask */ -#define DEVIER_DMA_5_Pos 29 /**< (DEVIER) DMA Channel 5 Interrupt Enable Position */ -#define DEVIER_DMA_5 (_U_(0x1) << DEVIER_DMA_5_Pos) /**< (DEVIER) DMA Channel 5 Interrupt Enable Mask */ -#define DEVIER_DMA_6_Pos 30 /**< (DEVIER) DMA Channel 6 Interrupt Enable Position */ -#define DEVIER_DMA_6 (_U_(0x1) << DEVIER_DMA_6_Pos) /**< (DEVIER) DMA Channel 6 Interrupt Enable Mask */ -#define DEVIER_DMA_7_Pos 31 /**< (DEVIER) DMA Channel 7 Interrupt Enable Position */ -#define DEVIER_DMA_7 (_U_(0x1) << DEVIER_DMA_7_Pos) /**< (DEVIER) DMA Channel 7 Interrupt Enable Mask */ -#define DEVIER_Msk _U_(0xFE3FF07F) /**< (DEVIER) Register Mask */ - -#define DEVIER_PEP__Pos 12 /**< (DEVIER Position) Endpoint x Interrupt Enable */ -#define DEVIER_PEP_ (_U_(0x3FF) << DEVIER_PEP__Pos) /**< (DEVIER Mask) PEP_ */ -#define DEVIER_DMA__Pos 25 /**< (DEVIER Position) DMA Channel 7 Interrupt Enable */ -#define DEVIER_DMA_ (_U_(0x7F) << DEVIER_DMA__Pos) /**< (DEVIER Mask) DMA_ */ - -/* -------- DEVEPT : (USBHS Offset: 0x1c) (R/W 32) Device Endpoint Register -------- */ - -#define DEVEPT_OFFSET (0x1C) /**< (DEVEPT) Device Endpoint Register Offset */ - -#define DEVEPT_EPEN0_Pos 0 /**< (DEVEPT) Endpoint 0 Enable Position */ -#define DEVEPT_EPEN0 (_U_(0x1) << DEVEPT_EPEN0_Pos) /**< (DEVEPT) Endpoint 0 Enable Mask */ -#define DEVEPT_EPEN1_Pos 1 /**< (DEVEPT) Endpoint 1 Enable Position */ -#define DEVEPT_EPEN1 (_U_(0x1) << DEVEPT_EPEN1_Pos) /**< (DEVEPT) Endpoint 1 Enable Mask */ -#define DEVEPT_EPEN2_Pos 2 /**< (DEVEPT) Endpoint 2 Enable Position */ -#define DEVEPT_EPEN2 (_U_(0x1) << DEVEPT_EPEN2_Pos) /**< (DEVEPT) Endpoint 2 Enable Mask */ -#define DEVEPT_EPEN3_Pos 3 /**< (DEVEPT) Endpoint 3 Enable Position */ -#define DEVEPT_EPEN3 (_U_(0x1) << DEVEPT_EPEN3_Pos) /**< (DEVEPT) Endpoint 3 Enable Mask */ -#define DEVEPT_EPEN4_Pos 4 /**< (DEVEPT) Endpoint 4 Enable Position */ -#define DEVEPT_EPEN4 (_U_(0x1) << DEVEPT_EPEN4_Pos) /**< (DEVEPT) Endpoint 4 Enable Mask */ -#define DEVEPT_EPEN5_Pos 5 /**< (DEVEPT) Endpoint 5 Enable Position */ -#define DEVEPT_EPEN5 (_U_(0x1) << DEVEPT_EPEN5_Pos) /**< (DEVEPT) Endpoint 5 Enable Mask */ -#define DEVEPT_EPEN6_Pos 6 /**< (DEVEPT) Endpoint 6 Enable Position */ -#define DEVEPT_EPEN6 (_U_(0x1) << DEVEPT_EPEN6_Pos) /**< (DEVEPT) Endpoint 6 Enable Mask */ -#define DEVEPT_EPEN7_Pos 7 /**< (DEVEPT) Endpoint 7 Enable Position */ -#define DEVEPT_EPEN7 (_U_(0x1) << DEVEPT_EPEN7_Pos) /**< (DEVEPT) Endpoint 7 Enable Mask */ -#define DEVEPT_EPEN8_Pos 8 /**< (DEVEPT) Endpoint 8 Enable Position */ -#define DEVEPT_EPEN8 (_U_(0x1) << DEVEPT_EPEN8_Pos) /**< (DEVEPT) Endpoint 8 Enable Mask */ -#define DEVEPT_EPEN9_Pos 9 /**< (DEVEPT) Endpoint 9 Enable Position */ -#define DEVEPT_EPEN9 (_U_(0x1) << DEVEPT_EPEN9_Pos) /**< (DEVEPT) Endpoint 9 Enable Mask */ -#define DEVEPT_EPRST0_Pos 16 /**< (DEVEPT) Endpoint 0 Reset Position */ -#define DEVEPT_EPRST0 (_U_(0x1) << DEVEPT_EPRST0_Pos) /**< (DEVEPT) Endpoint 0 Reset Mask */ -#define DEVEPT_EPRST1_Pos 17 /**< (DEVEPT) Endpoint 1 Reset Position */ -#define DEVEPT_EPRST1 (_U_(0x1) << DEVEPT_EPRST1_Pos) /**< (DEVEPT) Endpoint 1 Reset Mask */ -#define DEVEPT_EPRST2_Pos 18 /**< (DEVEPT) Endpoint 2 Reset Position */ -#define DEVEPT_EPRST2 (_U_(0x1) << DEVEPT_EPRST2_Pos) /**< (DEVEPT) Endpoint 2 Reset Mask */ -#define DEVEPT_EPRST3_Pos 19 /**< (DEVEPT) Endpoint 3 Reset Position */ -#define DEVEPT_EPRST3 (_U_(0x1) << DEVEPT_EPRST3_Pos) /**< (DEVEPT) Endpoint 3 Reset Mask */ -#define DEVEPT_EPRST4_Pos 20 /**< (DEVEPT) Endpoint 4 Reset Position */ -#define DEVEPT_EPRST4 (_U_(0x1) << DEVEPT_EPRST4_Pos) /**< (DEVEPT) Endpoint 4 Reset Mask */ -#define DEVEPT_EPRST5_Pos 21 /**< (DEVEPT) Endpoint 5 Reset Position */ -#define DEVEPT_EPRST5 (_U_(0x1) << DEVEPT_EPRST5_Pos) /**< (DEVEPT) Endpoint 5 Reset Mask */ -#define DEVEPT_EPRST6_Pos 22 /**< (DEVEPT) Endpoint 6 Reset Position */ -#define DEVEPT_EPRST6 (_U_(0x1) << DEVEPT_EPRST6_Pos) /**< (DEVEPT) Endpoint 6 Reset Mask */ -#define DEVEPT_EPRST7_Pos 23 /**< (DEVEPT) Endpoint 7 Reset Position */ -#define DEVEPT_EPRST7 (_U_(0x1) << DEVEPT_EPRST7_Pos) /**< (DEVEPT) Endpoint 7 Reset Mask */ -#define DEVEPT_EPRST8_Pos 24 /**< (DEVEPT) Endpoint 8 Reset Position */ -#define DEVEPT_EPRST8 (_U_(0x1) << DEVEPT_EPRST8_Pos) /**< (DEVEPT) Endpoint 8 Reset Mask */ -#define DEVEPT_EPRST9_Pos 25 /**< (DEVEPT) Endpoint 9 Reset Position */ -#define DEVEPT_EPRST9 (_U_(0x1) << DEVEPT_EPRST9_Pos) /**< (DEVEPT) Endpoint 9 Reset Mask */ -#define DEVEPT_Msk _U_(0x3FF03FF) /**< (DEVEPT) Register Mask */ - -#define DEVEPT_EPEN_Pos 0 /**< (DEVEPT Position) Endpoint x Enable */ -#define DEVEPT_EPEN (_U_(0x3FF) << DEVEPT_EPEN_Pos) /**< (DEVEPT Mask) EPEN */ -#define DEVEPT_EPRST_Pos 16 /**< (DEVEPT Position) Endpoint 9 Reset */ -#define DEVEPT_EPRST (_U_(0x3FF) << DEVEPT_EPRST_Pos) /**< (DEVEPT Mask) EPRST */ - -/* -------- DEVFNUM : (USBHS Offset: 0x20) (R/ 32) Device Frame Number Register -------- */ - -#define DEVFNUM_OFFSET (0x20) /**< (DEVFNUM) Device Frame Number Register Offset */ - -#define DEVFNUM_MFNUM_Pos 0 /**< (DEVFNUM) Micro Frame Number Position */ -#define DEVFNUM_MFNUM (_U_(0x7) << DEVFNUM_MFNUM_Pos) /**< (DEVFNUM) Micro Frame Number Mask */ -#define DEVFNUM_FNUM_Pos 3 /**< (DEVFNUM) Frame Number Position */ -#define DEVFNUM_FNUM (_U_(0x7FF) << DEVFNUM_FNUM_Pos) /**< (DEVFNUM) Frame Number Mask */ -#define DEVFNUM_FNCERR_Pos 15 /**< (DEVFNUM) Frame Number CRC Error Position */ -#define DEVFNUM_FNCERR (_U_(0x1) << DEVFNUM_FNCERR_Pos) /**< (DEVFNUM) Frame Number CRC Error Mask */ -#define DEVFNUM_Msk _U_(0xBFFF) /**< (DEVFNUM) Register Mask */ - - -/* -------- DEVEPTCFG : (USBHS Offset: 0x100) (R/W 32) Device Endpoint Configuration Register -------- */ - -#define DEVEPTCFG_OFFSET (0x100) /**< (DEVEPTCFG) Device Endpoint Configuration Register Offset */ - -#define DEVEPTCFG_ALLOC_Pos 1 /**< (DEVEPTCFG) Endpoint Memory Allocate Position */ -#define DEVEPTCFG_ALLOC (_U_(0x1) << DEVEPTCFG_ALLOC_Pos) /**< (DEVEPTCFG) Endpoint Memory Allocate Mask */ -#define DEVEPTCFG_EPBK_Pos 2 /**< (DEVEPTCFG) Endpoint Banks Position */ -#define DEVEPTCFG_EPBK (_U_(0x3) << DEVEPTCFG_EPBK_Pos) /**< (DEVEPTCFG) Endpoint Banks Mask */ -#define DEVEPTCFG_EPBK_1_BANK_Val _U_(0x0) /**< (DEVEPTCFG) Single-bank endpoint */ -#define DEVEPTCFG_EPBK_2_BANK_Val _U_(0x1) /**< (DEVEPTCFG) Double-bank endpoint */ -#define DEVEPTCFG_EPBK_3_BANK_Val _U_(0x2) /**< (DEVEPTCFG) Triple-bank endpoint */ -#define DEVEPTCFG_EPBK_1_BANK (DEVEPTCFG_EPBK_1_BANK_Val << DEVEPTCFG_EPBK_Pos) /**< (DEVEPTCFG) Single-bank endpoint Position */ -#define DEVEPTCFG_EPBK_2_BANK (DEVEPTCFG_EPBK_2_BANK_Val << DEVEPTCFG_EPBK_Pos) /**< (DEVEPTCFG) Double-bank endpoint Position */ -#define DEVEPTCFG_EPBK_3_BANK (DEVEPTCFG_EPBK_3_BANK_Val << DEVEPTCFG_EPBK_Pos) /**< (DEVEPTCFG) Triple-bank endpoint Position */ -#define DEVEPTCFG_EPSIZE_Pos 4 /**< (DEVEPTCFG) Endpoint Size Position */ -#define DEVEPTCFG_EPSIZE (_U_(0x7) << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) Endpoint Size Mask */ -#define DEVEPTCFG_EPSIZE_8_BYTE_Val _U_(0x0) /**< (DEVEPTCFG) 8 bytes */ -#define DEVEPTCFG_EPSIZE_16_BYTE_Val _U_(0x1) /**< (DEVEPTCFG) 16 bytes */ -#define DEVEPTCFG_EPSIZE_32_BYTE_Val _U_(0x2) /**< (DEVEPTCFG) 32 bytes */ -#define DEVEPTCFG_EPSIZE_64_BYTE_Val _U_(0x3) /**< (DEVEPTCFG) 64 bytes */ -#define DEVEPTCFG_EPSIZE_128_BYTE_Val _U_(0x4) /**< (DEVEPTCFG) 128 bytes */ -#define DEVEPTCFG_EPSIZE_256_BYTE_Val _U_(0x5) /**< (DEVEPTCFG) 256 bytes */ -#define DEVEPTCFG_EPSIZE_512_BYTE_Val _U_(0x6) /**< (DEVEPTCFG) 512 bytes */ -#define DEVEPTCFG_EPSIZE_1024_BYTE_Val _U_(0x7) /**< (DEVEPTCFG) 1024 bytes */ -#define DEVEPTCFG_EPSIZE_8_BYTE (DEVEPTCFG_EPSIZE_8_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 8 bytes Position */ -#define DEVEPTCFG_EPSIZE_16_BYTE (DEVEPTCFG_EPSIZE_16_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 16 bytes Position */ -#define DEVEPTCFG_EPSIZE_32_BYTE (DEVEPTCFG_EPSIZE_32_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 32 bytes Position */ -#define DEVEPTCFG_EPSIZE_64_BYTE (DEVEPTCFG_EPSIZE_64_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 64 bytes Position */ -#define DEVEPTCFG_EPSIZE_128_BYTE (DEVEPTCFG_EPSIZE_128_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 128 bytes Position */ -#define DEVEPTCFG_EPSIZE_256_BYTE (DEVEPTCFG_EPSIZE_256_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 256 bytes Position */ -#define DEVEPTCFG_EPSIZE_512_BYTE (DEVEPTCFG_EPSIZE_512_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 512 bytes Position */ -#define DEVEPTCFG_EPSIZE_1024_BYTE (DEVEPTCFG_EPSIZE_1024_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 1024 bytes Position */ -#define DEVEPTCFG_EPDIR_Pos 8 /**< (DEVEPTCFG) Endpoint Direction Position */ -#define DEVEPTCFG_EPDIR (_U_(0x1) << DEVEPTCFG_EPDIR_Pos) /**< (DEVEPTCFG) Endpoint Direction Mask */ -#define DEVEPTCFG_EPDIR_OUT_Val _U_(0x0) /**< (DEVEPTCFG) The endpoint direction is OUT. */ -#define DEVEPTCFG_EPDIR_IN_Val _U_(0x1) /**< (DEVEPTCFG) The endpoint direction is IN (nor for control endpoints). */ -#define DEVEPTCFG_EPDIR_OUT (DEVEPTCFG_EPDIR_OUT_Val << DEVEPTCFG_EPDIR_Pos) /**< (DEVEPTCFG) The endpoint direction is OUT. Position */ -#define DEVEPTCFG_EPDIR_IN (DEVEPTCFG_EPDIR_IN_Val << DEVEPTCFG_EPDIR_Pos) /**< (DEVEPTCFG) The endpoint direction is IN (nor for control endpoints). Position */ -#define DEVEPTCFG_AUTOSW_Pos 9 /**< (DEVEPTCFG) Automatic Switch Position */ -#define DEVEPTCFG_AUTOSW (_U_(0x1) << DEVEPTCFG_AUTOSW_Pos) /**< (DEVEPTCFG) Automatic Switch Mask */ -#define DEVEPTCFG_EPTYPE_Pos 11 /**< (DEVEPTCFG) Endpoint Type Position */ -#define DEVEPTCFG_EPTYPE (_U_(0x3) << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Endpoint Type Mask */ -#define DEVEPTCFG_EPTYPE_CTRL_Val _U_(0x0) /**< (DEVEPTCFG) Control */ -#define DEVEPTCFG_EPTYPE_ISO_Val _U_(0x1) /**< (DEVEPTCFG) Isochronous */ -#define DEVEPTCFG_EPTYPE_BLK_Val _U_(0x2) /**< (DEVEPTCFG) Bulk */ -#define DEVEPTCFG_EPTYPE_INTRPT_Val _U_(0x3) /**< (DEVEPTCFG) Interrupt */ -#define DEVEPTCFG_EPTYPE_CTRL (DEVEPTCFG_EPTYPE_CTRL_Val << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Control Position */ -#define DEVEPTCFG_EPTYPE_ISO (DEVEPTCFG_EPTYPE_ISO_Val << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Isochronous Position */ -#define DEVEPTCFG_EPTYPE_BLK (DEVEPTCFG_EPTYPE_BLK_Val << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Bulk Position */ -#define DEVEPTCFG_EPTYPE_INTRPT (DEVEPTCFG_EPTYPE_INTRPT_Val << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Interrupt Position */ -#define DEVEPTCFG_NBTRANS_Pos 13 /**< (DEVEPTCFG) Number of transactions per microframe for isochronous endpoint Position */ -#define DEVEPTCFG_NBTRANS (_U_(0x3) << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Number of transactions per microframe for isochronous endpoint Mask */ -#define DEVEPTCFG_NBTRANS_0_TRANS_Val _U_(0x0) /**< (DEVEPTCFG) Reserved to endpoint that does not have the high-bandwidth isochronous capability. */ -#define DEVEPTCFG_NBTRANS_1_TRANS_Val _U_(0x1) /**< (DEVEPTCFG) Default value: one transaction per microframe. */ -#define DEVEPTCFG_NBTRANS_2_TRANS_Val _U_(0x2) /**< (DEVEPTCFG) Two transactions per microframe. This endpoint should be configured as double-bank. */ -#define DEVEPTCFG_NBTRANS_3_TRANS_Val _U_(0x3) /**< (DEVEPTCFG) Three transactions per microframe. This endpoint should be configured as triple-bank. */ -#define DEVEPTCFG_NBTRANS_0_TRANS (DEVEPTCFG_NBTRANS_0_TRANS_Val << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Reserved to endpoint that does not have the high-bandwidth isochronous capability. Position */ -#define DEVEPTCFG_NBTRANS_1_TRANS (DEVEPTCFG_NBTRANS_1_TRANS_Val << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Default value: one transaction per microframe. Position */ -#define DEVEPTCFG_NBTRANS_2_TRANS (DEVEPTCFG_NBTRANS_2_TRANS_Val << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Two transactions per microframe. This endpoint should be configured as double-bank. Position */ -#define DEVEPTCFG_NBTRANS_3_TRANS (DEVEPTCFG_NBTRANS_3_TRANS_Val << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Three transactions per microframe. This endpoint should be configured as triple-bank. Position */ -#define DEVEPTCFG_Msk _U_(0x7B7E) /**< (DEVEPTCFG) Register Mask */ - - -/* -------- DEVEPTISR : (USBHS Offset: 0x130) (R/ 32) Device Endpoint Interrupt Status Register -------- */ - -#define DEVEPTISR_OFFSET (0x130) /**< (DEVEPTISR) Device Endpoint Interrupt Status Register Offset */ - -#define DEVEPTISR_TXINI_Pos 0 /**< (DEVEPTISR) Transmitted IN Data Interrupt Position */ -#define DEVEPTISR_TXINI (_U_(0x1) << DEVEPTISR_TXINI_Pos) /**< (DEVEPTISR) Transmitted IN Data Interrupt Mask */ -#define DEVEPTISR_RXOUTI_Pos 1 /**< (DEVEPTISR) Received OUT Data Interrupt Position */ -#define DEVEPTISR_RXOUTI (_U_(0x1) << DEVEPTISR_RXOUTI_Pos) /**< (DEVEPTISR) Received OUT Data Interrupt Mask */ -#define DEVEPTISR_OVERFI_Pos 5 /**< (DEVEPTISR) Overflow Interrupt Position */ -#define DEVEPTISR_OVERFI (_U_(0x1) << DEVEPTISR_OVERFI_Pos) /**< (DEVEPTISR) Overflow Interrupt Mask */ -#define DEVEPTISR_SHORTPACKET_Pos 7 /**< (DEVEPTISR) Short Packet Interrupt Position */ -#define DEVEPTISR_SHORTPACKET (_U_(0x1) << DEVEPTISR_SHORTPACKET_Pos) /**< (DEVEPTISR) Short Packet Interrupt Mask */ -#define DEVEPTISR_DTSEQ_Pos 8 /**< (DEVEPTISR) Data Toggle Sequence Position */ -#define DEVEPTISR_DTSEQ (_U_(0x3) << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Data Toggle Sequence Mask */ -#define DEVEPTISR_DTSEQ_DATA0_Val _U_(0x0) /**< (DEVEPTISR) Data0 toggle sequence */ -#define DEVEPTISR_DTSEQ_DATA1_Val _U_(0x1) /**< (DEVEPTISR) Data1 toggle sequence */ -#define DEVEPTISR_DTSEQ_DATA2_Val _U_(0x2) /**< (DEVEPTISR) Reserved for high-bandwidth isochronous endpoint */ -#define DEVEPTISR_DTSEQ_MDATA_Val _U_(0x3) /**< (DEVEPTISR) Reserved for high-bandwidth isochronous endpoint */ -#define DEVEPTISR_DTSEQ_DATA0 (DEVEPTISR_DTSEQ_DATA0_Val << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Data0 toggle sequence Position */ -#define DEVEPTISR_DTSEQ_DATA1 (DEVEPTISR_DTSEQ_DATA1_Val << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Data1 toggle sequence Position */ -#define DEVEPTISR_DTSEQ_DATA2 (DEVEPTISR_DTSEQ_DATA2_Val << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Reserved for high-bandwidth isochronous endpoint Position */ -#define DEVEPTISR_DTSEQ_MDATA (DEVEPTISR_DTSEQ_MDATA_Val << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Reserved for high-bandwidth isochronous endpoint Position */ -#define DEVEPTISR_NBUSYBK_Pos 12 /**< (DEVEPTISR) Number of Busy Banks Position */ -#define DEVEPTISR_NBUSYBK (_U_(0x3) << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) Number of Busy Banks Mask */ -#define DEVEPTISR_NBUSYBK_0_BUSY_Val _U_(0x0) /**< (DEVEPTISR) 0 busy bank (all banks free) */ -#define DEVEPTISR_NBUSYBK_1_BUSY_Val _U_(0x1) /**< (DEVEPTISR) 1 busy bank */ -#define DEVEPTISR_NBUSYBK_2_BUSY_Val _U_(0x2) /**< (DEVEPTISR) 2 busy banks */ -#define DEVEPTISR_NBUSYBK_3_BUSY_Val _U_(0x3) /**< (DEVEPTISR) 3 busy banks */ -#define DEVEPTISR_NBUSYBK_0_BUSY (DEVEPTISR_NBUSYBK_0_BUSY_Val << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) 0 busy bank (all banks free) Position */ -#define DEVEPTISR_NBUSYBK_1_BUSY (DEVEPTISR_NBUSYBK_1_BUSY_Val << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) 1 busy bank Position */ -#define DEVEPTISR_NBUSYBK_2_BUSY (DEVEPTISR_NBUSYBK_2_BUSY_Val << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) 2 busy banks Position */ -#define DEVEPTISR_NBUSYBK_3_BUSY (DEVEPTISR_NBUSYBK_3_BUSY_Val << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) 3 busy banks Position */ -#define DEVEPTISR_CURRBK_Pos 14 /**< (DEVEPTISR) Current Bank Position */ -#define DEVEPTISR_CURRBK (_U_(0x3) << DEVEPTISR_CURRBK_Pos) /**< (DEVEPTISR) Current Bank Mask */ -#define DEVEPTISR_CURRBK_BANK0_Val _U_(0x0) /**< (DEVEPTISR) Current bank is bank0 */ -#define DEVEPTISR_CURRBK_BANK1_Val _U_(0x1) /**< (DEVEPTISR) Current bank is bank1 */ -#define DEVEPTISR_CURRBK_BANK2_Val _U_(0x2) /**< (DEVEPTISR) Current bank is bank2 */ -#define DEVEPTISR_CURRBK_BANK0 (DEVEPTISR_CURRBK_BANK0_Val << DEVEPTISR_CURRBK_Pos) /**< (DEVEPTISR) Current bank is bank0 Position */ -#define DEVEPTISR_CURRBK_BANK1 (DEVEPTISR_CURRBK_BANK1_Val << DEVEPTISR_CURRBK_Pos) /**< (DEVEPTISR) Current bank is bank1 Position */ -#define DEVEPTISR_CURRBK_BANK2 (DEVEPTISR_CURRBK_BANK2_Val << DEVEPTISR_CURRBK_Pos) /**< (DEVEPTISR) Current bank is bank2 Position */ -#define DEVEPTISR_RWALL_Pos 16 /**< (DEVEPTISR) Read/Write Allowed Position */ -#define DEVEPTISR_RWALL (_U_(0x1) << DEVEPTISR_RWALL_Pos) /**< (DEVEPTISR) Read/Write Allowed Mask */ -#define DEVEPTISR_CFGOK_Pos 18 /**< (DEVEPTISR) Configuration OK Status Position */ -#define DEVEPTISR_CFGOK (_U_(0x1) << DEVEPTISR_CFGOK_Pos) /**< (DEVEPTISR) Configuration OK Status Mask */ -#define DEVEPTISR_BYCT_Pos 20 /**< (DEVEPTISR) Byte Count Position */ -#define DEVEPTISR_BYCT (_U_(0x7FF) << DEVEPTISR_BYCT_Pos) /**< (DEVEPTISR) Byte Count Mask */ -#define DEVEPTISR_Msk _U_(0x7FF5F3A3) /**< (DEVEPTISR) Register Mask */ - -/* CTRL mode */ -#define DEVEPTISR_CTRL_RXSTPI_Pos 2 /**< (DEVEPTISR) Received SETUP Interrupt Position */ -#define DEVEPTISR_CTRL_RXSTPI (_U_(0x1) << DEVEPTISR_CTRL_RXSTPI_Pos) /**< (DEVEPTISR) Received SETUP Interrupt Mask */ -#define DEVEPTISR_CTRL_NAKOUTI_Pos 3 /**< (DEVEPTISR) NAKed OUT Interrupt Position */ -#define DEVEPTISR_CTRL_NAKOUTI (_U_(0x1) << DEVEPTISR_CTRL_NAKOUTI_Pos) /**< (DEVEPTISR) NAKed OUT Interrupt Mask */ -#define DEVEPTISR_CTRL_NAKINI_Pos 4 /**< (DEVEPTISR) NAKed IN Interrupt Position */ -#define DEVEPTISR_CTRL_NAKINI (_U_(0x1) << DEVEPTISR_CTRL_NAKINI_Pos) /**< (DEVEPTISR) NAKed IN Interrupt Mask */ -#define DEVEPTISR_CTRL_STALLEDI_Pos 6 /**< (DEVEPTISR) STALLed Interrupt Position */ -#define DEVEPTISR_CTRL_STALLEDI (_U_(0x1) << DEVEPTISR_CTRL_STALLEDI_Pos) /**< (DEVEPTISR) STALLed Interrupt Mask */ -#define DEVEPTISR_CTRL_CTRLDIR_Pos 17 /**< (DEVEPTISR) Control Direction Position */ -#define DEVEPTISR_CTRL_CTRLDIR (_U_(0x1) << DEVEPTISR_CTRL_CTRLDIR_Pos) /**< (DEVEPTISR) Control Direction Mask */ -#define DEVEPTISR_CTRL_Msk _U_(0x2005C) /**< (DEVEPTISR_CTRL) Register Mask */ - -/* ISO mode */ -#define DEVEPTISR_ISO_UNDERFI_Pos 2 /**< (DEVEPTISR) Underflow Interrupt Position */ -#define DEVEPTISR_ISO_UNDERFI (_U_(0x1) << DEVEPTISR_ISO_UNDERFI_Pos) /**< (DEVEPTISR) Underflow Interrupt Mask */ -#define DEVEPTISR_ISO_HBISOINERRI_Pos 3 /**< (DEVEPTISR) High Bandwidth Isochronous IN Underflow Error Interrupt Position */ -#define DEVEPTISR_ISO_HBISOINERRI (_U_(0x1) << DEVEPTISR_ISO_HBISOINERRI_Pos) /**< (DEVEPTISR) High Bandwidth Isochronous IN Underflow Error Interrupt Mask */ -#define DEVEPTISR_ISO_HBISOFLUSHI_Pos 4 /**< (DEVEPTISR) High Bandwidth Isochronous IN Flush Interrupt Position */ -#define DEVEPTISR_ISO_HBISOFLUSHI (_U_(0x1) << DEVEPTISR_ISO_HBISOFLUSHI_Pos) /**< (DEVEPTISR) High Bandwidth Isochronous IN Flush Interrupt Mask */ -#define DEVEPTISR_ISO_CRCERRI_Pos 6 /**< (DEVEPTISR) CRC Error Interrupt Position */ -#define DEVEPTISR_ISO_CRCERRI (_U_(0x1) << DEVEPTISR_ISO_CRCERRI_Pos) /**< (DEVEPTISR) CRC Error Interrupt Mask */ -#define DEVEPTISR_ISO_ERRORTRANS_Pos 10 /**< (DEVEPTISR) High-bandwidth Isochronous OUT Endpoint Transaction Error Interrupt Position */ -#define DEVEPTISR_ISO_ERRORTRANS (_U_(0x1) << DEVEPTISR_ISO_ERRORTRANS_Pos) /**< (DEVEPTISR) High-bandwidth Isochronous OUT Endpoint Transaction Error Interrupt Mask */ -#define DEVEPTISR_ISO_Msk _U_(0x45C) /**< (DEVEPTISR_ISO) Register Mask */ - -/* BLK mode */ -#define DEVEPTISR_BLK_RXSTPI_Pos 2 /**< (DEVEPTISR) Received SETUP Interrupt Position */ -#define DEVEPTISR_BLK_RXSTPI (_U_(0x1) << DEVEPTISR_BLK_RXSTPI_Pos) /**< (DEVEPTISR) Received SETUP Interrupt Mask */ -#define DEVEPTISR_BLK_NAKOUTI_Pos 3 /**< (DEVEPTISR) NAKed OUT Interrupt Position */ -#define DEVEPTISR_BLK_NAKOUTI (_U_(0x1) << DEVEPTISR_BLK_NAKOUTI_Pos) /**< (DEVEPTISR) NAKed OUT Interrupt Mask */ -#define DEVEPTISR_BLK_NAKINI_Pos 4 /**< (DEVEPTISR) NAKed IN Interrupt Position */ -#define DEVEPTISR_BLK_NAKINI (_U_(0x1) << DEVEPTISR_BLK_NAKINI_Pos) /**< (DEVEPTISR) NAKed IN Interrupt Mask */ -#define DEVEPTISR_BLK_STALLEDI_Pos 6 /**< (DEVEPTISR) STALLed Interrupt Position */ -#define DEVEPTISR_BLK_STALLEDI (_U_(0x1) << DEVEPTISR_BLK_STALLEDI_Pos) /**< (DEVEPTISR) STALLed Interrupt Mask */ -#define DEVEPTISR_BLK_CTRLDIR_Pos 17 /**< (DEVEPTISR) Control Direction Position */ -#define DEVEPTISR_BLK_CTRLDIR (_U_(0x1) << DEVEPTISR_BLK_CTRLDIR_Pos) /**< (DEVEPTISR) Control Direction Mask */ -#define DEVEPTISR_BLK_Msk _U_(0x2005C) /**< (DEVEPTISR_BLK) Register Mask */ - -/* INTRPT mode */ -#define DEVEPTISR_INTRPT_RXSTPI_Pos 2 /**< (DEVEPTISR) Received SETUP Interrupt Position */ -#define DEVEPTISR_INTRPT_RXSTPI (_U_(0x1) << DEVEPTISR_INTRPT_RXSTPI_Pos) /**< (DEVEPTISR) Received SETUP Interrupt Mask */ -#define DEVEPTISR_INTRPT_NAKOUTI_Pos 3 /**< (DEVEPTISR) NAKed OUT Interrupt Position */ -#define DEVEPTISR_INTRPT_NAKOUTI (_U_(0x1) << DEVEPTISR_INTRPT_NAKOUTI_Pos) /**< (DEVEPTISR) NAKed OUT Interrupt Mask */ -#define DEVEPTISR_INTRPT_NAKINI_Pos 4 /**< (DEVEPTISR) NAKed IN Interrupt Position */ -#define DEVEPTISR_INTRPT_NAKINI (_U_(0x1) << DEVEPTISR_INTRPT_NAKINI_Pos) /**< (DEVEPTISR) NAKed IN Interrupt Mask */ -#define DEVEPTISR_INTRPT_STALLEDI_Pos 6 /**< (DEVEPTISR) STALLed Interrupt Position */ -#define DEVEPTISR_INTRPT_STALLEDI (_U_(0x1) << DEVEPTISR_INTRPT_STALLEDI_Pos) /**< (DEVEPTISR) STALLed Interrupt Mask */ -#define DEVEPTISR_INTRPT_CTRLDIR_Pos 17 /**< (DEVEPTISR) Control Direction Position */ -#define DEVEPTISR_INTRPT_CTRLDIR (_U_(0x1) << DEVEPTISR_INTRPT_CTRLDIR_Pos) /**< (DEVEPTISR) Control Direction Mask */ -#define DEVEPTISR_INTRPT_Msk _U_(0x2005C) /**< (DEVEPTISR_INTRPT) Register Mask */ - - -/* -------- DEVEPTICR : (USBHS Offset: 0x160) (/W 32) Device Endpoint Interrupt Clear Register -------- */ - -#define DEVEPTICR_OFFSET (0x160) /**< (DEVEPTICR) Device Endpoint Interrupt Clear Register Offset */ - -#define DEVEPTICR_TXINIC_Pos 0 /**< (DEVEPTICR) Transmitted IN Data Interrupt Clear Position */ -#define DEVEPTICR_TXINIC (_U_(0x1) << DEVEPTICR_TXINIC_Pos) /**< (DEVEPTICR) Transmitted IN Data Interrupt Clear Mask */ -#define DEVEPTICR_RXOUTIC_Pos 1 /**< (DEVEPTICR) Received OUT Data Interrupt Clear Position */ -#define DEVEPTICR_RXOUTIC (_U_(0x1) << DEVEPTICR_RXOUTIC_Pos) /**< (DEVEPTICR) Received OUT Data Interrupt Clear Mask */ -#define DEVEPTICR_OVERFIC_Pos 5 /**< (DEVEPTICR) Overflow Interrupt Clear Position */ -#define DEVEPTICR_OVERFIC (_U_(0x1) << DEVEPTICR_OVERFIC_Pos) /**< (DEVEPTICR) Overflow Interrupt Clear Mask */ -#define DEVEPTICR_SHORTPACKETC_Pos 7 /**< (DEVEPTICR) Short Packet Interrupt Clear Position */ -#define DEVEPTICR_SHORTPACKETC (_U_(0x1) << DEVEPTICR_SHORTPACKETC_Pos) /**< (DEVEPTICR) Short Packet Interrupt Clear Mask */ -#define DEVEPTICR_Msk _U_(0xA3) /**< (DEVEPTICR) Register Mask */ - -/* CTRL mode */ -#define DEVEPTICR_CTRL_RXSTPIC_Pos 2 /**< (DEVEPTICR) Received SETUP Interrupt Clear Position */ -#define DEVEPTICR_CTRL_RXSTPIC (_U_(0x1) << DEVEPTICR_CTRL_RXSTPIC_Pos) /**< (DEVEPTICR) Received SETUP Interrupt Clear Mask */ -#define DEVEPTICR_CTRL_NAKOUTIC_Pos 3 /**< (DEVEPTICR) NAKed OUT Interrupt Clear Position */ -#define DEVEPTICR_CTRL_NAKOUTIC (_U_(0x1) << DEVEPTICR_CTRL_NAKOUTIC_Pos) /**< (DEVEPTICR) NAKed OUT Interrupt Clear Mask */ -#define DEVEPTICR_CTRL_NAKINIC_Pos 4 /**< (DEVEPTICR) NAKed IN Interrupt Clear Position */ -#define DEVEPTICR_CTRL_NAKINIC (_U_(0x1) << DEVEPTICR_CTRL_NAKINIC_Pos) /**< (DEVEPTICR) NAKed IN Interrupt Clear Mask */ -#define DEVEPTICR_CTRL_STALLEDIC_Pos 6 /**< (DEVEPTICR) STALLed Interrupt Clear Position */ -#define DEVEPTICR_CTRL_STALLEDIC (_U_(0x1) << DEVEPTICR_CTRL_STALLEDIC_Pos) /**< (DEVEPTICR) STALLed Interrupt Clear Mask */ -#define DEVEPTICR_CTRL_Msk _U_(0x5C) /**< (DEVEPTICR_CTRL) Register Mask */ - -/* ISO mode */ -#define DEVEPTICR_ISO_UNDERFIC_Pos 2 /**< (DEVEPTICR) Underflow Interrupt Clear Position */ -#define DEVEPTICR_ISO_UNDERFIC (_U_(0x1) << DEVEPTICR_ISO_UNDERFIC_Pos) /**< (DEVEPTICR) Underflow Interrupt Clear Mask */ -#define DEVEPTICR_ISO_HBISOINERRIC_Pos 3 /**< (DEVEPTICR) High Bandwidth Isochronous IN Underflow Error Interrupt Clear Position */ -#define DEVEPTICR_ISO_HBISOINERRIC (_U_(0x1) << DEVEPTICR_ISO_HBISOINERRIC_Pos) /**< (DEVEPTICR) High Bandwidth Isochronous IN Underflow Error Interrupt Clear Mask */ -#define DEVEPTICR_ISO_HBISOFLUSHIC_Pos 4 /**< (DEVEPTICR) High Bandwidth Isochronous IN Flush Interrupt Clear Position */ -#define DEVEPTICR_ISO_HBISOFLUSHIC (_U_(0x1) << DEVEPTICR_ISO_HBISOFLUSHIC_Pos) /**< (DEVEPTICR) High Bandwidth Isochronous IN Flush Interrupt Clear Mask */ -#define DEVEPTICR_ISO_CRCERRIC_Pos 6 /**< (DEVEPTICR) CRC Error Interrupt Clear Position */ -#define DEVEPTICR_ISO_CRCERRIC (_U_(0x1) << DEVEPTICR_ISO_CRCERRIC_Pos) /**< (DEVEPTICR) CRC Error Interrupt Clear Mask */ -#define DEVEPTICR_ISO_Msk _U_(0x5C) /**< (DEVEPTICR_ISO) Register Mask */ - -/* BLK mode */ -#define DEVEPTICR_BLK_RXSTPIC_Pos 2 /**< (DEVEPTICR) Received SETUP Interrupt Clear Position */ -#define DEVEPTICR_BLK_RXSTPIC (_U_(0x1) << DEVEPTICR_BLK_RXSTPIC_Pos) /**< (DEVEPTICR) Received SETUP Interrupt Clear Mask */ -#define DEVEPTICR_BLK_NAKOUTIC_Pos 3 /**< (DEVEPTICR) NAKed OUT Interrupt Clear Position */ -#define DEVEPTICR_BLK_NAKOUTIC (_U_(0x1) << DEVEPTICR_BLK_NAKOUTIC_Pos) /**< (DEVEPTICR) NAKed OUT Interrupt Clear Mask */ -#define DEVEPTICR_BLK_NAKINIC_Pos 4 /**< (DEVEPTICR) NAKed IN Interrupt Clear Position */ -#define DEVEPTICR_BLK_NAKINIC (_U_(0x1) << DEVEPTICR_BLK_NAKINIC_Pos) /**< (DEVEPTICR) NAKed IN Interrupt Clear Mask */ -#define DEVEPTICR_BLK_STALLEDIC_Pos 6 /**< (DEVEPTICR) STALLed Interrupt Clear Position */ -#define DEVEPTICR_BLK_STALLEDIC (_U_(0x1) << DEVEPTICR_BLK_STALLEDIC_Pos) /**< (DEVEPTICR) STALLed Interrupt Clear Mask */ -#define DEVEPTICR_BLK_Msk _U_(0x5C) /**< (DEVEPTICR_BLK) Register Mask */ - -/* INTRPT mode */ -#define DEVEPTICR_INTRPT_RXSTPIC_Pos 2 /**< (DEVEPTICR) Received SETUP Interrupt Clear Position */ -#define DEVEPTICR_INTRPT_RXSTPIC (_U_(0x1) << DEVEPTICR_INTRPT_RXSTPIC_Pos) /**< (DEVEPTICR) Received SETUP Interrupt Clear Mask */ -#define DEVEPTICR_INTRPT_NAKOUTIC_Pos 3 /**< (DEVEPTICR) NAKed OUT Interrupt Clear Position */ -#define DEVEPTICR_INTRPT_NAKOUTIC (_U_(0x1) << DEVEPTICR_INTRPT_NAKOUTIC_Pos) /**< (DEVEPTICR) NAKed OUT Interrupt Clear Mask */ -#define DEVEPTICR_INTRPT_NAKINIC_Pos 4 /**< (DEVEPTICR) NAKed IN Interrupt Clear Position */ -#define DEVEPTICR_INTRPT_NAKINIC (_U_(0x1) << DEVEPTICR_INTRPT_NAKINIC_Pos) /**< (DEVEPTICR) NAKed IN Interrupt Clear Mask */ -#define DEVEPTICR_INTRPT_STALLEDIC_Pos 6 /**< (DEVEPTICR) STALLed Interrupt Clear Position */ -#define DEVEPTICR_INTRPT_STALLEDIC (_U_(0x1) << DEVEPTICR_INTRPT_STALLEDIC_Pos) /**< (DEVEPTICR) STALLed Interrupt Clear Mask */ -#define DEVEPTICR_INTRPT_Msk _U_(0x5C) /**< (DEVEPTICR_INTRPT) Register Mask */ - - -/* -------- DEVEPTIFR : (USBHS Offset: 0x190) (/W 32) Device Endpoint Interrupt Set Register -------- */ - -#define DEVEPTIFR_OFFSET (0x190) /**< (DEVEPTIFR) Device Endpoint Interrupt Set Register Offset */ - -#define DEVEPTIFR_TXINIS_Pos 0 /**< (DEVEPTIFR) Transmitted IN Data Interrupt Set Position */ -#define DEVEPTIFR_TXINIS (_U_(0x1) << DEVEPTIFR_TXINIS_Pos) /**< (DEVEPTIFR) Transmitted IN Data Interrupt Set Mask */ -#define DEVEPTIFR_RXOUTIS_Pos 1 /**< (DEVEPTIFR) Received OUT Data Interrupt Set Position */ -#define DEVEPTIFR_RXOUTIS (_U_(0x1) << DEVEPTIFR_RXOUTIS_Pos) /**< (DEVEPTIFR) Received OUT Data Interrupt Set Mask */ -#define DEVEPTIFR_OVERFIS_Pos 5 /**< (DEVEPTIFR) Overflow Interrupt Set Position */ -#define DEVEPTIFR_OVERFIS (_U_(0x1) << DEVEPTIFR_OVERFIS_Pos) /**< (DEVEPTIFR) Overflow Interrupt Set Mask */ -#define DEVEPTIFR_SHORTPACKETS_Pos 7 /**< (DEVEPTIFR) Short Packet Interrupt Set Position */ -#define DEVEPTIFR_SHORTPACKETS (_U_(0x1) << DEVEPTIFR_SHORTPACKETS_Pos) /**< (DEVEPTIFR) Short Packet Interrupt Set Mask */ -#define DEVEPTIFR_NBUSYBKS_Pos 12 /**< (DEVEPTIFR) Number of Busy Banks Interrupt Set Position */ -#define DEVEPTIFR_NBUSYBKS (_U_(0x1) << DEVEPTIFR_NBUSYBKS_Pos) /**< (DEVEPTIFR) Number of Busy Banks Interrupt Set Mask */ -#define DEVEPTIFR_Msk _U_(0x10A3) /**< (DEVEPTIFR) Register Mask */ - -/* CTRL mode */ -#define DEVEPTIFR_CTRL_RXSTPIS_Pos 2 /**< (DEVEPTIFR) Received SETUP Interrupt Set Position */ -#define DEVEPTIFR_CTRL_RXSTPIS (_U_(0x1) << DEVEPTIFR_CTRL_RXSTPIS_Pos) /**< (DEVEPTIFR) Received SETUP Interrupt Set Mask */ -#define DEVEPTIFR_CTRL_NAKOUTIS_Pos 3 /**< (DEVEPTIFR) NAKed OUT Interrupt Set Position */ -#define DEVEPTIFR_CTRL_NAKOUTIS (_U_(0x1) << DEVEPTIFR_CTRL_NAKOUTIS_Pos) /**< (DEVEPTIFR) NAKed OUT Interrupt Set Mask */ -#define DEVEPTIFR_CTRL_NAKINIS_Pos 4 /**< (DEVEPTIFR) NAKed IN Interrupt Set Position */ -#define DEVEPTIFR_CTRL_NAKINIS (_U_(0x1) << DEVEPTIFR_CTRL_NAKINIS_Pos) /**< (DEVEPTIFR) NAKed IN Interrupt Set Mask */ -#define DEVEPTIFR_CTRL_STALLEDIS_Pos 6 /**< (DEVEPTIFR) STALLed Interrupt Set Position */ -#define DEVEPTIFR_CTRL_STALLEDIS (_U_(0x1) << DEVEPTIFR_CTRL_STALLEDIS_Pos) /**< (DEVEPTIFR) STALLed Interrupt Set Mask */ -#define DEVEPTIFR_CTRL_Msk _U_(0x5C) /**< (DEVEPTIFR_CTRL) Register Mask */ - -/* ISO mode */ -#define DEVEPTIFR_ISO_UNDERFIS_Pos 2 /**< (DEVEPTIFR) Underflow Interrupt Set Position */ -#define DEVEPTIFR_ISO_UNDERFIS (_U_(0x1) << DEVEPTIFR_ISO_UNDERFIS_Pos) /**< (DEVEPTIFR) Underflow Interrupt Set Mask */ -#define DEVEPTIFR_ISO_HBISOINERRIS_Pos 3 /**< (DEVEPTIFR) High Bandwidth Isochronous IN Underflow Error Interrupt Set Position */ -#define DEVEPTIFR_ISO_HBISOINERRIS (_U_(0x1) << DEVEPTIFR_ISO_HBISOINERRIS_Pos) /**< (DEVEPTIFR) High Bandwidth Isochronous IN Underflow Error Interrupt Set Mask */ -#define DEVEPTIFR_ISO_HBISOFLUSHIS_Pos 4 /**< (DEVEPTIFR) High Bandwidth Isochronous IN Flush Interrupt Set Position */ -#define DEVEPTIFR_ISO_HBISOFLUSHIS (_U_(0x1) << DEVEPTIFR_ISO_HBISOFLUSHIS_Pos) /**< (DEVEPTIFR) High Bandwidth Isochronous IN Flush Interrupt Set Mask */ -#define DEVEPTIFR_ISO_CRCERRIS_Pos 6 /**< (DEVEPTIFR) CRC Error Interrupt Set Position */ -#define DEVEPTIFR_ISO_CRCERRIS (_U_(0x1) << DEVEPTIFR_ISO_CRCERRIS_Pos) /**< (DEVEPTIFR) CRC Error Interrupt Set Mask */ -#define DEVEPTIFR_ISO_Msk _U_(0x5C) /**< (DEVEPTIFR_ISO) Register Mask */ - -/* BLK mode */ -#define DEVEPTIFR_BLK_RXSTPIS_Pos 2 /**< (DEVEPTIFR) Received SETUP Interrupt Set Position */ -#define DEVEPTIFR_BLK_RXSTPIS (_U_(0x1) << DEVEPTIFR_BLK_RXSTPIS_Pos) /**< (DEVEPTIFR) Received SETUP Interrupt Set Mask */ -#define DEVEPTIFR_BLK_NAKOUTIS_Pos 3 /**< (DEVEPTIFR) NAKed OUT Interrupt Set Position */ -#define DEVEPTIFR_BLK_NAKOUTIS (_U_(0x1) << DEVEPTIFR_BLK_NAKOUTIS_Pos) /**< (DEVEPTIFR) NAKed OUT Interrupt Set Mask */ -#define DEVEPTIFR_BLK_NAKINIS_Pos 4 /**< (DEVEPTIFR) NAKed IN Interrupt Set Position */ -#define DEVEPTIFR_BLK_NAKINIS (_U_(0x1) << DEVEPTIFR_BLK_NAKINIS_Pos) /**< (DEVEPTIFR) NAKed IN Interrupt Set Mask */ -#define DEVEPTIFR_BLK_STALLEDIS_Pos 6 /**< (DEVEPTIFR) STALLed Interrupt Set Position */ -#define DEVEPTIFR_BLK_STALLEDIS (_U_(0x1) << DEVEPTIFR_BLK_STALLEDIS_Pos) /**< (DEVEPTIFR) STALLed Interrupt Set Mask */ -#define DEVEPTIFR_BLK_Msk _U_(0x5C) /**< (DEVEPTIFR_BLK) Register Mask */ - -/* INTRPT mode */ -#define DEVEPTIFR_INTRPT_RXSTPIS_Pos 2 /**< (DEVEPTIFR) Received SETUP Interrupt Set Position */ -#define DEVEPTIFR_INTRPT_RXSTPIS (_U_(0x1) << DEVEPTIFR_INTRPT_RXSTPIS_Pos) /**< (DEVEPTIFR) Received SETUP Interrupt Set Mask */ -#define DEVEPTIFR_INTRPT_NAKOUTIS_Pos 3 /**< (DEVEPTIFR) NAKed OUT Interrupt Set Position */ -#define DEVEPTIFR_INTRPT_NAKOUTIS (_U_(0x1) << DEVEPTIFR_INTRPT_NAKOUTIS_Pos) /**< (DEVEPTIFR) NAKed OUT Interrupt Set Mask */ -#define DEVEPTIFR_INTRPT_NAKINIS_Pos 4 /**< (DEVEPTIFR) NAKed IN Interrupt Set Position */ -#define DEVEPTIFR_INTRPT_NAKINIS (_U_(0x1) << DEVEPTIFR_INTRPT_NAKINIS_Pos) /**< (DEVEPTIFR) NAKed IN Interrupt Set Mask */ -#define DEVEPTIFR_INTRPT_STALLEDIS_Pos 6 /**< (DEVEPTIFR) STALLed Interrupt Set Position */ -#define DEVEPTIFR_INTRPT_STALLEDIS (_U_(0x1) << DEVEPTIFR_INTRPT_STALLEDIS_Pos) /**< (DEVEPTIFR) STALLed Interrupt Set Mask */ -#define DEVEPTIFR_INTRPT_Msk _U_(0x5C) /**< (DEVEPTIFR_INTRPT) Register Mask */ - - -/* -------- DEVEPTIMR : (USBHS Offset: 0x1c0) (R/ 32) Device Endpoint Interrupt Mask Register -------- */ - -#define DEVEPTIMR_OFFSET (0x1C0) /**< (DEVEPTIMR) Device Endpoint Interrupt Mask Register Offset */ - -#define DEVEPTIMR_TXINE_Pos 0 /**< (DEVEPTIMR) Transmitted IN Data Interrupt Position */ -#define DEVEPTIMR_TXINE (_U_(0x1) << DEVEPTIMR_TXINE_Pos) /**< (DEVEPTIMR) Transmitted IN Data Interrupt Mask */ -#define DEVEPTIMR_RXOUTE_Pos 1 /**< (DEVEPTIMR) Received OUT Data Interrupt Position */ -#define DEVEPTIMR_RXOUTE (_U_(0x1) << DEVEPTIMR_RXOUTE_Pos) /**< (DEVEPTIMR) Received OUT Data Interrupt Mask */ -#define DEVEPTIMR_OVERFE_Pos 5 /**< (DEVEPTIMR) Overflow Interrupt Position */ -#define DEVEPTIMR_OVERFE (_U_(0x1) << DEVEPTIMR_OVERFE_Pos) /**< (DEVEPTIMR) Overflow Interrupt Mask */ -#define DEVEPTIMR_SHORTPACKETE_Pos 7 /**< (DEVEPTIMR) Short Packet Interrupt Position */ -#define DEVEPTIMR_SHORTPACKETE (_U_(0x1) << DEVEPTIMR_SHORTPACKETE_Pos) /**< (DEVEPTIMR) Short Packet Interrupt Mask */ -#define DEVEPTIMR_NBUSYBKE_Pos 12 /**< (DEVEPTIMR) Number of Busy Banks Interrupt Position */ -#define DEVEPTIMR_NBUSYBKE (_U_(0x1) << DEVEPTIMR_NBUSYBKE_Pos) /**< (DEVEPTIMR) Number of Busy Banks Interrupt Mask */ -#define DEVEPTIMR_KILLBK_Pos 13 /**< (DEVEPTIMR) Kill IN Bank Position */ -#define DEVEPTIMR_KILLBK (_U_(0x1) << DEVEPTIMR_KILLBK_Pos) /**< (DEVEPTIMR) Kill IN Bank Mask */ -#define DEVEPTIMR_FIFOCON_Pos 14 /**< (DEVEPTIMR) FIFO Control Position */ -#define DEVEPTIMR_FIFOCON (_U_(0x1) << DEVEPTIMR_FIFOCON_Pos) /**< (DEVEPTIMR) FIFO Control Mask */ -#define DEVEPTIMR_EPDISHDMA_Pos 16 /**< (DEVEPTIMR) Endpoint Interrupts Disable HDMA Request Position */ -#define DEVEPTIMR_EPDISHDMA (_U_(0x1) << DEVEPTIMR_EPDISHDMA_Pos) /**< (DEVEPTIMR) Endpoint Interrupts Disable HDMA Request Mask */ -#define DEVEPTIMR_RSTDT_Pos 18 /**< (DEVEPTIMR) Reset Data Toggle Position */ -#define DEVEPTIMR_RSTDT (_U_(0x1) << DEVEPTIMR_RSTDT_Pos) /**< (DEVEPTIMR) Reset Data Toggle Mask */ -#define DEVEPTIMR_Msk _U_(0x570A3) /**< (DEVEPTIMR) Register Mask */ - -/* CTRL mode */ -#define DEVEPTIMR_CTRL_RXSTPE_Pos 2 /**< (DEVEPTIMR) Received SETUP Interrupt Position */ -#define DEVEPTIMR_CTRL_RXSTPE (_U_(0x1) << DEVEPTIMR_CTRL_RXSTPE_Pos) /**< (DEVEPTIMR) Received SETUP Interrupt Mask */ -#define DEVEPTIMR_CTRL_NAKOUTE_Pos 3 /**< (DEVEPTIMR) NAKed OUT Interrupt Position */ -#define DEVEPTIMR_CTRL_NAKOUTE (_U_(0x1) << DEVEPTIMR_CTRL_NAKOUTE_Pos) /**< (DEVEPTIMR) NAKed OUT Interrupt Mask */ -#define DEVEPTIMR_CTRL_NAKINE_Pos 4 /**< (DEVEPTIMR) NAKed IN Interrupt Position */ -#define DEVEPTIMR_CTRL_NAKINE (_U_(0x1) << DEVEPTIMR_CTRL_NAKINE_Pos) /**< (DEVEPTIMR) NAKed IN Interrupt Mask */ -#define DEVEPTIMR_CTRL_STALLEDE_Pos 6 /**< (DEVEPTIMR) STALLed Interrupt Position */ -#define DEVEPTIMR_CTRL_STALLEDE (_U_(0x1) << DEVEPTIMR_CTRL_STALLEDE_Pos) /**< (DEVEPTIMR) STALLed Interrupt Mask */ -#define DEVEPTIMR_CTRL_NYETDIS_Pos 17 /**< (DEVEPTIMR) NYET Token Disable Position */ -#define DEVEPTIMR_CTRL_NYETDIS (_U_(0x1) << DEVEPTIMR_CTRL_NYETDIS_Pos) /**< (DEVEPTIMR) NYET Token Disable Mask */ -#define DEVEPTIMR_CTRL_STALLRQ_Pos 19 /**< (DEVEPTIMR) STALL Request Position */ -#define DEVEPTIMR_CTRL_STALLRQ (_U_(0x1) << DEVEPTIMR_CTRL_STALLRQ_Pos) /**< (DEVEPTIMR) STALL Request Mask */ -#define DEVEPTIMR_CTRL_Msk _U_(0xA005C) /**< (DEVEPTIMR_CTRL) Register Mask */ - -/* ISO mode */ -#define DEVEPTIMR_ISO_UNDERFE_Pos 2 /**< (DEVEPTIMR) Underflow Interrupt Position */ -#define DEVEPTIMR_ISO_UNDERFE (_U_(0x1) << DEVEPTIMR_ISO_UNDERFE_Pos) /**< (DEVEPTIMR) Underflow Interrupt Mask */ -#define DEVEPTIMR_ISO_HBISOINERRE_Pos 3 /**< (DEVEPTIMR) High Bandwidth Isochronous IN Underflow Error Interrupt Position */ -#define DEVEPTIMR_ISO_HBISOINERRE (_U_(0x1) << DEVEPTIMR_ISO_HBISOINERRE_Pos) /**< (DEVEPTIMR) High Bandwidth Isochronous IN Underflow Error Interrupt Mask */ -#define DEVEPTIMR_ISO_HBISOFLUSHE_Pos 4 /**< (DEVEPTIMR) High Bandwidth Isochronous IN Flush Interrupt Position */ -#define DEVEPTIMR_ISO_HBISOFLUSHE (_U_(0x1) << DEVEPTIMR_ISO_HBISOFLUSHE_Pos) /**< (DEVEPTIMR) High Bandwidth Isochronous IN Flush Interrupt Mask */ -#define DEVEPTIMR_ISO_CRCERRE_Pos 6 /**< (DEVEPTIMR) CRC Error Interrupt Position */ -#define DEVEPTIMR_ISO_CRCERRE (_U_(0x1) << DEVEPTIMR_ISO_CRCERRE_Pos) /**< (DEVEPTIMR) CRC Error Interrupt Mask */ -#define DEVEPTIMR_ISO_MDATAE_Pos 8 /**< (DEVEPTIMR) MData Interrupt Position */ -#define DEVEPTIMR_ISO_MDATAE (_U_(0x1) << DEVEPTIMR_ISO_MDATAE_Pos) /**< (DEVEPTIMR) MData Interrupt Mask */ -#define DEVEPTIMR_ISO_DATAXE_Pos 9 /**< (DEVEPTIMR) DataX Interrupt Position */ -#define DEVEPTIMR_ISO_DATAXE (_U_(0x1) << DEVEPTIMR_ISO_DATAXE_Pos) /**< (DEVEPTIMR) DataX Interrupt Mask */ -#define DEVEPTIMR_ISO_ERRORTRANSE_Pos 10 /**< (DEVEPTIMR) Transaction Error Interrupt Position */ -#define DEVEPTIMR_ISO_ERRORTRANSE (_U_(0x1) << DEVEPTIMR_ISO_ERRORTRANSE_Pos) /**< (DEVEPTIMR) Transaction Error Interrupt Mask */ -#define DEVEPTIMR_ISO_Msk _U_(0x75C) /**< (DEVEPTIMR_ISO) Register Mask */ - -/* BLK mode */ -#define DEVEPTIMR_BLK_RXSTPE_Pos 2 /**< (DEVEPTIMR) Received SETUP Interrupt Position */ -#define DEVEPTIMR_BLK_RXSTPE (_U_(0x1) << DEVEPTIMR_BLK_RXSTPE_Pos) /**< (DEVEPTIMR) Received SETUP Interrupt Mask */ -#define DEVEPTIMR_BLK_NAKOUTE_Pos 3 /**< (DEVEPTIMR) NAKed OUT Interrupt Position */ -#define DEVEPTIMR_BLK_NAKOUTE (_U_(0x1) << DEVEPTIMR_BLK_NAKOUTE_Pos) /**< (DEVEPTIMR) NAKed OUT Interrupt Mask */ -#define DEVEPTIMR_BLK_NAKINE_Pos 4 /**< (DEVEPTIMR) NAKed IN Interrupt Position */ -#define DEVEPTIMR_BLK_NAKINE (_U_(0x1) << DEVEPTIMR_BLK_NAKINE_Pos) /**< (DEVEPTIMR) NAKed IN Interrupt Mask */ -#define DEVEPTIMR_BLK_STALLEDE_Pos 6 /**< (DEVEPTIMR) STALLed Interrupt Position */ -#define DEVEPTIMR_BLK_STALLEDE (_U_(0x1) << DEVEPTIMR_BLK_STALLEDE_Pos) /**< (DEVEPTIMR) STALLed Interrupt Mask */ -#define DEVEPTIMR_BLK_NYETDIS_Pos 17 /**< (DEVEPTIMR) NYET Token Disable Position */ -#define DEVEPTIMR_BLK_NYETDIS (_U_(0x1) << DEVEPTIMR_BLK_NYETDIS_Pos) /**< (DEVEPTIMR) NYET Token Disable Mask */ -#define DEVEPTIMR_BLK_STALLRQ_Pos 19 /**< (DEVEPTIMR) STALL Request Position */ -#define DEVEPTIMR_BLK_STALLRQ (_U_(0x1) << DEVEPTIMR_BLK_STALLRQ_Pos) /**< (DEVEPTIMR) STALL Request Mask */ -#define DEVEPTIMR_BLK_Msk _U_(0xA005C) /**< (DEVEPTIMR_BLK) Register Mask */ - -/* INTRPT mode */ -#define DEVEPTIMR_INTRPT_RXSTPE_Pos 2 /**< (DEVEPTIMR) Received SETUP Interrupt Position */ -#define DEVEPTIMR_INTRPT_RXSTPE (_U_(0x1) << DEVEPTIMR_INTRPT_RXSTPE_Pos) /**< (DEVEPTIMR) Received SETUP Interrupt Mask */ -#define DEVEPTIMR_INTRPT_NAKOUTE_Pos 3 /**< (DEVEPTIMR) NAKed OUT Interrupt Position */ -#define DEVEPTIMR_INTRPT_NAKOUTE (_U_(0x1) << DEVEPTIMR_INTRPT_NAKOUTE_Pos) /**< (DEVEPTIMR) NAKed OUT Interrupt Mask */ -#define DEVEPTIMR_INTRPT_NAKINE_Pos 4 /**< (DEVEPTIMR) NAKed IN Interrupt Position */ -#define DEVEPTIMR_INTRPT_NAKINE (_U_(0x1) << DEVEPTIMR_INTRPT_NAKINE_Pos) /**< (DEVEPTIMR) NAKed IN Interrupt Mask */ -#define DEVEPTIMR_INTRPT_STALLEDE_Pos 6 /**< (DEVEPTIMR) STALLed Interrupt Position */ -#define DEVEPTIMR_INTRPT_STALLEDE (_U_(0x1) << DEVEPTIMR_INTRPT_STALLEDE_Pos) /**< (DEVEPTIMR) STALLed Interrupt Mask */ -#define DEVEPTIMR_INTRPT_NYETDIS_Pos 17 /**< (DEVEPTIMR) NYET Token Disable Position */ -#define DEVEPTIMR_INTRPT_NYETDIS (_U_(0x1) << DEVEPTIMR_INTRPT_NYETDIS_Pos) /**< (DEVEPTIMR) NYET Token Disable Mask */ -#define DEVEPTIMR_INTRPT_STALLRQ_Pos 19 /**< (DEVEPTIMR) STALL Request Position */ -#define DEVEPTIMR_INTRPT_STALLRQ (_U_(0x1) << DEVEPTIMR_INTRPT_STALLRQ_Pos) /**< (DEVEPTIMR) STALL Request Mask */ -#define DEVEPTIMR_INTRPT_Msk _U_(0xA005C) /**< (DEVEPTIMR_INTRPT) Register Mask */ - - -/* -------- DEVEPTIER : (USBHS Offset: 0x1f0) (/W 32) Device Endpoint Interrupt Enable Register -------- */ - -#define DEVEPTIER_OFFSET (0x1F0) /**< (DEVEPTIER) Device Endpoint Interrupt Enable Register Offset */ - -#define DEVEPTIER_TXINES_Pos 0 /**< (DEVEPTIER) Transmitted IN Data Interrupt Enable Position */ -#define DEVEPTIER_TXINES (_U_(0x1) << DEVEPTIER_TXINES_Pos) /**< (DEVEPTIER) Transmitted IN Data Interrupt Enable Mask */ -#define DEVEPTIER_RXOUTES_Pos 1 /**< (DEVEPTIER) Received OUT Data Interrupt Enable Position */ -#define DEVEPTIER_RXOUTES (_U_(0x1) << DEVEPTIER_RXOUTES_Pos) /**< (DEVEPTIER) Received OUT Data Interrupt Enable Mask */ -#define DEVEPTIER_OVERFES_Pos 5 /**< (DEVEPTIER) Overflow Interrupt Enable Position */ -#define DEVEPTIER_OVERFES (_U_(0x1) << DEVEPTIER_OVERFES_Pos) /**< (DEVEPTIER) Overflow Interrupt Enable Mask */ -#define DEVEPTIER_SHORTPACKETES_Pos 7 /**< (DEVEPTIER) Short Packet Interrupt Enable Position */ -#define DEVEPTIER_SHORTPACKETES (_U_(0x1) << DEVEPTIER_SHORTPACKETES_Pos) /**< (DEVEPTIER) Short Packet Interrupt Enable Mask */ -#define DEVEPTIER_NBUSYBKES_Pos 12 /**< (DEVEPTIER) Number of Busy Banks Interrupt Enable Position */ -#define DEVEPTIER_NBUSYBKES (_U_(0x1) << DEVEPTIER_NBUSYBKES_Pos) /**< (DEVEPTIER) Number of Busy Banks Interrupt Enable Mask */ -#define DEVEPTIER_KILLBKS_Pos 13 /**< (DEVEPTIER) Kill IN Bank Position */ -#define DEVEPTIER_KILLBKS (_U_(0x1) << DEVEPTIER_KILLBKS_Pos) /**< (DEVEPTIER) Kill IN Bank Mask */ -#define DEVEPTIER_FIFOCONS_Pos 14 /**< (DEVEPTIER) FIFO Control Position */ -#define DEVEPTIER_FIFOCONS (_U_(0x1) << DEVEPTIER_FIFOCONS_Pos) /**< (DEVEPTIER) FIFO Control Mask */ -#define DEVEPTIER_EPDISHDMAS_Pos 16 /**< (DEVEPTIER) Endpoint Interrupts Disable HDMA Request Enable Position */ -#define DEVEPTIER_EPDISHDMAS (_U_(0x1) << DEVEPTIER_EPDISHDMAS_Pos) /**< (DEVEPTIER) Endpoint Interrupts Disable HDMA Request Enable Mask */ -#define DEVEPTIER_RSTDTS_Pos 18 /**< (DEVEPTIER) Reset Data Toggle Enable Position */ -#define DEVEPTIER_RSTDTS (_U_(0x1) << DEVEPTIER_RSTDTS_Pos) /**< (DEVEPTIER) Reset Data Toggle Enable Mask */ -#define DEVEPTIER_Msk _U_(0x570A3) /**< (DEVEPTIER) Register Mask */ - -/* CTRL mode */ -#define DEVEPTIER_CTRL_RXSTPES_Pos 2 /**< (DEVEPTIER) Received SETUP Interrupt Enable Position */ -#define DEVEPTIER_CTRL_RXSTPES (_U_(0x1) << DEVEPTIER_CTRL_RXSTPES_Pos) /**< (DEVEPTIER) Received SETUP Interrupt Enable Mask */ -#define DEVEPTIER_CTRL_NAKOUTES_Pos 3 /**< (DEVEPTIER) NAKed OUT Interrupt Enable Position */ -#define DEVEPTIER_CTRL_NAKOUTES (_U_(0x1) << DEVEPTIER_CTRL_NAKOUTES_Pos) /**< (DEVEPTIER) NAKed OUT Interrupt Enable Mask */ -#define DEVEPTIER_CTRL_NAKINES_Pos 4 /**< (DEVEPTIER) NAKed IN Interrupt Enable Position */ -#define DEVEPTIER_CTRL_NAKINES (_U_(0x1) << DEVEPTIER_CTRL_NAKINES_Pos) /**< (DEVEPTIER) NAKed IN Interrupt Enable Mask */ -#define DEVEPTIER_CTRL_STALLEDES_Pos 6 /**< (DEVEPTIER) STALLed Interrupt Enable Position */ -#define DEVEPTIER_CTRL_STALLEDES (_U_(0x1) << DEVEPTIER_CTRL_STALLEDES_Pos) /**< (DEVEPTIER) STALLed Interrupt Enable Mask */ -#define DEVEPTIER_CTRL_NYETDISS_Pos 17 /**< (DEVEPTIER) NYET Token Disable Enable Position */ -#define DEVEPTIER_CTRL_NYETDISS (_U_(0x1) << DEVEPTIER_CTRL_NYETDISS_Pos) /**< (DEVEPTIER) NYET Token Disable Enable Mask */ -#define DEVEPTIER_CTRL_STALLRQS_Pos 19 /**< (DEVEPTIER) STALL Request Enable Position */ -#define DEVEPTIER_CTRL_STALLRQS (_U_(0x1) << DEVEPTIER_CTRL_STALLRQS_Pos) /**< (DEVEPTIER) STALL Request Enable Mask */ -#define DEVEPTIER_CTRL_Msk _U_(0xA005C) /**< (DEVEPTIER_CTRL) Register Mask */ - -/* ISO mode */ -#define DEVEPTIER_ISO_UNDERFES_Pos 2 /**< (DEVEPTIER) Underflow Interrupt Enable Position */ -#define DEVEPTIER_ISO_UNDERFES (_U_(0x1) << DEVEPTIER_ISO_UNDERFES_Pos) /**< (DEVEPTIER) Underflow Interrupt Enable Mask */ -#define DEVEPTIER_ISO_HBISOINERRES_Pos 3 /**< (DEVEPTIER) High Bandwidth Isochronous IN Underflow Error Interrupt Enable Position */ -#define DEVEPTIER_ISO_HBISOINERRES (_U_(0x1) << DEVEPTIER_ISO_HBISOINERRES_Pos) /**< (DEVEPTIER) High Bandwidth Isochronous IN Underflow Error Interrupt Enable Mask */ -#define DEVEPTIER_ISO_HBISOFLUSHES_Pos 4 /**< (DEVEPTIER) High Bandwidth Isochronous IN Flush Interrupt Enable Position */ -#define DEVEPTIER_ISO_HBISOFLUSHES (_U_(0x1) << DEVEPTIER_ISO_HBISOFLUSHES_Pos) /**< (DEVEPTIER) High Bandwidth Isochronous IN Flush Interrupt Enable Mask */ -#define DEVEPTIER_ISO_CRCERRES_Pos 6 /**< (DEVEPTIER) CRC Error Interrupt Enable Position */ -#define DEVEPTIER_ISO_CRCERRES (_U_(0x1) << DEVEPTIER_ISO_CRCERRES_Pos) /**< (DEVEPTIER) CRC Error Interrupt Enable Mask */ -#define DEVEPTIER_ISO_MDATAES_Pos 8 /**< (DEVEPTIER) MData Interrupt Enable Position */ -#define DEVEPTIER_ISO_MDATAES (_U_(0x1) << DEVEPTIER_ISO_MDATAES_Pos) /**< (DEVEPTIER) MData Interrupt Enable Mask */ -#define DEVEPTIER_ISO_DATAXES_Pos 9 /**< (DEVEPTIER) DataX Interrupt Enable Position */ -#define DEVEPTIER_ISO_DATAXES (_U_(0x1) << DEVEPTIER_ISO_DATAXES_Pos) /**< (DEVEPTIER) DataX Interrupt Enable Mask */ -#define DEVEPTIER_ISO_ERRORTRANSES_Pos 10 /**< (DEVEPTIER) Transaction Error Interrupt Enable Position */ -#define DEVEPTIER_ISO_ERRORTRANSES (_U_(0x1) << DEVEPTIER_ISO_ERRORTRANSES_Pos) /**< (DEVEPTIER) Transaction Error Interrupt Enable Mask */ -#define DEVEPTIER_ISO_Msk _U_(0x75C) /**< (DEVEPTIER_ISO) Register Mask */ - -/* BLK mode */ -#define DEVEPTIER_BLK_RXSTPES_Pos 2 /**< (DEVEPTIER) Received SETUP Interrupt Enable Position */ -#define DEVEPTIER_BLK_RXSTPES (_U_(0x1) << DEVEPTIER_BLK_RXSTPES_Pos) /**< (DEVEPTIER) Received SETUP Interrupt Enable Mask */ -#define DEVEPTIER_BLK_NAKOUTES_Pos 3 /**< (DEVEPTIER) NAKed OUT Interrupt Enable Position */ -#define DEVEPTIER_BLK_NAKOUTES (_U_(0x1) << DEVEPTIER_BLK_NAKOUTES_Pos) /**< (DEVEPTIER) NAKed OUT Interrupt Enable Mask */ -#define DEVEPTIER_BLK_NAKINES_Pos 4 /**< (DEVEPTIER) NAKed IN Interrupt Enable Position */ -#define DEVEPTIER_BLK_NAKINES (_U_(0x1) << DEVEPTIER_BLK_NAKINES_Pos) /**< (DEVEPTIER) NAKed IN Interrupt Enable Mask */ -#define DEVEPTIER_BLK_STALLEDES_Pos 6 /**< (DEVEPTIER) STALLed Interrupt Enable Position */ -#define DEVEPTIER_BLK_STALLEDES (_U_(0x1) << DEVEPTIER_BLK_STALLEDES_Pos) /**< (DEVEPTIER) STALLed Interrupt Enable Mask */ -#define DEVEPTIER_BLK_NYETDISS_Pos 17 /**< (DEVEPTIER) NYET Token Disable Enable Position */ -#define DEVEPTIER_BLK_NYETDISS (_U_(0x1) << DEVEPTIER_BLK_NYETDISS_Pos) /**< (DEVEPTIER) NYET Token Disable Enable Mask */ -#define DEVEPTIER_BLK_STALLRQS_Pos 19 /**< (DEVEPTIER) STALL Request Enable Position */ -#define DEVEPTIER_BLK_STALLRQS (_U_(0x1) << DEVEPTIER_BLK_STALLRQS_Pos) /**< (DEVEPTIER) STALL Request Enable Mask */ -#define DEVEPTIER_BLK_Msk _U_(0xA005C) /**< (DEVEPTIER_BLK) Register Mask */ - -/* INTRPT mode */ -#define DEVEPTIER_INTRPT_RXSTPES_Pos 2 /**< (DEVEPTIER) Received SETUP Interrupt Enable Position */ -#define DEVEPTIER_INTRPT_RXSTPES (_U_(0x1) << DEVEPTIER_INTRPT_RXSTPES_Pos) /**< (DEVEPTIER) Received SETUP Interrupt Enable Mask */ -#define DEVEPTIER_INTRPT_NAKOUTES_Pos 3 /**< (DEVEPTIER) NAKed OUT Interrupt Enable Position */ -#define DEVEPTIER_INTRPT_NAKOUTES (_U_(0x1) << DEVEPTIER_INTRPT_NAKOUTES_Pos) /**< (DEVEPTIER) NAKed OUT Interrupt Enable Mask */ -#define DEVEPTIER_INTRPT_NAKINES_Pos 4 /**< (DEVEPTIER) NAKed IN Interrupt Enable Position */ -#define DEVEPTIER_INTRPT_NAKINES (_U_(0x1) << DEVEPTIER_INTRPT_NAKINES_Pos) /**< (DEVEPTIER) NAKed IN Interrupt Enable Mask */ -#define DEVEPTIER_INTRPT_STALLEDES_Pos 6 /**< (DEVEPTIER) STALLed Interrupt Enable Position */ -#define DEVEPTIER_INTRPT_STALLEDES (_U_(0x1) << DEVEPTIER_INTRPT_STALLEDES_Pos) /**< (DEVEPTIER) STALLed Interrupt Enable Mask */ -#define DEVEPTIER_INTRPT_NYETDISS_Pos 17 /**< (DEVEPTIER) NYET Token Disable Enable Position */ -#define DEVEPTIER_INTRPT_NYETDISS (_U_(0x1) << DEVEPTIER_INTRPT_NYETDISS_Pos) /**< (DEVEPTIER) NYET Token Disable Enable Mask */ -#define DEVEPTIER_INTRPT_STALLRQS_Pos 19 /**< (DEVEPTIER) STALL Request Enable Position */ -#define DEVEPTIER_INTRPT_STALLRQS (_U_(0x1) << DEVEPTIER_INTRPT_STALLRQS_Pos) /**< (DEVEPTIER) STALL Request Enable Mask */ -#define DEVEPTIER_INTRPT_Msk _U_(0xA005C) /**< (DEVEPTIER_INTRPT) Register Mask */ - - -/* -------- DEVEPTIDR : (USBHS Offset: 0x220) (/W 32) Device Endpoint Interrupt Disable Register -------- */ - -#define DEVEPTIDR_OFFSET (0x220) /**< (DEVEPTIDR) Device Endpoint Interrupt Disable Register Offset */ - -#define DEVEPTIDR_TXINEC_Pos 0 /**< (DEVEPTIDR) Transmitted IN Interrupt Clear Position */ -#define DEVEPTIDR_TXINEC (_U_(0x1) << DEVEPTIDR_TXINEC_Pos) /**< (DEVEPTIDR) Transmitted IN Interrupt Clear Mask */ -#define DEVEPTIDR_RXOUTEC_Pos 1 /**< (DEVEPTIDR) Received OUT Data Interrupt Clear Position */ -#define DEVEPTIDR_RXOUTEC (_U_(0x1) << DEVEPTIDR_RXOUTEC_Pos) /**< (DEVEPTIDR) Received OUT Data Interrupt Clear Mask */ -#define DEVEPTIDR_OVERFEC_Pos 5 /**< (DEVEPTIDR) Overflow Interrupt Clear Position */ -#define DEVEPTIDR_OVERFEC (_U_(0x1) << DEVEPTIDR_OVERFEC_Pos) /**< (DEVEPTIDR) Overflow Interrupt Clear Mask */ -#define DEVEPTIDR_SHORTPACKETEC_Pos 7 /**< (DEVEPTIDR) Shortpacket Interrupt Clear Position */ -#define DEVEPTIDR_SHORTPACKETEC (_U_(0x1) << DEVEPTIDR_SHORTPACKETEC_Pos) /**< (DEVEPTIDR) Shortpacket Interrupt Clear Mask */ -#define DEVEPTIDR_NBUSYBKEC_Pos 12 /**< (DEVEPTIDR) Number of Busy Banks Interrupt Clear Position */ -#define DEVEPTIDR_NBUSYBKEC (_U_(0x1) << DEVEPTIDR_NBUSYBKEC_Pos) /**< (DEVEPTIDR) Number of Busy Banks Interrupt Clear Mask */ -#define DEVEPTIDR_FIFOCONC_Pos 14 /**< (DEVEPTIDR) FIFO Control Clear Position */ -#define DEVEPTIDR_FIFOCONC (_U_(0x1) << DEVEPTIDR_FIFOCONC_Pos) /**< (DEVEPTIDR) FIFO Control Clear Mask */ -#define DEVEPTIDR_EPDISHDMAC_Pos 16 /**< (DEVEPTIDR) Endpoint Interrupts Disable HDMA Request Clear Position */ -#define DEVEPTIDR_EPDISHDMAC (_U_(0x1) << DEVEPTIDR_EPDISHDMAC_Pos) /**< (DEVEPTIDR) Endpoint Interrupts Disable HDMA Request Clear Mask */ -#define DEVEPTIDR_Msk _U_(0x150A3) /**< (DEVEPTIDR) Register Mask */ - -/* CTRL mode */ -#define DEVEPTIDR_CTRL_RXSTPEC_Pos 2 /**< (DEVEPTIDR) Received SETUP Interrupt Clear Position */ -#define DEVEPTIDR_CTRL_RXSTPEC (_U_(0x1) << DEVEPTIDR_CTRL_RXSTPEC_Pos) /**< (DEVEPTIDR) Received SETUP Interrupt Clear Mask */ -#define DEVEPTIDR_CTRL_NAKOUTEC_Pos 3 /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Position */ -#define DEVEPTIDR_CTRL_NAKOUTEC (_U_(0x1) << DEVEPTIDR_CTRL_NAKOUTEC_Pos) /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Mask */ -#define DEVEPTIDR_CTRL_NAKINEC_Pos 4 /**< (DEVEPTIDR) NAKed IN Interrupt Clear Position */ -#define DEVEPTIDR_CTRL_NAKINEC (_U_(0x1) << DEVEPTIDR_CTRL_NAKINEC_Pos) /**< (DEVEPTIDR) NAKed IN Interrupt Clear Mask */ -#define DEVEPTIDR_CTRL_STALLEDEC_Pos 6 /**< (DEVEPTIDR) STALLed Interrupt Clear Position */ -#define DEVEPTIDR_CTRL_STALLEDEC (_U_(0x1) << DEVEPTIDR_CTRL_STALLEDEC_Pos) /**< (DEVEPTIDR) STALLed Interrupt Clear Mask */ -#define DEVEPTIDR_CTRL_NYETDISC_Pos 17 /**< (DEVEPTIDR) NYET Token Disable Clear Position */ -#define DEVEPTIDR_CTRL_NYETDISC (_U_(0x1) << DEVEPTIDR_CTRL_NYETDISC_Pos) /**< (DEVEPTIDR) NYET Token Disable Clear Mask */ -#define DEVEPTIDR_CTRL_STALLRQC_Pos 19 /**< (DEVEPTIDR) STALL Request Clear Position */ -#define DEVEPTIDR_CTRL_STALLRQC (_U_(0x1) << DEVEPTIDR_CTRL_STALLRQC_Pos) /**< (DEVEPTIDR) STALL Request Clear Mask */ -#define DEVEPTIDR_CTRL_Msk _U_(0xA005C) /**< (DEVEPTIDR_CTRL) Register Mask */ - -/* ISO mode */ -#define DEVEPTIDR_ISO_UNDERFEC_Pos 2 /**< (DEVEPTIDR) Underflow Interrupt Clear Position */ -#define DEVEPTIDR_ISO_UNDERFEC (_U_(0x1) << DEVEPTIDR_ISO_UNDERFEC_Pos) /**< (DEVEPTIDR) Underflow Interrupt Clear Mask */ -#define DEVEPTIDR_ISO_HBISOINERREC_Pos 3 /**< (DEVEPTIDR) High Bandwidth Isochronous IN Underflow Error Interrupt Clear Position */ -#define DEVEPTIDR_ISO_HBISOINERREC (_U_(0x1) << DEVEPTIDR_ISO_HBISOINERREC_Pos) /**< (DEVEPTIDR) High Bandwidth Isochronous IN Underflow Error Interrupt Clear Mask */ -#define DEVEPTIDR_ISO_HBISOFLUSHEC_Pos 4 /**< (DEVEPTIDR) High Bandwidth Isochronous IN Flush Interrupt Clear Position */ -#define DEVEPTIDR_ISO_HBISOFLUSHEC (_U_(0x1) << DEVEPTIDR_ISO_HBISOFLUSHEC_Pos) /**< (DEVEPTIDR) High Bandwidth Isochronous IN Flush Interrupt Clear Mask */ -#define DEVEPTIDR_ISO_MDATAEC_Pos 8 /**< (DEVEPTIDR) MData Interrupt Clear Position */ -#define DEVEPTIDR_ISO_MDATAEC (_U_(0x1) << DEVEPTIDR_ISO_MDATAEC_Pos) /**< (DEVEPTIDR) MData Interrupt Clear Mask */ -#define DEVEPTIDR_ISO_DATAXEC_Pos 9 /**< (DEVEPTIDR) DataX Interrupt Clear Position */ -#define DEVEPTIDR_ISO_DATAXEC (_U_(0x1) << DEVEPTIDR_ISO_DATAXEC_Pos) /**< (DEVEPTIDR) DataX Interrupt Clear Mask */ -#define DEVEPTIDR_ISO_ERRORTRANSEC_Pos 10 /**< (DEVEPTIDR) Transaction Error Interrupt Clear Position */ -#define DEVEPTIDR_ISO_ERRORTRANSEC (_U_(0x1) << DEVEPTIDR_ISO_ERRORTRANSEC_Pos) /**< (DEVEPTIDR) Transaction Error Interrupt Clear Mask */ -#define DEVEPTIDR_ISO_Msk _U_(0x71C) /**< (DEVEPTIDR_ISO) Register Mask */ - -/* BLK mode */ -#define DEVEPTIDR_BLK_RXSTPEC_Pos 2 /**< (DEVEPTIDR) Received SETUP Interrupt Clear Position */ -#define DEVEPTIDR_BLK_RXSTPEC (_U_(0x1) << DEVEPTIDR_BLK_RXSTPEC_Pos) /**< (DEVEPTIDR) Received SETUP Interrupt Clear Mask */ -#define DEVEPTIDR_BLK_NAKOUTEC_Pos 3 /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Position */ -#define DEVEPTIDR_BLK_NAKOUTEC (_U_(0x1) << DEVEPTIDR_BLK_NAKOUTEC_Pos) /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Mask */ -#define DEVEPTIDR_BLK_NAKINEC_Pos 4 /**< (DEVEPTIDR) NAKed IN Interrupt Clear Position */ -#define DEVEPTIDR_BLK_NAKINEC (_U_(0x1) << DEVEPTIDR_BLK_NAKINEC_Pos) /**< (DEVEPTIDR) NAKed IN Interrupt Clear Mask */ -#define DEVEPTIDR_BLK_STALLEDEC_Pos 6 /**< (DEVEPTIDR) STALLed Interrupt Clear Position */ -#define DEVEPTIDR_BLK_STALLEDEC (_U_(0x1) << DEVEPTIDR_BLK_STALLEDEC_Pos) /**< (DEVEPTIDR) STALLed Interrupt Clear Mask */ -#define DEVEPTIDR_BLK_NYETDISC_Pos 17 /**< (DEVEPTIDR) NYET Token Disable Clear Position */ -#define DEVEPTIDR_BLK_NYETDISC (_U_(0x1) << DEVEPTIDR_BLK_NYETDISC_Pos) /**< (DEVEPTIDR) NYET Token Disable Clear Mask */ -#define DEVEPTIDR_BLK_STALLRQC_Pos 19 /**< (DEVEPTIDR) STALL Request Clear Position */ -#define DEVEPTIDR_BLK_STALLRQC (_U_(0x1) << DEVEPTIDR_BLK_STALLRQC_Pos) /**< (DEVEPTIDR) STALL Request Clear Mask */ -#define DEVEPTIDR_BLK_Msk _U_(0xA005C) /**< (DEVEPTIDR_BLK) Register Mask */ - -/* INTRPT mode */ -#define DEVEPTIDR_INTRPT_RXSTPEC_Pos 2 /**< (DEVEPTIDR) Received SETUP Interrupt Clear Position */ -#define DEVEPTIDR_INTRPT_RXSTPEC (_U_(0x1) << DEVEPTIDR_INTRPT_RXSTPEC_Pos) /**< (DEVEPTIDR) Received SETUP Interrupt Clear Mask */ -#define DEVEPTIDR_INTRPT_NAKOUTEC_Pos 3 /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Position */ -#define DEVEPTIDR_INTRPT_NAKOUTEC (_U_(0x1) << DEVEPTIDR_INTRPT_NAKOUTEC_Pos) /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Mask */ -#define DEVEPTIDR_INTRPT_NAKINEC_Pos 4 /**< (DEVEPTIDR) NAKed IN Interrupt Clear Position */ -#define DEVEPTIDR_INTRPT_NAKINEC (_U_(0x1) << DEVEPTIDR_INTRPT_NAKINEC_Pos) /**< (DEVEPTIDR) NAKed IN Interrupt Clear Mask */ -#define DEVEPTIDR_INTRPT_STALLEDEC_Pos 6 /**< (DEVEPTIDR) STALLed Interrupt Clear Position */ -#define DEVEPTIDR_INTRPT_STALLEDEC (_U_(0x1) << DEVEPTIDR_INTRPT_STALLEDEC_Pos) /**< (DEVEPTIDR) STALLed Interrupt Clear Mask */ -#define DEVEPTIDR_INTRPT_NYETDISC_Pos 17 /**< (DEVEPTIDR) NYET Token Disable Clear Position */ -#define DEVEPTIDR_INTRPT_NYETDISC (_U_(0x1) << DEVEPTIDR_INTRPT_NYETDISC_Pos) /**< (DEVEPTIDR) NYET Token Disable Clear Mask */ -#define DEVEPTIDR_INTRPT_STALLRQC_Pos 19 /**< (DEVEPTIDR) STALL Request Clear Position */ -#define DEVEPTIDR_INTRPT_STALLRQC (_U_(0x1) << DEVEPTIDR_INTRPT_STALLRQC_Pos) /**< (DEVEPTIDR) STALL Request Clear Mask */ -#define DEVEPTIDR_INTRPT_Msk _U_(0xA005C) /**< (DEVEPTIDR_INTRPT) Register Mask */ - - -/* -------- HSTCTRL : (USBHS Offset: 0x400) (R/W 32) Host General Control Register -------- */ - -#define HSTCTRL_OFFSET (0x400) /**< (HSTCTRL) Host General Control Register Offset */ - -#define HSTCTRL_SOFE_Pos 8 /**< (HSTCTRL) Start of Frame Generation Enable Position */ -#define HSTCTRL_SOFE (_U_(0x1) << HSTCTRL_SOFE_Pos) /**< (HSTCTRL) Start of Frame Generation Enable Mask */ -#define HSTCTRL_RESET_Pos 9 /**< (HSTCTRL) Send USB Reset Position */ -#define HSTCTRL_RESET (_U_(0x1) << HSTCTRL_RESET_Pos) /**< (HSTCTRL) Send USB Reset Mask */ -#define HSTCTRL_RESUME_Pos 10 /**< (HSTCTRL) Send USB Resume Position */ -#define HSTCTRL_RESUME (_U_(0x1) << HSTCTRL_RESUME_Pos) /**< (HSTCTRL) Send USB Resume Mask */ -#define HSTCTRL_SPDCONF_Pos 12 /**< (HSTCTRL) Mode Configuration Position */ -#define HSTCTRL_SPDCONF (_U_(0x3) << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) Mode Configuration Mask */ -#define HSTCTRL_SPDCONF_NORMAL_Val _U_(0x0) /**< (HSTCTRL) The host starts in Full-speed mode and performs a high-speed reset to switch to High-speed mode if the downstream peripheral is high-speed capable. */ -#define HSTCTRL_SPDCONF_LOW_POWER_Val _U_(0x1) /**< (HSTCTRL) For a better consumption, if high speed is not needed. */ -#define HSTCTRL_SPDCONF_HIGH_SPEED_Val _U_(0x2) /**< (HSTCTRL) Forced high speed. */ -#define HSTCTRL_SPDCONF_FORCED_FS_Val _U_(0x3) /**< (HSTCTRL) The host remains in Full-speed mode whatever the peripheral speed capability. */ -#define HSTCTRL_SPDCONF_NORMAL (HSTCTRL_SPDCONF_NORMAL_Val << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) The host starts in Full-speed mode and performs a high-speed reset to switch to High-speed mode if the downstream peripheral is high-speed capable. Position */ -#define HSTCTRL_SPDCONF_LOW_POWER (HSTCTRL_SPDCONF_LOW_POWER_Val << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) For a better consumption, if high speed is not needed. Position */ -#define HSTCTRL_SPDCONF_HIGH_SPEED (HSTCTRL_SPDCONF_HIGH_SPEED_Val << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) Forced high speed. Position */ -#define HSTCTRL_SPDCONF_FORCED_FS (HSTCTRL_SPDCONF_FORCED_FS_Val << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) The host remains in Full-speed mode whatever the peripheral speed capability. Position */ -#define HSTCTRL_Msk _U_(0x3700) /**< (HSTCTRL) Register Mask */ - - -/* -------- HSTISR : (USBHS Offset: 0x404) (R/ 32) Host Global Interrupt Status Register -------- */ - -#define HSTISR_OFFSET (0x404) /**< (HSTISR) Host Global Interrupt Status Register Offset */ - -#define HSTISR_DCONNI_Pos 0 /**< (HSTISR) Device Connection Interrupt Position */ -#define HSTISR_DCONNI (_U_(0x1) << HSTISR_DCONNI_Pos) /**< (HSTISR) Device Connection Interrupt Mask */ -#define HSTISR_DDISCI_Pos 1 /**< (HSTISR) Device Disconnection Interrupt Position */ -#define HSTISR_DDISCI (_U_(0x1) << HSTISR_DDISCI_Pos) /**< (HSTISR) Device Disconnection Interrupt Mask */ -#define HSTISR_RSTI_Pos 2 /**< (HSTISR) USB Reset Sent Interrupt Position */ -#define HSTISR_RSTI (_U_(0x1) << HSTISR_RSTI_Pos) /**< (HSTISR) USB Reset Sent Interrupt Mask */ -#define HSTISR_RSMEDI_Pos 3 /**< (HSTISR) Downstream Resume Sent Interrupt Position */ -#define HSTISR_RSMEDI (_U_(0x1) << HSTISR_RSMEDI_Pos) /**< (HSTISR) Downstream Resume Sent Interrupt Mask */ -#define HSTISR_RXRSMI_Pos 4 /**< (HSTISR) Upstream Resume Received Interrupt Position */ -#define HSTISR_RXRSMI (_U_(0x1) << HSTISR_RXRSMI_Pos) /**< (HSTISR) Upstream Resume Received Interrupt Mask */ -#define HSTISR_HSOFI_Pos 5 /**< (HSTISR) Host Start of Frame Interrupt Position */ -#define HSTISR_HSOFI (_U_(0x1) << HSTISR_HSOFI_Pos) /**< (HSTISR) Host Start of Frame Interrupt Mask */ -#define HSTISR_HWUPI_Pos 6 /**< (HSTISR) Host Wake-Up Interrupt Position */ -#define HSTISR_HWUPI (_U_(0x1) << HSTISR_HWUPI_Pos) /**< (HSTISR) Host Wake-Up Interrupt Mask */ -#define HSTISR_PEP_0_Pos 8 /**< (HSTISR) Pipe 0 Interrupt Position */ -#define HSTISR_PEP_0 (_U_(0x1) << HSTISR_PEP_0_Pos) /**< (HSTISR) Pipe 0 Interrupt Mask */ -#define HSTISR_PEP_1_Pos 9 /**< (HSTISR) Pipe 1 Interrupt Position */ -#define HSTISR_PEP_1 (_U_(0x1) << HSTISR_PEP_1_Pos) /**< (HSTISR) Pipe 1 Interrupt Mask */ -#define HSTISR_PEP_2_Pos 10 /**< (HSTISR) Pipe 2 Interrupt Position */ -#define HSTISR_PEP_2 (_U_(0x1) << HSTISR_PEP_2_Pos) /**< (HSTISR) Pipe 2 Interrupt Mask */ -#define HSTISR_PEP_3_Pos 11 /**< (HSTISR) Pipe 3 Interrupt Position */ -#define HSTISR_PEP_3 (_U_(0x1) << HSTISR_PEP_3_Pos) /**< (HSTISR) Pipe 3 Interrupt Mask */ -#define HSTISR_PEP_4_Pos 12 /**< (HSTISR) Pipe 4 Interrupt Position */ -#define HSTISR_PEP_4 (_U_(0x1) << HSTISR_PEP_4_Pos) /**< (HSTISR) Pipe 4 Interrupt Mask */ -#define HSTISR_PEP_5_Pos 13 /**< (HSTISR) Pipe 5 Interrupt Position */ -#define HSTISR_PEP_5 (_U_(0x1) << HSTISR_PEP_5_Pos) /**< (HSTISR) Pipe 5 Interrupt Mask */ -#define HSTISR_PEP_6_Pos 14 /**< (HSTISR) Pipe 6 Interrupt Position */ -#define HSTISR_PEP_6 (_U_(0x1) << HSTISR_PEP_6_Pos) /**< (HSTISR) Pipe 6 Interrupt Mask */ -#define HSTISR_PEP_7_Pos 15 /**< (HSTISR) Pipe 7 Interrupt Position */ -#define HSTISR_PEP_7 (_U_(0x1) << HSTISR_PEP_7_Pos) /**< (HSTISR) Pipe 7 Interrupt Mask */ -#define HSTISR_PEP_8_Pos 16 /**< (HSTISR) Pipe 8 Interrupt Position */ -#define HSTISR_PEP_8 (_U_(0x1) << HSTISR_PEP_8_Pos) /**< (HSTISR) Pipe 8 Interrupt Mask */ -#define HSTISR_PEP_9_Pos 17 /**< (HSTISR) Pipe 9 Interrupt Position */ -#define HSTISR_PEP_9 (_U_(0x1) << HSTISR_PEP_9_Pos) /**< (HSTISR) Pipe 9 Interrupt Mask */ -#define HSTISR_DMA_0_Pos 25 /**< (HSTISR) DMA Channel 0 Interrupt Position */ -#define HSTISR_DMA_0 (_U_(0x1) << HSTISR_DMA_0_Pos) /**< (HSTISR) DMA Channel 0 Interrupt Mask */ -#define HSTISR_DMA_1_Pos 26 /**< (HSTISR) DMA Channel 1 Interrupt Position */ -#define HSTISR_DMA_1 (_U_(0x1) << HSTISR_DMA_1_Pos) /**< (HSTISR) DMA Channel 1 Interrupt Mask */ -#define HSTISR_DMA_2_Pos 27 /**< (HSTISR) DMA Channel 2 Interrupt Position */ -#define HSTISR_DMA_2 (_U_(0x1) << HSTISR_DMA_2_Pos) /**< (HSTISR) DMA Channel 2 Interrupt Mask */ -#define HSTISR_DMA_3_Pos 28 /**< (HSTISR) DMA Channel 3 Interrupt Position */ -#define HSTISR_DMA_3 (_U_(0x1) << HSTISR_DMA_3_Pos) /**< (HSTISR) DMA Channel 3 Interrupt Mask */ -#define HSTISR_DMA_4_Pos 29 /**< (HSTISR) DMA Channel 4 Interrupt Position */ -#define HSTISR_DMA_4 (_U_(0x1) << HSTISR_DMA_4_Pos) /**< (HSTISR) DMA Channel 4 Interrupt Mask */ -#define HSTISR_DMA_5_Pos 30 /**< (HSTISR) DMA Channel 5 Interrupt Position */ -#define HSTISR_DMA_5 (_U_(0x1) << HSTISR_DMA_5_Pos) /**< (HSTISR) DMA Channel 5 Interrupt Mask */ -#define HSTISR_DMA_6_Pos 31 /**< (HSTISR) DMA Channel 6 Interrupt Position */ -#define HSTISR_DMA_6 (_U_(0x1) << HSTISR_DMA_6_Pos) /**< (HSTISR) DMA Channel 6 Interrupt Mask */ -#define HSTISR_Msk _U_(0xFE03FF7F) /**< (HSTISR) Register Mask */ - -#define HSTISR_PEP__Pos 8 /**< (HSTISR Position) Pipe x Interrupt */ -#define HSTISR_PEP_ (_U_(0x3FF) << HSTISR_PEP__Pos) /**< (HSTISR Mask) PEP_ */ -#define HSTISR_DMA__Pos 25 /**< (HSTISR Position) DMA Channel 6 Interrupt */ -#define HSTISR_DMA_ (_U_(0x7F) << HSTISR_DMA__Pos) /**< (HSTISR Mask) DMA_ */ - -/* -------- HSTICR : (USBHS Offset: 0x408) (/W 32) Host Global Interrupt Clear Register -------- */ - -#define HSTICR_OFFSET (0x408) /**< (HSTICR) Host Global Interrupt Clear Register Offset */ - -#define HSTICR_DCONNIC_Pos 0 /**< (HSTICR) Device Connection Interrupt Clear Position */ -#define HSTICR_DCONNIC (_U_(0x1) << HSTICR_DCONNIC_Pos) /**< (HSTICR) Device Connection Interrupt Clear Mask */ -#define HSTICR_DDISCIC_Pos 1 /**< (HSTICR) Device Disconnection Interrupt Clear Position */ -#define HSTICR_DDISCIC (_U_(0x1) << HSTICR_DDISCIC_Pos) /**< (HSTICR) Device Disconnection Interrupt Clear Mask */ -#define HSTICR_RSTIC_Pos 2 /**< (HSTICR) USB Reset Sent Interrupt Clear Position */ -#define HSTICR_RSTIC (_U_(0x1) << HSTICR_RSTIC_Pos) /**< (HSTICR) USB Reset Sent Interrupt Clear Mask */ -#define HSTICR_RSMEDIC_Pos 3 /**< (HSTICR) Downstream Resume Sent Interrupt Clear Position */ -#define HSTICR_RSMEDIC (_U_(0x1) << HSTICR_RSMEDIC_Pos) /**< (HSTICR) Downstream Resume Sent Interrupt Clear Mask */ -#define HSTICR_RXRSMIC_Pos 4 /**< (HSTICR) Upstream Resume Received Interrupt Clear Position */ -#define HSTICR_RXRSMIC (_U_(0x1) << HSTICR_RXRSMIC_Pos) /**< (HSTICR) Upstream Resume Received Interrupt Clear Mask */ -#define HSTICR_HSOFIC_Pos 5 /**< (HSTICR) Host Start of Frame Interrupt Clear Position */ -#define HSTICR_HSOFIC (_U_(0x1) << HSTICR_HSOFIC_Pos) /**< (HSTICR) Host Start of Frame Interrupt Clear Mask */ -#define HSTICR_HWUPIC_Pos 6 /**< (HSTICR) Host Wake-Up Interrupt Clear Position */ -#define HSTICR_HWUPIC (_U_(0x1) << HSTICR_HWUPIC_Pos) /**< (HSTICR) Host Wake-Up Interrupt Clear Mask */ -#define HSTICR_Msk _U_(0x7F) /**< (HSTICR) Register Mask */ - - -/* -------- HSTIFR : (USBHS Offset: 0x40c) (/W 32) Host Global Interrupt Set Register -------- */ - -#define HSTIFR_OFFSET (0x40C) /**< (HSTIFR) Host Global Interrupt Set Register Offset */ - -#define HSTIFR_DCONNIS_Pos 0 /**< (HSTIFR) Device Connection Interrupt Set Position */ -#define HSTIFR_DCONNIS (_U_(0x1) << HSTIFR_DCONNIS_Pos) /**< (HSTIFR) Device Connection Interrupt Set Mask */ -#define HSTIFR_DDISCIS_Pos 1 /**< (HSTIFR) Device Disconnection Interrupt Set Position */ -#define HSTIFR_DDISCIS (_U_(0x1) << HSTIFR_DDISCIS_Pos) /**< (HSTIFR) Device Disconnection Interrupt Set Mask */ -#define HSTIFR_RSTIS_Pos 2 /**< (HSTIFR) USB Reset Sent Interrupt Set Position */ -#define HSTIFR_RSTIS (_U_(0x1) << HSTIFR_RSTIS_Pos) /**< (HSTIFR) USB Reset Sent Interrupt Set Mask */ -#define HSTIFR_RSMEDIS_Pos 3 /**< (HSTIFR) Downstream Resume Sent Interrupt Set Position */ -#define HSTIFR_RSMEDIS (_U_(0x1) << HSTIFR_RSMEDIS_Pos) /**< (HSTIFR) Downstream Resume Sent Interrupt Set Mask */ -#define HSTIFR_RXRSMIS_Pos 4 /**< (HSTIFR) Upstream Resume Received Interrupt Set Position */ -#define HSTIFR_RXRSMIS (_U_(0x1) << HSTIFR_RXRSMIS_Pos) /**< (HSTIFR) Upstream Resume Received Interrupt Set Mask */ -#define HSTIFR_HSOFIS_Pos 5 /**< (HSTIFR) Host Start of Frame Interrupt Set Position */ -#define HSTIFR_HSOFIS (_U_(0x1) << HSTIFR_HSOFIS_Pos) /**< (HSTIFR) Host Start of Frame Interrupt Set Mask */ -#define HSTIFR_HWUPIS_Pos 6 /**< (HSTIFR) Host Wake-Up Interrupt Set Position */ -#define HSTIFR_HWUPIS (_U_(0x1) << HSTIFR_HWUPIS_Pos) /**< (HSTIFR) Host Wake-Up Interrupt Set Mask */ -#define HSTIFR_DMA_0_Pos 25 /**< (HSTIFR) DMA Channel 0 Interrupt Set Position */ -#define HSTIFR_DMA_0 (_U_(0x1) << HSTIFR_DMA_0_Pos) /**< (HSTIFR) DMA Channel 0 Interrupt Set Mask */ -#define HSTIFR_DMA_1_Pos 26 /**< (HSTIFR) DMA Channel 1 Interrupt Set Position */ -#define HSTIFR_DMA_1 (_U_(0x1) << HSTIFR_DMA_1_Pos) /**< (HSTIFR) DMA Channel 1 Interrupt Set Mask */ -#define HSTIFR_DMA_2_Pos 27 /**< (HSTIFR) DMA Channel 2 Interrupt Set Position */ -#define HSTIFR_DMA_2 (_U_(0x1) << HSTIFR_DMA_2_Pos) /**< (HSTIFR) DMA Channel 2 Interrupt Set Mask */ -#define HSTIFR_DMA_3_Pos 28 /**< (HSTIFR) DMA Channel 3 Interrupt Set Position */ -#define HSTIFR_DMA_3 (_U_(0x1) << HSTIFR_DMA_3_Pos) /**< (HSTIFR) DMA Channel 3 Interrupt Set Mask */ -#define HSTIFR_DMA_4_Pos 29 /**< (HSTIFR) DMA Channel 4 Interrupt Set Position */ -#define HSTIFR_DMA_4 (_U_(0x1) << HSTIFR_DMA_4_Pos) /**< (HSTIFR) DMA Channel 4 Interrupt Set Mask */ -#define HSTIFR_DMA_5_Pos 30 /**< (HSTIFR) DMA Channel 5 Interrupt Set Position */ -#define HSTIFR_DMA_5 (_U_(0x1) << HSTIFR_DMA_5_Pos) /**< (HSTIFR) DMA Channel 5 Interrupt Set Mask */ -#define HSTIFR_DMA_6_Pos 31 /**< (HSTIFR) DMA Channel 6 Interrupt Set Position */ -#define HSTIFR_DMA_6 (_U_(0x1) << HSTIFR_DMA_6_Pos) /**< (HSTIFR) DMA Channel 6 Interrupt Set Mask */ -#define HSTIFR_Msk _U_(0xFE00007F) /**< (HSTIFR) Register Mask */ - -#define HSTIFR_DMA__Pos 25 /**< (HSTIFR Position) DMA Channel 6 Interrupt Set */ -#define HSTIFR_DMA_ (_U_(0x7F) << HSTIFR_DMA__Pos) /**< (HSTIFR Mask) DMA_ */ - -/* -------- HSTIMR : (USBHS Offset: 0x410) (R/ 32) Host Global Interrupt Mask Register -------- */ - -#define HSTIMR_OFFSET (0x410) /**< (HSTIMR) Host Global Interrupt Mask Register Offset */ - -#define HSTIMR_DCONNIE_Pos 0 /**< (HSTIMR) Device Connection Interrupt Enable Position */ -#define HSTIMR_DCONNIE (_U_(0x1) << HSTIMR_DCONNIE_Pos) /**< (HSTIMR) Device Connection Interrupt Enable Mask */ -#define HSTIMR_DDISCIE_Pos 1 /**< (HSTIMR) Device Disconnection Interrupt Enable Position */ -#define HSTIMR_DDISCIE (_U_(0x1) << HSTIMR_DDISCIE_Pos) /**< (HSTIMR) Device Disconnection Interrupt Enable Mask */ -#define HSTIMR_RSTIE_Pos 2 /**< (HSTIMR) USB Reset Sent Interrupt Enable Position */ -#define HSTIMR_RSTIE (_U_(0x1) << HSTIMR_RSTIE_Pos) /**< (HSTIMR) USB Reset Sent Interrupt Enable Mask */ -#define HSTIMR_RSMEDIE_Pos 3 /**< (HSTIMR) Downstream Resume Sent Interrupt Enable Position */ -#define HSTIMR_RSMEDIE (_U_(0x1) << HSTIMR_RSMEDIE_Pos) /**< (HSTIMR) Downstream Resume Sent Interrupt Enable Mask */ -#define HSTIMR_RXRSMIE_Pos 4 /**< (HSTIMR) Upstream Resume Received Interrupt Enable Position */ -#define HSTIMR_RXRSMIE (_U_(0x1) << HSTIMR_RXRSMIE_Pos) /**< (HSTIMR) Upstream Resume Received Interrupt Enable Mask */ -#define HSTIMR_HSOFIE_Pos 5 /**< (HSTIMR) Host Start of Frame Interrupt Enable Position */ -#define HSTIMR_HSOFIE (_U_(0x1) << HSTIMR_HSOFIE_Pos) /**< (HSTIMR) Host Start of Frame Interrupt Enable Mask */ -#define HSTIMR_HWUPIE_Pos 6 /**< (HSTIMR) Host Wake-Up Interrupt Enable Position */ -#define HSTIMR_HWUPIE (_U_(0x1) << HSTIMR_HWUPIE_Pos) /**< (HSTIMR) Host Wake-Up Interrupt Enable Mask */ -#define HSTIMR_PEP_0_Pos 8 /**< (HSTIMR) Pipe 0 Interrupt Enable Position */ -#define HSTIMR_PEP_0 (_U_(0x1) << HSTIMR_PEP_0_Pos) /**< (HSTIMR) Pipe 0 Interrupt Enable Mask */ -#define HSTIMR_PEP_1_Pos 9 /**< (HSTIMR) Pipe 1 Interrupt Enable Position */ -#define HSTIMR_PEP_1 (_U_(0x1) << HSTIMR_PEP_1_Pos) /**< (HSTIMR) Pipe 1 Interrupt Enable Mask */ -#define HSTIMR_PEP_2_Pos 10 /**< (HSTIMR) Pipe 2 Interrupt Enable Position */ -#define HSTIMR_PEP_2 (_U_(0x1) << HSTIMR_PEP_2_Pos) /**< (HSTIMR) Pipe 2 Interrupt Enable Mask */ -#define HSTIMR_PEP_3_Pos 11 /**< (HSTIMR) Pipe 3 Interrupt Enable Position */ -#define HSTIMR_PEP_3 (_U_(0x1) << HSTIMR_PEP_3_Pos) /**< (HSTIMR) Pipe 3 Interrupt Enable Mask */ -#define HSTIMR_PEP_4_Pos 12 /**< (HSTIMR) Pipe 4 Interrupt Enable Position */ -#define HSTIMR_PEP_4 (_U_(0x1) << HSTIMR_PEP_4_Pos) /**< (HSTIMR) Pipe 4 Interrupt Enable Mask */ -#define HSTIMR_PEP_5_Pos 13 /**< (HSTIMR) Pipe 5 Interrupt Enable Position */ -#define HSTIMR_PEP_5 (_U_(0x1) << HSTIMR_PEP_5_Pos) /**< (HSTIMR) Pipe 5 Interrupt Enable Mask */ -#define HSTIMR_PEP_6_Pos 14 /**< (HSTIMR) Pipe 6 Interrupt Enable Position */ -#define HSTIMR_PEP_6 (_U_(0x1) << HSTIMR_PEP_6_Pos) /**< (HSTIMR) Pipe 6 Interrupt Enable Mask */ -#define HSTIMR_PEP_7_Pos 15 /**< (HSTIMR) Pipe 7 Interrupt Enable Position */ -#define HSTIMR_PEP_7 (_U_(0x1) << HSTIMR_PEP_7_Pos) /**< (HSTIMR) Pipe 7 Interrupt Enable Mask */ -#define HSTIMR_PEP_8_Pos 16 /**< (HSTIMR) Pipe 8 Interrupt Enable Position */ -#define HSTIMR_PEP_8 (_U_(0x1) << HSTIMR_PEP_8_Pos) /**< (HSTIMR) Pipe 8 Interrupt Enable Mask */ -#define HSTIMR_PEP_9_Pos 17 /**< (HSTIMR) Pipe 9 Interrupt Enable Position */ -#define HSTIMR_PEP_9 (_U_(0x1) << HSTIMR_PEP_9_Pos) /**< (HSTIMR) Pipe 9 Interrupt Enable Mask */ -#define HSTIMR_DMA_0_Pos 25 /**< (HSTIMR) DMA Channel 0 Interrupt Enable Position */ -#define HSTIMR_DMA_0 (_U_(0x1) << HSTIMR_DMA_0_Pos) /**< (HSTIMR) DMA Channel 0 Interrupt Enable Mask */ -#define HSTIMR_DMA_1_Pos 26 /**< (HSTIMR) DMA Channel 1 Interrupt Enable Position */ -#define HSTIMR_DMA_1 (_U_(0x1) << HSTIMR_DMA_1_Pos) /**< (HSTIMR) DMA Channel 1 Interrupt Enable Mask */ -#define HSTIMR_DMA_2_Pos 27 /**< (HSTIMR) DMA Channel 2 Interrupt Enable Position */ -#define HSTIMR_DMA_2 (_U_(0x1) << HSTIMR_DMA_2_Pos) /**< (HSTIMR) DMA Channel 2 Interrupt Enable Mask */ -#define HSTIMR_DMA_3_Pos 28 /**< (HSTIMR) DMA Channel 3 Interrupt Enable Position */ -#define HSTIMR_DMA_3 (_U_(0x1) << HSTIMR_DMA_3_Pos) /**< (HSTIMR) DMA Channel 3 Interrupt Enable Mask */ -#define HSTIMR_DMA_4_Pos 29 /**< (HSTIMR) DMA Channel 4 Interrupt Enable Position */ -#define HSTIMR_DMA_4 (_U_(0x1) << HSTIMR_DMA_4_Pos) /**< (HSTIMR) DMA Channel 4 Interrupt Enable Mask */ -#define HSTIMR_DMA_5_Pos 30 /**< (HSTIMR) DMA Channel 5 Interrupt Enable Position */ -#define HSTIMR_DMA_5 (_U_(0x1) << HSTIMR_DMA_5_Pos) /**< (HSTIMR) DMA Channel 5 Interrupt Enable Mask */ -#define HSTIMR_DMA_6_Pos 31 /**< (HSTIMR) DMA Channel 6 Interrupt Enable Position */ -#define HSTIMR_DMA_6 (_U_(0x1) << HSTIMR_DMA_6_Pos) /**< (HSTIMR) DMA Channel 6 Interrupt Enable Mask */ -#define HSTIMR_Msk _U_(0xFE03FF7F) /**< (HSTIMR) Register Mask */ - -#define HSTIMR_PEP__Pos 8 /**< (HSTIMR Position) Pipe x Interrupt Enable */ -#define HSTIMR_PEP_ (_U_(0x3FF) << HSTIMR_PEP__Pos) /**< (HSTIMR Mask) PEP_ */ -#define HSTIMR_DMA__Pos 25 /**< (HSTIMR Position) DMA Channel 6 Interrupt Enable */ -#define HSTIMR_DMA_ (_U_(0x7F) << HSTIMR_DMA__Pos) /**< (HSTIMR Mask) DMA_ */ - -/* -------- HSTIDR : (USBHS Offset: 0x414) (/W 32) Host Global Interrupt Disable Register -------- */ - -#define HSTIDR_OFFSET (0x414) /**< (HSTIDR) Host Global Interrupt Disable Register Offset */ - -#define HSTIDR_DCONNIEC_Pos 0 /**< (HSTIDR) Device Connection Interrupt Disable Position */ -#define HSTIDR_DCONNIEC (_U_(0x1) << HSTIDR_DCONNIEC_Pos) /**< (HSTIDR) Device Connection Interrupt Disable Mask */ -#define HSTIDR_DDISCIEC_Pos 1 /**< (HSTIDR) Device Disconnection Interrupt Disable Position */ -#define HSTIDR_DDISCIEC (_U_(0x1) << HSTIDR_DDISCIEC_Pos) /**< (HSTIDR) Device Disconnection Interrupt Disable Mask */ -#define HSTIDR_RSTIEC_Pos 2 /**< (HSTIDR) USB Reset Sent Interrupt Disable Position */ -#define HSTIDR_RSTIEC (_U_(0x1) << HSTIDR_RSTIEC_Pos) /**< (HSTIDR) USB Reset Sent Interrupt Disable Mask */ -#define HSTIDR_RSMEDIEC_Pos 3 /**< (HSTIDR) Downstream Resume Sent Interrupt Disable Position */ -#define HSTIDR_RSMEDIEC (_U_(0x1) << HSTIDR_RSMEDIEC_Pos) /**< (HSTIDR) Downstream Resume Sent Interrupt Disable Mask */ -#define HSTIDR_RXRSMIEC_Pos 4 /**< (HSTIDR) Upstream Resume Received Interrupt Disable Position */ -#define HSTIDR_RXRSMIEC (_U_(0x1) << HSTIDR_RXRSMIEC_Pos) /**< (HSTIDR) Upstream Resume Received Interrupt Disable Mask */ -#define HSTIDR_HSOFIEC_Pos 5 /**< (HSTIDR) Host Start of Frame Interrupt Disable Position */ -#define HSTIDR_HSOFIEC (_U_(0x1) << HSTIDR_HSOFIEC_Pos) /**< (HSTIDR) Host Start of Frame Interrupt Disable Mask */ -#define HSTIDR_HWUPIEC_Pos 6 /**< (HSTIDR) Host Wake-Up Interrupt Disable Position */ -#define HSTIDR_HWUPIEC (_U_(0x1) << HSTIDR_HWUPIEC_Pos) /**< (HSTIDR) Host Wake-Up Interrupt Disable Mask */ -#define HSTIDR_PEP_0_Pos 8 /**< (HSTIDR) Pipe 0 Interrupt Disable Position */ -#define HSTIDR_PEP_0 (_U_(0x1) << HSTIDR_PEP_0_Pos) /**< (HSTIDR) Pipe 0 Interrupt Disable Mask */ -#define HSTIDR_PEP_1_Pos 9 /**< (HSTIDR) Pipe 1 Interrupt Disable Position */ -#define HSTIDR_PEP_1 (_U_(0x1) << HSTIDR_PEP_1_Pos) /**< (HSTIDR) Pipe 1 Interrupt Disable Mask */ -#define HSTIDR_PEP_2_Pos 10 /**< (HSTIDR) Pipe 2 Interrupt Disable Position */ -#define HSTIDR_PEP_2 (_U_(0x1) << HSTIDR_PEP_2_Pos) /**< (HSTIDR) Pipe 2 Interrupt Disable Mask */ -#define HSTIDR_PEP_3_Pos 11 /**< (HSTIDR) Pipe 3 Interrupt Disable Position */ -#define HSTIDR_PEP_3 (_U_(0x1) << HSTIDR_PEP_3_Pos) /**< (HSTIDR) Pipe 3 Interrupt Disable Mask */ -#define HSTIDR_PEP_4_Pos 12 /**< (HSTIDR) Pipe 4 Interrupt Disable Position */ -#define HSTIDR_PEP_4 (_U_(0x1) << HSTIDR_PEP_4_Pos) /**< (HSTIDR) Pipe 4 Interrupt Disable Mask */ -#define HSTIDR_PEP_5_Pos 13 /**< (HSTIDR) Pipe 5 Interrupt Disable Position */ -#define HSTIDR_PEP_5 (_U_(0x1) << HSTIDR_PEP_5_Pos) /**< (HSTIDR) Pipe 5 Interrupt Disable Mask */ -#define HSTIDR_PEP_6_Pos 14 /**< (HSTIDR) Pipe 6 Interrupt Disable Position */ -#define HSTIDR_PEP_6 (_U_(0x1) << HSTIDR_PEP_6_Pos) /**< (HSTIDR) Pipe 6 Interrupt Disable Mask */ -#define HSTIDR_PEP_7_Pos 15 /**< (HSTIDR) Pipe 7 Interrupt Disable Position */ -#define HSTIDR_PEP_7 (_U_(0x1) << HSTIDR_PEP_7_Pos) /**< (HSTIDR) Pipe 7 Interrupt Disable Mask */ -#define HSTIDR_PEP_8_Pos 16 /**< (HSTIDR) Pipe 8 Interrupt Disable Position */ -#define HSTIDR_PEP_8 (_U_(0x1) << HSTIDR_PEP_8_Pos) /**< (HSTIDR) Pipe 8 Interrupt Disable Mask */ -#define HSTIDR_PEP_9_Pos 17 /**< (HSTIDR) Pipe 9 Interrupt Disable Position */ -#define HSTIDR_PEP_9 (_U_(0x1) << HSTIDR_PEP_9_Pos) /**< (HSTIDR) Pipe 9 Interrupt Disable Mask */ -#define HSTIDR_DMA_0_Pos 25 /**< (HSTIDR) DMA Channel 0 Interrupt Disable Position */ -#define HSTIDR_DMA_0 (_U_(0x1) << HSTIDR_DMA_0_Pos) /**< (HSTIDR) DMA Channel 0 Interrupt Disable Mask */ -#define HSTIDR_DMA_1_Pos 26 /**< (HSTIDR) DMA Channel 1 Interrupt Disable Position */ -#define HSTIDR_DMA_1 (_U_(0x1) << HSTIDR_DMA_1_Pos) /**< (HSTIDR) DMA Channel 1 Interrupt Disable Mask */ -#define HSTIDR_DMA_2_Pos 27 /**< (HSTIDR) DMA Channel 2 Interrupt Disable Position */ -#define HSTIDR_DMA_2 (_U_(0x1) << HSTIDR_DMA_2_Pos) /**< (HSTIDR) DMA Channel 2 Interrupt Disable Mask */ -#define HSTIDR_DMA_3_Pos 28 /**< (HSTIDR) DMA Channel 3 Interrupt Disable Position */ -#define HSTIDR_DMA_3 (_U_(0x1) << HSTIDR_DMA_3_Pos) /**< (HSTIDR) DMA Channel 3 Interrupt Disable Mask */ -#define HSTIDR_DMA_4_Pos 29 /**< (HSTIDR) DMA Channel 4 Interrupt Disable Position */ -#define HSTIDR_DMA_4 (_U_(0x1) << HSTIDR_DMA_4_Pos) /**< (HSTIDR) DMA Channel 4 Interrupt Disable Mask */ -#define HSTIDR_DMA_5_Pos 30 /**< (HSTIDR) DMA Channel 5 Interrupt Disable Position */ -#define HSTIDR_DMA_5 (_U_(0x1) << HSTIDR_DMA_5_Pos) /**< (HSTIDR) DMA Channel 5 Interrupt Disable Mask */ -#define HSTIDR_DMA_6_Pos 31 /**< (HSTIDR) DMA Channel 6 Interrupt Disable Position */ -#define HSTIDR_DMA_6 (_U_(0x1) << HSTIDR_DMA_6_Pos) /**< (HSTIDR) DMA Channel 6 Interrupt Disable Mask */ -#define HSTIDR_Msk _U_(0xFE03FF7F) /**< (HSTIDR) Register Mask */ - -#define HSTIDR_PEP__Pos 8 /**< (HSTIDR Position) Pipe x Interrupt Disable */ -#define HSTIDR_PEP_ (_U_(0x3FF) << HSTIDR_PEP__Pos) /**< (HSTIDR Mask) PEP_ */ -#define HSTIDR_DMA__Pos 25 /**< (HSTIDR Position) DMA Channel 6 Interrupt Disable */ -#define HSTIDR_DMA_ (_U_(0x7F) << HSTIDR_DMA__Pos) /**< (HSTIDR Mask) DMA_ */ - -/* -------- HSTIER : (USBHS Offset: 0x418) (/W 32) Host Global Interrupt Enable Register -------- */ - -#define HSTIER_OFFSET (0x418) /**< (HSTIER) Host Global Interrupt Enable Register Offset */ - -#define HSTIER_DCONNIES_Pos 0 /**< (HSTIER) Device Connection Interrupt Enable Position */ -#define HSTIER_DCONNIES (_U_(0x1) << HSTIER_DCONNIES_Pos) /**< (HSTIER) Device Connection Interrupt Enable Mask */ -#define HSTIER_DDISCIES_Pos 1 /**< (HSTIER) Device Disconnection Interrupt Enable Position */ -#define HSTIER_DDISCIES (_U_(0x1) << HSTIER_DDISCIES_Pos) /**< (HSTIER) Device Disconnection Interrupt Enable Mask */ -#define HSTIER_RSTIES_Pos 2 /**< (HSTIER) USB Reset Sent Interrupt Enable Position */ -#define HSTIER_RSTIES (_U_(0x1) << HSTIER_RSTIES_Pos) /**< (HSTIER) USB Reset Sent Interrupt Enable Mask */ -#define HSTIER_RSMEDIES_Pos 3 /**< (HSTIER) Downstream Resume Sent Interrupt Enable Position */ -#define HSTIER_RSMEDIES (_U_(0x1) << HSTIER_RSMEDIES_Pos) /**< (HSTIER) Downstream Resume Sent Interrupt Enable Mask */ -#define HSTIER_RXRSMIES_Pos 4 /**< (HSTIER) Upstream Resume Received Interrupt Enable Position */ -#define HSTIER_RXRSMIES (_U_(0x1) << HSTIER_RXRSMIES_Pos) /**< (HSTIER) Upstream Resume Received Interrupt Enable Mask */ -#define HSTIER_HSOFIES_Pos 5 /**< (HSTIER) Host Start of Frame Interrupt Enable Position */ -#define HSTIER_HSOFIES (_U_(0x1) << HSTIER_HSOFIES_Pos) /**< (HSTIER) Host Start of Frame Interrupt Enable Mask */ -#define HSTIER_HWUPIES_Pos 6 /**< (HSTIER) Host Wake-Up Interrupt Enable Position */ -#define HSTIER_HWUPIES (_U_(0x1) << HSTIER_HWUPIES_Pos) /**< (HSTIER) Host Wake-Up Interrupt Enable Mask */ -#define HSTIER_PEP_0_Pos 8 /**< (HSTIER) Pipe 0 Interrupt Enable Position */ -#define HSTIER_PEP_0 (_U_(0x1) << HSTIER_PEP_0_Pos) /**< (HSTIER) Pipe 0 Interrupt Enable Mask */ -#define HSTIER_PEP_1_Pos 9 /**< (HSTIER) Pipe 1 Interrupt Enable Position */ -#define HSTIER_PEP_1 (_U_(0x1) << HSTIER_PEP_1_Pos) /**< (HSTIER) Pipe 1 Interrupt Enable Mask */ -#define HSTIER_PEP_2_Pos 10 /**< (HSTIER) Pipe 2 Interrupt Enable Position */ -#define HSTIER_PEP_2 (_U_(0x1) << HSTIER_PEP_2_Pos) /**< (HSTIER) Pipe 2 Interrupt Enable Mask */ -#define HSTIER_PEP_3_Pos 11 /**< (HSTIER) Pipe 3 Interrupt Enable Position */ -#define HSTIER_PEP_3 (_U_(0x1) << HSTIER_PEP_3_Pos) /**< (HSTIER) Pipe 3 Interrupt Enable Mask */ -#define HSTIER_PEP_4_Pos 12 /**< (HSTIER) Pipe 4 Interrupt Enable Position */ -#define HSTIER_PEP_4 (_U_(0x1) << HSTIER_PEP_4_Pos) /**< (HSTIER) Pipe 4 Interrupt Enable Mask */ -#define HSTIER_PEP_5_Pos 13 /**< (HSTIER) Pipe 5 Interrupt Enable Position */ -#define HSTIER_PEP_5 (_U_(0x1) << HSTIER_PEP_5_Pos) /**< (HSTIER) Pipe 5 Interrupt Enable Mask */ -#define HSTIER_PEP_6_Pos 14 /**< (HSTIER) Pipe 6 Interrupt Enable Position */ -#define HSTIER_PEP_6 (_U_(0x1) << HSTIER_PEP_6_Pos) /**< (HSTIER) Pipe 6 Interrupt Enable Mask */ -#define HSTIER_PEP_7_Pos 15 /**< (HSTIER) Pipe 7 Interrupt Enable Position */ -#define HSTIER_PEP_7 (_U_(0x1) << HSTIER_PEP_7_Pos) /**< (HSTIER) Pipe 7 Interrupt Enable Mask */ -#define HSTIER_PEP_8_Pos 16 /**< (HSTIER) Pipe 8 Interrupt Enable Position */ -#define HSTIER_PEP_8 (_U_(0x1) << HSTIER_PEP_8_Pos) /**< (HSTIER) Pipe 8 Interrupt Enable Mask */ -#define HSTIER_PEP_9_Pos 17 /**< (HSTIER) Pipe 9 Interrupt Enable Position */ -#define HSTIER_PEP_9 (_U_(0x1) << HSTIER_PEP_9_Pos) /**< (HSTIER) Pipe 9 Interrupt Enable Mask */ -#define HSTIER_DMA_0_Pos 25 /**< (HSTIER) DMA Channel 0 Interrupt Enable Position */ -#define HSTIER_DMA_0 (_U_(0x1) << HSTIER_DMA_0_Pos) /**< (HSTIER) DMA Channel 0 Interrupt Enable Mask */ -#define HSTIER_DMA_1_Pos 26 /**< (HSTIER) DMA Channel 1 Interrupt Enable Position */ -#define HSTIER_DMA_1 (_U_(0x1) << HSTIER_DMA_1_Pos) /**< (HSTIER) DMA Channel 1 Interrupt Enable Mask */ -#define HSTIER_DMA_2_Pos 27 /**< (HSTIER) DMA Channel 2 Interrupt Enable Position */ -#define HSTIER_DMA_2 (_U_(0x1) << HSTIER_DMA_2_Pos) /**< (HSTIER) DMA Channel 2 Interrupt Enable Mask */ -#define HSTIER_DMA_3_Pos 28 /**< (HSTIER) DMA Channel 3 Interrupt Enable Position */ -#define HSTIER_DMA_3 (_U_(0x1) << HSTIER_DMA_3_Pos) /**< (HSTIER) DMA Channel 3 Interrupt Enable Mask */ -#define HSTIER_DMA_4_Pos 29 /**< (HSTIER) DMA Channel 4 Interrupt Enable Position */ -#define HSTIER_DMA_4 (_U_(0x1) << HSTIER_DMA_4_Pos) /**< (HSTIER) DMA Channel 4 Interrupt Enable Mask */ -#define HSTIER_DMA_5_Pos 30 /**< (HSTIER) DMA Channel 5 Interrupt Enable Position */ -#define HSTIER_DMA_5 (_U_(0x1) << HSTIER_DMA_5_Pos) /**< (HSTIER) DMA Channel 5 Interrupt Enable Mask */ -#define HSTIER_DMA_6_Pos 31 /**< (HSTIER) DMA Channel 6 Interrupt Enable Position */ -#define HSTIER_DMA_6 (_U_(0x1) << HSTIER_DMA_6_Pos) /**< (HSTIER) DMA Channel 6 Interrupt Enable Mask */ -#define HSTIER_Msk _U_(0xFE03FF7F) /**< (HSTIER) Register Mask */ - -#define HSTIER_PEP__Pos 8 /**< (HSTIER Position) Pipe x Interrupt Enable */ -#define HSTIER_PEP_ (_U_(0x3FF) << HSTIER_PEP__Pos) /**< (HSTIER Mask) PEP_ */ -#define HSTIER_DMA__Pos 25 /**< (HSTIER Position) DMA Channel 6 Interrupt Enable */ -#define HSTIER_DMA_ (_U_(0x7F) << HSTIER_DMA__Pos) /**< (HSTIER Mask) DMA_ */ - -/* -------- HSTPIP : (USBHS Offset: 0x41c) (R/W 32) Host Pipe Register -------- */ - -#define HSTPIP_OFFSET (0x41C) /**< (HSTPIP) Host Pipe Register Offset */ - -#define HSTPIP_PEN0_Pos 0 /**< (HSTPIP) Pipe 0 Enable Position */ -#define HSTPIP_PEN0 (_U_(0x1) << HSTPIP_PEN0_Pos) /**< (HSTPIP) Pipe 0 Enable Mask */ -#define HSTPIP_PEN1_Pos 1 /**< (HSTPIP) Pipe 1 Enable Position */ -#define HSTPIP_PEN1 (_U_(0x1) << HSTPIP_PEN1_Pos) /**< (HSTPIP) Pipe 1 Enable Mask */ -#define HSTPIP_PEN2_Pos 2 /**< (HSTPIP) Pipe 2 Enable Position */ -#define HSTPIP_PEN2 (_U_(0x1) << HSTPIP_PEN2_Pos) /**< (HSTPIP) Pipe 2 Enable Mask */ -#define HSTPIP_PEN3_Pos 3 /**< (HSTPIP) Pipe 3 Enable Position */ -#define HSTPIP_PEN3 (_U_(0x1) << HSTPIP_PEN3_Pos) /**< (HSTPIP) Pipe 3 Enable Mask */ -#define HSTPIP_PEN4_Pos 4 /**< (HSTPIP) Pipe 4 Enable Position */ -#define HSTPIP_PEN4 (_U_(0x1) << HSTPIP_PEN4_Pos) /**< (HSTPIP) Pipe 4 Enable Mask */ -#define HSTPIP_PEN5_Pos 5 /**< (HSTPIP) Pipe 5 Enable Position */ -#define HSTPIP_PEN5 (_U_(0x1) << HSTPIP_PEN5_Pos) /**< (HSTPIP) Pipe 5 Enable Mask */ -#define HSTPIP_PEN6_Pos 6 /**< (HSTPIP) Pipe 6 Enable Position */ -#define HSTPIP_PEN6 (_U_(0x1) << HSTPIP_PEN6_Pos) /**< (HSTPIP) Pipe 6 Enable Mask */ -#define HSTPIP_PEN7_Pos 7 /**< (HSTPIP) Pipe 7 Enable Position */ -#define HSTPIP_PEN7 (_U_(0x1) << HSTPIP_PEN7_Pos) /**< (HSTPIP) Pipe 7 Enable Mask */ -#define HSTPIP_PEN8_Pos 8 /**< (HSTPIP) Pipe 8 Enable Position */ -#define HSTPIP_PEN8 (_U_(0x1) << HSTPIP_PEN8_Pos) /**< (HSTPIP) Pipe 8 Enable Mask */ -#define HSTPIP_PRST0_Pos 16 /**< (HSTPIP) Pipe 0 Reset Position */ -#define HSTPIP_PRST0 (_U_(0x1) << HSTPIP_PRST0_Pos) /**< (HSTPIP) Pipe 0 Reset Mask */ -#define HSTPIP_PRST1_Pos 17 /**< (HSTPIP) Pipe 1 Reset Position */ -#define HSTPIP_PRST1 (_U_(0x1) << HSTPIP_PRST1_Pos) /**< (HSTPIP) Pipe 1 Reset Mask */ -#define HSTPIP_PRST2_Pos 18 /**< (HSTPIP) Pipe 2 Reset Position */ -#define HSTPIP_PRST2 (_U_(0x1) << HSTPIP_PRST2_Pos) /**< (HSTPIP) Pipe 2 Reset Mask */ -#define HSTPIP_PRST3_Pos 19 /**< (HSTPIP) Pipe 3 Reset Position */ -#define HSTPIP_PRST3 (_U_(0x1) << HSTPIP_PRST3_Pos) /**< (HSTPIP) Pipe 3 Reset Mask */ -#define HSTPIP_PRST4_Pos 20 /**< (HSTPIP) Pipe 4 Reset Position */ -#define HSTPIP_PRST4 (_U_(0x1) << HSTPIP_PRST4_Pos) /**< (HSTPIP) Pipe 4 Reset Mask */ -#define HSTPIP_PRST5_Pos 21 /**< (HSTPIP) Pipe 5 Reset Position */ -#define HSTPIP_PRST5 (_U_(0x1) << HSTPIP_PRST5_Pos) /**< (HSTPIP) Pipe 5 Reset Mask */ -#define HSTPIP_PRST6_Pos 22 /**< (HSTPIP) Pipe 6 Reset Position */ -#define HSTPIP_PRST6 (_U_(0x1) << HSTPIP_PRST6_Pos) /**< (HSTPIP) Pipe 6 Reset Mask */ -#define HSTPIP_PRST7_Pos 23 /**< (HSTPIP) Pipe 7 Reset Position */ -#define HSTPIP_PRST7 (_U_(0x1) << HSTPIP_PRST7_Pos) /**< (HSTPIP) Pipe 7 Reset Mask */ -#define HSTPIP_PRST8_Pos 24 /**< (HSTPIP) Pipe 8 Reset Position */ -#define HSTPIP_PRST8 (_U_(0x1) << HSTPIP_PRST8_Pos) /**< (HSTPIP) Pipe 8 Reset Mask */ -#define HSTPIP_Msk _U_(0x1FF01FF) /**< (HSTPIP) Register Mask */ - -#define HSTPIP_PEN_Pos 0 /**< (HSTPIP Position) Pipe x Enable */ -#define HSTPIP_PEN (_U_(0x1FF) << HSTPIP_PEN_Pos) /**< (HSTPIP Mask) PEN */ -#define HSTPIP_PRST_Pos 16 /**< (HSTPIP Position) Pipe 8 Reset */ -#define HSTPIP_PRST (_U_(0x1FF) << HSTPIP_PRST_Pos) /**< (HSTPIP Mask) PRST */ - -/* -------- HSTFNUM : (USBHS Offset: 0x420) (R/W 32) Host Frame Number Register -------- */ - -#define HSTFNUM_OFFSET (0x420) /**< (HSTFNUM) Host Frame Number Register Offset */ - -#define HSTFNUM_MFNUM_Pos 0 /**< (HSTFNUM) Micro Frame Number Position */ -#define HSTFNUM_MFNUM (_U_(0x7) << HSTFNUM_MFNUM_Pos) /**< (HSTFNUM) Micro Frame Number Mask */ -#define HSTFNUM_FNUM_Pos 3 /**< (HSTFNUM) Frame Number Position */ -#define HSTFNUM_FNUM (_U_(0x7FF) << HSTFNUM_FNUM_Pos) /**< (HSTFNUM) Frame Number Mask */ -#define HSTFNUM_FLENHIGH_Pos 16 /**< (HSTFNUM) Frame Length Position */ -#define HSTFNUM_FLENHIGH (_U_(0xFF) << HSTFNUM_FLENHIGH_Pos) /**< (HSTFNUM) Frame Length Mask */ -#define HSTFNUM_Msk _U_(0xFF3FFF) /**< (HSTFNUM) Register Mask */ - - -/* -------- HSTADDR1 : (USBHS Offset: 0x424) (R/W 32) Host Address 1 Register -------- */ - -#define HSTADDR1_OFFSET (0x424) /**< (HSTADDR1) Host Address 1 Register Offset */ - -#define HSTADDR1_HSTADDRP0_Pos 0 /**< (HSTADDR1) USB Host Address Position */ -#define HSTADDR1_HSTADDRP0 (_U_(0x7F) << HSTADDR1_HSTADDRP0_Pos) /**< (HSTADDR1) USB Host Address Mask */ -#define HSTADDR1_HSTADDRP1_Pos 8 /**< (HSTADDR1) USB Host Address Position */ -#define HSTADDR1_HSTADDRP1 (_U_(0x7F) << HSTADDR1_HSTADDRP1_Pos) /**< (HSTADDR1) USB Host Address Mask */ -#define HSTADDR1_HSTADDRP2_Pos 16 /**< (HSTADDR1) USB Host Address Position */ -#define HSTADDR1_HSTADDRP2 (_U_(0x7F) << HSTADDR1_HSTADDRP2_Pos) /**< (HSTADDR1) USB Host Address Mask */ -#define HSTADDR1_HSTADDRP3_Pos 24 /**< (HSTADDR1) USB Host Address Position */ -#define HSTADDR1_HSTADDRP3 (_U_(0x7F) << HSTADDR1_HSTADDRP3_Pos) /**< (HSTADDR1) USB Host Address Mask */ -#define HSTADDR1_Msk _U_(0x7F7F7F7F) /**< (HSTADDR1) Register Mask */ - - -/* -------- HSTADDR2 : (USBHS Offset: 0x428) (R/W 32) Host Address 2 Register -------- */ - -#define HSTADDR2_OFFSET (0x428) /**< (HSTADDR2) Host Address 2 Register Offset */ - -#define HSTADDR2_HSTADDRP4_Pos 0 /**< (HSTADDR2) USB Host Address Position */ -#define HSTADDR2_HSTADDRP4 (_U_(0x7F) << HSTADDR2_HSTADDRP4_Pos) /**< (HSTADDR2) USB Host Address Mask */ -#define HSTADDR2_HSTADDRP5_Pos 8 /**< (HSTADDR2) USB Host Address Position */ -#define HSTADDR2_HSTADDRP5 (_U_(0x7F) << HSTADDR2_HSTADDRP5_Pos) /**< (HSTADDR2) USB Host Address Mask */ -#define HSTADDR2_HSTADDRP6_Pos 16 /**< (HSTADDR2) USB Host Address Position */ -#define HSTADDR2_HSTADDRP6 (_U_(0x7F) << HSTADDR2_HSTADDRP6_Pos) /**< (HSTADDR2) USB Host Address Mask */ -#define HSTADDR2_HSTADDRP7_Pos 24 /**< (HSTADDR2) USB Host Address Position */ -#define HSTADDR2_HSTADDRP7 (_U_(0x7F) << HSTADDR2_HSTADDRP7_Pos) /**< (HSTADDR2) USB Host Address Mask */ -#define HSTADDR2_Msk _U_(0x7F7F7F7F) /**< (HSTADDR2) Register Mask */ - - -/* -------- HSTADDR3 : (USBHS Offset: 0x42c) (R/W 32) Host Address 3 Register -------- */ - -#define HSTADDR3_OFFSET (0x42C) /**< (HSTADDR3) Host Address 3 Register Offset */ - -#define HSTADDR3_HSTADDRP8_Pos 0 /**< (HSTADDR3) USB Host Address Position */ -#define HSTADDR3_HSTADDRP8 (_U_(0x7F) << HSTADDR3_HSTADDRP8_Pos) /**< (HSTADDR3) USB Host Address Mask */ -#define HSTADDR3_HSTADDRP9_Pos 8 /**< (HSTADDR3) USB Host Address Position */ -#define HSTADDR3_HSTADDRP9 (_U_(0x7F) << HSTADDR3_HSTADDRP9_Pos) /**< (HSTADDR3) USB Host Address Mask */ -#define HSTADDR3_Msk _U_(0x7F7F) /**< (HSTADDR3) Register Mask */ - - -/* -------- HSTPIPCFG : (USBHS Offset: 0x500) (R/W 32) Host Pipe Configuration Register -------- */ - -#define HSTPIPCFG_OFFSET (0x500) /**< (HSTPIPCFG) Host Pipe Configuration Register Offset */ - -#define HSTPIPCFG_ALLOC_Pos 1 /**< (HSTPIPCFG) Pipe Memory Allocate Position */ -#define HSTPIPCFG_ALLOC (_U_(0x1) << HSTPIPCFG_ALLOC_Pos) /**< (HSTPIPCFG) Pipe Memory Allocate Mask */ -#define HSTPIPCFG_PBK_Pos 2 /**< (HSTPIPCFG) Pipe Banks Position */ -#define HSTPIPCFG_PBK (_U_(0x3) << HSTPIPCFG_PBK_Pos) /**< (HSTPIPCFG) Pipe Banks Mask */ -#define HSTPIPCFG_PBK_1_BANK_Val _U_(0x0) /**< (HSTPIPCFG) Single-bank pipe */ -#define HSTPIPCFG_PBK_2_BANK_Val _U_(0x1) /**< (HSTPIPCFG) Double-bank pipe */ -#define HSTPIPCFG_PBK_3_BANK_Val _U_(0x2) /**< (HSTPIPCFG) Triple-bank pipe */ -#define HSTPIPCFG_PBK_1_BANK (HSTPIPCFG_PBK_1_BANK_Val << HSTPIPCFG_PBK_Pos) /**< (HSTPIPCFG) Single-bank pipe Position */ -#define HSTPIPCFG_PBK_2_BANK (HSTPIPCFG_PBK_2_BANK_Val << HSTPIPCFG_PBK_Pos) /**< (HSTPIPCFG) Double-bank pipe Position */ -#define HSTPIPCFG_PBK_3_BANK (HSTPIPCFG_PBK_3_BANK_Val << HSTPIPCFG_PBK_Pos) /**< (HSTPIPCFG) Triple-bank pipe Position */ -#define HSTPIPCFG_PSIZE_Pos 4 /**< (HSTPIPCFG) Pipe Size Position */ -#define HSTPIPCFG_PSIZE (_U_(0x7) << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) Pipe Size Mask */ -#define HSTPIPCFG_PSIZE_8_BYTE_Val _U_(0x0) /**< (HSTPIPCFG) 8 bytes */ -#define HSTPIPCFG_PSIZE_16_BYTE_Val _U_(0x1) /**< (HSTPIPCFG) 16 bytes */ -#define HSTPIPCFG_PSIZE_32_BYTE_Val _U_(0x2) /**< (HSTPIPCFG) 32 bytes */ -#define HSTPIPCFG_PSIZE_64_BYTE_Val _U_(0x3) /**< (HSTPIPCFG) 64 bytes */ -#define HSTPIPCFG_PSIZE_128_BYTE_Val _U_(0x4) /**< (HSTPIPCFG) 128 bytes */ -#define HSTPIPCFG_PSIZE_256_BYTE_Val _U_(0x5) /**< (HSTPIPCFG) 256 bytes */ -#define HSTPIPCFG_PSIZE_512_BYTE_Val _U_(0x6) /**< (HSTPIPCFG) 512 bytes */ -#define HSTPIPCFG_PSIZE_1024_BYTE_Val _U_(0x7) /**< (HSTPIPCFG) 1024 bytes */ -#define HSTPIPCFG_PSIZE_8_BYTE (HSTPIPCFG_PSIZE_8_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 8 bytes Position */ -#define HSTPIPCFG_PSIZE_16_BYTE (HSTPIPCFG_PSIZE_16_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 16 bytes Position */ -#define HSTPIPCFG_PSIZE_32_BYTE (HSTPIPCFG_PSIZE_32_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 32 bytes Position */ -#define HSTPIPCFG_PSIZE_64_BYTE (HSTPIPCFG_PSIZE_64_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 64 bytes Position */ -#define HSTPIPCFG_PSIZE_128_BYTE (HSTPIPCFG_PSIZE_128_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 128 bytes Position */ -#define HSTPIPCFG_PSIZE_256_BYTE (HSTPIPCFG_PSIZE_256_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 256 bytes Position */ -#define HSTPIPCFG_PSIZE_512_BYTE (HSTPIPCFG_PSIZE_512_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 512 bytes Position */ -#define HSTPIPCFG_PSIZE_1024_BYTE (HSTPIPCFG_PSIZE_1024_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 1024 bytes Position */ -#define HSTPIPCFG_PTOKEN_Pos 8 /**< (HSTPIPCFG) Pipe Token Position */ -#define HSTPIPCFG_PTOKEN (_U_(0x3) << HSTPIPCFG_PTOKEN_Pos) /**< (HSTPIPCFG) Pipe Token Mask */ -#define HSTPIPCFG_PTOKEN_SETUP_Val _U_(0x0) /**< (HSTPIPCFG) SETUP */ -#define HSTPIPCFG_PTOKEN_IN_Val _U_(0x1) /**< (HSTPIPCFG) IN */ -#define HSTPIPCFG_PTOKEN_OUT_Val _U_(0x2) /**< (HSTPIPCFG) OUT */ -#define HSTPIPCFG_PTOKEN_SETUP (HSTPIPCFG_PTOKEN_SETUP_Val << HSTPIPCFG_PTOKEN_Pos) /**< (HSTPIPCFG) SETUP Position */ -#define HSTPIPCFG_PTOKEN_IN (HSTPIPCFG_PTOKEN_IN_Val << HSTPIPCFG_PTOKEN_Pos) /**< (HSTPIPCFG) IN Position */ -#define HSTPIPCFG_PTOKEN_OUT (HSTPIPCFG_PTOKEN_OUT_Val << HSTPIPCFG_PTOKEN_Pos) /**< (HSTPIPCFG) OUT Position */ -#define HSTPIPCFG_AUTOSW_Pos 10 /**< (HSTPIPCFG) Automatic Switch Position */ -#define HSTPIPCFG_AUTOSW (_U_(0x1) << HSTPIPCFG_AUTOSW_Pos) /**< (HSTPIPCFG) Automatic Switch Mask */ -#define HSTPIPCFG_PTYPE_Pos 12 /**< (HSTPIPCFG) Pipe Type Position */ -#define HSTPIPCFG_PTYPE (_U_(0x3) << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Pipe Type Mask */ -#define HSTPIPCFG_PTYPE_CTRL_Val _U_(0x0) /**< (HSTPIPCFG) Control */ -#define HSTPIPCFG_PTYPE_ISO_Val _U_(0x1) /**< (HSTPIPCFG) Isochronous */ -#define HSTPIPCFG_PTYPE_BLK_Val _U_(0x2) /**< (HSTPIPCFG) Bulk */ -#define HSTPIPCFG_PTYPE_INTRPT_Val _U_(0x3) /**< (HSTPIPCFG) Interrupt */ -#define HSTPIPCFG_PTYPE_CTRL (HSTPIPCFG_PTYPE_CTRL_Val << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Control Position */ -#define HSTPIPCFG_PTYPE_ISO (HSTPIPCFG_PTYPE_ISO_Val << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Isochronous Position */ -#define HSTPIPCFG_PTYPE_BLK (HSTPIPCFG_PTYPE_BLK_Val << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Bulk Position */ -#define HSTPIPCFG_PTYPE_INTRPT (HSTPIPCFG_PTYPE_INTRPT_Val << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Interrupt Position */ -#define HSTPIPCFG_PEPNUM_Pos 16 /**< (HSTPIPCFG) Pipe Endpoint Number Position */ -#define HSTPIPCFG_PEPNUM (_U_(0xF) << HSTPIPCFG_PEPNUM_Pos) /**< (HSTPIPCFG) Pipe Endpoint Number Mask */ -#define HSTPIPCFG_INTFRQ_Pos 24 /**< (HSTPIPCFG) Pipe Interrupt Request Frequency Position */ -#define HSTPIPCFG_INTFRQ (_U_(0xFF) << HSTPIPCFG_INTFRQ_Pos) /**< (HSTPIPCFG) Pipe Interrupt Request Frequency Mask */ -#define HSTPIPCFG_Msk _U_(0xFF0F377E) /**< (HSTPIPCFG) Register Mask */ - -/* CTRL_BULK mode */ -#define HSTPIPCFG_CTRL_BULK_PINGEN_Pos 20 /**< (HSTPIPCFG) Ping Enable Position */ -#define HSTPIPCFG_CTRL_BULK_PINGEN (_U_(0x1) << HSTPIPCFG_CTRL_BULK_PINGEN_Pos) /**< (HSTPIPCFG) Ping Enable Mask */ -#define HSTPIPCFG_CTRL_BULK_BINTERVAL_Pos 24 /**< (HSTPIPCFG) bInterval Parameter for the Bulk-Out/Ping Transaction Position */ -#define HSTPIPCFG_CTRL_BULK_BINTERVAL (_U_(0xFF) << HSTPIPCFG_CTRL_BULK_BINTERVAL_Pos) /**< (HSTPIPCFG) bInterval Parameter for the Bulk-Out/Ping Transaction Mask */ -#define HSTPIPCFG_CTRL_BULK_Msk _U_(0xFF100000) /**< (HSTPIPCFG_CTRL_BULK) Register Mask */ - - -/* -------- HSTPIPISR : (USBHS Offset: 0x530) (R/ 32) Host Pipe Status Register -------- */ - -#define HSTPIPISR_OFFSET (0x530) /**< (HSTPIPISR) Host Pipe Status Register Offset */ - -#define HSTPIPISR_RXINI_Pos 0 /**< (HSTPIPISR) Received IN Data Interrupt Position */ -#define HSTPIPISR_RXINI (_U_(0x1) << HSTPIPISR_RXINI_Pos) /**< (HSTPIPISR) Received IN Data Interrupt Mask */ -#define HSTPIPISR_TXOUTI_Pos 1 /**< (HSTPIPISR) Transmitted OUT Data Interrupt Position */ -#define HSTPIPISR_TXOUTI (_U_(0x1) << HSTPIPISR_TXOUTI_Pos) /**< (HSTPIPISR) Transmitted OUT Data Interrupt Mask */ -#define HSTPIPISR_PERRI_Pos 3 /**< (HSTPIPISR) Pipe Error Interrupt Position */ -#define HSTPIPISR_PERRI (_U_(0x1) << HSTPIPISR_PERRI_Pos) /**< (HSTPIPISR) Pipe Error Interrupt Mask */ -#define HSTPIPISR_NAKEDI_Pos 4 /**< (HSTPIPISR) NAKed Interrupt Position */ -#define HSTPIPISR_NAKEDI (_U_(0x1) << HSTPIPISR_NAKEDI_Pos) /**< (HSTPIPISR) NAKed Interrupt Mask */ -#define HSTPIPISR_OVERFI_Pos 5 /**< (HSTPIPISR) Overflow Interrupt Position */ -#define HSTPIPISR_OVERFI (_U_(0x1) << HSTPIPISR_OVERFI_Pos) /**< (HSTPIPISR) Overflow Interrupt Mask */ -#define HSTPIPISR_SHORTPACKETI_Pos 7 /**< (HSTPIPISR) Short Packet Interrupt Position */ -#define HSTPIPISR_SHORTPACKETI (_U_(0x1) << HSTPIPISR_SHORTPACKETI_Pos) /**< (HSTPIPISR) Short Packet Interrupt Mask */ -#define HSTPIPISR_DTSEQ_Pos 8 /**< (HSTPIPISR) Data Toggle Sequence Position */ -#define HSTPIPISR_DTSEQ (_U_(0x3) << HSTPIPISR_DTSEQ_Pos) /**< (HSTPIPISR) Data Toggle Sequence Mask */ -#define HSTPIPISR_DTSEQ_DATA0_Val _U_(0x0) /**< (HSTPIPISR) Data0 toggle sequence */ -#define HSTPIPISR_DTSEQ_DATA1_Val _U_(0x1) /**< (HSTPIPISR) Data1 toggle sequence */ -#define HSTPIPISR_DTSEQ_DATA0 (HSTPIPISR_DTSEQ_DATA0_Val << HSTPIPISR_DTSEQ_Pos) /**< (HSTPIPISR) Data0 toggle sequence Position */ -#define HSTPIPISR_DTSEQ_DATA1 (HSTPIPISR_DTSEQ_DATA1_Val << HSTPIPISR_DTSEQ_Pos) /**< (HSTPIPISR) Data1 toggle sequence Position */ -#define HSTPIPISR_NBUSYBK_Pos 12 /**< (HSTPIPISR) Number of Busy Banks Position */ -#define HSTPIPISR_NBUSYBK (_U_(0x3) << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) Number of Busy Banks Mask */ -#define HSTPIPISR_NBUSYBK_0_BUSY_Val _U_(0x0) /**< (HSTPIPISR) 0 busy bank (all banks free) */ -#define HSTPIPISR_NBUSYBK_1_BUSY_Val _U_(0x1) /**< (HSTPIPISR) 1 busy bank */ -#define HSTPIPISR_NBUSYBK_2_BUSY_Val _U_(0x2) /**< (HSTPIPISR) 2 busy banks */ -#define HSTPIPISR_NBUSYBK_3_BUSY_Val _U_(0x3) /**< (HSTPIPISR) 3 busy banks */ -#define HSTPIPISR_NBUSYBK_0_BUSY (HSTPIPISR_NBUSYBK_0_BUSY_Val << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) 0 busy bank (all banks free) Position */ -#define HSTPIPISR_NBUSYBK_1_BUSY (HSTPIPISR_NBUSYBK_1_BUSY_Val << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) 1 busy bank Position */ -#define HSTPIPISR_NBUSYBK_2_BUSY (HSTPIPISR_NBUSYBK_2_BUSY_Val << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) 2 busy banks Position */ -#define HSTPIPISR_NBUSYBK_3_BUSY (HSTPIPISR_NBUSYBK_3_BUSY_Val << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) 3 busy banks Position */ -#define HSTPIPISR_CURRBK_Pos 14 /**< (HSTPIPISR) Current Bank Position */ -#define HSTPIPISR_CURRBK (_U_(0x3) << HSTPIPISR_CURRBK_Pos) /**< (HSTPIPISR) Current Bank Mask */ -#define HSTPIPISR_CURRBK_BANK0_Val _U_(0x0) /**< (HSTPIPISR) Current bank is bank0 */ -#define HSTPIPISR_CURRBK_BANK1_Val _U_(0x1) /**< (HSTPIPISR) Current bank is bank1 */ -#define HSTPIPISR_CURRBK_BANK2_Val _U_(0x2) /**< (HSTPIPISR) Current bank is bank2 */ -#define HSTPIPISR_CURRBK_BANK0 (HSTPIPISR_CURRBK_BANK0_Val << HSTPIPISR_CURRBK_Pos) /**< (HSTPIPISR) Current bank is bank0 Position */ -#define HSTPIPISR_CURRBK_BANK1 (HSTPIPISR_CURRBK_BANK1_Val << HSTPIPISR_CURRBK_Pos) /**< (HSTPIPISR) Current bank is bank1 Position */ -#define HSTPIPISR_CURRBK_BANK2 (HSTPIPISR_CURRBK_BANK2_Val << HSTPIPISR_CURRBK_Pos) /**< (HSTPIPISR) Current bank is bank2 Position */ -#define HSTPIPISR_RWALL_Pos 16 /**< (HSTPIPISR) Read/Write Allowed Position */ -#define HSTPIPISR_RWALL (_U_(0x1) << HSTPIPISR_RWALL_Pos) /**< (HSTPIPISR) Read/Write Allowed Mask */ -#define HSTPIPISR_CFGOK_Pos 18 /**< (HSTPIPISR) Configuration OK Status Position */ -#define HSTPIPISR_CFGOK (_U_(0x1) << HSTPIPISR_CFGOK_Pos) /**< (HSTPIPISR) Configuration OK Status Mask */ -#define HSTPIPISR_PBYCT_Pos 20 /**< (HSTPIPISR) Pipe Byte Count Position */ -#define HSTPIPISR_PBYCT (_U_(0x7FF) << HSTPIPISR_PBYCT_Pos) /**< (HSTPIPISR) Pipe Byte Count Mask */ -#define HSTPIPISR_Msk _U_(0x7FF5F3BB) /**< (HSTPIPISR) Register Mask */ - -/* CTRL mode */ -#define HSTPIPISR_CTRL_TXSTPI_Pos 2 /**< (HSTPIPISR) Transmitted SETUP Interrupt Position */ -#define HSTPIPISR_CTRL_TXSTPI (_U_(0x1) << HSTPIPISR_CTRL_TXSTPI_Pos) /**< (HSTPIPISR) Transmitted SETUP Interrupt Mask */ -#define HSTPIPISR_CTRL_RXSTALLDI_Pos 6 /**< (HSTPIPISR) Received STALLed Interrupt Position */ -#define HSTPIPISR_CTRL_RXSTALLDI (_U_(0x1) << HSTPIPISR_CTRL_RXSTALLDI_Pos) /**< (HSTPIPISR) Received STALLed Interrupt Mask */ -#define HSTPIPISR_CTRL_Msk _U_(0x44) /**< (HSTPIPISR_CTRL) Register Mask */ - -/* ISO mode */ -#define HSTPIPISR_ISO_UNDERFI_Pos 2 /**< (HSTPIPISR) Underflow Interrupt Position */ -#define HSTPIPISR_ISO_UNDERFI (_U_(0x1) << HSTPIPISR_ISO_UNDERFI_Pos) /**< (HSTPIPISR) Underflow Interrupt Mask */ -#define HSTPIPISR_ISO_CRCERRI_Pos 6 /**< (HSTPIPISR) CRC Error Interrupt Position */ -#define HSTPIPISR_ISO_CRCERRI (_U_(0x1) << HSTPIPISR_ISO_CRCERRI_Pos) /**< (HSTPIPISR) CRC Error Interrupt Mask */ -#define HSTPIPISR_ISO_Msk _U_(0x44) /**< (HSTPIPISR_ISO) Register Mask */ - -/* BLK mode */ -#define HSTPIPISR_BLK_TXSTPI_Pos 2 /**< (HSTPIPISR) Transmitted SETUP Interrupt Position */ -#define HSTPIPISR_BLK_TXSTPI (_U_(0x1) << HSTPIPISR_BLK_TXSTPI_Pos) /**< (HSTPIPISR) Transmitted SETUP Interrupt Mask */ -#define HSTPIPISR_BLK_RXSTALLDI_Pos 6 /**< (HSTPIPISR) Received STALLed Interrupt Position */ -#define HSTPIPISR_BLK_RXSTALLDI (_U_(0x1) << HSTPIPISR_BLK_RXSTALLDI_Pos) /**< (HSTPIPISR) Received STALLed Interrupt Mask */ -#define HSTPIPISR_BLK_Msk _U_(0x44) /**< (HSTPIPISR_BLK) Register Mask */ - -/* INTRPT mode */ -#define HSTPIPISR_INTRPT_UNDERFI_Pos 2 /**< (HSTPIPISR) Underflow Interrupt Position */ -#define HSTPIPISR_INTRPT_UNDERFI (_U_(0x1) << HSTPIPISR_INTRPT_UNDERFI_Pos) /**< (HSTPIPISR) Underflow Interrupt Mask */ -#define HSTPIPISR_INTRPT_RXSTALLDI_Pos 6 /**< (HSTPIPISR) Received STALLed Interrupt Position */ -#define HSTPIPISR_INTRPT_RXSTALLDI (_U_(0x1) << HSTPIPISR_INTRPT_RXSTALLDI_Pos) /**< (HSTPIPISR) Received STALLed Interrupt Mask */ -#define HSTPIPISR_INTRPT_Msk _U_(0x44) /**< (HSTPIPISR_INTRPT) Register Mask */ - - -/* -------- HSTPIPICR : (USBHS Offset: 0x560) (/W 32) Host Pipe Clear Register -------- */ - -#define HSTPIPICR_OFFSET (0x560) /**< (HSTPIPICR) Host Pipe Clear Register Offset */ - -#define HSTPIPICR_RXINIC_Pos 0 /**< (HSTPIPICR) Received IN Data Interrupt Clear Position */ -#define HSTPIPICR_RXINIC (_U_(0x1) << HSTPIPICR_RXINIC_Pos) /**< (HSTPIPICR) Received IN Data Interrupt Clear Mask */ -#define HSTPIPICR_TXOUTIC_Pos 1 /**< (HSTPIPICR) Transmitted OUT Data Interrupt Clear Position */ -#define HSTPIPICR_TXOUTIC (_U_(0x1) << HSTPIPICR_TXOUTIC_Pos) /**< (HSTPIPICR) Transmitted OUT Data Interrupt Clear Mask */ -#define HSTPIPICR_NAKEDIC_Pos 4 /**< (HSTPIPICR) NAKed Interrupt Clear Position */ -#define HSTPIPICR_NAKEDIC (_U_(0x1) << HSTPIPICR_NAKEDIC_Pos) /**< (HSTPIPICR) NAKed Interrupt Clear Mask */ -#define HSTPIPICR_OVERFIC_Pos 5 /**< (HSTPIPICR) Overflow Interrupt Clear Position */ -#define HSTPIPICR_OVERFIC (_U_(0x1) << HSTPIPICR_OVERFIC_Pos) /**< (HSTPIPICR) Overflow Interrupt Clear Mask */ -#define HSTPIPICR_SHORTPACKETIC_Pos 7 /**< (HSTPIPICR) Short Packet Interrupt Clear Position */ -#define HSTPIPICR_SHORTPACKETIC (_U_(0x1) << HSTPIPICR_SHORTPACKETIC_Pos) /**< (HSTPIPICR) Short Packet Interrupt Clear Mask */ -#define HSTPIPICR_Msk _U_(0xB3) /**< (HSTPIPICR) Register Mask */ - -/* CTRL mode */ -#define HSTPIPICR_CTRL_TXSTPIC_Pos 2 /**< (HSTPIPICR) Transmitted SETUP Interrupt Clear Position */ -#define HSTPIPICR_CTRL_TXSTPIC (_U_(0x1) << HSTPIPICR_CTRL_TXSTPIC_Pos) /**< (HSTPIPICR) Transmitted SETUP Interrupt Clear Mask */ -#define HSTPIPICR_CTRL_RXSTALLDIC_Pos 6 /**< (HSTPIPICR) Received STALLed Interrupt Clear Position */ -#define HSTPIPICR_CTRL_RXSTALLDIC (_U_(0x1) << HSTPIPICR_CTRL_RXSTALLDIC_Pos) /**< (HSTPIPICR) Received STALLed Interrupt Clear Mask */ -#define HSTPIPICR_CTRL_Msk _U_(0x44) /**< (HSTPIPICR_CTRL) Register Mask */ - -/* ISO mode */ -#define HSTPIPICR_ISO_UNDERFIC_Pos 2 /**< (HSTPIPICR) Underflow Interrupt Clear Position */ -#define HSTPIPICR_ISO_UNDERFIC (_U_(0x1) << HSTPIPICR_ISO_UNDERFIC_Pos) /**< (HSTPIPICR) Underflow Interrupt Clear Mask */ -#define HSTPIPICR_ISO_CRCERRIC_Pos 6 /**< (HSTPIPICR) CRC Error Interrupt Clear Position */ -#define HSTPIPICR_ISO_CRCERRIC (_U_(0x1) << HSTPIPICR_ISO_CRCERRIC_Pos) /**< (HSTPIPICR) CRC Error Interrupt Clear Mask */ -#define HSTPIPICR_ISO_Msk _U_(0x44) /**< (HSTPIPICR_ISO) Register Mask */ - -/* BLK mode */ -#define HSTPIPICR_BLK_TXSTPIC_Pos 2 /**< (HSTPIPICR) Transmitted SETUP Interrupt Clear Position */ -#define HSTPIPICR_BLK_TXSTPIC (_U_(0x1) << HSTPIPICR_BLK_TXSTPIC_Pos) /**< (HSTPIPICR) Transmitted SETUP Interrupt Clear Mask */ -#define HSTPIPICR_BLK_RXSTALLDIC_Pos 6 /**< (HSTPIPICR) Received STALLed Interrupt Clear Position */ -#define HSTPIPICR_BLK_RXSTALLDIC (_U_(0x1) << HSTPIPICR_BLK_RXSTALLDIC_Pos) /**< (HSTPIPICR) Received STALLed Interrupt Clear Mask */ -#define HSTPIPICR_BLK_Msk _U_(0x44) /**< (HSTPIPICR_BLK) Register Mask */ - -/* INTRPT mode */ -#define HSTPIPICR_INTRPT_UNDERFIC_Pos 2 /**< (HSTPIPICR) Underflow Interrupt Clear Position */ -#define HSTPIPICR_INTRPT_UNDERFIC (_U_(0x1) << HSTPIPICR_INTRPT_UNDERFIC_Pos) /**< (HSTPIPICR) Underflow Interrupt Clear Mask */ -#define HSTPIPICR_INTRPT_RXSTALLDIC_Pos 6 /**< (HSTPIPICR) Received STALLed Interrupt Clear Position */ -#define HSTPIPICR_INTRPT_RXSTALLDIC (_U_(0x1) << HSTPIPICR_INTRPT_RXSTALLDIC_Pos) /**< (HSTPIPICR) Received STALLed Interrupt Clear Mask */ -#define HSTPIPICR_INTRPT_Msk _U_(0x44) /**< (HSTPIPICR_INTRPT) Register Mask */ - - -/* -------- HSTPIPIFR : (USBHS Offset: 0x590) (/W 32) Host Pipe Set Register -------- */ - -#define HSTPIPIFR_OFFSET (0x590) /**< (HSTPIPIFR) Host Pipe Set Register Offset */ - -#define HSTPIPIFR_RXINIS_Pos 0 /**< (HSTPIPIFR) Received IN Data Interrupt Set Position */ -#define HSTPIPIFR_RXINIS (_U_(0x1) << HSTPIPIFR_RXINIS_Pos) /**< (HSTPIPIFR) Received IN Data Interrupt Set Mask */ -#define HSTPIPIFR_TXOUTIS_Pos 1 /**< (HSTPIPIFR) Transmitted OUT Data Interrupt Set Position */ -#define HSTPIPIFR_TXOUTIS (_U_(0x1) << HSTPIPIFR_TXOUTIS_Pos) /**< (HSTPIPIFR) Transmitted OUT Data Interrupt Set Mask */ -#define HSTPIPIFR_PERRIS_Pos 3 /**< (HSTPIPIFR) Pipe Error Interrupt Set Position */ -#define HSTPIPIFR_PERRIS (_U_(0x1) << HSTPIPIFR_PERRIS_Pos) /**< (HSTPIPIFR) Pipe Error Interrupt Set Mask */ -#define HSTPIPIFR_NAKEDIS_Pos 4 /**< (HSTPIPIFR) NAKed Interrupt Set Position */ -#define HSTPIPIFR_NAKEDIS (_U_(0x1) << HSTPIPIFR_NAKEDIS_Pos) /**< (HSTPIPIFR) NAKed Interrupt Set Mask */ -#define HSTPIPIFR_OVERFIS_Pos 5 /**< (HSTPIPIFR) Overflow Interrupt Set Position */ -#define HSTPIPIFR_OVERFIS (_U_(0x1) << HSTPIPIFR_OVERFIS_Pos) /**< (HSTPIPIFR) Overflow Interrupt Set Mask */ -#define HSTPIPIFR_SHORTPACKETIS_Pos 7 /**< (HSTPIPIFR) Short Packet Interrupt Set Position */ -#define HSTPIPIFR_SHORTPACKETIS (_U_(0x1) << HSTPIPIFR_SHORTPACKETIS_Pos) /**< (HSTPIPIFR) Short Packet Interrupt Set Mask */ -#define HSTPIPIFR_NBUSYBKS_Pos 12 /**< (HSTPIPIFR) Number of Busy Banks Set Position */ -#define HSTPIPIFR_NBUSYBKS (_U_(0x1) << HSTPIPIFR_NBUSYBKS_Pos) /**< (HSTPIPIFR) Number of Busy Banks Set Mask */ -#define HSTPIPIFR_Msk _U_(0x10BB) /**< (HSTPIPIFR) Register Mask */ - -/* CTRL mode */ -#define HSTPIPIFR_CTRL_TXSTPIS_Pos 2 /**< (HSTPIPIFR) Transmitted SETUP Interrupt Set Position */ -#define HSTPIPIFR_CTRL_TXSTPIS (_U_(0x1) << HSTPIPIFR_CTRL_TXSTPIS_Pos) /**< (HSTPIPIFR) Transmitted SETUP Interrupt Set Mask */ -#define HSTPIPIFR_CTRL_RXSTALLDIS_Pos 6 /**< (HSTPIPIFR) Received STALLed Interrupt Set Position */ -#define HSTPIPIFR_CTRL_RXSTALLDIS (_U_(0x1) << HSTPIPIFR_CTRL_RXSTALLDIS_Pos) /**< (HSTPIPIFR) Received STALLed Interrupt Set Mask */ -#define HSTPIPIFR_CTRL_Msk _U_(0x44) /**< (HSTPIPIFR_CTRL) Register Mask */ - -/* ISO mode */ -#define HSTPIPIFR_ISO_UNDERFIS_Pos 2 /**< (HSTPIPIFR) Underflow Interrupt Set Position */ -#define HSTPIPIFR_ISO_UNDERFIS (_U_(0x1) << HSTPIPIFR_ISO_UNDERFIS_Pos) /**< (HSTPIPIFR) Underflow Interrupt Set Mask */ -#define HSTPIPIFR_ISO_CRCERRIS_Pos 6 /**< (HSTPIPIFR) CRC Error Interrupt Set Position */ -#define HSTPIPIFR_ISO_CRCERRIS (_U_(0x1) << HSTPIPIFR_ISO_CRCERRIS_Pos) /**< (HSTPIPIFR) CRC Error Interrupt Set Mask */ -#define HSTPIPIFR_ISO_Msk _U_(0x44) /**< (HSTPIPIFR_ISO) Register Mask */ - -/* BLK mode */ -#define HSTPIPIFR_BLK_TXSTPIS_Pos 2 /**< (HSTPIPIFR) Transmitted SETUP Interrupt Set Position */ -#define HSTPIPIFR_BLK_TXSTPIS (_U_(0x1) << HSTPIPIFR_BLK_TXSTPIS_Pos) /**< (HSTPIPIFR) Transmitted SETUP Interrupt Set Mask */ -#define HSTPIPIFR_BLK_RXSTALLDIS_Pos 6 /**< (HSTPIPIFR) Received STALLed Interrupt Set Position */ -#define HSTPIPIFR_BLK_RXSTALLDIS (_U_(0x1) << HSTPIPIFR_BLK_RXSTALLDIS_Pos) /**< (HSTPIPIFR) Received STALLed Interrupt Set Mask */ -#define HSTPIPIFR_BLK_Msk _U_(0x44) /**< (HSTPIPIFR_BLK) Register Mask */ - -/* INTRPT mode */ -#define HSTPIPIFR_INTRPT_UNDERFIS_Pos 2 /**< (HSTPIPIFR) Underflow Interrupt Set Position */ -#define HSTPIPIFR_INTRPT_UNDERFIS (_U_(0x1) << HSTPIPIFR_INTRPT_UNDERFIS_Pos) /**< (HSTPIPIFR) Underflow Interrupt Set Mask */ -#define HSTPIPIFR_INTRPT_RXSTALLDIS_Pos 6 /**< (HSTPIPIFR) Received STALLed Interrupt Set Position */ -#define HSTPIPIFR_INTRPT_RXSTALLDIS (_U_(0x1) << HSTPIPIFR_INTRPT_RXSTALLDIS_Pos) /**< (HSTPIPIFR) Received STALLed Interrupt Set Mask */ -#define HSTPIPIFR_INTRPT_Msk _U_(0x44) /**< (HSTPIPIFR_INTRPT) Register Mask */ - - -/* -------- HSTPIPIMR : (USBHS Offset: 0x5c0) (R/ 32) Host Pipe Mask Register -------- */ - -#define HSTPIPIMR_OFFSET (0x5C0) /**< (HSTPIPIMR) Host Pipe Mask Register Offset */ - -#define HSTPIPIMR_RXINE_Pos 0 /**< (HSTPIPIMR) Received IN Data Interrupt Enable Position */ -#define HSTPIPIMR_RXINE (_U_(0x1) << HSTPIPIMR_RXINE_Pos) /**< (HSTPIPIMR) Received IN Data Interrupt Enable Mask */ -#define HSTPIPIMR_TXOUTE_Pos 1 /**< (HSTPIPIMR) Transmitted OUT Data Interrupt Enable Position */ -#define HSTPIPIMR_TXOUTE (_U_(0x1) << HSTPIPIMR_TXOUTE_Pos) /**< (HSTPIPIMR) Transmitted OUT Data Interrupt Enable Mask */ -#define HSTPIPIMR_PERRE_Pos 3 /**< (HSTPIPIMR) Pipe Error Interrupt Enable Position */ -#define HSTPIPIMR_PERRE (_U_(0x1) << HSTPIPIMR_PERRE_Pos) /**< (HSTPIPIMR) Pipe Error Interrupt Enable Mask */ -#define HSTPIPIMR_NAKEDE_Pos 4 /**< (HSTPIPIMR) NAKed Interrupt Enable Position */ -#define HSTPIPIMR_NAKEDE (_U_(0x1) << HSTPIPIMR_NAKEDE_Pos) /**< (HSTPIPIMR) NAKed Interrupt Enable Mask */ -#define HSTPIPIMR_OVERFIE_Pos 5 /**< (HSTPIPIMR) Overflow Interrupt Enable Position */ -#define HSTPIPIMR_OVERFIE (_U_(0x1) << HSTPIPIMR_OVERFIE_Pos) /**< (HSTPIPIMR) Overflow Interrupt Enable Mask */ -#define HSTPIPIMR_SHORTPACKETIE_Pos 7 /**< (HSTPIPIMR) Short Packet Interrupt Enable Position */ -#define HSTPIPIMR_SHORTPACKETIE (_U_(0x1) << HSTPIPIMR_SHORTPACKETIE_Pos) /**< (HSTPIPIMR) Short Packet Interrupt Enable Mask */ -#define HSTPIPIMR_NBUSYBKE_Pos 12 /**< (HSTPIPIMR) Number of Busy Banks Interrupt Enable Position */ -#define HSTPIPIMR_NBUSYBKE (_U_(0x1) << HSTPIPIMR_NBUSYBKE_Pos) /**< (HSTPIPIMR) Number of Busy Banks Interrupt Enable Mask */ -#define HSTPIPIMR_FIFOCON_Pos 14 /**< (HSTPIPIMR) FIFO Control Position */ -#define HSTPIPIMR_FIFOCON (_U_(0x1) << HSTPIPIMR_FIFOCON_Pos) /**< (HSTPIPIMR) FIFO Control Mask */ -#define HSTPIPIMR_PDISHDMA_Pos 16 /**< (HSTPIPIMR) Pipe Interrupts Disable HDMA Request Enable Position */ -#define HSTPIPIMR_PDISHDMA (_U_(0x1) << HSTPIPIMR_PDISHDMA_Pos) /**< (HSTPIPIMR) Pipe Interrupts Disable HDMA Request Enable Mask */ -#define HSTPIPIMR_PFREEZE_Pos 17 /**< (HSTPIPIMR) Pipe Freeze Position */ -#define HSTPIPIMR_PFREEZE (_U_(0x1) << HSTPIPIMR_PFREEZE_Pos) /**< (HSTPIPIMR) Pipe Freeze Mask */ -#define HSTPIPIMR_RSTDT_Pos 18 /**< (HSTPIPIMR) Reset Data Toggle Position */ -#define HSTPIPIMR_RSTDT (_U_(0x1) << HSTPIPIMR_RSTDT_Pos) /**< (HSTPIPIMR) Reset Data Toggle Mask */ -#define HSTPIPIMR_Msk _U_(0x750BB) /**< (HSTPIPIMR) Register Mask */ - -/* CTRL mode */ -#define HSTPIPIMR_CTRL_TXSTPE_Pos 2 /**< (HSTPIPIMR) Transmitted SETUP Interrupt Enable Position */ -#define HSTPIPIMR_CTRL_TXSTPE (_U_(0x1) << HSTPIPIMR_CTRL_TXSTPE_Pos) /**< (HSTPIPIMR) Transmitted SETUP Interrupt Enable Mask */ -#define HSTPIPIMR_CTRL_RXSTALLDE_Pos 6 /**< (HSTPIPIMR) Received STALLed Interrupt Enable Position */ -#define HSTPIPIMR_CTRL_RXSTALLDE (_U_(0x1) << HSTPIPIMR_CTRL_RXSTALLDE_Pos) /**< (HSTPIPIMR) Received STALLed Interrupt Enable Mask */ -#define HSTPIPIMR_CTRL_Msk _U_(0x44) /**< (HSTPIPIMR_CTRL) Register Mask */ - -/* ISO mode */ -#define HSTPIPIMR_ISO_UNDERFIE_Pos 2 /**< (HSTPIPIMR) Underflow Interrupt Enable Position */ -#define HSTPIPIMR_ISO_UNDERFIE (_U_(0x1) << HSTPIPIMR_ISO_UNDERFIE_Pos) /**< (HSTPIPIMR) Underflow Interrupt Enable Mask */ -#define HSTPIPIMR_ISO_CRCERRE_Pos 6 /**< (HSTPIPIMR) CRC Error Interrupt Enable Position */ -#define HSTPIPIMR_ISO_CRCERRE (_U_(0x1) << HSTPIPIMR_ISO_CRCERRE_Pos) /**< (HSTPIPIMR) CRC Error Interrupt Enable Mask */ -#define HSTPIPIMR_ISO_Msk _U_(0x44) /**< (HSTPIPIMR_ISO) Register Mask */ - -/* BLK mode */ -#define HSTPIPIMR_BLK_TXSTPE_Pos 2 /**< (HSTPIPIMR) Transmitted SETUP Interrupt Enable Position */ -#define HSTPIPIMR_BLK_TXSTPE (_U_(0x1) << HSTPIPIMR_BLK_TXSTPE_Pos) /**< (HSTPIPIMR) Transmitted SETUP Interrupt Enable Mask */ -#define HSTPIPIMR_BLK_RXSTALLDE_Pos 6 /**< (HSTPIPIMR) Received STALLed Interrupt Enable Position */ -#define HSTPIPIMR_BLK_RXSTALLDE (_U_(0x1) << HSTPIPIMR_BLK_RXSTALLDE_Pos) /**< (HSTPIPIMR) Received STALLed Interrupt Enable Mask */ -#define HSTPIPIMR_BLK_Msk _U_(0x44) /**< (HSTPIPIMR_BLK) Register Mask */ - -/* INTRPT mode */ -#define HSTPIPIMR_INTRPT_UNDERFIE_Pos 2 /**< (HSTPIPIMR) Underflow Interrupt Enable Position */ -#define HSTPIPIMR_INTRPT_UNDERFIE (_U_(0x1) << HSTPIPIMR_INTRPT_UNDERFIE_Pos) /**< (HSTPIPIMR) Underflow Interrupt Enable Mask */ -#define HSTPIPIMR_INTRPT_RXSTALLDE_Pos 6 /**< (HSTPIPIMR) Received STALLed Interrupt Enable Position */ -#define HSTPIPIMR_INTRPT_RXSTALLDE (_U_(0x1) << HSTPIPIMR_INTRPT_RXSTALLDE_Pos) /**< (HSTPIPIMR) Received STALLed Interrupt Enable Mask */ -#define HSTPIPIMR_INTRPT_Msk _U_(0x44) /**< (HSTPIPIMR_INTRPT) Register Mask */ - - -/* -------- HSTPIPIER : (USBHS Offset: 0x5f0) (/W 32) Host Pipe Enable Register -------- */ - -#define HSTPIPIER_OFFSET (0x5F0) /**< (HSTPIPIER) Host Pipe Enable Register Offset */ - -#define HSTPIPIER_RXINES_Pos 0 /**< (HSTPIPIER) Received IN Data Interrupt Enable Position */ -#define HSTPIPIER_RXINES (_U_(0x1) << HSTPIPIER_RXINES_Pos) /**< (HSTPIPIER) Received IN Data Interrupt Enable Mask */ -#define HSTPIPIER_TXOUTES_Pos 1 /**< (HSTPIPIER) Transmitted OUT Data Interrupt Enable Position */ -#define HSTPIPIER_TXOUTES (_U_(0x1) << HSTPIPIER_TXOUTES_Pos) /**< (HSTPIPIER) Transmitted OUT Data Interrupt Enable Mask */ -#define HSTPIPIER_PERRES_Pos 3 /**< (HSTPIPIER) Pipe Error Interrupt Enable Position */ -#define HSTPIPIER_PERRES (_U_(0x1) << HSTPIPIER_PERRES_Pos) /**< (HSTPIPIER) Pipe Error Interrupt Enable Mask */ -#define HSTPIPIER_NAKEDES_Pos 4 /**< (HSTPIPIER) NAKed Interrupt Enable Position */ -#define HSTPIPIER_NAKEDES (_U_(0x1) << HSTPIPIER_NAKEDES_Pos) /**< (HSTPIPIER) NAKed Interrupt Enable Mask */ -#define HSTPIPIER_OVERFIES_Pos 5 /**< (HSTPIPIER) Overflow Interrupt Enable Position */ -#define HSTPIPIER_OVERFIES (_U_(0x1) << HSTPIPIER_OVERFIES_Pos) /**< (HSTPIPIER) Overflow Interrupt Enable Mask */ -#define HSTPIPIER_SHORTPACKETIES_Pos 7 /**< (HSTPIPIER) Short Packet Interrupt Enable Position */ -#define HSTPIPIER_SHORTPACKETIES (_U_(0x1) << HSTPIPIER_SHORTPACKETIES_Pos) /**< (HSTPIPIER) Short Packet Interrupt Enable Mask */ -#define HSTPIPIER_NBUSYBKES_Pos 12 /**< (HSTPIPIER) Number of Busy Banks Enable Position */ -#define HSTPIPIER_NBUSYBKES (_U_(0x1) << HSTPIPIER_NBUSYBKES_Pos) /**< (HSTPIPIER) Number of Busy Banks Enable Mask */ -#define HSTPIPIER_PDISHDMAS_Pos 16 /**< (HSTPIPIER) Pipe Interrupts Disable HDMA Request Enable Position */ -#define HSTPIPIER_PDISHDMAS (_U_(0x1) << HSTPIPIER_PDISHDMAS_Pos) /**< (HSTPIPIER) Pipe Interrupts Disable HDMA Request Enable Mask */ -#define HSTPIPIER_PFREEZES_Pos 17 /**< (HSTPIPIER) Pipe Freeze Enable Position */ -#define HSTPIPIER_PFREEZES (_U_(0x1) << HSTPIPIER_PFREEZES_Pos) /**< (HSTPIPIER) Pipe Freeze Enable Mask */ -#define HSTPIPIER_RSTDTS_Pos 18 /**< (HSTPIPIER) Reset Data Toggle Enable Position */ -#define HSTPIPIER_RSTDTS (_U_(0x1) << HSTPIPIER_RSTDTS_Pos) /**< (HSTPIPIER) Reset Data Toggle Enable Mask */ -#define HSTPIPIER_Msk _U_(0x710BB) /**< (HSTPIPIER) Register Mask */ - -/* CTRL mode */ -#define HSTPIPIER_CTRL_TXSTPES_Pos 2 /**< (HSTPIPIER) Transmitted SETUP Interrupt Enable Position */ -#define HSTPIPIER_CTRL_TXSTPES (_U_(0x1) << HSTPIPIER_CTRL_TXSTPES_Pos) /**< (HSTPIPIER) Transmitted SETUP Interrupt Enable Mask */ -#define HSTPIPIER_CTRL_RXSTALLDES_Pos 6 /**< (HSTPIPIER) Received STALLed Interrupt Enable Position */ -#define HSTPIPIER_CTRL_RXSTALLDES (_U_(0x1) << HSTPIPIER_CTRL_RXSTALLDES_Pos) /**< (HSTPIPIER) Received STALLed Interrupt Enable Mask */ -#define HSTPIPIER_CTRL_Msk _U_(0x44) /**< (HSTPIPIER_CTRL) Register Mask */ - -/* ISO mode */ -#define HSTPIPIER_ISO_UNDERFIES_Pos 2 /**< (HSTPIPIER) Underflow Interrupt Enable Position */ -#define HSTPIPIER_ISO_UNDERFIES (_U_(0x1) << HSTPIPIER_ISO_UNDERFIES_Pos) /**< (HSTPIPIER) Underflow Interrupt Enable Mask */ -#define HSTPIPIER_ISO_CRCERRES_Pos 6 /**< (HSTPIPIER) CRC Error Interrupt Enable Position */ -#define HSTPIPIER_ISO_CRCERRES (_U_(0x1) << HSTPIPIER_ISO_CRCERRES_Pos) /**< (HSTPIPIER) CRC Error Interrupt Enable Mask */ -#define HSTPIPIER_ISO_Msk _U_(0x44) /**< (HSTPIPIER_ISO) Register Mask */ - -/* BLK mode */ -#define HSTPIPIER_BLK_TXSTPES_Pos 2 /**< (HSTPIPIER) Transmitted SETUP Interrupt Enable Position */ -#define HSTPIPIER_BLK_TXSTPES (_U_(0x1) << HSTPIPIER_BLK_TXSTPES_Pos) /**< (HSTPIPIER) Transmitted SETUP Interrupt Enable Mask */ -#define HSTPIPIER_BLK_RXSTALLDES_Pos 6 /**< (HSTPIPIER) Received STALLed Interrupt Enable Position */ -#define HSTPIPIER_BLK_RXSTALLDES (_U_(0x1) << HSTPIPIER_BLK_RXSTALLDES_Pos) /**< (HSTPIPIER) Received STALLed Interrupt Enable Mask */ -#define HSTPIPIER_BLK_Msk _U_(0x44) /**< (HSTPIPIER_BLK) Register Mask */ - -/* INTRPT mode */ -#define HSTPIPIER_INTRPT_UNDERFIES_Pos 2 /**< (HSTPIPIER) Underflow Interrupt Enable Position */ -#define HSTPIPIER_INTRPT_UNDERFIES (_U_(0x1) << HSTPIPIER_INTRPT_UNDERFIES_Pos) /**< (HSTPIPIER) Underflow Interrupt Enable Mask */ -#define HSTPIPIER_INTRPT_RXSTALLDES_Pos 6 /**< (HSTPIPIER) Received STALLed Interrupt Enable Position */ -#define HSTPIPIER_INTRPT_RXSTALLDES (_U_(0x1) << HSTPIPIER_INTRPT_RXSTALLDES_Pos) /**< (HSTPIPIER) Received STALLed Interrupt Enable Mask */ -#define HSTPIPIER_INTRPT_Msk _U_(0x44) /**< (HSTPIPIER_INTRPT) Register Mask */ - - -/* -------- HSTPIPIDR : (USBHS Offset: 0x620) (/W 32) Host Pipe Disable Register -------- */ - -#define HSTPIPIDR_OFFSET (0x620) /**< (HSTPIPIDR) Host Pipe Disable Register Offset */ - -#define HSTPIPIDR_RXINEC_Pos 0 /**< (HSTPIPIDR) Received IN Data Interrupt Disable Position */ -#define HSTPIPIDR_RXINEC (_U_(0x1) << HSTPIPIDR_RXINEC_Pos) /**< (HSTPIPIDR) Received IN Data Interrupt Disable Mask */ -#define HSTPIPIDR_TXOUTEC_Pos 1 /**< (HSTPIPIDR) Transmitted OUT Data Interrupt Disable Position */ -#define HSTPIPIDR_TXOUTEC (_U_(0x1) << HSTPIPIDR_TXOUTEC_Pos) /**< (HSTPIPIDR) Transmitted OUT Data Interrupt Disable Mask */ -#define HSTPIPIDR_PERREC_Pos 3 /**< (HSTPIPIDR) Pipe Error Interrupt Disable Position */ -#define HSTPIPIDR_PERREC (_U_(0x1) << HSTPIPIDR_PERREC_Pos) /**< (HSTPIPIDR) Pipe Error Interrupt Disable Mask */ -#define HSTPIPIDR_NAKEDEC_Pos 4 /**< (HSTPIPIDR) NAKed Interrupt Disable Position */ -#define HSTPIPIDR_NAKEDEC (_U_(0x1) << HSTPIPIDR_NAKEDEC_Pos) /**< (HSTPIPIDR) NAKed Interrupt Disable Mask */ -#define HSTPIPIDR_OVERFIEC_Pos 5 /**< (HSTPIPIDR) Overflow Interrupt Disable Position */ -#define HSTPIPIDR_OVERFIEC (_U_(0x1) << HSTPIPIDR_OVERFIEC_Pos) /**< (HSTPIPIDR) Overflow Interrupt Disable Mask */ -#define HSTPIPIDR_SHORTPACKETIEC_Pos 7 /**< (HSTPIPIDR) Short Packet Interrupt Disable Position */ -#define HSTPIPIDR_SHORTPACKETIEC (_U_(0x1) << HSTPIPIDR_SHORTPACKETIEC_Pos) /**< (HSTPIPIDR) Short Packet Interrupt Disable Mask */ -#define HSTPIPIDR_NBUSYBKEC_Pos 12 /**< (HSTPIPIDR) Number of Busy Banks Disable Position */ -#define HSTPIPIDR_NBUSYBKEC (_U_(0x1) << HSTPIPIDR_NBUSYBKEC_Pos) /**< (HSTPIPIDR) Number of Busy Banks Disable Mask */ -#define HSTPIPIDR_FIFOCONC_Pos 14 /**< (HSTPIPIDR) FIFO Control Disable Position */ -#define HSTPIPIDR_FIFOCONC (_U_(0x1) << HSTPIPIDR_FIFOCONC_Pos) /**< (HSTPIPIDR) FIFO Control Disable Mask */ -#define HSTPIPIDR_PDISHDMAC_Pos 16 /**< (HSTPIPIDR) Pipe Interrupts Disable HDMA Request Disable Position */ -#define HSTPIPIDR_PDISHDMAC (_U_(0x1) << HSTPIPIDR_PDISHDMAC_Pos) /**< (HSTPIPIDR) Pipe Interrupts Disable HDMA Request Disable Mask */ -#define HSTPIPIDR_PFREEZEC_Pos 17 /**< (HSTPIPIDR) Pipe Freeze Disable Position */ -#define HSTPIPIDR_PFREEZEC (_U_(0x1) << HSTPIPIDR_PFREEZEC_Pos) /**< (HSTPIPIDR) Pipe Freeze Disable Mask */ -#define HSTPIPIDR_Msk _U_(0x350BB) /**< (HSTPIPIDR) Register Mask */ - -/* CTRL mode */ -#define HSTPIPIDR_CTRL_TXSTPEC_Pos 2 /**< (HSTPIPIDR) Transmitted SETUP Interrupt Disable Position */ -#define HSTPIPIDR_CTRL_TXSTPEC (_U_(0x1) << HSTPIPIDR_CTRL_TXSTPEC_Pos) /**< (HSTPIPIDR) Transmitted SETUP Interrupt Disable Mask */ -#define HSTPIPIDR_CTRL_RXSTALLDEC_Pos 6 /**< (HSTPIPIDR) Received STALLed Interrupt Disable Position */ -#define HSTPIPIDR_CTRL_RXSTALLDEC (_U_(0x1) << HSTPIPIDR_CTRL_RXSTALLDEC_Pos) /**< (HSTPIPIDR) Received STALLed Interrupt Disable Mask */ -#define HSTPIPIDR_CTRL_Msk _U_(0x44) /**< (HSTPIPIDR_CTRL) Register Mask */ - -/* ISO mode */ -#define HSTPIPIDR_ISO_UNDERFIEC_Pos 2 /**< (HSTPIPIDR) Underflow Interrupt Disable Position */ -#define HSTPIPIDR_ISO_UNDERFIEC (_U_(0x1) << HSTPIPIDR_ISO_UNDERFIEC_Pos) /**< (HSTPIPIDR) Underflow Interrupt Disable Mask */ -#define HSTPIPIDR_ISO_CRCERREC_Pos 6 /**< (HSTPIPIDR) CRC Error Interrupt Disable Position */ -#define HSTPIPIDR_ISO_CRCERREC (_U_(0x1) << HSTPIPIDR_ISO_CRCERREC_Pos) /**< (HSTPIPIDR) CRC Error Interrupt Disable Mask */ -#define HSTPIPIDR_ISO_Msk _U_(0x44) /**< (HSTPIPIDR_ISO) Register Mask */ - -/* BLK mode */ -#define HSTPIPIDR_BLK_TXSTPEC_Pos 2 /**< (HSTPIPIDR) Transmitted SETUP Interrupt Disable Position */ -#define HSTPIPIDR_BLK_TXSTPEC (_U_(0x1) << HSTPIPIDR_BLK_TXSTPEC_Pos) /**< (HSTPIPIDR) Transmitted SETUP Interrupt Disable Mask */ -#define HSTPIPIDR_BLK_RXSTALLDEC_Pos 6 /**< (HSTPIPIDR) Received STALLed Interrupt Disable Position */ -#define HSTPIPIDR_BLK_RXSTALLDEC (_U_(0x1) << HSTPIPIDR_BLK_RXSTALLDEC_Pos) /**< (HSTPIPIDR) Received STALLed Interrupt Disable Mask */ -#define HSTPIPIDR_BLK_Msk _U_(0x44) /**< (HSTPIPIDR_BLK) Register Mask */ - -/* INTRPT mode */ -#define HSTPIPIDR_INTRPT_UNDERFIEC_Pos 2 /**< (HSTPIPIDR) Underflow Interrupt Disable Position */ -#define HSTPIPIDR_INTRPT_UNDERFIEC (_U_(0x1) << HSTPIPIDR_INTRPT_UNDERFIEC_Pos) /**< (HSTPIPIDR) Underflow Interrupt Disable Mask */ -#define HSTPIPIDR_INTRPT_RXSTALLDEC_Pos 6 /**< (HSTPIPIDR) Received STALLed Interrupt Disable Position */ -#define HSTPIPIDR_INTRPT_RXSTALLDEC (_U_(0x1) << HSTPIPIDR_INTRPT_RXSTALLDEC_Pos) /**< (HSTPIPIDR) Received STALLed Interrupt Disable Mask */ -#define HSTPIPIDR_INTRPT_Msk _U_(0x44) /**< (HSTPIPIDR_INTRPT) Register Mask */ - - -/* -------- HSTPIPINRQ : (USBHS Offset: 0x650) (R/W 32) Host Pipe IN Request Register -------- */ - -#define HSTPIPINRQ_OFFSET (0x650) /**< (HSTPIPINRQ) Host Pipe IN Request Register Offset */ - -#define HSTPIPINRQ_INRQ_Pos 0 /**< (HSTPIPINRQ) IN Request Number before Freeze Position */ -#define HSTPIPINRQ_INRQ (_U_(0xFF) << HSTPIPINRQ_INRQ_Pos) /**< (HSTPIPINRQ) IN Request Number before Freeze Mask */ -#define HSTPIPINRQ_INMODE_Pos 8 /**< (HSTPIPINRQ) IN Request Mode Position */ -#define HSTPIPINRQ_INMODE (_U_(0x1) << HSTPIPINRQ_INMODE_Pos) /**< (HSTPIPINRQ) IN Request Mode Mask */ -#define HSTPIPINRQ_Msk _U_(0x1FF) /**< (HSTPIPINRQ) Register Mask */ - - -/* -------- HSTPIPERR : (USBHS Offset: 0x680) (R/W 32) Host Pipe Error Register -------- */ - -#define HSTPIPERR_OFFSET (0x680) /**< (HSTPIPERR) Host Pipe Error Register Offset */ - -#define HSTPIPERR_DATATGL_Pos 0 /**< (HSTPIPERR) Data Toggle Error Position */ -#define HSTPIPERR_DATATGL (_U_(0x1) << HSTPIPERR_DATATGL_Pos) /**< (HSTPIPERR) Data Toggle Error Mask */ -#define HSTPIPERR_DATAPID_Pos 1 /**< (HSTPIPERR) Data PID Error Position */ -#define HSTPIPERR_DATAPID (_U_(0x1) << HSTPIPERR_DATAPID_Pos) /**< (HSTPIPERR) Data PID Error Mask */ -#define HSTPIPERR_PID_Pos 2 /**< (HSTPIPERR) Data PID Error Position */ -#define HSTPIPERR_PID (_U_(0x1) << HSTPIPERR_PID_Pos) /**< (HSTPIPERR) Data PID Error Mask */ -#define HSTPIPERR_TIMEOUT_Pos 3 /**< (HSTPIPERR) Time-Out Error Position */ -#define HSTPIPERR_TIMEOUT (_U_(0x1) << HSTPIPERR_TIMEOUT_Pos) /**< (HSTPIPERR) Time-Out Error Mask */ -#define HSTPIPERR_CRC16_Pos 4 /**< (HSTPIPERR) CRC16 Error Position */ -#define HSTPIPERR_CRC16 (_U_(0x1) << HSTPIPERR_CRC16_Pos) /**< (HSTPIPERR) CRC16 Error Mask */ -#define HSTPIPERR_COUNTER_Pos 5 /**< (HSTPIPERR) Error Counter Position */ -#define HSTPIPERR_COUNTER (_U_(0x3) << HSTPIPERR_COUNTER_Pos) /**< (HSTPIPERR) Error Counter Mask */ -#define HSTPIPERR_Msk _U_(0x7F) /**< (HSTPIPERR) Register Mask */ - -#define HSTPIPERR_CRC_Pos 4 /**< (HSTPIPERR Position) CRCx6 Error */ -#define HSTPIPERR_CRC (_U_(0x1) << HSTPIPERR_CRC_Pos) /**< (HSTPIPERR Mask) CRC */ - -/* -------- CTRL : (USBHS Offset: 0x800) (R/W 32) General Control Register -------- */ - -#define CTRL_OFFSET (0x800) /**< (CTRL) General Control Register Offset */ - -#define CTRL_RDERRE_Pos 4 /**< (CTRL) Remote Device Connection Error Interrupt Enable Position */ -#define CTRL_RDERRE (_U_(0x1) << CTRL_RDERRE_Pos) /**< (CTRL) Remote Device Connection Error Interrupt Enable Mask */ -#define CTRL_VBUSHWC_Pos 8 /**< (CTRL) VBUS Hardware Control Position */ -#define CTRL_VBUSHWC (_U_(0x1) << CTRL_VBUSHWC_Pos) /**< (CTRL) VBUS Hardware Control Mask */ -#define CTRL_FRZCLK_Pos 14 /**< (CTRL) Freeze USB Clock Position */ -#define CTRL_FRZCLK (_U_(0x1) << CTRL_FRZCLK_Pos) /**< (CTRL) Freeze USB Clock Mask */ -#define CTRL_USBE_Pos 15 /**< (CTRL) USBHS Enable Position */ -#define CTRL_USBE (_U_(0x1) << CTRL_USBE_Pos) /**< (CTRL) USBHS Enable Mask */ -#define CTRL_UID_Pos 24 /**< (CTRL) UID Pin Enable Position */ -#define CTRL_UID (_U_(0x1) << CTRL_UID_Pos) /**< (CTRL) UID Pin Enable Mask */ -#define CTRL_UIMOD_Pos 25 /**< (CTRL) USBHS Mode Position */ -#define CTRL_UIMOD (_U_(0x1) << CTRL_UIMOD_Pos) /**< (CTRL) USBHS Mode Mask */ -#define CTRL_UIMOD_HOST_Val _U_(0x0) /**< (CTRL) The module is in USB Host mode. */ -#define CTRL_UIMOD_DEVICE_Val _U_(0x1) /**< (CTRL) The module is in USB Device mode. */ -#define CTRL_UIMOD_HOST (CTRL_UIMOD_HOST_Val << CTRL_UIMOD_Pos) /**< (CTRL) The module is in USB Host mode. Position */ -#define CTRL_UIMOD_DEVICE (CTRL_UIMOD_DEVICE_Val << CTRL_UIMOD_Pos) /**< (CTRL) The module is in USB Device mode. Position */ -#define CTRL_Msk _U_(0x300C110) /**< (CTRL) Register Mask */ - - -/* -------- SR : (USBHS Offset: 0x804) (R/ 32) General Status Register -------- */ - -#define SR_OFFSET (0x804) /**< (SR) General Status Register Offset */ - -#define SR_RDERRI_Pos 4 /**< (SR) Remote Device Connection Error Interrupt (Host mode only) Position */ -#define SR_RDERRI (_U_(0x1) << SR_RDERRI_Pos) /**< (SR) Remote Device Connection Error Interrupt (Host mode only) Mask */ -#define SR_SPEED_Pos 12 /**< (SR) Speed Status (Device mode only) Position */ -#define SR_SPEED (_U_(0x3) << SR_SPEED_Pos) /**< (SR) Speed Status (Device mode only) Mask */ -#define SR_SPEED_FULL_SPEED_Val _U_(0x0) /**< (SR) Full-Speed mode */ -#define SR_SPEED_HIGH_SPEED_Val _U_(0x1) /**< (SR) High-Speed mode */ -#define SR_SPEED_LOW_SPEED_Val _U_(0x2) /**< (SR) Low-Speed mode */ -#define SR_SPEED_FULL_SPEED (SR_SPEED_FULL_SPEED_Val << SR_SPEED_Pos) /**< (SR) Full-Speed mode Position */ -#define SR_SPEED_HIGH_SPEED (SR_SPEED_HIGH_SPEED_Val << SR_SPEED_Pos) /**< (SR) High-Speed mode Position */ -#define SR_SPEED_LOW_SPEED (SR_SPEED_LOW_SPEED_Val << SR_SPEED_Pos) /**< (SR) Low-Speed mode Position */ -#define SR_CLKUSABLE_Pos 14 /**< (SR) UTMI Clock Usable Position */ -#define SR_CLKUSABLE (_U_(0x1) << SR_CLKUSABLE_Pos) /**< (SR) UTMI Clock Usable Mask */ -#define SR_Msk _U_(0x7010) /**< (SR) Register Mask */ - - -/* -------- SCR : (USBHS Offset: 0x808) (/W 32) General Status Clear Register -------- */ - -#define SCR_OFFSET (0x808) /**< (SCR) General Status Clear Register Offset */ - -#define SCR_RDERRIC_Pos 4 /**< (SCR) Remote Device Connection Error Interrupt Clear Position */ -#define SCR_RDERRIC (_U_(0x1) << SCR_RDERRIC_Pos) /**< (SCR) Remote Device Connection Error Interrupt Clear Mask */ -#define SCR_Msk _U_(0x10) /**< (SCR) Register Mask */ - - -/* -------- SFR : (USBHS Offset: 0x80c) (/W 32) General Status Set Register -------- */ - -#define SFR_OFFSET (0x80C) /**< (SFR) General Status Set Register Offset */ - -#define SFR_RDERRIS_Pos 4 /**< (SFR) Remote Device Connection Error Interrupt Set Position */ -#define SFR_RDERRIS (_U_(0x1) << SFR_RDERRIS_Pos) /**< (SFR) Remote Device Connection Error Interrupt Set Mask */ -#define SFR_VBUSRQS_Pos 9 /**< (SFR) VBUS Request Set Position */ -#define SFR_VBUSRQS (_U_(0x1) << SFR_VBUSRQS_Pos) /**< (SFR) VBUS Request Set Mask */ -#define SFR_Msk _U_(0x210) /**< (SFR) Register Mask */ - - -/** \brief DEVDMA hardware registers */ -typedef struct -{ - __IO uint32_t DEVDMANXTDSC; /**< (DEVDMA Offset: 0x00) Device DMA Channel Next Descriptor Address Register */ - __IO uint32_t DEVDMAADDRESS; /**< (DEVDMA Offset: 0x04) Device DMA Channel Address Register */ - __IO uint32_t DEVDMACONTROL; /**< (DEVDMA Offset: 0x08) Device DMA Channel Control Register */ - __IO uint32_t DEVDMASTATUS; /**< (DEVDMA Offset: 0x0C) Device DMA Channel Status Register */ -} devdma_t; - -/** \brief HSTDMA hardware registers */ -typedef struct -{ - __IO uint32_t HSTDMANXTDSC; /**< (HSTDMA Offset: 0x00) Host DMA Channel Next Descriptor Address Register */ - __IO uint32_t HSTDMAADDRESS; /**< (HSTDMA Offset: 0x04) Host DMA Channel Address Register */ - __IO uint32_t HSTDMACONTROL; /**< (HSTDMA Offset: 0x08) Host DMA Channel Control Register */ - __IO uint32_t HSTDMASTATUS; /**< (HSTDMA Offset: 0x0C) Host DMA Channel Status Register */ -} hstdma_t; - -/** \brief USBHS hardware registers */ -typedef struct -{ - __IO uint32_t DEVCTRL; /**< (USBHS Offset: 0x00) Device General Control Register */ - __I uint32_t DEVISR; /**< (USBHS Offset: 0x04) Device Global Interrupt Status Register */ - __O uint32_t DEVICR; /**< (USBHS Offset: 0x08) Device Global Interrupt Clear Register */ - __O uint32_t DEVIFR; /**< (USBHS Offset: 0x0C) Device Global Interrupt Set Register */ - __I uint32_t DEVIMR; /**< (USBHS Offset: 0x10) Device Global Interrupt Mask Register */ - __O uint32_t DEVIDR; /**< (USBHS Offset: 0x14) Device Global Interrupt Disable Register */ - __O uint32_t DEVIER; /**< (USBHS Offset: 0x18) Device Global Interrupt Enable Register */ - __IO uint32_t DEVEPT; /**< (USBHS Offset: 0x1C) Device Endpoint Register */ - __I uint32_t DEVFNUM; /**< (USBHS Offset: 0x20) Device Frame Number Register */ - __I uint8_t Reserved1[220]; - __IO uint32_t DEVEPTCFG[10]; /**< (USBHS Offset: 0x100) Device Endpoint Configuration Register */ - __I uint8_t Reserved2[8]; - __I uint32_t DEVEPTISR[10]; /**< (USBHS Offset: 0x130) Device Endpoint Interrupt Status Register */ - __I uint8_t Reserved3[8]; - __O uint32_t DEVEPTICR[10]; /**< (USBHS Offset: 0x160) Device Endpoint Interrupt Clear Register */ - __I uint8_t Reserved4[8]; - __O uint32_t DEVEPTIFR[10]; /**< (USBHS Offset: 0x190) Device Endpoint Interrupt Set Register */ - __I uint8_t Reserved5[8]; - __I uint32_t DEVEPTIMR[10]; /**< (USBHS Offset: 0x1C0) Device Endpoint Interrupt Mask Register */ - __I uint8_t Reserved6[8]; - __O uint32_t DEVEPTIER[10]; /**< (USBHS Offset: 0x1F0) Device Endpoint Interrupt Enable Register */ - __I uint8_t Reserved7[8]; - __O uint32_t DEVEPTIDR[10]; /**< (USBHS Offset: 0x220) Device Endpoint Interrupt Disable Register */ - __I uint8_t Reserved8[200]; - devdma_t DEVDMA[7]; /**< Offset: 0x310 Device DMA Channel Next Descriptor Address Register */ - __I uint8_t Reserved9[128]; - __IO uint32_t HSTCTRL; /**< (USBHS Offset: 0x400) Host General Control Register */ - __I uint32_t HSTISR; /**< (USBHS Offset: 0x404) Host Global Interrupt Status Register */ - __O uint32_t HSTICR; /**< (USBHS Offset: 0x408) Host Global Interrupt Clear Register */ - __O uint32_t HSTIFR; /**< (USBHS Offset: 0x40C) Host Global Interrupt Set Register */ - __I uint32_t HSTIMR; /**< (USBHS Offset: 0x410) Host Global Interrupt Mask Register */ - __O uint32_t HSTIDR; /**< (USBHS Offset: 0x414) Host Global Interrupt Disable Register */ - __O uint32_t HSTIER; /**< (USBHS Offset: 0x418) Host Global Interrupt Enable Register */ - __IO uint32_t HSTPIP; /**< (USBHS Offset: 0x41C) Host Pipe Register */ - __IO uint32_t HSTFNUM; /**< (USBHS Offset: 0x420) Host Frame Number Register */ - __IO uint32_t HSTADDR1; /**< (USBHS Offset: 0x424) Host Address 1 Register */ - __IO uint32_t HSTADDR2; /**< (USBHS Offset: 0x428) Host Address 2 Register */ - __IO uint32_t HSTADDR3; /**< (USBHS Offset: 0x42C) Host Address 3 Register */ - __I uint8_t Reserved10[208]; - __IO uint32_t HSTPIPCFG[10]; /**< (USBHS Offset: 0x500) Host Pipe Configuration Register */ - __I uint8_t Reserved11[8]; - __I uint32_t HSTPIPISR[10]; /**< (USBHS Offset: 0x530) Host Pipe Status Register */ - __I uint8_t Reserved12[8]; - __O uint32_t HSTPIPICR[10]; /**< (USBHS Offset: 0x560) Host Pipe Clear Register */ - __I uint8_t Reserved13[8]; - __O uint32_t HSTPIPIFR[10]; /**< (USBHS Offset: 0x590) Host Pipe Set Register */ - __I uint8_t Reserved14[8]; - __I uint32_t HSTPIPIMR[10]; /**< (USBHS Offset: 0x5C0) Host Pipe Mask Register */ - __I uint8_t Reserved15[8]; - __O uint32_t HSTPIPIER[10]; /**< (USBHS Offset: 0x5F0) Host Pipe Enable Register */ - __I uint8_t Reserved16[8]; - __O uint32_t HSTPIPIDR[10]; /**< (USBHS Offset: 0x620) Host Pipe Disable Register */ - __I uint8_t Reserved17[8]; - __IO uint32_t HSTPIPINRQ[10]; /**< (USBHS Offset: 0x650) Host Pipe IN Request Register */ - __I uint8_t Reserved18[8]; - __IO uint32_t HSTPIPERR[10]; /**< (USBHS Offset: 0x680) Host Pipe Error Register */ - __I uint8_t Reserved19[104]; - hstdma_t HSTDMA[7]; /**< Offset: 0x710 Host DMA Channel Next Descriptor Address Register */ - __I uint8_t Reserved20[128]; - __IO uint32_t CTRL; /**< (USBHS Offset: 0x800) General Control Register */ - __I uint32_t SR; /**< (USBHS Offset: 0x804) General Status Register */ - __O uint32_t SCR; /**< (USBHS Offset: 0x808) General Status Clear Register */ - __O uint32_t SFR; /**< (USBHS Offset: 0x80C) General Status Set Register */ -} dcd_registers_t; - -#define USB_REG ((dcd_registers_t *)0x40038000U) /**< \brief (USBHS) Base Address */ - -#define EP_MAX 10 - -#define FIFO_RAM_ADDR 0xA0100000u - -// Errata: The DMA feature is not available for Pipe/Endpoint 7 -#define EP_DMA_SUPPORT(epnum) (epnum >= 1 && epnum <= 6) - -#else // TODO : SAM3U - - -#endif - -#endif /* _COMMON_USB_REGS_H_ */ diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c index b0a053c01..979d08fe9 100644 --- a/src/portable/microchip/samx7x/dcd_samx7x.c +++ b/src/portable/microchip/samx7x/dcd_samx7x.c @@ -31,7 +31,7 @@ #include "device/dcd.h" #include "sam.h" -#include "common_usb_regs.h" +#include "samx7x_common.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ @@ -87,18 +87,22 @@ static const tusb_desc_endpoint_t ep0_desc = .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, }; -TU_ATTR_ALWAYS_INLINE static inline void CleanInValidateCache(uint32_t *addr, int32_t size) -{ - if (SCB->CCR & SCB_CCR_DC_Msk) - { - SCB_CleanInvalidateDCache_by_Addr(addr, size); - } - else - { - __DSB(); - __ISB(); - } +#if CFG_TUD_MEM_DCACHE_ENABLE +bool dcd_dcache_clean(const void* addr, uint32_t data_size) { + TU_VERIFY(addr && data_size); + return samx7x_dcache_clean(addr, data_size); } + +bool dcd_dcache_invalidate(const void* addr, uint32_t data_size) { + TU_VERIFY(addr && data_size); + return samx7x_dcache_invalidate(addr, data_size); +} + +bool dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size) { + TU_VERIFY(addr && data_size); + return samx7x_dcache_clean_invalidate(addr, data_size); +} +#endif //------------------------------------------------------------------ // Device API //------------------------------------------------------------------ @@ -255,7 +259,7 @@ static void dcd_ep_handler(uint8_t ep_ix) memcpy(xfer->buffer + xfer->queued_len, ptr, count); } else { - tu_fifo_write_n(xfer->fifo, ptr, count); + tu_hwfifo_read_to_fifo(ptr, xfer->fifo, count, NULL); } xfer->queued_len = (uint16_t)(xfer->queued_len + count); } @@ -309,7 +313,7 @@ static void dcd_ep_handler(uint8_t ep_ix) { memcpy(xfer->buffer + xfer->queued_len, ptr, count); } else { - tu_fifo_write_n(xfer->fifo, ptr, count); + tu_hwfifo_read_to_fifo(ptr, xfer->fifo, count, NULL); } xfer->queued_len = (uint16_t)(xfer->queued_len + count); } @@ -362,6 +366,7 @@ static void dcd_dma_handler(uint8_t ep_ix) dcd_event_xfer_complete(0, 0x80 + ep_ix, count, XFER_RESULT_SUCCESS, true); } else { + dcd_dcache_invalidate(xfer->buffer, xfer->total_len); dcd_event_xfer_complete(0, ep_ix, count, XFER_RESULT_SUCCESS, true); } } @@ -588,7 +593,7 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint8_t ep_ix) } else { - tu_fifo_read_n(xfer->fifo, ptr, len); + tu_hwfifo_write_from_fifo(ptr, xfer->fifo, len, NULL); } __DSB(); __ISB(); @@ -623,35 +628,18 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t if (EP_DMA_SUPPORT(epnum) && total_bytes != 0) { - // Force the CPU to flush the buffer. We increase the size by 32 because the call aligns the - // address to 32-byte boundaries. - CleanInValidateCache((uint32_t*) tu_align((uint32_t) buffer, 4), total_bytes + 31); uint32_t udd_dma_ctrl = total_bytes << DEVDMACONTROL_BUFF_LENGTH_Pos; if (dir == TUSB_DIR_OUT) { udd_dma_ctrl |= DEVDMACONTROL_END_TR_IT | DEVDMACONTROL_END_TR_EN; } else { udd_dma_ctrl |= DEVDMACONTROL_END_B_EN; + dcd_dcache_clean(xfer->buffer, total_bytes); } USB_REG->DEVDMA[epnum - 1].DEVDMAADDRESS = (uint32_t)buffer; udd_dma_ctrl |= DEVDMACONTROL_END_BUFFIT | DEVDMACONTROL_CHANN_ENB; - // Disable IRQs to have a short sequence - // between read of EOT_STA and DMA enable - uint32_t irq_state = __get_PRIMASK(); - __disable_irq(); - if (!(USB_REG->DEVDMA[epnum - 1].DEVDMASTATUS & DEVDMASTATUS_END_TR_ST)) - { - USB_REG->DEVDMA[epnum - 1].DEVDMACONTROL = udd_dma_ctrl; - USB_REG->DEVIER = DEVIER_DMA_1 << (epnum - 1); - __set_PRIMASK(irq_state); - return true; - } - __set_PRIMASK(irq_state); - - // Here a ZLP has been received - // and the DMA transfer must be not started. - // It is the end of transfer - return false; + USB_REG->DEVDMA[epnum - 1].DEVDMACONTROL = udd_dma_ctrl; + USB_REG->DEVIER = DEVIER_DMA_1 << (epnum - 1); } else { if (dir == TUSB_DIR_OUT) diff --git a/src/portable/microchip/samx7x/samx7x_common.h b/src/portable/microchip/samx7x/samx7x_common.h new file mode 100644 index 000000000..4fd63b7f8 --- /dev/null +++ b/src/portable/microchip/samx7x/samx7x_common.h @@ -0,0 +1,2173 @@ + /* +* The MIT License (MIT) +* +* Copyright (c) 2019 Microchip Technology Inc. +* Copyright (c) 2018, hathach (tinyusb.org) +* Copyright (c) 2021, HiFiPhile +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +* +* This file is part of the TinyUSB stack. +*/ + +#ifndef _COMMON_USB_REGS_H_ +#define _COMMON_USB_REGS_H_ + +#if CFG_TUSB_MCU == OPT_MCU_SAMX7X + +/* -------- DEVDMANXTDSC : (USBHS Offset: 0x00) (R/W 32) Device DMA Channel Next Descriptor Address Register -------- */ + +#define DEVDMANXTDSC_OFFSET (0x00) /**< (DEVDMANXTDSC) Device DMA Channel Next Descriptor Address Register Offset */ + +#define DEVDMANXTDSC_NXT_DSC_ADD_Pos 0 /**< (DEVDMANXTDSC) Next Descriptor Address Position */ +#define DEVDMANXTDSC_NXT_DSC_ADD (_U_(0xFFFFFFFF) << DEVDMANXTDSC_NXT_DSC_ADD_Pos) /**< (DEVDMANXTDSC) Next Descriptor Address Mask */ +#define DEVDMANXTDSC_Msk _U_(0xFFFFFFFF) /**< (DEVDMANXTDSC) Register Mask */ + + +/* -------- DEVDMAADDRESS : (USBHS Offset: 0x04) (R/W 32) Device DMA Channel Address Register -------- */ + +#define DEVDMAADDRESS_OFFSET (0x04) /**< (DEVDMAADDRESS) Device DMA Channel Address Register Offset */ + +#define DEVDMAADDRESS_BUFF_ADD_Pos 0 /**< (DEVDMAADDRESS) Buffer Address Position */ +#define DEVDMAADDRESS_BUFF_ADD (_U_(0xFFFFFFFF) << DEVDMAADDRESS_BUFF_ADD_Pos) /**< (DEVDMAADDRESS) Buffer Address Mask */ +#define DEVDMAADDRESS_Msk _U_(0xFFFFFFFF) /**< (DEVDMAADDRESS) Register Mask */ + + +/* -------- DEVDMACONTROL : (USBHS Offset: 0x08) (R/W 32) Device DMA Channel Control Register -------- */ + +#define DEVDMACONTROL_OFFSET (0x08) /**< (DEVDMACONTROL) Device DMA Channel Control Register Offset */ + +#define DEVDMACONTROL_CHANN_ENB_Pos 0 /**< (DEVDMACONTROL) Channel Enable Command Position */ +#define DEVDMACONTROL_CHANN_ENB (_U_(0x1) << DEVDMACONTROL_CHANN_ENB_Pos) /**< (DEVDMACONTROL) Channel Enable Command Mask */ +#define DEVDMACONTROL_LDNXT_DSC_Pos 1 /**< (DEVDMACONTROL) Load Next Channel Transfer Descriptor Enable Command Position */ +#define DEVDMACONTROL_LDNXT_DSC (_U_(0x1) << DEVDMACONTROL_LDNXT_DSC_Pos) /**< (DEVDMACONTROL) Load Next Channel Transfer Descriptor Enable Command Mask */ +#define DEVDMACONTROL_END_TR_EN_Pos 2 /**< (DEVDMACONTROL) End of Transfer Enable Control (OUT transfers only) Position */ +#define DEVDMACONTROL_END_TR_EN (_U_(0x1) << DEVDMACONTROL_END_TR_EN_Pos) /**< (DEVDMACONTROL) End of Transfer Enable Control (OUT transfers only) Mask */ +#define DEVDMACONTROL_END_B_EN_Pos 3 /**< (DEVDMACONTROL) End of Buffer Enable Control Position */ +#define DEVDMACONTROL_END_B_EN (_U_(0x1) << DEVDMACONTROL_END_B_EN_Pos) /**< (DEVDMACONTROL) End of Buffer Enable Control Mask */ +#define DEVDMACONTROL_END_TR_IT_Pos 4 /**< (DEVDMACONTROL) End of Transfer Interrupt Enable Position */ +#define DEVDMACONTROL_END_TR_IT (_U_(0x1) << DEVDMACONTROL_END_TR_IT_Pos) /**< (DEVDMACONTROL) End of Transfer Interrupt Enable Mask */ +#define DEVDMACONTROL_END_BUFFIT_Pos 5 /**< (DEVDMACONTROL) End of Buffer Interrupt Enable Position */ +#define DEVDMACONTROL_END_BUFFIT (_U_(0x1) << DEVDMACONTROL_END_BUFFIT_Pos) /**< (DEVDMACONTROL) End of Buffer Interrupt Enable Mask */ +#define DEVDMACONTROL_DESC_LD_IT_Pos 6 /**< (DEVDMACONTROL) Descriptor Loaded Interrupt Enable Position */ +#define DEVDMACONTROL_DESC_LD_IT (_U_(0x1) << DEVDMACONTROL_DESC_LD_IT_Pos) /**< (DEVDMACONTROL) Descriptor Loaded Interrupt Enable Mask */ +#define DEVDMACONTROL_BURST_LCK_Pos 7 /**< (DEVDMACONTROL) Burst Lock Enable Position */ +#define DEVDMACONTROL_BURST_LCK (_U_(0x1) << DEVDMACONTROL_BURST_LCK_Pos) /**< (DEVDMACONTROL) Burst Lock Enable Mask */ +#define DEVDMACONTROL_BUFF_LENGTH_Pos 16 /**< (DEVDMACONTROL) Buffer Byte Length (Write-only) Position */ +#define DEVDMACONTROL_BUFF_LENGTH (_U_(0xFFFF) << DEVDMACONTROL_BUFF_LENGTH_Pos) /**< (DEVDMACONTROL) Buffer Byte Length (Write-only) Mask */ +#define DEVDMACONTROL_Msk _U_(0xFFFF00FF) /**< (DEVDMACONTROL) Register Mask */ + + +/* -------- DEVDMASTATUS : (USBHS Offset: 0x0c) (R/W 32) Device DMA Channel Status Register -------- */ + +#define DEVDMASTATUS_OFFSET (0x0C) /**< (DEVDMASTATUS) Device DMA Channel Status Register Offset */ + +#define DEVDMASTATUS_CHANN_ENB_Pos 0 /**< (DEVDMASTATUS) Channel Enable Status Position */ +#define DEVDMASTATUS_CHANN_ENB (_U_(0x1) << DEVDMASTATUS_CHANN_ENB_Pos) /**< (DEVDMASTATUS) Channel Enable Status Mask */ +#define DEVDMASTATUS_CHANN_ACT_Pos 1 /**< (DEVDMASTATUS) Channel Active Status Position */ +#define DEVDMASTATUS_CHANN_ACT (_U_(0x1) << DEVDMASTATUS_CHANN_ACT_Pos) /**< (DEVDMASTATUS) Channel Active Status Mask */ +#define DEVDMASTATUS_END_TR_ST_Pos 4 /**< (DEVDMASTATUS) End of Channel Transfer Status Position */ +#define DEVDMASTATUS_END_TR_ST (_U_(0x1) << DEVDMASTATUS_END_TR_ST_Pos) /**< (DEVDMASTATUS) End of Channel Transfer Status Mask */ +#define DEVDMASTATUS_END_BF_ST_Pos 5 /**< (DEVDMASTATUS) End of Channel Buffer Status Position */ +#define DEVDMASTATUS_END_BF_ST (_U_(0x1) << DEVDMASTATUS_END_BF_ST_Pos) /**< (DEVDMASTATUS) End of Channel Buffer Status Mask */ +#define DEVDMASTATUS_DESC_LDST_Pos 6 /**< (DEVDMASTATUS) Descriptor Loaded Status Position */ +#define DEVDMASTATUS_DESC_LDST (_U_(0x1) << DEVDMASTATUS_DESC_LDST_Pos) /**< (DEVDMASTATUS) Descriptor Loaded Status Mask */ +#define DEVDMASTATUS_BUFF_COUNT_Pos 16 /**< (DEVDMASTATUS) Buffer Byte Count Position */ +#define DEVDMASTATUS_BUFF_COUNT (_U_(0xFFFF) << DEVDMASTATUS_BUFF_COUNT_Pos) /**< (DEVDMASTATUS) Buffer Byte Count Mask */ +#define DEVDMASTATUS_Msk _U_(0xFFFF0073) /**< (DEVDMASTATUS) Register Mask */ + + +/* -------- HSTDMANXTDSC : (USBHS Offset: 0x00) (R/W 32) Host DMA Channel Next Descriptor Address Register -------- */ + +#define HSTDMANXTDSC_OFFSET (0x00) /**< (HSTDMANXTDSC) Host DMA Channel Next Descriptor Address Register Offset */ + +#define HSTDMANXTDSC_NXT_DSC_ADD_Pos 0 /**< (HSTDMANXTDSC) Next Descriptor Address Position */ +#define HSTDMANXTDSC_NXT_DSC_ADD (_U_(0xFFFFFFFF) << HSTDMANXTDSC_NXT_DSC_ADD_Pos) /**< (HSTDMANXTDSC) Next Descriptor Address Mask */ +#define HSTDMANXTDSC_Msk _U_(0xFFFFFFFF) /**< (HSTDMANXTDSC) Register Mask */ + + +/* -------- HSTDMAADDRESS : (USBHS Offset: 0x04) (R/W 32) Host DMA Channel Address Register -------- */ + +#define HSTDMAADDRESS_OFFSET (0x04) /**< (HSTDMAADDRESS) Host DMA Channel Address Register Offset */ + +#define HSTDMAADDRESS_BUFF_ADD_Pos 0 /**< (HSTDMAADDRESS) Buffer Address Position */ +#define HSTDMAADDRESS_BUFF_ADD (_U_(0xFFFFFFFF) << HSTDMAADDRESS_BUFF_ADD_Pos) /**< (HSTDMAADDRESS) Buffer Address Mask */ +#define HSTDMAADDRESS_Msk _U_(0xFFFFFFFF) /**< (HSTDMAADDRESS) Register Mask */ + + +/* -------- HSTDMACONTROL : (USBHS Offset: 0x08) (R/W 32) Host DMA Channel Control Register -------- */ + +#define HSTDMACONTROL_OFFSET (0x08) /**< (HSTDMACONTROL) Host DMA Channel Control Register Offset */ + +#define HSTDMACONTROL_CHANN_ENB_Pos 0 /**< (HSTDMACONTROL) Channel Enable Command Position */ +#define HSTDMACONTROL_CHANN_ENB (_U_(0x1) << HSTDMACONTROL_CHANN_ENB_Pos) /**< (HSTDMACONTROL) Channel Enable Command Mask */ +#define HSTDMACONTROL_LDNXT_DSC_Pos 1 /**< (HSTDMACONTROL) Load Next Channel Transfer Descriptor Enable Command Position */ +#define HSTDMACONTROL_LDNXT_DSC (_U_(0x1) << HSTDMACONTROL_LDNXT_DSC_Pos) /**< (HSTDMACONTROL) Load Next Channel Transfer Descriptor Enable Command Mask */ +#define HSTDMACONTROL_END_TR_EN_Pos 2 /**< (HSTDMACONTROL) End of Transfer Enable Control (OUT transfers only) Position */ +#define HSTDMACONTROL_END_TR_EN (_U_(0x1) << HSTDMACONTROL_END_TR_EN_Pos) /**< (HSTDMACONTROL) End of Transfer Enable Control (OUT transfers only) Mask */ +#define HSTDMACONTROL_END_B_EN_Pos 3 /**< (HSTDMACONTROL) End of Buffer Enable Control Position */ +#define HSTDMACONTROL_END_B_EN (_U_(0x1) << HSTDMACONTROL_END_B_EN_Pos) /**< (HSTDMACONTROL) End of Buffer Enable Control Mask */ +#define HSTDMACONTROL_END_TR_IT_Pos 4 /**< (HSTDMACONTROL) End of Transfer Interrupt Enable Position */ +#define HSTDMACONTROL_END_TR_IT (_U_(0x1) << HSTDMACONTROL_END_TR_IT_Pos) /**< (HSTDMACONTROL) End of Transfer Interrupt Enable Mask */ +#define HSTDMACONTROL_END_BUFFIT_Pos 5 /**< (HSTDMACONTROL) End of Buffer Interrupt Enable Position */ +#define HSTDMACONTROL_END_BUFFIT (_U_(0x1) << HSTDMACONTROL_END_BUFFIT_Pos) /**< (HSTDMACONTROL) End of Buffer Interrupt Enable Mask */ +#define HSTDMACONTROL_DESC_LD_IT_Pos 6 /**< (HSTDMACONTROL) Descriptor Loaded Interrupt Enable Position */ +#define HSTDMACONTROL_DESC_LD_IT (_U_(0x1) << HSTDMACONTROL_DESC_LD_IT_Pos) /**< (HSTDMACONTROL) Descriptor Loaded Interrupt Enable Mask */ +#define HSTDMACONTROL_BURST_LCK_Pos 7 /**< (HSTDMACONTROL) Burst Lock Enable Position */ +#define HSTDMACONTROL_BURST_LCK (_U_(0x1) << HSTDMACONTROL_BURST_LCK_Pos) /**< (HSTDMACONTROL) Burst Lock Enable Mask */ +#define HSTDMACONTROL_BUFF_LENGTH_Pos 16 /**< (HSTDMACONTROL) Buffer Byte Length (Write-only) Position */ +#define HSTDMACONTROL_BUFF_LENGTH (_U_(0xFFFF) << HSTDMACONTROL_BUFF_LENGTH_Pos) /**< (HSTDMACONTROL) Buffer Byte Length (Write-only) Mask */ +#define HSTDMACONTROL_Msk _U_(0xFFFF00FF) /**< (HSTDMACONTROL) Register Mask */ + + +/* -------- HSTDMASTATUS : (USBHS Offset: 0x0c) (R/W 32) Host DMA Channel Status Register -------- */ + +#define HSTDMASTATUS_OFFSET (0x0C) /**< (HSTDMASTATUS) Host DMA Channel Status Register Offset */ + +#define HSTDMASTATUS_CHANN_ENB_Pos 0 /**< (HSTDMASTATUS) Channel Enable Status Position */ +#define HSTDMASTATUS_CHANN_ENB (_U_(0x1) << HSTDMASTATUS_CHANN_ENB_Pos) /**< (HSTDMASTATUS) Channel Enable Status Mask */ +#define HSTDMASTATUS_CHANN_ACT_Pos 1 /**< (HSTDMASTATUS) Channel Active Status Position */ +#define HSTDMASTATUS_CHANN_ACT (_U_(0x1) << HSTDMASTATUS_CHANN_ACT_Pos) /**< (HSTDMASTATUS) Channel Active Status Mask */ +#define HSTDMASTATUS_END_TR_ST_Pos 4 /**< (HSTDMASTATUS) End of Channel Transfer Status Position */ +#define HSTDMASTATUS_END_TR_ST (_U_(0x1) << HSTDMASTATUS_END_TR_ST_Pos) /**< (HSTDMASTATUS) End of Channel Transfer Status Mask */ +#define HSTDMASTATUS_END_BF_ST_Pos 5 /**< (HSTDMASTATUS) End of Channel Buffer Status Position */ +#define HSTDMASTATUS_END_BF_ST (_U_(0x1) << HSTDMASTATUS_END_BF_ST_Pos) /**< (HSTDMASTATUS) End of Channel Buffer Status Mask */ +#define HSTDMASTATUS_DESC_LDST_Pos 6 /**< (HSTDMASTATUS) Descriptor Loaded Status Position */ +#define HSTDMASTATUS_DESC_LDST (_U_(0x1) << HSTDMASTATUS_DESC_LDST_Pos) /**< (HSTDMASTATUS) Descriptor Loaded Status Mask */ +#define HSTDMASTATUS_BUFF_COUNT_Pos 16 /**< (HSTDMASTATUS) Buffer Byte Count Position */ +#define HSTDMASTATUS_BUFF_COUNT (_U_(0xFFFF) << HSTDMASTATUS_BUFF_COUNT_Pos) /**< (HSTDMASTATUS) Buffer Byte Count Mask */ +#define HSTDMASTATUS_Msk _U_(0xFFFF0073) /**< (HSTDMASTATUS) Register Mask */ + + +/* -------- DEVCTRL : (USBHS Offset: 0x00) (R/W 32) Device General Control Register -------- */ + +#define DEVCTRL_OFFSET (0x00) /**< (DEVCTRL) Device General Control Register Offset */ + +#define DEVCTRL_UADD_Pos 0 /**< (DEVCTRL) USB Address Position */ +#define DEVCTRL_UADD (_U_(0x7F) << DEVCTRL_UADD_Pos) /**< (DEVCTRL) USB Address Mask */ +#define DEVCTRL_ADDEN_Pos 7 /**< (DEVCTRL) Address Enable Position */ +#define DEVCTRL_ADDEN (_U_(0x1) << DEVCTRL_ADDEN_Pos) /**< (DEVCTRL) Address Enable Mask */ +#define DEVCTRL_DETACH_Pos 8 /**< (DEVCTRL) Detach Position */ +#define DEVCTRL_DETACH (_U_(0x1) << DEVCTRL_DETACH_Pos) /**< (DEVCTRL) Detach Mask */ +#define DEVCTRL_RMWKUP_Pos 9 /**< (DEVCTRL) Remote Wake-Up Position */ +#define DEVCTRL_RMWKUP (_U_(0x1) << DEVCTRL_RMWKUP_Pos) /**< (DEVCTRL) Remote Wake-Up Mask */ +#define DEVCTRL_SPDCONF_Pos 10 /**< (DEVCTRL) Mode Configuration Position */ +#define DEVCTRL_SPDCONF (_U_(0x3) << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) Mode Configuration Mask */ +#define DEVCTRL_SPDCONF_NORMAL_Val _U_(0x0) /**< (DEVCTRL) The peripheral starts in Full-speed mode and performs a high-speed reset to switch to High-speed mode if the host is high-speed-capable. */ +#define DEVCTRL_SPDCONF_LOW_POWER_Val _U_(0x1) /**< (DEVCTRL) For a better consumption, if high speed is not needed. */ +#define DEVCTRL_SPDCONF_HIGH_SPEED_Val _U_(0x2) /**< (DEVCTRL) Forced high speed. */ +#define DEVCTRL_SPDCONF_FORCED_FS_Val _U_(0x3) /**< (DEVCTRL) The peripheral remains in Full-speed mode whatever the host speed capability. */ +#define DEVCTRL_SPDCONF_NORMAL (DEVCTRL_SPDCONF_NORMAL_Val << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) The peripheral starts in Full-speed mode and performs a high-speed reset to switch to High-speed mode if the host is high-speed-capable. Position */ +#define DEVCTRL_SPDCONF_LOW_POWER (DEVCTRL_SPDCONF_LOW_POWER_Val << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) For a better consumption, if high speed is not needed. Position */ +#define DEVCTRL_SPDCONF_HIGH_SPEED (DEVCTRL_SPDCONF_HIGH_SPEED_Val << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) Forced high speed. Position */ +#define DEVCTRL_SPDCONF_FORCED_FS (DEVCTRL_SPDCONF_FORCED_FS_Val << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) The peripheral remains in Full-speed mode whatever the host speed capability. Position */ +#define DEVCTRL_LS_Pos 12 /**< (DEVCTRL) Low-Speed Mode Force Position */ +#define DEVCTRL_LS (_U_(0x1) << DEVCTRL_LS_Pos) /**< (DEVCTRL) Low-Speed Mode Force Mask */ +#define DEVCTRL_TSTJ_Pos 13 /**< (DEVCTRL) Test mode J Position */ +#define DEVCTRL_TSTJ (_U_(0x1) << DEVCTRL_TSTJ_Pos) /**< (DEVCTRL) Test mode J Mask */ +#define DEVCTRL_TSTK_Pos 14 /**< (DEVCTRL) Test mode K Position */ +#define DEVCTRL_TSTK (_U_(0x1) << DEVCTRL_TSTK_Pos) /**< (DEVCTRL) Test mode K Mask */ +#define DEVCTRL_TSTPCKT_Pos 15 /**< (DEVCTRL) Test packet mode Position */ +#define DEVCTRL_TSTPCKT (_U_(0x1) << DEVCTRL_TSTPCKT_Pos) /**< (DEVCTRL) Test packet mode Mask */ +#define DEVCTRL_OPMODE2_Pos 16 /**< (DEVCTRL) Specific Operational mode Position */ +#define DEVCTRL_OPMODE2 (_U_(0x1) << DEVCTRL_OPMODE2_Pos) /**< (DEVCTRL) Specific Operational mode Mask */ +#define DEVCTRL_Msk _U_(0x1FFFF) /**< (DEVCTRL) Register Mask */ + +#define DEVCTRL_OPMODE_Pos 16 /**< (DEVCTRL Position) Specific Operational mode */ +#define DEVCTRL_OPMODE (_U_(0x1) << DEVCTRL_OPMODE_Pos) /**< (DEVCTRL Mask) OPMODE */ + +/* -------- DEVISR : (USBHS Offset: 0x04) (R/ 32) Device Global Interrupt Status Register -------- */ + +#define DEVISR_OFFSET (0x04) /**< (DEVISR) Device Global Interrupt Status Register Offset */ + +#define DEVISR_SUSP_Pos 0 /**< (DEVISR) Suspend Interrupt Position */ +#define DEVISR_SUSP (_U_(0x1) << DEVISR_SUSP_Pos) /**< (DEVISR) Suspend Interrupt Mask */ +#define DEVISR_MSOF_Pos 1 /**< (DEVISR) Micro Start of Frame Interrupt Position */ +#define DEVISR_MSOF (_U_(0x1) << DEVISR_MSOF_Pos) /**< (DEVISR) Micro Start of Frame Interrupt Mask */ +#define DEVISR_SOF_Pos 2 /**< (DEVISR) Start of Frame Interrupt Position */ +#define DEVISR_SOF (_U_(0x1) << DEVISR_SOF_Pos) /**< (DEVISR) Start of Frame Interrupt Mask */ +#define DEVISR_EORST_Pos 3 /**< (DEVISR) End of Reset Interrupt Position */ +#define DEVISR_EORST (_U_(0x1) << DEVISR_EORST_Pos) /**< (DEVISR) End of Reset Interrupt Mask */ +#define DEVISR_WAKEUP_Pos 4 /**< (DEVISR) Wake-Up Interrupt Position */ +#define DEVISR_WAKEUP (_U_(0x1) << DEVISR_WAKEUP_Pos) /**< (DEVISR) Wake-Up Interrupt Mask */ +#define DEVISR_EORSM_Pos 5 /**< (DEVISR) End of Resume Interrupt Position */ +#define DEVISR_EORSM (_U_(0x1) << DEVISR_EORSM_Pos) /**< (DEVISR) End of Resume Interrupt Mask */ +#define DEVISR_UPRSM_Pos 6 /**< (DEVISR) Upstream Resume Interrupt Position */ +#define DEVISR_UPRSM (_U_(0x1) << DEVISR_UPRSM_Pos) /**< (DEVISR) Upstream Resume Interrupt Mask */ +#define DEVISR_PEP_0_Pos 12 /**< (DEVISR) Endpoint 0 Interrupt Position */ +#define DEVISR_PEP_0 (_U_(0x1) << DEVISR_PEP_0_Pos) /**< (DEVISR) Endpoint 0 Interrupt Mask */ +#define DEVISR_PEP_1_Pos 13 /**< (DEVISR) Endpoint 1 Interrupt Position */ +#define DEVISR_PEP_1 (_U_(0x1) << DEVISR_PEP_1_Pos) /**< (DEVISR) Endpoint 1 Interrupt Mask */ +#define DEVISR_PEP_2_Pos 14 /**< (DEVISR) Endpoint 2 Interrupt Position */ +#define DEVISR_PEP_2 (_U_(0x1) << DEVISR_PEP_2_Pos) /**< (DEVISR) Endpoint 2 Interrupt Mask */ +#define DEVISR_PEP_3_Pos 15 /**< (DEVISR) Endpoint 3 Interrupt Position */ +#define DEVISR_PEP_3 (_U_(0x1) << DEVISR_PEP_3_Pos) /**< (DEVISR) Endpoint 3 Interrupt Mask */ +#define DEVISR_PEP_4_Pos 16 /**< (DEVISR) Endpoint 4 Interrupt Position */ +#define DEVISR_PEP_4 (_U_(0x1) << DEVISR_PEP_4_Pos) /**< (DEVISR) Endpoint 4 Interrupt Mask */ +#define DEVISR_PEP_5_Pos 17 /**< (DEVISR) Endpoint 5 Interrupt Position */ +#define DEVISR_PEP_5 (_U_(0x1) << DEVISR_PEP_5_Pos) /**< (DEVISR) Endpoint 5 Interrupt Mask */ +#define DEVISR_PEP_6_Pos 18 /**< (DEVISR) Endpoint 6 Interrupt Position */ +#define DEVISR_PEP_6 (_U_(0x1) << DEVISR_PEP_6_Pos) /**< (DEVISR) Endpoint 6 Interrupt Mask */ +#define DEVISR_PEP_7_Pos 19 /**< (DEVISR) Endpoint 7 Interrupt Position */ +#define DEVISR_PEP_7 (_U_(0x1) << DEVISR_PEP_7_Pos) /**< (DEVISR) Endpoint 7 Interrupt Mask */ +#define DEVISR_PEP_8_Pos 20 /**< (DEVISR) Endpoint 8 Interrupt Position */ +#define DEVISR_PEP_8 (_U_(0x1) << DEVISR_PEP_8_Pos) /**< (DEVISR) Endpoint 8 Interrupt Mask */ +#define DEVISR_PEP_9_Pos 21 /**< (DEVISR) Endpoint 9 Interrupt Position */ +#define DEVISR_PEP_9 (_U_(0x1) << DEVISR_PEP_9_Pos) /**< (DEVISR) Endpoint 9 Interrupt Mask */ +#define DEVISR_DMA_1_Pos 25 /**< (DEVISR) DMA Channel 1 Interrupt Position */ +#define DEVISR_DMA_1 (_U_(0x1) << DEVISR_DMA_1_Pos) /**< (DEVISR) DMA Channel 1 Interrupt Mask */ +#define DEVISR_DMA_2_Pos 26 /**< (DEVISR) DMA Channel 2 Interrupt Position */ +#define DEVISR_DMA_2 (_U_(0x1) << DEVISR_DMA_2_Pos) /**< (DEVISR) DMA Channel 2 Interrupt Mask */ +#define DEVISR_DMA_3_Pos 27 /**< (DEVISR) DMA Channel 3 Interrupt Position */ +#define DEVISR_DMA_3 (_U_(0x1) << DEVISR_DMA_3_Pos) /**< (DEVISR) DMA Channel 3 Interrupt Mask */ +#define DEVISR_DMA_4_Pos 28 /**< (DEVISR) DMA Channel 4 Interrupt Position */ +#define DEVISR_DMA_4 (_U_(0x1) << DEVISR_DMA_4_Pos) /**< (DEVISR) DMA Channel 4 Interrupt Mask */ +#define DEVISR_DMA_5_Pos 29 /**< (DEVISR) DMA Channel 5 Interrupt Position */ +#define DEVISR_DMA_5 (_U_(0x1) << DEVISR_DMA_5_Pos) /**< (DEVISR) DMA Channel 5 Interrupt Mask */ +#define DEVISR_DMA_6_Pos 30 /**< (DEVISR) DMA Channel 6 Interrupt Position */ +#define DEVISR_DMA_6 (_U_(0x1) << DEVISR_DMA_6_Pos) /**< (DEVISR) DMA Channel 6 Interrupt Mask */ +#define DEVISR_DMA_7_Pos 31 /**< (DEVISR) DMA Channel 7 Interrupt Position */ +#define DEVISR_DMA_7 (_U_(0x1) << DEVISR_DMA_7_Pos) /**< (DEVISR) DMA Channel 7 Interrupt Mask */ +#define DEVISR_Msk _U_(0xFE3FF07F) /**< (DEVISR) Register Mask */ + +#define DEVISR_PEP__Pos 12 /**< (DEVISR Position) Endpoint x Interrupt */ +#define DEVISR_PEP_ (_U_(0x3FF) << DEVISR_PEP__Pos) /**< (DEVISR Mask) PEP_ */ +#define DEVISR_DMA__Pos 25 /**< (DEVISR Position) DMA Channel 7 Interrupt */ +#define DEVISR_DMA_ (_U_(0x7F) << DEVISR_DMA__Pos) /**< (DEVISR Mask) DMA_ */ + +/* -------- DEVICR : (USBHS Offset: 0x08) (/W 32) Device Global Interrupt Clear Register -------- */ + +#define DEVICR_OFFSET (0x08) /**< (DEVICR) Device Global Interrupt Clear Register Offset */ + +#define DEVICR_SUSPC_Pos 0 /**< (DEVICR) Suspend Interrupt Clear Position */ +#define DEVICR_SUSPC (_U_(0x1) << DEVICR_SUSPC_Pos) /**< (DEVICR) Suspend Interrupt Clear Mask */ +#define DEVICR_MSOFC_Pos 1 /**< (DEVICR) Micro Start of Frame Interrupt Clear Position */ +#define DEVICR_MSOFC (_U_(0x1) << DEVICR_MSOFC_Pos) /**< (DEVICR) Micro Start of Frame Interrupt Clear Mask */ +#define DEVICR_SOFC_Pos 2 /**< (DEVICR) Start of Frame Interrupt Clear Position */ +#define DEVICR_SOFC (_U_(0x1) << DEVICR_SOFC_Pos) /**< (DEVICR) Start of Frame Interrupt Clear Mask */ +#define DEVICR_EORSTC_Pos 3 /**< (DEVICR) End of Reset Interrupt Clear Position */ +#define DEVICR_EORSTC (_U_(0x1) << DEVICR_EORSTC_Pos) /**< (DEVICR) End of Reset Interrupt Clear Mask */ +#define DEVICR_WAKEUPC_Pos 4 /**< (DEVICR) Wake-Up Interrupt Clear Position */ +#define DEVICR_WAKEUPC (_U_(0x1) << DEVICR_WAKEUPC_Pos) /**< (DEVICR) Wake-Up Interrupt Clear Mask */ +#define DEVICR_EORSMC_Pos 5 /**< (DEVICR) End of Resume Interrupt Clear Position */ +#define DEVICR_EORSMC (_U_(0x1) << DEVICR_EORSMC_Pos) /**< (DEVICR) End of Resume Interrupt Clear Mask */ +#define DEVICR_UPRSMC_Pos 6 /**< (DEVICR) Upstream Resume Interrupt Clear Position */ +#define DEVICR_UPRSMC (_U_(0x1) << DEVICR_UPRSMC_Pos) /**< (DEVICR) Upstream Resume Interrupt Clear Mask */ +#define DEVICR_Msk _U_(0x7F) /**< (DEVICR) Register Mask */ + + +/* -------- DEVIFR : (USBHS Offset: 0x0c) (/W 32) Device Global Interrupt Set Register -------- */ + +#define DEVIFR_OFFSET (0x0C) /**< (DEVIFR) Device Global Interrupt Set Register Offset */ + +#define DEVIFR_SUSPS_Pos 0 /**< (DEVIFR) Suspend Interrupt Set Position */ +#define DEVIFR_SUSPS (_U_(0x1) << DEVIFR_SUSPS_Pos) /**< (DEVIFR) Suspend Interrupt Set Mask */ +#define DEVIFR_MSOFS_Pos 1 /**< (DEVIFR) Micro Start of Frame Interrupt Set Position */ +#define DEVIFR_MSOFS (_U_(0x1) << DEVIFR_MSOFS_Pos) /**< (DEVIFR) Micro Start of Frame Interrupt Set Mask */ +#define DEVIFR_SOFS_Pos 2 /**< (DEVIFR) Start of Frame Interrupt Set Position */ +#define DEVIFR_SOFS (_U_(0x1) << DEVIFR_SOFS_Pos) /**< (DEVIFR) Start of Frame Interrupt Set Mask */ +#define DEVIFR_EORSTS_Pos 3 /**< (DEVIFR) End of Reset Interrupt Set Position */ +#define DEVIFR_EORSTS (_U_(0x1) << DEVIFR_EORSTS_Pos) /**< (DEVIFR) End of Reset Interrupt Set Mask */ +#define DEVIFR_WAKEUPS_Pos 4 /**< (DEVIFR) Wake-Up Interrupt Set Position */ +#define DEVIFR_WAKEUPS (_U_(0x1) << DEVIFR_WAKEUPS_Pos) /**< (DEVIFR) Wake-Up Interrupt Set Mask */ +#define DEVIFR_EORSMS_Pos 5 /**< (DEVIFR) End of Resume Interrupt Set Position */ +#define DEVIFR_EORSMS (_U_(0x1) << DEVIFR_EORSMS_Pos) /**< (DEVIFR) End of Resume Interrupt Set Mask */ +#define DEVIFR_UPRSMS_Pos 6 /**< (DEVIFR) Upstream Resume Interrupt Set Position */ +#define DEVIFR_UPRSMS (_U_(0x1) << DEVIFR_UPRSMS_Pos) /**< (DEVIFR) Upstream Resume Interrupt Set Mask */ +#define DEVIFR_DMA_1_Pos 25 /**< (DEVIFR) DMA Channel 1 Interrupt Set Position */ +#define DEVIFR_DMA_1 (_U_(0x1) << DEVIFR_DMA_1_Pos) /**< (DEVIFR) DMA Channel 1 Interrupt Set Mask */ +#define DEVIFR_DMA_2_Pos 26 /**< (DEVIFR) DMA Channel 2 Interrupt Set Position */ +#define DEVIFR_DMA_2 (_U_(0x1) << DEVIFR_DMA_2_Pos) /**< (DEVIFR) DMA Channel 2 Interrupt Set Mask */ +#define DEVIFR_DMA_3_Pos 27 /**< (DEVIFR) DMA Channel 3 Interrupt Set Position */ +#define DEVIFR_DMA_3 (_U_(0x1) << DEVIFR_DMA_3_Pos) /**< (DEVIFR) DMA Channel 3 Interrupt Set Mask */ +#define DEVIFR_DMA_4_Pos 28 /**< (DEVIFR) DMA Channel 4 Interrupt Set Position */ +#define DEVIFR_DMA_4 (_U_(0x1) << DEVIFR_DMA_4_Pos) /**< (DEVIFR) DMA Channel 4 Interrupt Set Mask */ +#define DEVIFR_DMA_5_Pos 29 /**< (DEVIFR) DMA Channel 5 Interrupt Set Position */ +#define DEVIFR_DMA_5 (_U_(0x1) << DEVIFR_DMA_5_Pos) /**< (DEVIFR) DMA Channel 5 Interrupt Set Mask */ +#define DEVIFR_DMA_6_Pos 30 /**< (DEVIFR) DMA Channel 6 Interrupt Set Position */ +#define DEVIFR_DMA_6 (_U_(0x1) << DEVIFR_DMA_6_Pos) /**< (DEVIFR) DMA Channel 6 Interrupt Set Mask */ +#define DEVIFR_DMA_7_Pos 31 /**< (DEVIFR) DMA Channel 7 Interrupt Set Position */ +#define DEVIFR_DMA_7 (_U_(0x1) << DEVIFR_DMA_7_Pos) /**< (DEVIFR) DMA Channel 7 Interrupt Set Mask */ +#define DEVIFR_Msk _U_(0xFE00007F) /**< (DEVIFR) Register Mask */ + +#define DEVIFR_DMA__Pos 25 /**< (DEVIFR Position) DMA Channel 7 Interrupt Set */ +#define DEVIFR_DMA_ (_U_(0x7F) << DEVIFR_DMA__Pos) /**< (DEVIFR Mask) DMA_ */ + +/* -------- DEVIMR : (USBHS Offset: 0x10) (R/ 32) Device Global Interrupt Mask Register -------- */ + +#define DEVIMR_OFFSET (0x10) /**< (DEVIMR) Device Global Interrupt Mask Register Offset */ + +#define DEVIMR_SUSPE_Pos 0 /**< (DEVIMR) Suspend Interrupt Mask Position */ +#define DEVIMR_SUSPE (_U_(0x1) << DEVIMR_SUSPE_Pos) /**< (DEVIMR) Suspend Interrupt Mask Mask */ +#define DEVIMR_MSOFE_Pos 1 /**< (DEVIMR) Micro Start of Frame Interrupt Mask Position */ +#define DEVIMR_MSOFE (_U_(0x1) << DEVIMR_MSOFE_Pos) /**< (DEVIMR) Micro Start of Frame Interrupt Mask Mask */ +#define DEVIMR_SOFE_Pos 2 /**< (DEVIMR) Start of Frame Interrupt Mask Position */ +#define DEVIMR_SOFE (_U_(0x1) << DEVIMR_SOFE_Pos) /**< (DEVIMR) Start of Frame Interrupt Mask Mask */ +#define DEVIMR_EORSTE_Pos 3 /**< (DEVIMR) End of Reset Interrupt Mask Position */ +#define DEVIMR_EORSTE (_U_(0x1) << DEVIMR_EORSTE_Pos) /**< (DEVIMR) End of Reset Interrupt Mask Mask */ +#define DEVIMR_WAKEUPE_Pos 4 /**< (DEVIMR) Wake-Up Interrupt Mask Position */ +#define DEVIMR_WAKEUPE (_U_(0x1) << DEVIMR_WAKEUPE_Pos) /**< (DEVIMR) Wake-Up Interrupt Mask Mask */ +#define DEVIMR_EORSME_Pos 5 /**< (DEVIMR) End of Resume Interrupt Mask Position */ +#define DEVIMR_EORSME (_U_(0x1) << DEVIMR_EORSME_Pos) /**< (DEVIMR) End of Resume Interrupt Mask Mask */ +#define DEVIMR_UPRSME_Pos 6 /**< (DEVIMR) Upstream Resume Interrupt Mask Position */ +#define DEVIMR_UPRSME (_U_(0x1) << DEVIMR_UPRSME_Pos) /**< (DEVIMR) Upstream Resume Interrupt Mask Mask */ +#define DEVIMR_PEP_0_Pos 12 /**< (DEVIMR) Endpoint 0 Interrupt Mask Position */ +#define DEVIMR_PEP_0 (_U_(0x1) << DEVIMR_PEP_0_Pos) /**< (DEVIMR) Endpoint 0 Interrupt Mask Mask */ +#define DEVIMR_PEP_1_Pos 13 /**< (DEVIMR) Endpoint 1 Interrupt Mask Position */ +#define DEVIMR_PEP_1 (_U_(0x1) << DEVIMR_PEP_1_Pos) /**< (DEVIMR) Endpoint 1 Interrupt Mask Mask */ +#define DEVIMR_PEP_2_Pos 14 /**< (DEVIMR) Endpoint 2 Interrupt Mask Position */ +#define DEVIMR_PEP_2 (_U_(0x1) << DEVIMR_PEP_2_Pos) /**< (DEVIMR) Endpoint 2 Interrupt Mask Mask */ +#define DEVIMR_PEP_3_Pos 15 /**< (DEVIMR) Endpoint 3 Interrupt Mask Position */ +#define DEVIMR_PEP_3 (_U_(0x1) << DEVIMR_PEP_3_Pos) /**< (DEVIMR) Endpoint 3 Interrupt Mask Mask */ +#define DEVIMR_PEP_4_Pos 16 /**< (DEVIMR) Endpoint 4 Interrupt Mask Position */ +#define DEVIMR_PEP_4 (_U_(0x1) << DEVIMR_PEP_4_Pos) /**< (DEVIMR) Endpoint 4 Interrupt Mask Mask */ +#define DEVIMR_PEP_5_Pos 17 /**< (DEVIMR) Endpoint 5 Interrupt Mask Position */ +#define DEVIMR_PEP_5 (_U_(0x1) << DEVIMR_PEP_5_Pos) /**< (DEVIMR) Endpoint 5 Interrupt Mask Mask */ +#define DEVIMR_PEP_6_Pos 18 /**< (DEVIMR) Endpoint 6 Interrupt Mask Position */ +#define DEVIMR_PEP_6 (_U_(0x1) << DEVIMR_PEP_6_Pos) /**< (DEVIMR) Endpoint 6 Interrupt Mask Mask */ +#define DEVIMR_PEP_7_Pos 19 /**< (DEVIMR) Endpoint 7 Interrupt Mask Position */ +#define DEVIMR_PEP_7 (_U_(0x1) << DEVIMR_PEP_7_Pos) /**< (DEVIMR) Endpoint 7 Interrupt Mask Mask */ +#define DEVIMR_PEP_8_Pos 20 /**< (DEVIMR) Endpoint 8 Interrupt Mask Position */ +#define DEVIMR_PEP_8 (_U_(0x1) << DEVIMR_PEP_8_Pos) /**< (DEVIMR) Endpoint 8 Interrupt Mask Mask */ +#define DEVIMR_PEP_9_Pos 21 /**< (DEVIMR) Endpoint 9 Interrupt Mask Position */ +#define DEVIMR_PEP_9 (_U_(0x1) << DEVIMR_PEP_9_Pos) /**< (DEVIMR) Endpoint 9 Interrupt Mask Mask */ +#define DEVIMR_DMA_1_Pos 25 /**< (DEVIMR) DMA Channel 1 Interrupt Mask Position */ +#define DEVIMR_DMA_1 (_U_(0x1) << DEVIMR_DMA_1_Pos) /**< (DEVIMR) DMA Channel 1 Interrupt Mask Mask */ +#define DEVIMR_DMA_2_Pos 26 /**< (DEVIMR) DMA Channel 2 Interrupt Mask Position */ +#define DEVIMR_DMA_2 (_U_(0x1) << DEVIMR_DMA_2_Pos) /**< (DEVIMR) DMA Channel 2 Interrupt Mask Mask */ +#define DEVIMR_DMA_3_Pos 27 /**< (DEVIMR) DMA Channel 3 Interrupt Mask Position */ +#define DEVIMR_DMA_3 (_U_(0x1) << DEVIMR_DMA_3_Pos) /**< (DEVIMR) DMA Channel 3 Interrupt Mask Mask */ +#define DEVIMR_DMA_4_Pos 28 /**< (DEVIMR) DMA Channel 4 Interrupt Mask Position */ +#define DEVIMR_DMA_4 (_U_(0x1) << DEVIMR_DMA_4_Pos) /**< (DEVIMR) DMA Channel 4 Interrupt Mask Mask */ +#define DEVIMR_DMA_5_Pos 29 /**< (DEVIMR) DMA Channel 5 Interrupt Mask Position */ +#define DEVIMR_DMA_5 (_U_(0x1) << DEVIMR_DMA_5_Pos) /**< (DEVIMR) DMA Channel 5 Interrupt Mask Mask */ +#define DEVIMR_DMA_6_Pos 30 /**< (DEVIMR) DMA Channel 6 Interrupt Mask Position */ +#define DEVIMR_DMA_6 (_U_(0x1) << DEVIMR_DMA_6_Pos) /**< (DEVIMR) DMA Channel 6 Interrupt Mask Mask */ +#define DEVIMR_DMA_7_Pos 31 /**< (DEVIMR) DMA Channel 7 Interrupt Mask Position */ +#define DEVIMR_DMA_7 (_U_(0x1) << DEVIMR_DMA_7_Pos) /**< (DEVIMR) DMA Channel 7 Interrupt Mask Mask */ +#define DEVIMR_Msk _U_(0xFE3FF07F) /**< (DEVIMR) Register Mask */ + +#define DEVIMR_PEP__Pos 12 /**< (DEVIMR Position) Endpoint x Interrupt Mask */ +#define DEVIMR_PEP_ (_U_(0x3FF) << DEVIMR_PEP__Pos) /**< (DEVIMR Mask) PEP_ */ +#define DEVIMR_DMA__Pos 25 /**< (DEVIMR Position) DMA Channel 7 Interrupt Mask */ +#define DEVIMR_DMA_ (_U_(0x7F) << DEVIMR_DMA__Pos) /**< (DEVIMR Mask) DMA_ */ + +/* -------- DEVIDR : (USBHS Offset: 0x14) (/W 32) Device Global Interrupt Disable Register -------- */ + +#define DEVIDR_OFFSET (0x14) /**< (DEVIDR) Device Global Interrupt Disable Register Offset */ + +#define DEVIDR_SUSPEC_Pos 0 /**< (DEVIDR) Suspend Interrupt Disable Position */ +#define DEVIDR_SUSPEC (_U_(0x1) << DEVIDR_SUSPEC_Pos) /**< (DEVIDR) Suspend Interrupt Disable Mask */ +#define DEVIDR_MSOFEC_Pos 1 /**< (DEVIDR) Micro Start of Frame Interrupt Disable Position */ +#define DEVIDR_MSOFEC (_U_(0x1) << DEVIDR_MSOFEC_Pos) /**< (DEVIDR) Micro Start of Frame Interrupt Disable Mask */ +#define DEVIDR_SOFEC_Pos 2 /**< (DEVIDR) Start of Frame Interrupt Disable Position */ +#define DEVIDR_SOFEC (_U_(0x1) << DEVIDR_SOFEC_Pos) /**< (DEVIDR) Start of Frame Interrupt Disable Mask */ +#define DEVIDR_EORSTEC_Pos 3 /**< (DEVIDR) End of Reset Interrupt Disable Position */ +#define DEVIDR_EORSTEC (_U_(0x1) << DEVIDR_EORSTEC_Pos) /**< (DEVIDR) End of Reset Interrupt Disable Mask */ +#define DEVIDR_WAKEUPEC_Pos 4 /**< (DEVIDR) Wake-Up Interrupt Disable Position */ +#define DEVIDR_WAKEUPEC (_U_(0x1) << DEVIDR_WAKEUPEC_Pos) /**< (DEVIDR) Wake-Up Interrupt Disable Mask */ +#define DEVIDR_EORSMEC_Pos 5 /**< (DEVIDR) End of Resume Interrupt Disable Position */ +#define DEVIDR_EORSMEC (_U_(0x1) << DEVIDR_EORSMEC_Pos) /**< (DEVIDR) End of Resume Interrupt Disable Mask */ +#define DEVIDR_UPRSMEC_Pos 6 /**< (DEVIDR) Upstream Resume Interrupt Disable Position */ +#define DEVIDR_UPRSMEC (_U_(0x1) << DEVIDR_UPRSMEC_Pos) /**< (DEVIDR) Upstream Resume Interrupt Disable Mask */ +#define DEVIDR_PEP_0_Pos 12 /**< (DEVIDR) Endpoint 0 Interrupt Disable Position */ +#define DEVIDR_PEP_0 (_U_(0x1) << DEVIDR_PEP_0_Pos) /**< (DEVIDR) Endpoint 0 Interrupt Disable Mask */ +#define DEVIDR_PEP_1_Pos 13 /**< (DEVIDR) Endpoint 1 Interrupt Disable Position */ +#define DEVIDR_PEP_1 (_U_(0x1) << DEVIDR_PEP_1_Pos) /**< (DEVIDR) Endpoint 1 Interrupt Disable Mask */ +#define DEVIDR_PEP_2_Pos 14 /**< (DEVIDR) Endpoint 2 Interrupt Disable Position */ +#define DEVIDR_PEP_2 (_U_(0x1) << DEVIDR_PEP_2_Pos) /**< (DEVIDR) Endpoint 2 Interrupt Disable Mask */ +#define DEVIDR_PEP_3_Pos 15 /**< (DEVIDR) Endpoint 3 Interrupt Disable Position */ +#define DEVIDR_PEP_3 (_U_(0x1) << DEVIDR_PEP_3_Pos) /**< (DEVIDR) Endpoint 3 Interrupt Disable Mask */ +#define DEVIDR_PEP_4_Pos 16 /**< (DEVIDR) Endpoint 4 Interrupt Disable Position */ +#define DEVIDR_PEP_4 (_U_(0x1) << DEVIDR_PEP_4_Pos) /**< (DEVIDR) Endpoint 4 Interrupt Disable Mask */ +#define DEVIDR_PEP_5_Pos 17 /**< (DEVIDR) Endpoint 5 Interrupt Disable Position */ +#define DEVIDR_PEP_5 (_U_(0x1) << DEVIDR_PEP_5_Pos) /**< (DEVIDR) Endpoint 5 Interrupt Disable Mask */ +#define DEVIDR_PEP_6_Pos 18 /**< (DEVIDR) Endpoint 6 Interrupt Disable Position */ +#define DEVIDR_PEP_6 (_U_(0x1) << DEVIDR_PEP_6_Pos) /**< (DEVIDR) Endpoint 6 Interrupt Disable Mask */ +#define DEVIDR_PEP_7_Pos 19 /**< (DEVIDR) Endpoint 7 Interrupt Disable Position */ +#define DEVIDR_PEP_7 (_U_(0x1) << DEVIDR_PEP_7_Pos) /**< (DEVIDR) Endpoint 7 Interrupt Disable Mask */ +#define DEVIDR_PEP_8_Pos 20 /**< (DEVIDR) Endpoint 8 Interrupt Disable Position */ +#define DEVIDR_PEP_8 (_U_(0x1) << DEVIDR_PEP_8_Pos) /**< (DEVIDR) Endpoint 8 Interrupt Disable Mask */ +#define DEVIDR_PEP_9_Pos 21 /**< (DEVIDR) Endpoint 9 Interrupt Disable Position */ +#define DEVIDR_PEP_9 (_U_(0x1) << DEVIDR_PEP_9_Pos) /**< (DEVIDR) Endpoint 9 Interrupt Disable Mask */ +#define DEVIDR_DMA_1_Pos 25 /**< (DEVIDR) DMA Channel 1 Interrupt Disable Position */ +#define DEVIDR_DMA_1 (_U_(0x1) << DEVIDR_DMA_1_Pos) /**< (DEVIDR) DMA Channel 1 Interrupt Disable Mask */ +#define DEVIDR_DMA_2_Pos 26 /**< (DEVIDR) DMA Channel 2 Interrupt Disable Position */ +#define DEVIDR_DMA_2 (_U_(0x1) << DEVIDR_DMA_2_Pos) /**< (DEVIDR) DMA Channel 2 Interrupt Disable Mask */ +#define DEVIDR_DMA_3_Pos 27 /**< (DEVIDR) DMA Channel 3 Interrupt Disable Position */ +#define DEVIDR_DMA_3 (_U_(0x1) << DEVIDR_DMA_3_Pos) /**< (DEVIDR) DMA Channel 3 Interrupt Disable Mask */ +#define DEVIDR_DMA_4_Pos 28 /**< (DEVIDR) DMA Channel 4 Interrupt Disable Position */ +#define DEVIDR_DMA_4 (_U_(0x1) << DEVIDR_DMA_4_Pos) /**< (DEVIDR) DMA Channel 4 Interrupt Disable Mask */ +#define DEVIDR_DMA_5_Pos 29 /**< (DEVIDR) DMA Channel 5 Interrupt Disable Position */ +#define DEVIDR_DMA_5 (_U_(0x1) << DEVIDR_DMA_5_Pos) /**< (DEVIDR) DMA Channel 5 Interrupt Disable Mask */ +#define DEVIDR_DMA_6_Pos 30 /**< (DEVIDR) DMA Channel 6 Interrupt Disable Position */ +#define DEVIDR_DMA_6 (_U_(0x1) << DEVIDR_DMA_6_Pos) /**< (DEVIDR) DMA Channel 6 Interrupt Disable Mask */ +#define DEVIDR_DMA_7_Pos 31 /**< (DEVIDR) DMA Channel 7 Interrupt Disable Position */ +#define DEVIDR_DMA_7 (_U_(0x1) << DEVIDR_DMA_7_Pos) /**< (DEVIDR) DMA Channel 7 Interrupt Disable Mask */ +#define DEVIDR_Msk _U_(0xFE3FF07F) /**< (DEVIDR) Register Mask */ + +#define DEVIDR_PEP__Pos 12 /**< (DEVIDR Position) Endpoint x Interrupt Disable */ +#define DEVIDR_PEP_ (_U_(0x3FF) << DEVIDR_PEP__Pos) /**< (DEVIDR Mask) PEP_ */ +#define DEVIDR_DMA__Pos 25 /**< (DEVIDR Position) DMA Channel 7 Interrupt Disable */ +#define DEVIDR_DMA_ (_U_(0x7F) << DEVIDR_DMA__Pos) /**< (DEVIDR Mask) DMA_ */ + +/* -------- DEVIER : (USBHS Offset: 0x18) (/W 32) Device Global Interrupt Enable Register -------- */ + +#define DEVIER_OFFSET (0x18) /**< (DEVIER) Device Global Interrupt Enable Register Offset */ + +#define DEVIER_SUSPES_Pos 0 /**< (DEVIER) Suspend Interrupt Enable Position */ +#define DEVIER_SUSPES (_U_(0x1) << DEVIER_SUSPES_Pos) /**< (DEVIER) Suspend Interrupt Enable Mask */ +#define DEVIER_MSOFES_Pos 1 /**< (DEVIER) Micro Start of Frame Interrupt Enable Position */ +#define DEVIER_MSOFES (_U_(0x1) << DEVIER_MSOFES_Pos) /**< (DEVIER) Micro Start of Frame Interrupt Enable Mask */ +#define DEVIER_SOFES_Pos 2 /**< (DEVIER) Start of Frame Interrupt Enable Position */ +#define DEVIER_SOFES (_U_(0x1) << DEVIER_SOFES_Pos) /**< (DEVIER) Start of Frame Interrupt Enable Mask */ +#define DEVIER_EORSTES_Pos 3 /**< (DEVIER) End of Reset Interrupt Enable Position */ +#define DEVIER_EORSTES (_U_(0x1) << DEVIER_EORSTES_Pos) /**< (DEVIER) End of Reset Interrupt Enable Mask */ +#define DEVIER_WAKEUPES_Pos 4 /**< (DEVIER) Wake-Up Interrupt Enable Position */ +#define DEVIER_WAKEUPES (_U_(0x1) << DEVIER_WAKEUPES_Pos) /**< (DEVIER) Wake-Up Interrupt Enable Mask */ +#define DEVIER_EORSMES_Pos 5 /**< (DEVIER) End of Resume Interrupt Enable Position */ +#define DEVIER_EORSMES (_U_(0x1) << DEVIER_EORSMES_Pos) /**< (DEVIER) End of Resume Interrupt Enable Mask */ +#define DEVIER_UPRSMES_Pos 6 /**< (DEVIER) Upstream Resume Interrupt Enable Position */ +#define DEVIER_UPRSMES (_U_(0x1) << DEVIER_UPRSMES_Pos) /**< (DEVIER) Upstream Resume Interrupt Enable Mask */ +#define DEVIER_PEP_0_Pos 12 /**< (DEVIER) Endpoint 0 Interrupt Enable Position */ +#define DEVIER_PEP_0 (_U_(0x1) << DEVIER_PEP_0_Pos) /**< (DEVIER) Endpoint 0 Interrupt Enable Mask */ +#define DEVIER_PEP_1_Pos 13 /**< (DEVIER) Endpoint 1 Interrupt Enable Position */ +#define DEVIER_PEP_1 (_U_(0x1) << DEVIER_PEP_1_Pos) /**< (DEVIER) Endpoint 1 Interrupt Enable Mask */ +#define DEVIER_PEP_2_Pos 14 /**< (DEVIER) Endpoint 2 Interrupt Enable Position */ +#define DEVIER_PEP_2 (_U_(0x1) << DEVIER_PEP_2_Pos) /**< (DEVIER) Endpoint 2 Interrupt Enable Mask */ +#define DEVIER_PEP_3_Pos 15 /**< (DEVIER) Endpoint 3 Interrupt Enable Position */ +#define DEVIER_PEP_3 (_U_(0x1) << DEVIER_PEP_3_Pos) /**< (DEVIER) Endpoint 3 Interrupt Enable Mask */ +#define DEVIER_PEP_4_Pos 16 /**< (DEVIER) Endpoint 4 Interrupt Enable Position */ +#define DEVIER_PEP_4 (_U_(0x1) << DEVIER_PEP_4_Pos) /**< (DEVIER) Endpoint 4 Interrupt Enable Mask */ +#define DEVIER_PEP_5_Pos 17 /**< (DEVIER) Endpoint 5 Interrupt Enable Position */ +#define DEVIER_PEP_5 (_U_(0x1) << DEVIER_PEP_5_Pos) /**< (DEVIER) Endpoint 5 Interrupt Enable Mask */ +#define DEVIER_PEP_6_Pos 18 /**< (DEVIER) Endpoint 6 Interrupt Enable Position */ +#define DEVIER_PEP_6 (_U_(0x1) << DEVIER_PEP_6_Pos) /**< (DEVIER) Endpoint 6 Interrupt Enable Mask */ +#define DEVIER_PEP_7_Pos 19 /**< (DEVIER) Endpoint 7 Interrupt Enable Position */ +#define DEVIER_PEP_7 (_U_(0x1) << DEVIER_PEP_7_Pos) /**< (DEVIER) Endpoint 7 Interrupt Enable Mask */ +#define DEVIER_PEP_8_Pos 20 /**< (DEVIER) Endpoint 8 Interrupt Enable Position */ +#define DEVIER_PEP_8 (_U_(0x1) << DEVIER_PEP_8_Pos) /**< (DEVIER) Endpoint 8 Interrupt Enable Mask */ +#define DEVIER_PEP_9_Pos 21 /**< (DEVIER) Endpoint 9 Interrupt Enable Position */ +#define DEVIER_PEP_9 (_U_(0x1) << DEVIER_PEP_9_Pos) /**< (DEVIER) Endpoint 9 Interrupt Enable Mask */ +#define DEVIER_DMA_1_Pos 25 /**< (DEVIER) DMA Channel 1 Interrupt Enable Position */ +#define DEVIER_DMA_1 (_U_(0x1) << DEVIER_DMA_1_Pos) /**< (DEVIER) DMA Channel 1 Interrupt Enable Mask */ +#define DEVIER_DMA_2_Pos 26 /**< (DEVIER) DMA Channel 2 Interrupt Enable Position */ +#define DEVIER_DMA_2 (_U_(0x1) << DEVIER_DMA_2_Pos) /**< (DEVIER) DMA Channel 2 Interrupt Enable Mask */ +#define DEVIER_DMA_3_Pos 27 /**< (DEVIER) DMA Channel 3 Interrupt Enable Position */ +#define DEVIER_DMA_3 (_U_(0x1) << DEVIER_DMA_3_Pos) /**< (DEVIER) DMA Channel 3 Interrupt Enable Mask */ +#define DEVIER_DMA_4_Pos 28 /**< (DEVIER) DMA Channel 4 Interrupt Enable Position */ +#define DEVIER_DMA_4 (_U_(0x1) << DEVIER_DMA_4_Pos) /**< (DEVIER) DMA Channel 4 Interrupt Enable Mask */ +#define DEVIER_DMA_5_Pos 29 /**< (DEVIER) DMA Channel 5 Interrupt Enable Position */ +#define DEVIER_DMA_5 (_U_(0x1) << DEVIER_DMA_5_Pos) /**< (DEVIER) DMA Channel 5 Interrupt Enable Mask */ +#define DEVIER_DMA_6_Pos 30 /**< (DEVIER) DMA Channel 6 Interrupt Enable Position */ +#define DEVIER_DMA_6 (_U_(0x1) << DEVIER_DMA_6_Pos) /**< (DEVIER) DMA Channel 6 Interrupt Enable Mask */ +#define DEVIER_DMA_7_Pos 31 /**< (DEVIER) DMA Channel 7 Interrupt Enable Position */ +#define DEVIER_DMA_7 (_U_(0x1) << DEVIER_DMA_7_Pos) /**< (DEVIER) DMA Channel 7 Interrupt Enable Mask */ +#define DEVIER_Msk _U_(0xFE3FF07F) /**< (DEVIER) Register Mask */ + +#define DEVIER_PEP__Pos 12 /**< (DEVIER Position) Endpoint x Interrupt Enable */ +#define DEVIER_PEP_ (_U_(0x3FF) << DEVIER_PEP__Pos) /**< (DEVIER Mask) PEP_ */ +#define DEVIER_DMA__Pos 25 /**< (DEVIER Position) DMA Channel 7 Interrupt Enable */ +#define DEVIER_DMA_ (_U_(0x7F) << DEVIER_DMA__Pos) /**< (DEVIER Mask) DMA_ */ + +/* -------- DEVEPT : (USBHS Offset: 0x1c) (R/W 32) Device Endpoint Register -------- */ + +#define DEVEPT_OFFSET (0x1C) /**< (DEVEPT) Device Endpoint Register Offset */ + +#define DEVEPT_EPEN0_Pos 0 /**< (DEVEPT) Endpoint 0 Enable Position */ +#define DEVEPT_EPEN0 (_U_(0x1) << DEVEPT_EPEN0_Pos) /**< (DEVEPT) Endpoint 0 Enable Mask */ +#define DEVEPT_EPEN1_Pos 1 /**< (DEVEPT) Endpoint 1 Enable Position */ +#define DEVEPT_EPEN1 (_U_(0x1) << DEVEPT_EPEN1_Pos) /**< (DEVEPT) Endpoint 1 Enable Mask */ +#define DEVEPT_EPEN2_Pos 2 /**< (DEVEPT) Endpoint 2 Enable Position */ +#define DEVEPT_EPEN2 (_U_(0x1) << DEVEPT_EPEN2_Pos) /**< (DEVEPT) Endpoint 2 Enable Mask */ +#define DEVEPT_EPEN3_Pos 3 /**< (DEVEPT) Endpoint 3 Enable Position */ +#define DEVEPT_EPEN3 (_U_(0x1) << DEVEPT_EPEN3_Pos) /**< (DEVEPT) Endpoint 3 Enable Mask */ +#define DEVEPT_EPEN4_Pos 4 /**< (DEVEPT) Endpoint 4 Enable Position */ +#define DEVEPT_EPEN4 (_U_(0x1) << DEVEPT_EPEN4_Pos) /**< (DEVEPT) Endpoint 4 Enable Mask */ +#define DEVEPT_EPEN5_Pos 5 /**< (DEVEPT) Endpoint 5 Enable Position */ +#define DEVEPT_EPEN5 (_U_(0x1) << DEVEPT_EPEN5_Pos) /**< (DEVEPT) Endpoint 5 Enable Mask */ +#define DEVEPT_EPEN6_Pos 6 /**< (DEVEPT) Endpoint 6 Enable Position */ +#define DEVEPT_EPEN6 (_U_(0x1) << DEVEPT_EPEN6_Pos) /**< (DEVEPT) Endpoint 6 Enable Mask */ +#define DEVEPT_EPEN7_Pos 7 /**< (DEVEPT) Endpoint 7 Enable Position */ +#define DEVEPT_EPEN7 (_U_(0x1) << DEVEPT_EPEN7_Pos) /**< (DEVEPT) Endpoint 7 Enable Mask */ +#define DEVEPT_EPEN8_Pos 8 /**< (DEVEPT) Endpoint 8 Enable Position */ +#define DEVEPT_EPEN8 (_U_(0x1) << DEVEPT_EPEN8_Pos) /**< (DEVEPT) Endpoint 8 Enable Mask */ +#define DEVEPT_EPEN9_Pos 9 /**< (DEVEPT) Endpoint 9 Enable Position */ +#define DEVEPT_EPEN9 (_U_(0x1) << DEVEPT_EPEN9_Pos) /**< (DEVEPT) Endpoint 9 Enable Mask */ +#define DEVEPT_EPRST0_Pos 16 /**< (DEVEPT) Endpoint 0 Reset Position */ +#define DEVEPT_EPRST0 (_U_(0x1) << DEVEPT_EPRST0_Pos) /**< (DEVEPT) Endpoint 0 Reset Mask */ +#define DEVEPT_EPRST1_Pos 17 /**< (DEVEPT) Endpoint 1 Reset Position */ +#define DEVEPT_EPRST1 (_U_(0x1) << DEVEPT_EPRST1_Pos) /**< (DEVEPT) Endpoint 1 Reset Mask */ +#define DEVEPT_EPRST2_Pos 18 /**< (DEVEPT) Endpoint 2 Reset Position */ +#define DEVEPT_EPRST2 (_U_(0x1) << DEVEPT_EPRST2_Pos) /**< (DEVEPT) Endpoint 2 Reset Mask */ +#define DEVEPT_EPRST3_Pos 19 /**< (DEVEPT) Endpoint 3 Reset Position */ +#define DEVEPT_EPRST3 (_U_(0x1) << DEVEPT_EPRST3_Pos) /**< (DEVEPT) Endpoint 3 Reset Mask */ +#define DEVEPT_EPRST4_Pos 20 /**< (DEVEPT) Endpoint 4 Reset Position */ +#define DEVEPT_EPRST4 (_U_(0x1) << DEVEPT_EPRST4_Pos) /**< (DEVEPT) Endpoint 4 Reset Mask */ +#define DEVEPT_EPRST5_Pos 21 /**< (DEVEPT) Endpoint 5 Reset Position */ +#define DEVEPT_EPRST5 (_U_(0x1) << DEVEPT_EPRST5_Pos) /**< (DEVEPT) Endpoint 5 Reset Mask */ +#define DEVEPT_EPRST6_Pos 22 /**< (DEVEPT) Endpoint 6 Reset Position */ +#define DEVEPT_EPRST6 (_U_(0x1) << DEVEPT_EPRST6_Pos) /**< (DEVEPT) Endpoint 6 Reset Mask */ +#define DEVEPT_EPRST7_Pos 23 /**< (DEVEPT) Endpoint 7 Reset Position */ +#define DEVEPT_EPRST7 (_U_(0x1) << DEVEPT_EPRST7_Pos) /**< (DEVEPT) Endpoint 7 Reset Mask */ +#define DEVEPT_EPRST8_Pos 24 /**< (DEVEPT) Endpoint 8 Reset Position */ +#define DEVEPT_EPRST8 (_U_(0x1) << DEVEPT_EPRST8_Pos) /**< (DEVEPT) Endpoint 8 Reset Mask */ +#define DEVEPT_EPRST9_Pos 25 /**< (DEVEPT) Endpoint 9 Reset Position */ +#define DEVEPT_EPRST9 (_U_(0x1) << DEVEPT_EPRST9_Pos) /**< (DEVEPT) Endpoint 9 Reset Mask */ +#define DEVEPT_Msk _U_(0x3FF03FF) /**< (DEVEPT) Register Mask */ + +#define DEVEPT_EPEN_Pos 0 /**< (DEVEPT Position) Endpoint x Enable */ +#define DEVEPT_EPEN (_U_(0x3FF) << DEVEPT_EPEN_Pos) /**< (DEVEPT Mask) EPEN */ +#define DEVEPT_EPRST_Pos 16 /**< (DEVEPT Position) Endpoint 9 Reset */ +#define DEVEPT_EPRST (_U_(0x3FF) << DEVEPT_EPRST_Pos) /**< (DEVEPT Mask) EPRST */ + +/* -------- DEVFNUM : (USBHS Offset: 0x20) (R/ 32) Device Frame Number Register -------- */ + +#define DEVFNUM_OFFSET (0x20) /**< (DEVFNUM) Device Frame Number Register Offset */ + +#define DEVFNUM_MFNUM_Pos 0 /**< (DEVFNUM) Micro Frame Number Position */ +#define DEVFNUM_MFNUM (_U_(0x7) << DEVFNUM_MFNUM_Pos) /**< (DEVFNUM) Micro Frame Number Mask */ +#define DEVFNUM_FNUM_Pos 3 /**< (DEVFNUM) Frame Number Position */ +#define DEVFNUM_FNUM (_U_(0x7FF) << DEVFNUM_FNUM_Pos) /**< (DEVFNUM) Frame Number Mask */ +#define DEVFNUM_FNCERR_Pos 15 /**< (DEVFNUM) Frame Number CRC Error Position */ +#define DEVFNUM_FNCERR (_U_(0x1) << DEVFNUM_FNCERR_Pos) /**< (DEVFNUM) Frame Number CRC Error Mask */ +#define DEVFNUM_Msk _U_(0xBFFF) /**< (DEVFNUM) Register Mask */ + + +/* -------- DEVEPTCFG : (USBHS Offset: 0x100) (R/W 32) Device Endpoint Configuration Register -------- */ + +#define DEVEPTCFG_OFFSET (0x100) /**< (DEVEPTCFG) Device Endpoint Configuration Register Offset */ + +#define DEVEPTCFG_ALLOC_Pos 1 /**< (DEVEPTCFG) Endpoint Memory Allocate Position */ +#define DEVEPTCFG_ALLOC (_U_(0x1) << DEVEPTCFG_ALLOC_Pos) /**< (DEVEPTCFG) Endpoint Memory Allocate Mask */ +#define DEVEPTCFG_EPBK_Pos 2 /**< (DEVEPTCFG) Endpoint Banks Position */ +#define DEVEPTCFG_EPBK (_U_(0x3) << DEVEPTCFG_EPBK_Pos) /**< (DEVEPTCFG) Endpoint Banks Mask */ +#define DEVEPTCFG_EPBK_1_BANK_Val _U_(0x0) /**< (DEVEPTCFG) Single-bank endpoint */ +#define DEVEPTCFG_EPBK_2_BANK_Val _U_(0x1) /**< (DEVEPTCFG) Double-bank endpoint */ +#define DEVEPTCFG_EPBK_3_BANK_Val _U_(0x2) /**< (DEVEPTCFG) Triple-bank endpoint */ +#define DEVEPTCFG_EPBK_1_BANK (DEVEPTCFG_EPBK_1_BANK_Val << DEVEPTCFG_EPBK_Pos) /**< (DEVEPTCFG) Single-bank endpoint Position */ +#define DEVEPTCFG_EPBK_2_BANK (DEVEPTCFG_EPBK_2_BANK_Val << DEVEPTCFG_EPBK_Pos) /**< (DEVEPTCFG) Double-bank endpoint Position */ +#define DEVEPTCFG_EPBK_3_BANK (DEVEPTCFG_EPBK_3_BANK_Val << DEVEPTCFG_EPBK_Pos) /**< (DEVEPTCFG) Triple-bank endpoint Position */ +#define DEVEPTCFG_EPSIZE_Pos 4 /**< (DEVEPTCFG) Endpoint Size Position */ +#define DEVEPTCFG_EPSIZE (_U_(0x7) << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) Endpoint Size Mask */ +#define DEVEPTCFG_EPSIZE_8_BYTE_Val _U_(0x0) /**< (DEVEPTCFG) 8 bytes */ +#define DEVEPTCFG_EPSIZE_16_BYTE_Val _U_(0x1) /**< (DEVEPTCFG) 16 bytes */ +#define DEVEPTCFG_EPSIZE_32_BYTE_Val _U_(0x2) /**< (DEVEPTCFG) 32 bytes */ +#define DEVEPTCFG_EPSIZE_64_BYTE_Val _U_(0x3) /**< (DEVEPTCFG) 64 bytes */ +#define DEVEPTCFG_EPSIZE_128_BYTE_Val _U_(0x4) /**< (DEVEPTCFG) 128 bytes */ +#define DEVEPTCFG_EPSIZE_256_BYTE_Val _U_(0x5) /**< (DEVEPTCFG) 256 bytes */ +#define DEVEPTCFG_EPSIZE_512_BYTE_Val _U_(0x6) /**< (DEVEPTCFG) 512 bytes */ +#define DEVEPTCFG_EPSIZE_1024_BYTE_Val _U_(0x7) /**< (DEVEPTCFG) 1024 bytes */ +#define DEVEPTCFG_EPSIZE_8_BYTE (DEVEPTCFG_EPSIZE_8_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 8 bytes Position */ +#define DEVEPTCFG_EPSIZE_16_BYTE (DEVEPTCFG_EPSIZE_16_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 16 bytes Position */ +#define DEVEPTCFG_EPSIZE_32_BYTE (DEVEPTCFG_EPSIZE_32_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 32 bytes Position */ +#define DEVEPTCFG_EPSIZE_64_BYTE (DEVEPTCFG_EPSIZE_64_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 64 bytes Position */ +#define DEVEPTCFG_EPSIZE_128_BYTE (DEVEPTCFG_EPSIZE_128_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 128 bytes Position */ +#define DEVEPTCFG_EPSIZE_256_BYTE (DEVEPTCFG_EPSIZE_256_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 256 bytes Position */ +#define DEVEPTCFG_EPSIZE_512_BYTE (DEVEPTCFG_EPSIZE_512_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 512 bytes Position */ +#define DEVEPTCFG_EPSIZE_1024_BYTE (DEVEPTCFG_EPSIZE_1024_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 1024 bytes Position */ +#define DEVEPTCFG_EPDIR_Pos 8 /**< (DEVEPTCFG) Endpoint Direction Position */ +#define DEVEPTCFG_EPDIR (_U_(0x1) << DEVEPTCFG_EPDIR_Pos) /**< (DEVEPTCFG) Endpoint Direction Mask */ +#define DEVEPTCFG_EPDIR_OUT_Val _U_(0x0) /**< (DEVEPTCFG) The endpoint direction is OUT. */ +#define DEVEPTCFG_EPDIR_IN_Val _U_(0x1) /**< (DEVEPTCFG) The endpoint direction is IN (nor for control endpoints). */ +#define DEVEPTCFG_EPDIR_OUT (DEVEPTCFG_EPDIR_OUT_Val << DEVEPTCFG_EPDIR_Pos) /**< (DEVEPTCFG) The endpoint direction is OUT. Position */ +#define DEVEPTCFG_EPDIR_IN (DEVEPTCFG_EPDIR_IN_Val << DEVEPTCFG_EPDIR_Pos) /**< (DEVEPTCFG) The endpoint direction is IN (nor for control endpoints). Position */ +#define DEVEPTCFG_AUTOSW_Pos 9 /**< (DEVEPTCFG) Automatic Switch Position */ +#define DEVEPTCFG_AUTOSW (_U_(0x1) << DEVEPTCFG_AUTOSW_Pos) /**< (DEVEPTCFG) Automatic Switch Mask */ +#define DEVEPTCFG_EPTYPE_Pos 11 /**< (DEVEPTCFG) Endpoint Type Position */ +#define DEVEPTCFG_EPTYPE (_U_(0x3) << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Endpoint Type Mask */ +#define DEVEPTCFG_EPTYPE_CTRL_Val _U_(0x0) /**< (DEVEPTCFG) Control */ +#define DEVEPTCFG_EPTYPE_ISO_Val _U_(0x1) /**< (DEVEPTCFG) Isochronous */ +#define DEVEPTCFG_EPTYPE_BLK_Val _U_(0x2) /**< (DEVEPTCFG) Bulk */ +#define DEVEPTCFG_EPTYPE_INTRPT_Val _U_(0x3) /**< (DEVEPTCFG) Interrupt */ +#define DEVEPTCFG_EPTYPE_CTRL (DEVEPTCFG_EPTYPE_CTRL_Val << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Control Position */ +#define DEVEPTCFG_EPTYPE_ISO (DEVEPTCFG_EPTYPE_ISO_Val << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Isochronous Position */ +#define DEVEPTCFG_EPTYPE_BLK (DEVEPTCFG_EPTYPE_BLK_Val << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Bulk Position */ +#define DEVEPTCFG_EPTYPE_INTRPT (DEVEPTCFG_EPTYPE_INTRPT_Val << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Interrupt Position */ +#define DEVEPTCFG_NBTRANS_Pos 13 /**< (DEVEPTCFG) Number of transactions per microframe for isochronous endpoint Position */ +#define DEVEPTCFG_NBTRANS (_U_(0x3) << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Number of transactions per microframe for isochronous endpoint Mask */ +#define DEVEPTCFG_NBTRANS_0_TRANS_Val _U_(0x0) /**< (DEVEPTCFG) Reserved to endpoint that does not have the high-bandwidth isochronous capability. */ +#define DEVEPTCFG_NBTRANS_1_TRANS_Val _U_(0x1) /**< (DEVEPTCFG) Default value: one transaction per microframe. */ +#define DEVEPTCFG_NBTRANS_2_TRANS_Val _U_(0x2) /**< (DEVEPTCFG) Two transactions per microframe. This endpoint should be configured as double-bank. */ +#define DEVEPTCFG_NBTRANS_3_TRANS_Val _U_(0x3) /**< (DEVEPTCFG) Three transactions per microframe. This endpoint should be configured as triple-bank. */ +#define DEVEPTCFG_NBTRANS_0_TRANS (DEVEPTCFG_NBTRANS_0_TRANS_Val << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Reserved to endpoint that does not have the high-bandwidth isochronous capability. Position */ +#define DEVEPTCFG_NBTRANS_1_TRANS (DEVEPTCFG_NBTRANS_1_TRANS_Val << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Default value: one transaction per microframe. Position */ +#define DEVEPTCFG_NBTRANS_2_TRANS (DEVEPTCFG_NBTRANS_2_TRANS_Val << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Two transactions per microframe. This endpoint should be configured as double-bank. Position */ +#define DEVEPTCFG_NBTRANS_3_TRANS (DEVEPTCFG_NBTRANS_3_TRANS_Val << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Three transactions per microframe. This endpoint should be configured as triple-bank. Position */ +#define DEVEPTCFG_Msk _U_(0x7B7E) /**< (DEVEPTCFG) Register Mask */ + + +/* -------- DEVEPTISR : (USBHS Offset: 0x130) (R/ 32) Device Endpoint Interrupt Status Register -------- */ + +#define DEVEPTISR_OFFSET (0x130) /**< (DEVEPTISR) Device Endpoint Interrupt Status Register Offset */ + +#define DEVEPTISR_TXINI_Pos 0 /**< (DEVEPTISR) Transmitted IN Data Interrupt Position */ +#define DEVEPTISR_TXINI (_U_(0x1) << DEVEPTISR_TXINI_Pos) /**< (DEVEPTISR) Transmitted IN Data Interrupt Mask */ +#define DEVEPTISR_RXOUTI_Pos 1 /**< (DEVEPTISR) Received OUT Data Interrupt Position */ +#define DEVEPTISR_RXOUTI (_U_(0x1) << DEVEPTISR_RXOUTI_Pos) /**< (DEVEPTISR) Received OUT Data Interrupt Mask */ +#define DEVEPTISR_OVERFI_Pos 5 /**< (DEVEPTISR) Overflow Interrupt Position */ +#define DEVEPTISR_OVERFI (_U_(0x1) << DEVEPTISR_OVERFI_Pos) /**< (DEVEPTISR) Overflow Interrupt Mask */ +#define DEVEPTISR_SHORTPACKET_Pos 7 /**< (DEVEPTISR) Short Packet Interrupt Position */ +#define DEVEPTISR_SHORTPACKET (_U_(0x1) << DEVEPTISR_SHORTPACKET_Pos) /**< (DEVEPTISR) Short Packet Interrupt Mask */ +#define DEVEPTISR_DTSEQ_Pos 8 /**< (DEVEPTISR) Data Toggle Sequence Position */ +#define DEVEPTISR_DTSEQ (_U_(0x3) << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Data Toggle Sequence Mask */ +#define DEVEPTISR_DTSEQ_DATA0_Val _U_(0x0) /**< (DEVEPTISR) Data0 toggle sequence */ +#define DEVEPTISR_DTSEQ_DATA1_Val _U_(0x1) /**< (DEVEPTISR) Data1 toggle sequence */ +#define DEVEPTISR_DTSEQ_DATA2_Val _U_(0x2) /**< (DEVEPTISR) Reserved for high-bandwidth isochronous endpoint */ +#define DEVEPTISR_DTSEQ_MDATA_Val _U_(0x3) /**< (DEVEPTISR) Reserved for high-bandwidth isochronous endpoint */ +#define DEVEPTISR_DTSEQ_DATA0 (DEVEPTISR_DTSEQ_DATA0_Val << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Data0 toggle sequence Position */ +#define DEVEPTISR_DTSEQ_DATA1 (DEVEPTISR_DTSEQ_DATA1_Val << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Data1 toggle sequence Position */ +#define DEVEPTISR_DTSEQ_DATA2 (DEVEPTISR_DTSEQ_DATA2_Val << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Reserved for high-bandwidth isochronous endpoint Position */ +#define DEVEPTISR_DTSEQ_MDATA (DEVEPTISR_DTSEQ_MDATA_Val << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Reserved for high-bandwidth isochronous endpoint Position */ +#define DEVEPTISR_NBUSYBK_Pos 12 /**< (DEVEPTISR) Number of Busy Banks Position */ +#define DEVEPTISR_NBUSYBK (_U_(0x3) << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) Number of Busy Banks Mask */ +#define DEVEPTISR_NBUSYBK_0_BUSY_Val _U_(0x0) /**< (DEVEPTISR) 0 busy bank (all banks free) */ +#define DEVEPTISR_NBUSYBK_1_BUSY_Val _U_(0x1) /**< (DEVEPTISR) 1 busy bank */ +#define DEVEPTISR_NBUSYBK_2_BUSY_Val _U_(0x2) /**< (DEVEPTISR) 2 busy banks */ +#define DEVEPTISR_NBUSYBK_3_BUSY_Val _U_(0x3) /**< (DEVEPTISR) 3 busy banks */ +#define DEVEPTISR_NBUSYBK_0_BUSY (DEVEPTISR_NBUSYBK_0_BUSY_Val << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) 0 busy bank (all banks free) Position */ +#define DEVEPTISR_NBUSYBK_1_BUSY (DEVEPTISR_NBUSYBK_1_BUSY_Val << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) 1 busy bank Position */ +#define DEVEPTISR_NBUSYBK_2_BUSY (DEVEPTISR_NBUSYBK_2_BUSY_Val << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) 2 busy banks Position */ +#define DEVEPTISR_NBUSYBK_3_BUSY (DEVEPTISR_NBUSYBK_3_BUSY_Val << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) 3 busy banks Position */ +#define DEVEPTISR_CURRBK_Pos 14 /**< (DEVEPTISR) Current Bank Position */ +#define DEVEPTISR_CURRBK (_U_(0x3) << DEVEPTISR_CURRBK_Pos) /**< (DEVEPTISR) Current Bank Mask */ +#define DEVEPTISR_CURRBK_BANK0_Val _U_(0x0) /**< (DEVEPTISR) Current bank is bank0 */ +#define DEVEPTISR_CURRBK_BANK1_Val _U_(0x1) /**< (DEVEPTISR) Current bank is bank1 */ +#define DEVEPTISR_CURRBK_BANK2_Val _U_(0x2) /**< (DEVEPTISR) Current bank is bank2 */ +#define DEVEPTISR_CURRBK_BANK0 (DEVEPTISR_CURRBK_BANK0_Val << DEVEPTISR_CURRBK_Pos) /**< (DEVEPTISR) Current bank is bank0 Position */ +#define DEVEPTISR_CURRBK_BANK1 (DEVEPTISR_CURRBK_BANK1_Val << DEVEPTISR_CURRBK_Pos) /**< (DEVEPTISR) Current bank is bank1 Position */ +#define DEVEPTISR_CURRBK_BANK2 (DEVEPTISR_CURRBK_BANK2_Val << DEVEPTISR_CURRBK_Pos) /**< (DEVEPTISR) Current bank is bank2 Position */ +#define DEVEPTISR_RWALL_Pos 16 /**< (DEVEPTISR) Read/Write Allowed Position */ +#define DEVEPTISR_RWALL (_U_(0x1) << DEVEPTISR_RWALL_Pos) /**< (DEVEPTISR) Read/Write Allowed Mask */ +#define DEVEPTISR_CFGOK_Pos 18 /**< (DEVEPTISR) Configuration OK Status Position */ +#define DEVEPTISR_CFGOK (_U_(0x1) << DEVEPTISR_CFGOK_Pos) /**< (DEVEPTISR) Configuration OK Status Mask */ +#define DEVEPTISR_BYCT_Pos 20 /**< (DEVEPTISR) Byte Count Position */ +#define DEVEPTISR_BYCT (_U_(0x7FF) << DEVEPTISR_BYCT_Pos) /**< (DEVEPTISR) Byte Count Mask */ +#define DEVEPTISR_Msk _U_(0x7FF5F3A3) /**< (DEVEPTISR) Register Mask */ + +/* CTRL mode */ +#define DEVEPTISR_CTRL_RXSTPI_Pos 2 /**< (DEVEPTISR) Received SETUP Interrupt Position */ +#define DEVEPTISR_CTRL_RXSTPI (_U_(0x1) << DEVEPTISR_CTRL_RXSTPI_Pos) /**< (DEVEPTISR) Received SETUP Interrupt Mask */ +#define DEVEPTISR_CTRL_NAKOUTI_Pos 3 /**< (DEVEPTISR) NAKed OUT Interrupt Position */ +#define DEVEPTISR_CTRL_NAKOUTI (_U_(0x1) << DEVEPTISR_CTRL_NAKOUTI_Pos) /**< (DEVEPTISR) NAKed OUT Interrupt Mask */ +#define DEVEPTISR_CTRL_NAKINI_Pos 4 /**< (DEVEPTISR) NAKed IN Interrupt Position */ +#define DEVEPTISR_CTRL_NAKINI (_U_(0x1) << DEVEPTISR_CTRL_NAKINI_Pos) /**< (DEVEPTISR) NAKed IN Interrupt Mask */ +#define DEVEPTISR_CTRL_STALLEDI_Pos 6 /**< (DEVEPTISR) STALLed Interrupt Position */ +#define DEVEPTISR_CTRL_STALLEDI (_U_(0x1) << DEVEPTISR_CTRL_STALLEDI_Pos) /**< (DEVEPTISR) STALLed Interrupt Mask */ +#define DEVEPTISR_CTRL_CTRLDIR_Pos 17 /**< (DEVEPTISR) Control Direction Position */ +#define DEVEPTISR_CTRL_CTRLDIR (_U_(0x1) << DEVEPTISR_CTRL_CTRLDIR_Pos) /**< (DEVEPTISR) Control Direction Mask */ +#define DEVEPTISR_CTRL_Msk _U_(0x2005C) /**< (DEVEPTISR_CTRL) Register Mask */ + +/* ISO mode */ +#define DEVEPTISR_ISO_UNDERFI_Pos 2 /**< (DEVEPTISR) Underflow Interrupt Position */ +#define DEVEPTISR_ISO_UNDERFI (_U_(0x1) << DEVEPTISR_ISO_UNDERFI_Pos) /**< (DEVEPTISR) Underflow Interrupt Mask */ +#define DEVEPTISR_ISO_HBISOINERRI_Pos 3 /**< (DEVEPTISR) High Bandwidth Isochronous IN Underflow Error Interrupt Position */ +#define DEVEPTISR_ISO_HBISOINERRI (_U_(0x1) << DEVEPTISR_ISO_HBISOINERRI_Pos) /**< (DEVEPTISR) High Bandwidth Isochronous IN Underflow Error Interrupt Mask */ +#define DEVEPTISR_ISO_HBISOFLUSHI_Pos 4 /**< (DEVEPTISR) High Bandwidth Isochronous IN Flush Interrupt Position */ +#define DEVEPTISR_ISO_HBISOFLUSHI (_U_(0x1) << DEVEPTISR_ISO_HBISOFLUSHI_Pos) /**< (DEVEPTISR) High Bandwidth Isochronous IN Flush Interrupt Mask */ +#define DEVEPTISR_ISO_CRCERRI_Pos 6 /**< (DEVEPTISR) CRC Error Interrupt Position */ +#define DEVEPTISR_ISO_CRCERRI (_U_(0x1) << DEVEPTISR_ISO_CRCERRI_Pos) /**< (DEVEPTISR) CRC Error Interrupt Mask */ +#define DEVEPTISR_ISO_ERRORTRANS_Pos 10 /**< (DEVEPTISR) High-bandwidth Isochronous OUT Endpoint Transaction Error Interrupt Position */ +#define DEVEPTISR_ISO_ERRORTRANS (_U_(0x1) << DEVEPTISR_ISO_ERRORTRANS_Pos) /**< (DEVEPTISR) High-bandwidth Isochronous OUT Endpoint Transaction Error Interrupt Mask */ +#define DEVEPTISR_ISO_Msk _U_(0x45C) /**< (DEVEPTISR_ISO) Register Mask */ + +/* BLK mode */ +#define DEVEPTISR_BLK_RXSTPI_Pos 2 /**< (DEVEPTISR) Received SETUP Interrupt Position */ +#define DEVEPTISR_BLK_RXSTPI (_U_(0x1) << DEVEPTISR_BLK_RXSTPI_Pos) /**< (DEVEPTISR) Received SETUP Interrupt Mask */ +#define DEVEPTISR_BLK_NAKOUTI_Pos 3 /**< (DEVEPTISR) NAKed OUT Interrupt Position */ +#define DEVEPTISR_BLK_NAKOUTI (_U_(0x1) << DEVEPTISR_BLK_NAKOUTI_Pos) /**< (DEVEPTISR) NAKed OUT Interrupt Mask */ +#define DEVEPTISR_BLK_NAKINI_Pos 4 /**< (DEVEPTISR) NAKed IN Interrupt Position */ +#define DEVEPTISR_BLK_NAKINI (_U_(0x1) << DEVEPTISR_BLK_NAKINI_Pos) /**< (DEVEPTISR) NAKed IN Interrupt Mask */ +#define DEVEPTISR_BLK_STALLEDI_Pos 6 /**< (DEVEPTISR) STALLed Interrupt Position */ +#define DEVEPTISR_BLK_STALLEDI (_U_(0x1) << DEVEPTISR_BLK_STALLEDI_Pos) /**< (DEVEPTISR) STALLed Interrupt Mask */ +#define DEVEPTISR_BLK_CTRLDIR_Pos 17 /**< (DEVEPTISR) Control Direction Position */ +#define DEVEPTISR_BLK_CTRLDIR (_U_(0x1) << DEVEPTISR_BLK_CTRLDIR_Pos) /**< (DEVEPTISR) Control Direction Mask */ +#define DEVEPTISR_BLK_Msk _U_(0x2005C) /**< (DEVEPTISR_BLK) Register Mask */ + +/* INTRPT mode */ +#define DEVEPTISR_INTRPT_RXSTPI_Pos 2 /**< (DEVEPTISR) Received SETUP Interrupt Position */ +#define DEVEPTISR_INTRPT_RXSTPI (_U_(0x1) << DEVEPTISR_INTRPT_RXSTPI_Pos) /**< (DEVEPTISR) Received SETUP Interrupt Mask */ +#define DEVEPTISR_INTRPT_NAKOUTI_Pos 3 /**< (DEVEPTISR) NAKed OUT Interrupt Position */ +#define DEVEPTISR_INTRPT_NAKOUTI (_U_(0x1) << DEVEPTISR_INTRPT_NAKOUTI_Pos) /**< (DEVEPTISR) NAKed OUT Interrupt Mask */ +#define DEVEPTISR_INTRPT_NAKINI_Pos 4 /**< (DEVEPTISR) NAKed IN Interrupt Position */ +#define DEVEPTISR_INTRPT_NAKINI (_U_(0x1) << DEVEPTISR_INTRPT_NAKINI_Pos) /**< (DEVEPTISR) NAKed IN Interrupt Mask */ +#define DEVEPTISR_INTRPT_STALLEDI_Pos 6 /**< (DEVEPTISR) STALLed Interrupt Position */ +#define DEVEPTISR_INTRPT_STALLEDI (_U_(0x1) << DEVEPTISR_INTRPT_STALLEDI_Pos) /**< (DEVEPTISR) STALLed Interrupt Mask */ +#define DEVEPTISR_INTRPT_CTRLDIR_Pos 17 /**< (DEVEPTISR) Control Direction Position */ +#define DEVEPTISR_INTRPT_CTRLDIR (_U_(0x1) << DEVEPTISR_INTRPT_CTRLDIR_Pos) /**< (DEVEPTISR) Control Direction Mask */ +#define DEVEPTISR_INTRPT_Msk _U_(0x2005C) /**< (DEVEPTISR_INTRPT) Register Mask */ + + +/* -------- DEVEPTICR : (USBHS Offset: 0x160) (/W 32) Device Endpoint Interrupt Clear Register -------- */ + +#define DEVEPTICR_OFFSET (0x160) /**< (DEVEPTICR) Device Endpoint Interrupt Clear Register Offset */ + +#define DEVEPTICR_TXINIC_Pos 0 /**< (DEVEPTICR) Transmitted IN Data Interrupt Clear Position */ +#define DEVEPTICR_TXINIC (_U_(0x1) << DEVEPTICR_TXINIC_Pos) /**< (DEVEPTICR) Transmitted IN Data Interrupt Clear Mask */ +#define DEVEPTICR_RXOUTIC_Pos 1 /**< (DEVEPTICR) Received OUT Data Interrupt Clear Position */ +#define DEVEPTICR_RXOUTIC (_U_(0x1) << DEVEPTICR_RXOUTIC_Pos) /**< (DEVEPTICR) Received OUT Data Interrupt Clear Mask */ +#define DEVEPTICR_OVERFIC_Pos 5 /**< (DEVEPTICR) Overflow Interrupt Clear Position */ +#define DEVEPTICR_OVERFIC (_U_(0x1) << DEVEPTICR_OVERFIC_Pos) /**< (DEVEPTICR) Overflow Interrupt Clear Mask */ +#define DEVEPTICR_SHORTPACKETC_Pos 7 /**< (DEVEPTICR) Short Packet Interrupt Clear Position */ +#define DEVEPTICR_SHORTPACKETC (_U_(0x1) << DEVEPTICR_SHORTPACKETC_Pos) /**< (DEVEPTICR) Short Packet Interrupt Clear Mask */ +#define DEVEPTICR_Msk _U_(0xA3) /**< (DEVEPTICR) Register Mask */ + +/* CTRL mode */ +#define DEVEPTICR_CTRL_RXSTPIC_Pos 2 /**< (DEVEPTICR) Received SETUP Interrupt Clear Position */ +#define DEVEPTICR_CTRL_RXSTPIC (_U_(0x1) << DEVEPTICR_CTRL_RXSTPIC_Pos) /**< (DEVEPTICR) Received SETUP Interrupt Clear Mask */ +#define DEVEPTICR_CTRL_NAKOUTIC_Pos 3 /**< (DEVEPTICR) NAKed OUT Interrupt Clear Position */ +#define DEVEPTICR_CTRL_NAKOUTIC (_U_(0x1) << DEVEPTICR_CTRL_NAKOUTIC_Pos) /**< (DEVEPTICR) NAKed OUT Interrupt Clear Mask */ +#define DEVEPTICR_CTRL_NAKINIC_Pos 4 /**< (DEVEPTICR) NAKed IN Interrupt Clear Position */ +#define DEVEPTICR_CTRL_NAKINIC (_U_(0x1) << DEVEPTICR_CTRL_NAKINIC_Pos) /**< (DEVEPTICR) NAKed IN Interrupt Clear Mask */ +#define DEVEPTICR_CTRL_STALLEDIC_Pos 6 /**< (DEVEPTICR) STALLed Interrupt Clear Position */ +#define DEVEPTICR_CTRL_STALLEDIC (_U_(0x1) << DEVEPTICR_CTRL_STALLEDIC_Pos) /**< (DEVEPTICR) STALLed Interrupt Clear Mask */ +#define DEVEPTICR_CTRL_Msk _U_(0x5C) /**< (DEVEPTICR_CTRL) Register Mask */ + +/* ISO mode */ +#define DEVEPTICR_ISO_UNDERFIC_Pos 2 /**< (DEVEPTICR) Underflow Interrupt Clear Position */ +#define DEVEPTICR_ISO_UNDERFIC (_U_(0x1) << DEVEPTICR_ISO_UNDERFIC_Pos) /**< (DEVEPTICR) Underflow Interrupt Clear Mask */ +#define DEVEPTICR_ISO_HBISOINERRIC_Pos 3 /**< (DEVEPTICR) High Bandwidth Isochronous IN Underflow Error Interrupt Clear Position */ +#define DEVEPTICR_ISO_HBISOINERRIC (_U_(0x1) << DEVEPTICR_ISO_HBISOINERRIC_Pos) /**< (DEVEPTICR) High Bandwidth Isochronous IN Underflow Error Interrupt Clear Mask */ +#define DEVEPTICR_ISO_HBISOFLUSHIC_Pos 4 /**< (DEVEPTICR) High Bandwidth Isochronous IN Flush Interrupt Clear Position */ +#define DEVEPTICR_ISO_HBISOFLUSHIC (_U_(0x1) << DEVEPTICR_ISO_HBISOFLUSHIC_Pos) /**< (DEVEPTICR) High Bandwidth Isochronous IN Flush Interrupt Clear Mask */ +#define DEVEPTICR_ISO_CRCERRIC_Pos 6 /**< (DEVEPTICR) CRC Error Interrupt Clear Position */ +#define DEVEPTICR_ISO_CRCERRIC (_U_(0x1) << DEVEPTICR_ISO_CRCERRIC_Pos) /**< (DEVEPTICR) CRC Error Interrupt Clear Mask */ +#define DEVEPTICR_ISO_Msk _U_(0x5C) /**< (DEVEPTICR_ISO) Register Mask */ + +/* BLK mode */ +#define DEVEPTICR_BLK_RXSTPIC_Pos 2 /**< (DEVEPTICR) Received SETUP Interrupt Clear Position */ +#define DEVEPTICR_BLK_RXSTPIC (_U_(0x1) << DEVEPTICR_BLK_RXSTPIC_Pos) /**< (DEVEPTICR) Received SETUP Interrupt Clear Mask */ +#define DEVEPTICR_BLK_NAKOUTIC_Pos 3 /**< (DEVEPTICR) NAKed OUT Interrupt Clear Position */ +#define DEVEPTICR_BLK_NAKOUTIC (_U_(0x1) << DEVEPTICR_BLK_NAKOUTIC_Pos) /**< (DEVEPTICR) NAKed OUT Interrupt Clear Mask */ +#define DEVEPTICR_BLK_NAKINIC_Pos 4 /**< (DEVEPTICR) NAKed IN Interrupt Clear Position */ +#define DEVEPTICR_BLK_NAKINIC (_U_(0x1) << DEVEPTICR_BLK_NAKINIC_Pos) /**< (DEVEPTICR) NAKed IN Interrupt Clear Mask */ +#define DEVEPTICR_BLK_STALLEDIC_Pos 6 /**< (DEVEPTICR) STALLed Interrupt Clear Position */ +#define DEVEPTICR_BLK_STALLEDIC (_U_(0x1) << DEVEPTICR_BLK_STALLEDIC_Pos) /**< (DEVEPTICR) STALLed Interrupt Clear Mask */ +#define DEVEPTICR_BLK_Msk _U_(0x5C) /**< (DEVEPTICR_BLK) Register Mask */ + +/* INTRPT mode */ +#define DEVEPTICR_INTRPT_RXSTPIC_Pos 2 /**< (DEVEPTICR) Received SETUP Interrupt Clear Position */ +#define DEVEPTICR_INTRPT_RXSTPIC (_U_(0x1) << DEVEPTICR_INTRPT_RXSTPIC_Pos) /**< (DEVEPTICR) Received SETUP Interrupt Clear Mask */ +#define DEVEPTICR_INTRPT_NAKOUTIC_Pos 3 /**< (DEVEPTICR) NAKed OUT Interrupt Clear Position */ +#define DEVEPTICR_INTRPT_NAKOUTIC (_U_(0x1) << DEVEPTICR_INTRPT_NAKOUTIC_Pos) /**< (DEVEPTICR) NAKed OUT Interrupt Clear Mask */ +#define DEVEPTICR_INTRPT_NAKINIC_Pos 4 /**< (DEVEPTICR) NAKed IN Interrupt Clear Position */ +#define DEVEPTICR_INTRPT_NAKINIC (_U_(0x1) << DEVEPTICR_INTRPT_NAKINIC_Pos) /**< (DEVEPTICR) NAKed IN Interrupt Clear Mask */ +#define DEVEPTICR_INTRPT_STALLEDIC_Pos 6 /**< (DEVEPTICR) STALLed Interrupt Clear Position */ +#define DEVEPTICR_INTRPT_STALLEDIC (_U_(0x1) << DEVEPTICR_INTRPT_STALLEDIC_Pos) /**< (DEVEPTICR) STALLed Interrupt Clear Mask */ +#define DEVEPTICR_INTRPT_Msk _U_(0x5C) /**< (DEVEPTICR_INTRPT) Register Mask */ + + +/* -------- DEVEPTIFR : (USBHS Offset: 0x190) (/W 32) Device Endpoint Interrupt Set Register -------- */ + +#define DEVEPTIFR_OFFSET (0x190) /**< (DEVEPTIFR) Device Endpoint Interrupt Set Register Offset */ + +#define DEVEPTIFR_TXINIS_Pos 0 /**< (DEVEPTIFR) Transmitted IN Data Interrupt Set Position */ +#define DEVEPTIFR_TXINIS (_U_(0x1) << DEVEPTIFR_TXINIS_Pos) /**< (DEVEPTIFR) Transmitted IN Data Interrupt Set Mask */ +#define DEVEPTIFR_RXOUTIS_Pos 1 /**< (DEVEPTIFR) Received OUT Data Interrupt Set Position */ +#define DEVEPTIFR_RXOUTIS (_U_(0x1) << DEVEPTIFR_RXOUTIS_Pos) /**< (DEVEPTIFR) Received OUT Data Interrupt Set Mask */ +#define DEVEPTIFR_OVERFIS_Pos 5 /**< (DEVEPTIFR) Overflow Interrupt Set Position */ +#define DEVEPTIFR_OVERFIS (_U_(0x1) << DEVEPTIFR_OVERFIS_Pos) /**< (DEVEPTIFR) Overflow Interrupt Set Mask */ +#define DEVEPTIFR_SHORTPACKETS_Pos 7 /**< (DEVEPTIFR) Short Packet Interrupt Set Position */ +#define DEVEPTIFR_SHORTPACKETS (_U_(0x1) << DEVEPTIFR_SHORTPACKETS_Pos) /**< (DEVEPTIFR) Short Packet Interrupt Set Mask */ +#define DEVEPTIFR_NBUSYBKS_Pos 12 /**< (DEVEPTIFR) Number of Busy Banks Interrupt Set Position */ +#define DEVEPTIFR_NBUSYBKS (_U_(0x1) << DEVEPTIFR_NBUSYBKS_Pos) /**< (DEVEPTIFR) Number of Busy Banks Interrupt Set Mask */ +#define DEVEPTIFR_Msk _U_(0x10A3) /**< (DEVEPTIFR) Register Mask */ + +/* CTRL mode */ +#define DEVEPTIFR_CTRL_RXSTPIS_Pos 2 /**< (DEVEPTIFR) Received SETUP Interrupt Set Position */ +#define DEVEPTIFR_CTRL_RXSTPIS (_U_(0x1) << DEVEPTIFR_CTRL_RXSTPIS_Pos) /**< (DEVEPTIFR) Received SETUP Interrupt Set Mask */ +#define DEVEPTIFR_CTRL_NAKOUTIS_Pos 3 /**< (DEVEPTIFR) NAKed OUT Interrupt Set Position */ +#define DEVEPTIFR_CTRL_NAKOUTIS (_U_(0x1) << DEVEPTIFR_CTRL_NAKOUTIS_Pos) /**< (DEVEPTIFR) NAKed OUT Interrupt Set Mask */ +#define DEVEPTIFR_CTRL_NAKINIS_Pos 4 /**< (DEVEPTIFR) NAKed IN Interrupt Set Position */ +#define DEVEPTIFR_CTRL_NAKINIS (_U_(0x1) << DEVEPTIFR_CTRL_NAKINIS_Pos) /**< (DEVEPTIFR) NAKed IN Interrupt Set Mask */ +#define DEVEPTIFR_CTRL_STALLEDIS_Pos 6 /**< (DEVEPTIFR) STALLed Interrupt Set Position */ +#define DEVEPTIFR_CTRL_STALLEDIS (_U_(0x1) << DEVEPTIFR_CTRL_STALLEDIS_Pos) /**< (DEVEPTIFR) STALLed Interrupt Set Mask */ +#define DEVEPTIFR_CTRL_Msk _U_(0x5C) /**< (DEVEPTIFR_CTRL) Register Mask */ + +/* ISO mode */ +#define DEVEPTIFR_ISO_UNDERFIS_Pos 2 /**< (DEVEPTIFR) Underflow Interrupt Set Position */ +#define DEVEPTIFR_ISO_UNDERFIS (_U_(0x1) << DEVEPTIFR_ISO_UNDERFIS_Pos) /**< (DEVEPTIFR) Underflow Interrupt Set Mask */ +#define DEVEPTIFR_ISO_HBISOINERRIS_Pos 3 /**< (DEVEPTIFR) High Bandwidth Isochronous IN Underflow Error Interrupt Set Position */ +#define DEVEPTIFR_ISO_HBISOINERRIS (_U_(0x1) << DEVEPTIFR_ISO_HBISOINERRIS_Pos) /**< (DEVEPTIFR) High Bandwidth Isochronous IN Underflow Error Interrupt Set Mask */ +#define DEVEPTIFR_ISO_HBISOFLUSHIS_Pos 4 /**< (DEVEPTIFR) High Bandwidth Isochronous IN Flush Interrupt Set Position */ +#define DEVEPTIFR_ISO_HBISOFLUSHIS (_U_(0x1) << DEVEPTIFR_ISO_HBISOFLUSHIS_Pos) /**< (DEVEPTIFR) High Bandwidth Isochronous IN Flush Interrupt Set Mask */ +#define DEVEPTIFR_ISO_CRCERRIS_Pos 6 /**< (DEVEPTIFR) CRC Error Interrupt Set Position */ +#define DEVEPTIFR_ISO_CRCERRIS (_U_(0x1) << DEVEPTIFR_ISO_CRCERRIS_Pos) /**< (DEVEPTIFR) CRC Error Interrupt Set Mask */ +#define DEVEPTIFR_ISO_Msk _U_(0x5C) /**< (DEVEPTIFR_ISO) Register Mask */ + +/* BLK mode */ +#define DEVEPTIFR_BLK_RXSTPIS_Pos 2 /**< (DEVEPTIFR) Received SETUP Interrupt Set Position */ +#define DEVEPTIFR_BLK_RXSTPIS (_U_(0x1) << DEVEPTIFR_BLK_RXSTPIS_Pos) /**< (DEVEPTIFR) Received SETUP Interrupt Set Mask */ +#define DEVEPTIFR_BLK_NAKOUTIS_Pos 3 /**< (DEVEPTIFR) NAKed OUT Interrupt Set Position */ +#define DEVEPTIFR_BLK_NAKOUTIS (_U_(0x1) << DEVEPTIFR_BLK_NAKOUTIS_Pos) /**< (DEVEPTIFR) NAKed OUT Interrupt Set Mask */ +#define DEVEPTIFR_BLK_NAKINIS_Pos 4 /**< (DEVEPTIFR) NAKed IN Interrupt Set Position */ +#define DEVEPTIFR_BLK_NAKINIS (_U_(0x1) << DEVEPTIFR_BLK_NAKINIS_Pos) /**< (DEVEPTIFR) NAKed IN Interrupt Set Mask */ +#define DEVEPTIFR_BLK_STALLEDIS_Pos 6 /**< (DEVEPTIFR) STALLed Interrupt Set Position */ +#define DEVEPTIFR_BLK_STALLEDIS (_U_(0x1) << DEVEPTIFR_BLK_STALLEDIS_Pos) /**< (DEVEPTIFR) STALLed Interrupt Set Mask */ +#define DEVEPTIFR_BLK_Msk _U_(0x5C) /**< (DEVEPTIFR_BLK) Register Mask */ + +/* INTRPT mode */ +#define DEVEPTIFR_INTRPT_RXSTPIS_Pos 2 /**< (DEVEPTIFR) Received SETUP Interrupt Set Position */ +#define DEVEPTIFR_INTRPT_RXSTPIS (_U_(0x1) << DEVEPTIFR_INTRPT_RXSTPIS_Pos) /**< (DEVEPTIFR) Received SETUP Interrupt Set Mask */ +#define DEVEPTIFR_INTRPT_NAKOUTIS_Pos 3 /**< (DEVEPTIFR) NAKed OUT Interrupt Set Position */ +#define DEVEPTIFR_INTRPT_NAKOUTIS (_U_(0x1) << DEVEPTIFR_INTRPT_NAKOUTIS_Pos) /**< (DEVEPTIFR) NAKed OUT Interrupt Set Mask */ +#define DEVEPTIFR_INTRPT_NAKINIS_Pos 4 /**< (DEVEPTIFR) NAKed IN Interrupt Set Position */ +#define DEVEPTIFR_INTRPT_NAKINIS (_U_(0x1) << DEVEPTIFR_INTRPT_NAKINIS_Pos) /**< (DEVEPTIFR) NAKed IN Interrupt Set Mask */ +#define DEVEPTIFR_INTRPT_STALLEDIS_Pos 6 /**< (DEVEPTIFR) STALLed Interrupt Set Position */ +#define DEVEPTIFR_INTRPT_STALLEDIS (_U_(0x1) << DEVEPTIFR_INTRPT_STALLEDIS_Pos) /**< (DEVEPTIFR) STALLed Interrupt Set Mask */ +#define DEVEPTIFR_INTRPT_Msk _U_(0x5C) /**< (DEVEPTIFR_INTRPT) Register Mask */ + + +/* -------- DEVEPTIMR : (USBHS Offset: 0x1c0) (R/ 32) Device Endpoint Interrupt Mask Register -------- */ + +#define DEVEPTIMR_OFFSET (0x1C0) /**< (DEVEPTIMR) Device Endpoint Interrupt Mask Register Offset */ + +#define DEVEPTIMR_TXINE_Pos 0 /**< (DEVEPTIMR) Transmitted IN Data Interrupt Position */ +#define DEVEPTIMR_TXINE (_U_(0x1) << DEVEPTIMR_TXINE_Pos) /**< (DEVEPTIMR) Transmitted IN Data Interrupt Mask */ +#define DEVEPTIMR_RXOUTE_Pos 1 /**< (DEVEPTIMR) Received OUT Data Interrupt Position */ +#define DEVEPTIMR_RXOUTE (_U_(0x1) << DEVEPTIMR_RXOUTE_Pos) /**< (DEVEPTIMR) Received OUT Data Interrupt Mask */ +#define DEVEPTIMR_OVERFE_Pos 5 /**< (DEVEPTIMR) Overflow Interrupt Position */ +#define DEVEPTIMR_OVERFE (_U_(0x1) << DEVEPTIMR_OVERFE_Pos) /**< (DEVEPTIMR) Overflow Interrupt Mask */ +#define DEVEPTIMR_SHORTPACKETE_Pos 7 /**< (DEVEPTIMR) Short Packet Interrupt Position */ +#define DEVEPTIMR_SHORTPACKETE (_U_(0x1) << DEVEPTIMR_SHORTPACKETE_Pos) /**< (DEVEPTIMR) Short Packet Interrupt Mask */ +#define DEVEPTIMR_NBUSYBKE_Pos 12 /**< (DEVEPTIMR) Number of Busy Banks Interrupt Position */ +#define DEVEPTIMR_NBUSYBKE (_U_(0x1) << DEVEPTIMR_NBUSYBKE_Pos) /**< (DEVEPTIMR) Number of Busy Banks Interrupt Mask */ +#define DEVEPTIMR_KILLBK_Pos 13 /**< (DEVEPTIMR) Kill IN Bank Position */ +#define DEVEPTIMR_KILLBK (_U_(0x1) << DEVEPTIMR_KILLBK_Pos) /**< (DEVEPTIMR) Kill IN Bank Mask */ +#define DEVEPTIMR_FIFOCON_Pos 14 /**< (DEVEPTIMR) FIFO Control Position */ +#define DEVEPTIMR_FIFOCON (_U_(0x1) << DEVEPTIMR_FIFOCON_Pos) /**< (DEVEPTIMR) FIFO Control Mask */ +#define DEVEPTIMR_EPDISHDMA_Pos 16 /**< (DEVEPTIMR) Endpoint Interrupts Disable HDMA Request Position */ +#define DEVEPTIMR_EPDISHDMA (_U_(0x1) << DEVEPTIMR_EPDISHDMA_Pos) /**< (DEVEPTIMR) Endpoint Interrupts Disable HDMA Request Mask */ +#define DEVEPTIMR_RSTDT_Pos 18 /**< (DEVEPTIMR) Reset Data Toggle Position */ +#define DEVEPTIMR_RSTDT (_U_(0x1) << DEVEPTIMR_RSTDT_Pos) /**< (DEVEPTIMR) Reset Data Toggle Mask */ +#define DEVEPTIMR_Msk _U_(0x570A3) /**< (DEVEPTIMR) Register Mask */ + +/* CTRL mode */ +#define DEVEPTIMR_CTRL_RXSTPE_Pos 2 /**< (DEVEPTIMR) Received SETUP Interrupt Position */ +#define DEVEPTIMR_CTRL_RXSTPE (_U_(0x1) << DEVEPTIMR_CTRL_RXSTPE_Pos) /**< (DEVEPTIMR) Received SETUP Interrupt Mask */ +#define DEVEPTIMR_CTRL_NAKOUTE_Pos 3 /**< (DEVEPTIMR) NAKed OUT Interrupt Position */ +#define DEVEPTIMR_CTRL_NAKOUTE (_U_(0x1) << DEVEPTIMR_CTRL_NAKOUTE_Pos) /**< (DEVEPTIMR) NAKed OUT Interrupt Mask */ +#define DEVEPTIMR_CTRL_NAKINE_Pos 4 /**< (DEVEPTIMR) NAKed IN Interrupt Position */ +#define DEVEPTIMR_CTRL_NAKINE (_U_(0x1) << DEVEPTIMR_CTRL_NAKINE_Pos) /**< (DEVEPTIMR) NAKed IN Interrupt Mask */ +#define DEVEPTIMR_CTRL_STALLEDE_Pos 6 /**< (DEVEPTIMR) STALLed Interrupt Position */ +#define DEVEPTIMR_CTRL_STALLEDE (_U_(0x1) << DEVEPTIMR_CTRL_STALLEDE_Pos) /**< (DEVEPTIMR) STALLed Interrupt Mask */ +#define DEVEPTIMR_CTRL_NYETDIS_Pos 17 /**< (DEVEPTIMR) NYET Token Disable Position */ +#define DEVEPTIMR_CTRL_NYETDIS (_U_(0x1) << DEVEPTIMR_CTRL_NYETDIS_Pos) /**< (DEVEPTIMR) NYET Token Disable Mask */ +#define DEVEPTIMR_CTRL_STALLRQ_Pos 19 /**< (DEVEPTIMR) STALL Request Position */ +#define DEVEPTIMR_CTRL_STALLRQ (_U_(0x1) << DEVEPTIMR_CTRL_STALLRQ_Pos) /**< (DEVEPTIMR) STALL Request Mask */ +#define DEVEPTIMR_CTRL_Msk _U_(0xA005C) /**< (DEVEPTIMR_CTRL) Register Mask */ + +/* ISO mode */ +#define DEVEPTIMR_ISO_UNDERFE_Pos 2 /**< (DEVEPTIMR) Underflow Interrupt Position */ +#define DEVEPTIMR_ISO_UNDERFE (_U_(0x1) << DEVEPTIMR_ISO_UNDERFE_Pos) /**< (DEVEPTIMR) Underflow Interrupt Mask */ +#define DEVEPTIMR_ISO_HBISOINERRE_Pos 3 /**< (DEVEPTIMR) High Bandwidth Isochronous IN Underflow Error Interrupt Position */ +#define DEVEPTIMR_ISO_HBISOINERRE (_U_(0x1) << DEVEPTIMR_ISO_HBISOINERRE_Pos) /**< (DEVEPTIMR) High Bandwidth Isochronous IN Underflow Error Interrupt Mask */ +#define DEVEPTIMR_ISO_HBISOFLUSHE_Pos 4 /**< (DEVEPTIMR) High Bandwidth Isochronous IN Flush Interrupt Position */ +#define DEVEPTIMR_ISO_HBISOFLUSHE (_U_(0x1) << DEVEPTIMR_ISO_HBISOFLUSHE_Pos) /**< (DEVEPTIMR) High Bandwidth Isochronous IN Flush Interrupt Mask */ +#define DEVEPTIMR_ISO_CRCERRE_Pos 6 /**< (DEVEPTIMR) CRC Error Interrupt Position */ +#define DEVEPTIMR_ISO_CRCERRE (_U_(0x1) << DEVEPTIMR_ISO_CRCERRE_Pos) /**< (DEVEPTIMR) CRC Error Interrupt Mask */ +#define DEVEPTIMR_ISO_MDATAE_Pos 8 /**< (DEVEPTIMR) MData Interrupt Position */ +#define DEVEPTIMR_ISO_MDATAE (_U_(0x1) << DEVEPTIMR_ISO_MDATAE_Pos) /**< (DEVEPTIMR) MData Interrupt Mask */ +#define DEVEPTIMR_ISO_DATAXE_Pos 9 /**< (DEVEPTIMR) DataX Interrupt Position */ +#define DEVEPTIMR_ISO_DATAXE (_U_(0x1) << DEVEPTIMR_ISO_DATAXE_Pos) /**< (DEVEPTIMR) DataX Interrupt Mask */ +#define DEVEPTIMR_ISO_ERRORTRANSE_Pos 10 /**< (DEVEPTIMR) Transaction Error Interrupt Position */ +#define DEVEPTIMR_ISO_ERRORTRANSE (_U_(0x1) << DEVEPTIMR_ISO_ERRORTRANSE_Pos) /**< (DEVEPTIMR) Transaction Error Interrupt Mask */ +#define DEVEPTIMR_ISO_Msk _U_(0x75C) /**< (DEVEPTIMR_ISO) Register Mask */ + +/* BLK mode */ +#define DEVEPTIMR_BLK_RXSTPE_Pos 2 /**< (DEVEPTIMR) Received SETUP Interrupt Position */ +#define DEVEPTIMR_BLK_RXSTPE (_U_(0x1) << DEVEPTIMR_BLK_RXSTPE_Pos) /**< (DEVEPTIMR) Received SETUP Interrupt Mask */ +#define DEVEPTIMR_BLK_NAKOUTE_Pos 3 /**< (DEVEPTIMR) NAKed OUT Interrupt Position */ +#define DEVEPTIMR_BLK_NAKOUTE (_U_(0x1) << DEVEPTIMR_BLK_NAKOUTE_Pos) /**< (DEVEPTIMR) NAKed OUT Interrupt Mask */ +#define DEVEPTIMR_BLK_NAKINE_Pos 4 /**< (DEVEPTIMR) NAKed IN Interrupt Position */ +#define DEVEPTIMR_BLK_NAKINE (_U_(0x1) << DEVEPTIMR_BLK_NAKINE_Pos) /**< (DEVEPTIMR) NAKed IN Interrupt Mask */ +#define DEVEPTIMR_BLK_STALLEDE_Pos 6 /**< (DEVEPTIMR) STALLed Interrupt Position */ +#define DEVEPTIMR_BLK_STALLEDE (_U_(0x1) << DEVEPTIMR_BLK_STALLEDE_Pos) /**< (DEVEPTIMR) STALLed Interrupt Mask */ +#define DEVEPTIMR_BLK_NYETDIS_Pos 17 /**< (DEVEPTIMR) NYET Token Disable Position */ +#define DEVEPTIMR_BLK_NYETDIS (_U_(0x1) << DEVEPTIMR_BLK_NYETDIS_Pos) /**< (DEVEPTIMR) NYET Token Disable Mask */ +#define DEVEPTIMR_BLK_STALLRQ_Pos 19 /**< (DEVEPTIMR) STALL Request Position */ +#define DEVEPTIMR_BLK_STALLRQ (_U_(0x1) << DEVEPTIMR_BLK_STALLRQ_Pos) /**< (DEVEPTIMR) STALL Request Mask */ +#define DEVEPTIMR_BLK_Msk _U_(0xA005C) /**< (DEVEPTIMR_BLK) Register Mask */ + +/* INTRPT mode */ +#define DEVEPTIMR_INTRPT_RXSTPE_Pos 2 /**< (DEVEPTIMR) Received SETUP Interrupt Position */ +#define DEVEPTIMR_INTRPT_RXSTPE (_U_(0x1) << DEVEPTIMR_INTRPT_RXSTPE_Pos) /**< (DEVEPTIMR) Received SETUP Interrupt Mask */ +#define DEVEPTIMR_INTRPT_NAKOUTE_Pos 3 /**< (DEVEPTIMR) NAKed OUT Interrupt Position */ +#define DEVEPTIMR_INTRPT_NAKOUTE (_U_(0x1) << DEVEPTIMR_INTRPT_NAKOUTE_Pos) /**< (DEVEPTIMR) NAKed OUT Interrupt Mask */ +#define DEVEPTIMR_INTRPT_NAKINE_Pos 4 /**< (DEVEPTIMR) NAKed IN Interrupt Position */ +#define DEVEPTIMR_INTRPT_NAKINE (_U_(0x1) << DEVEPTIMR_INTRPT_NAKINE_Pos) /**< (DEVEPTIMR) NAKed IN Interrupt Mask */ +#define DEVEPTIMR_INTRPT_STALLEDE_Pos 6 /**< (DEVEPTIMR) STALLed Interrupt Position */ +#define DEVEPTIMR_INTRPT_STALLEDE (_U_(0x1) << DEVEPTIMR_INTRPT_STALLEDE_Pos) /**< (DEVEPTIMR) STALLed Interrupt Mask */ +#define DEVEPTIMR_INTRPT_NYETDIS_Pos 17 /**< (DEVEPTIMR) NYET Token Disable Position */ +#define DEVEPTIMR_INTRPT_NYETDIS (_U_(0x1) << DEVEPTIMR_INTRPT_NYETDIS_Pos) /**< (DEVEPTIMR) NYET Token Disable Mask */ +#define DEVEPTIMR_INTRPT_STALLRQ_Pos 19 /**< (DEVEPTIMR) STALL Request Position */ +#define DEVEPTIMR_INTRPT_STALLRQ (_U_(0x1) << DEVEPTIMR_INTRPT_STALLRQ_Pos) /**< (DEVEPTIMR) STALL Request Mask */ +#define DEVEPTIMR_INTRPT_Msk _U_(0xA005C) /**< (DEVEPTIMR_INTRPT) Register Mask */ + + +/* -------- DEVEPTIER : (USBHS Offset: 0x1f0) (/W 32) Device Endpoint Interrupt Enable Register -------- */ + +#define DEVEPTIER_OFFSET (0x1F0) /**< (DEVEPTIER) Device Endpoint Interrupt Enable Register Offset */ + +#define DEVEPTIER_TXINES_Pos 0 /**< (DEVEPTIER) Transmitted IN Data Interrupt Enable Position */ +#define DEVEPTIER_TXINES (_U_(0x1) << DEVEPTIER_TXINES_Pos) /**< (DEVEPTIER) Transmitted IN Data Interrupt Enable Mask */ +#define DEVEPTIER_RXOUTES_Pos 1 /**< (DEVEPTIER) Received OUT Data Interrupt Enable Position */ +#define DEVEPTIER_RXOUTES (_U_(0x1) << DEVEPTIER_RXOUTES_Pos) /**< (DEVEPTIER) Received OUT Data Interrupt Enable Mask */ +#define DEVEPTIER_OVERFES_Pos 5 /**< (DEVEPTIER) Overflow Interrupt Enable Position */ +#define DEVEPTIER_OVERFES (_U_(0x1) << DEVEPTIER_OVERFES_Pos) /**< (DEVEPTIER) Overflow Interrupt Enable Mask */ +#define DEVEPTIER_SHORTPACKETES_Pos 7 /**< (DEVEPTIER) Short Packet Interrupt Enable Position */ +#define DEVEPTIER_SHORTPACKETES (_U_(0x1) << DEVEPTIER_SHORTPACKETES_Pos) /**< (DEVEPTIER) Short Packet Interrupt Enable Mask */ +#define DEVEPTIER_NBUSYBKES_Pos 12 /**< (DEVEPTIER) Number of Busy Banks Interrupt Enable Position */ +#define DEVEPTIER_NBUSYBKES (_U_(0x1) << DEVEPTIER_NBUSYBKES_Pos) /**< (DEVEPTIER) Number of Busy Banks Interrupt Enable Mask */ +#define DEVEPTIER_KILLBKS_Pos 13 /**< (DEVEPTIER) Kill IN Bank Position */ +#define DEVEPTIER_KILLBKS (_U_(0x1) << DEVEPTIER_KILLBKS_Pos) /**< (DEVEPTIER) Kill IN Bank Mask */ +#define DEVEPTIER_FIFOCONS_Pos 14 /**< (DEVEPTIER) FIFO Control Position */ +#define DEVEPTIER_FIFOCONS (_U_(0x1) << DEVEPTIER_FIFOCONS_Pos) /**< (DEVEPTIER) FIFO Control Mask */ +#define DEVEPTIER_EPDISHDMAS_Pos 16 /**< (DEVEPTIER) Endpoint Interrupts Disable HDMA Request Enable Position */ +#define DEVEPTIER_EPDISHDMAS (_U_(0x1) << DEVEPTIER_EPDISHDMAS_Pos) /**< (DEVEPTIER) Endpoint Interrupts Disable HDMA Request Enable Mask */ +#define DEVEPTIER_RSTDTS_Pos 18 /**< (DEVEPTIER) Reset Data Toggle Enable Position */ +#define DEVEPTIER_RSTDTS (_U_(0x1) << DEVEPTIER_RSTDTS_Pos) /**< (DEVEPTIER) Reset Data Toggle Enable Mask */ +#define DEVEPTIER_Msk _U_(0x570A3) /**< (DEVEPTIER) Register Mask */ + +/* CTRL mode */ +#define DEVEPTIER_CTRL_RXSTPES_Pos 2 /**< (DEVEPTIER) Received SETUP Interrupt Enable Position */ +#define DEVEPTIER_CTRL_RXSTPES (_U_(0x1) << DEVEPTIER_CTRL_RXSTPES_Pos) /**< (DEVEPTIER) Received SETUP Interrupt Enable Mask */ +#define DEVEPTIER_CTRL_NAKOUTES_Pos 3 /**< (DEVEPTIER) NAKed OUT Interrupt Enable Position */ +#define DEVEPTIER_CTRL_NAKOUTES (_U_(0x1) << DEVEPTIER_CTRL_NAKOUTES_Pos) /**< (DEVEPTIER) NAKed OUT Interrupt Enable Mask */ +#define DEVEPTIER_CTRL_NAKINES_Pos 4 /**< (DEVEPTIER) NAKed IN Interrupt Enable Position */ +#define DEVEPTIER_CTRL_NAKINES (_U_(0x1) << DEVEPTIER_CTRL_NAKINES_Pos) /**< (DEVEPTIER) NAKed IN Interrupt Enable Mask */ +#define DEVEPTIER_CTRL_STALLEDES_Pos 6 /**< (DEVEPTIER) STALLed Interrupt Enable Position */ +#define DEVEPTIER_CTRL_STALLEDES (_U_(0x1) << DEVEPTIER_CTRL_STALLEDES_Pos) /**< (DEVEPTIER) STALLed Interrupt Enable Mask */ +#define DEVEPTIER_CTRL_NYETDISS_Pos 17 /**< (DEVEPTIER) NYET Token Disable Enable Position */ +#define DEVEPTIER_CTRL_NYETDISS (_U_(0x1) << DEVEPTIER_CTRL_NYETDISS_Pos) /**< (DEVEPTIER) NYET Token Disable Enable Mask */ +#define DEVEPTIER_CTRL_STALLRQS_Pos 19 /**< (DEVEPTIER) STALL Request Enable Position */ +#define DEVEPTIER_CTRL_STALLRQS (_U_(0x1) << DEVEPTIER_CTRL_STALLRQS_Pos) /**< (DEVEPTIER) STALL Request Enable Mask */ +#define DEVEPTIER_CTRL_Msk _U_(0xA005C) /**< (DEVEPTIER_CTRL) Register Mask */ + +/* ISO mode */ +#define DEVEPTIER_ISO_UNDERFES_Pos 2 /**< (DEVEPTIER) Underflow Interrupt Enable Position */ +#define DEVEPTIER_ISO_UNDERFES (_U_(0x1) << DEVEPTIER_ISO_UNDERFES_Pos) /**< (DEVEPTIER) Underflow Interrupt Enable Mask */ +#define DEVEPTIER_ISO_HBISOINERRES_Pos 3 /**< (DEVEPTIER) High Bandwidth Isochronous IN Underflow Error Interrupt Enable Position */ +#define DEVEPTIER_ISO_HBISOINERRES (_U_(0x1) << DEVEPTIER_ISO_HBISOINERRES_Pos) /**< (DEVEPTIER) High Bandwidth Isochronous IN Underflow Error Interrupt Enable Mask */ +#define DEVEPTIER_ISO_HBISOFLUSHES_Pos 4 /**< (DEVEPTIER) High Bandwidth Isochronous IN Flush Interrupt Enable Position */ +#define DEVEPTIER_ISO_HBISOFLUSHES (_U_(0x1) << DEVEPTIER_ISO_HBISOFLUSHES_Pos) /**< (DEVEPTIER) High Bandwidth Isochronous IN Flush Interrupt Enable Mask */ +#define DEVEPTIER_ISO_CRCERRES_Pos 6 /**< (DEVEPTIER) CRC Error Interrupt Enable Position */ +#define DEVEPTIER_ISO_CRCERRES (_U_(0x1) << DEVEPTIER_ISO_CRCERRES_Pos) /**< (DEVEPTIER) CRC Error Interrupt Enable Mask */ +#define DEVEPTIER_ISO_MDATAES_Pos 8 /**< (DEVEPTIER) MData Interrupt Enable Position */ +#define DEVEPTIER_ISO_MDATAES (_U_(0x1) << DEVEPTIER_ISO_MDATAES_Pos) /**< (DEVEPTIER) MData Interrupt Enable Mask */ +#define DEVEPTIER_ISO_DATAXES_Pos 9 /**< (DEVEPTIER) DataX Interrupt Enable Position */ +#define DEVEPTIER_ISO_DATAXES (_U_(0x1) << DEVEPTIER_ISO_DATAXES_Pos) /**< (DEVEPTIER) DataX Interrupt Enable Mask */ +#define DEVEPTIER_ISO_ERRORTRANSES_Pos 10 /**< (DEVEPTIER) Transaction Error Interrupt Enable Position */ +#define DEVEPTIER_ISO_ERRORTRANSES (_U_(0x1) << DEVEPTIER_ISO_ERRORTRANSES_Pos) /**< (DEVEPTIER) Transaction Error Interrupt Enable Mask */ +#define DEVEPTIER_ISO_Msk _U_(0x75C) /**< (DEVEPTIER_ISO) Register Mask */ + +/* BLK mode */ +#define DEVEPTIER_BLK_RXSTPES_Pos 2 /**< (DEVEPTIER) Received SETUP Interrupt Enable Position */ +#define DEVEPTIER_BLK_RXSTPES (_U_(0x1) << DEVEPTIER_BLK_RXSTPES_Pos) /**< (DEVEPTIER) Received SETUP Interrupt Enable Mask */ +#define DEVEPTIER_BLK_NAKOUTES_Pos 3 /**< (DEVEPTIER) NAKed OUT Interrupt Enable Position */ +#define DEVEPTIER_BLK_NAKOUTES (_U_(0x1) << DEVEPTIER_BLK_NAKOUTES_Pos) /**< (DEVEPTIER) NAKed OUT Interrupt Enable Mask */ +#define DEVEPTIER_BLK_NAKINES_Pos 4 /**< (DEVEPTIER) NAKed IN Interrupt Enable Position */ +#define DEVEPTIER_BLK_NAKINES (_U_(0x1) << DEVEPTIER_BLK_NAKINES_Pos) /**< (DEVEPTIER) NAKed IN Interrupt Enable Mask */ +#define DEVEPTIER_BLK_STALLEDES_Pos 6 /**< (DEVEPTIER) STALLed Interrupt Enable Position */ +#define DEVEPTIER_BLK_STALLEDES (_U_(0x1) << DEVEPTIER_BLK_STALLEDES_Pos) /**< (DEVEPTIER) STALLed Interrupt Enable Mask */ +#define DEVEPTIER_BLK_NYETDISS_Pos 17 /**< (DEVEPTIER) NYET Token Disable Enable Position */ +#define DEVEPTIER_BLK_NYETDISS (_U_(0x1) << DEVEPTIER_BLK_NYETDISS_Pos) /**< (DEVEPTIER) NYET Token Disable Enable Mask */ +#define DEVEPTIER_BLK_STALLRQS_Pos 19 /**< (DEVEPTIER) STALL Request Enable Position */ +#define DEVEPTIER_BLK_STALLRQS (_U_(0x1) << DEVEPTIER_BLK_STALLRQS_Pos) /**< (DEVEPTIER) STALL Request Enable Mask */ +#define DEVEPTIER_BLK_Msk _U_(0xA005C) /**< (DEVEPTIER_BLK) Register Mask */ + +/* INTRPT mode */ +#define DEVEPTIER_INTRPT_RXSTPES_Pos 2 /**< (DEVEPTIER) Received SETUP Interrupt Enable Position */ +#define DEVEPTIER_INTRPT_RXSTPES (_U_(0x1) << DEVEPTIER_INTRPT_RXSTPES_Pos) /**< (DEVEPTIER) Received SETUP Interrupt Enable Mask */ +#define DEVEPTIER_INTRPT_NAKOUTES_Pos 3 /**< (DEVEPTIER) NAKed OUT Interrupt Enable Position */ +#define DEVEPTIER_INTRPT_NAKOUTES (_U_(0x1) << DEVEPTIER_INTRPT_NAKOUTES_Pos) /**< (DEVEPTIER) NAKed OUT Interrupt Enable Mask */ +#define DEVEPTIER_INTRPT_NAKINES_Pos 4 /**< (DEVEPTIER) NAKed IN Interrupt Enable Position */ +#define DEVEPTIER_INTRPT_NAKINES (_U_(0x1) << DEVEPTIER_INTRPT_NAKINES_Pos) /**< (DEVEPTIER) NAKed IN Interrupt Enable Mask */ +#define DEVEPTIER_INTRPT_STALLEDES_Pos 6 /**< (DEVEPTIER) STALLed Interrupt Enable Position */ +#define DEVEPTIER_INTRPT_STALLEDES (_U_(0x1) << DEVEPTIER_INTRPT_STALLEDES_Pos) /**< (DEVEPTIER) STALLed Interrupt Enable Mask */ +#define DEVEPTIER_INTRPT_NYETDISS_Pos 17 /**< (DEVEPTIER) NYET Token Disable Enable Position */ +#define DEVEPTIER_INTRPT_NYETDISS (_U_(0x1) << DEVEPTIER_INTRPT_NYETDISS_Pos) /**< (DEVEPTIER) NYET Token Disable Enable Mask */ +#define DEVEPTIER_INTRPT_STALLRQS_Pos 19 /**< (DEVEPTIER) STALL Request Enable Position */ +#define DEVEPTIER_INTRPT_STALLRQS (_U_(0x1) << DEVEPTIER_INTRPT_STALLRQS_Pos) /**< (DEVEPTIER) STALL Request Enable Mask */ +#define DEVEPTIER_INTRPT_Msk _U_(0xA005C) /**< (DEVEPTIER_INTRPT) Register Mask */ + + +/* -------- DEVEPTIDR : (USBHS Offset: 0x220) (/W 32) Device Endpoint Interrupt Disable Register -------- */ + +#define DEVEPTIDR_OFFSET (0x220) /**< (DEVEPTIDR) Device Endpoint Interrupt Disable Register Offset */ + +#define DEVEPTIDR_TXINEC_Pos 0 /**< (DEVEPTIDR) Transmitted IN Interrupt Clear Position */ +#define DEVEPTIDR_TXINEC (_U_(0x1) << DEVEPTIDR_TXINEC_Pos) /**< (DEVEPTIDR) Transmitted IN Interrupt Clear Mask */ +#define DEVEPTIDR_RXOUTEC_Pos 1 /**< (DEVEPTIDR) Received OUT Data Interrupt Clear Position */ +#define DEVEPTIDR_RXOUTEC (_U_(0x1) << DEVEPTIDR_RXOUTEC_Pos) /**< (DEVEPTIDR) Received OUT Data Interrupt Clear Mask */ +#define DEVEPTIDR_OVERFEC_Pos 5 /**< (DEVEPTIDR) Overflow Interrupt Clear Position */ +#define DEVEPTIDR_OVERFEC (_U_(0x1) << DEVEPTIDR_OVERFEC_Pos) /**< (DEVEPTIDR) Overflow Interrupt Clear Mask */ +#define DEVEPTIDR_SHORTPACKETEC_Pos 7 /**< (DEVEPTIDR) Shortpacket Interrupt Clear Position */ +#define DEVEPTIDR_SHORTPACKETEC (_U_(0x1) << DEVEPTIDR_SHORTPACKETEC_Pos) /**< (DEVEPTIDR) Shortpacket Interrupt Clear Mask */ +#define DEVEPTIDR_NBUSYBKEC_Pos 12 /**< (DEVEPTIDR) Number of Busy Banks Interrupt Clear Position */ +#define DEVEPTIDR_NBUSYBKEC (_U_(0x1) << DEVEPTIDR_NBUSYBKEC_Pos) /**< (DEVEPTIDR) Number of Busy Banks Interrupt Clear Mask */ +#define DEVEPTIDR_FIFOCONC_Pos 14 /**< (DEVEPTIDR) FIFO Control Clear Position */ +#define DEVEPTIDR_FIFOCONC (_U_(0x1) << DEVEPTIDR_FIFOCONC_Pos) /**< (DEVEPTIDR) FIFO Control Clear Mask */ +#define DEVEPTIDR_EPDISHDMAC_Pos 16 /**< (DEVEPTIDR) Endpoint Interrupts Disable HDMA Request Clear Position */ +#define DEVEPTIDR_EPDISHDMAC (_U_(0x1) << DEVEPTIDR_EPDISHDMAC_Pos) /**< (DEVEPTIDR) Endpoint Interrupts Disable HDMA Request Clear Mask */ +#define DEVEPTIDR_Msk _U_(0x150A3) /**< (DEVEPTIDR) Register Mask */ + +/* CTRL mode */ +#define DEVEPTIDR_CTRL_RXSTPEC_Pos 2 /**< (DEVEPTIDR) Received SETUP Interrupt Clear Position */ +#define DEVEPTIDR_CTRL_RXSTPEC (_U_(0x1) << DEVEPTIDR_CTRL_RXSTPEC_Pos) /**< (DEVEPTIDR) Received SETUP Interrupt Clear Mask */ +#define DEVEPTIDR_CTRL_NAKOUTEC_Pos 3 /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Position */ +#define DEVEPTIDR_CTRL_NAKOUTEC (_U_(0x1) << DEVEPTIDR_CTRL_NAKOUTEC_Pos) /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Mask */ +#define DEVEPTIDR_CTRL_NAKINEC_Pos 4 /**< (DEVEPTIDR) NAKed IN Interrupt Clear Position */ +#define DEVEPTIDR_CTRL_NAKINEC (_U_(0x1) << DEVEPTIDR_CTRL_NAKINEC_Pos) /**< (DEVEPTIDR) NAKed IN Interrupt Clear Mask */ +#define DEVEPTIDR_CTRL_STALLEDEC_Pos 6 /**< (DEVEPTIDR) STALLed Interrupt Clear Position */ +#define DEVEPTIDR_CTRL_STALLEDEC (_U_(0x1) << DEVEPTIDR_CTRL_STALLEDEC_Pos) /**< (DEVEPTIDR) STALLed Interrupt Clear Mask */ +#define DEVEPTIDR_CTRL_NYETDISC_Pos 17 /**< (DEVEPTIDR) NYET Token Disable Clear Position */ +#define DEVEPTIDR_CTRL_NYETDISC (_U_(0x1) << DEVEPTIDR_CTRL_NYETDISC_Pos) /**< (DEVEPTIDR) NYET Token Disable Clear Mask */ +#define DEVEPTIDR_CTRL_STALLRQC_Pos 19 /**< (DEVEPTIDR) STALL Request Clear Position */ +#define DEVEPTIDR_CTRL_STALLRQC (_U_(0x1) << DEVEPTIDR_CTRL_STALLRQC_Pos) /**< (DEVEPTIDR) STALL Request Clear Mask */ +#define DEVEPTIDR_CTRL_Msk _U_(0xA005C) /**< (DEVEPTIDR_CTRL) Register Mask */ + +/* ISO mode */ +#define DEVEPTIDR_ISO_UNDERFEC_Pos 2 /**< (DEVEPTIDR) Underflow Interrupt Clear Position */ +#define DEVEPTIDR_ISO_UNDERFEC (_U_(0x1) << DEVEPTIDR_ISO_UNDERFEC_Pos) /**< (DEVEPTIDR) Underflow Interrupt Clear Mask */ +#define DEVEPTIDR_ISO_HBISOINERREC_Pos 3 /**< (DEVEPTIDR) High Bandwidth Isochronous IN Underflow Error Interrupt Clear Position */ +#define DEVEPTIDR_ISO_HBISOINERREC (_U_(0x1) << DEVEPTIDR_ISO_HBISOINERREC_Pos) /**< (DEVEPTIDR) High Bandwidth Isochronous IN Underflow Error Interrupt Clear Mask */ +#define DEVEPTIDR_ISO_HBISOFLUSHEC_Pos 4 /**< (DEVEPTIDR) High Bandwidth Isochronous IN Flush Interrupt Clear Position */ +#define DEVEPTIDR_ISO_HBISOFLUSHEC (_U_(0x1) << DEVEPTIDR_ISO_HBISOFLUSHEC_Pos) /**< (DEVEPTIDR) High Bandwidth Isochronous IN Flush Interrupt Clear Mask */ +#define DEVEPTIDR_ISO_MDATAEC_Pos 8 /**< (DEVEPTIDR) MData Interrupt Clear Position */ +#define DEVEPTIDR_ISO_MDATAEC (_U_(0x1) << DEVEPTIDR_ISO_MDATAEC_Pos) /**< (DEVEPTIDR) MData Interrupt Clear Mask */ +#define DEVEPTIDR_ISO_DATAXEC_Pos 9 /**< (DEVEPTIDR) DataX Interrupt Clear Position */ +#define DEVEPTIDR_ISO_DATAXEC (_U_(0x1) << DEVEPTIDR_ISO_DATAXEC_Pos) /**< (DEVEPTIDR) DataX Interrupt Clear Mask */ +#define DEVEPTIDR_ISO_ERRORTRANSEC_Pos 10 /**< (DEVEPTIDR) Transaction Error Interrupt Clear Position */ +#define DEVEPTIDR_ISO_ERRORTRANSEC (_U_(0x1) << DEVEPTIDR_ISO_ERRORTRANSEC_Pos) /**< (DEVEPTIDR) Transaction Error Interrupt Clear Mask */ +#define DEVEPTIDR_ISO_Msk _U_(0x71C) /**< (DEVEPTIDR_ISO) Register Mask */ + +/* BLK mode */ +#define DEVEPTIDR_BLK_RXSTPEC_Pos 2 /**< (DEVEPTIDR) Received SETUP Interrupt Clear Position */ +#define DEVEPTIDR_BLK_RXSTPEC (_U_(0x1) << DEVEPTIDR_BLK_RXSTPEC_Pos) /**< (DEVEPTIDR) Received SETUP Interrupt Clear Mask */ +#define DEVEPTIDR_BLK_NAKOUTEC_Pos 3 /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Position */ +#define DEVEPTIDR_BLK_NAKOUTEC (_U_(0x1) << DEVEPTIDR_BLK_NAKOUTEC_Pos) /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Mask */ +#define DEVEPTIDR_BLK_NAKINEC_Pos 4 /**< (DEVEPTIDR) NAKed IN Interrupt Clear Position */ +#define DEVEPTIDR_BLK_NAKINEC (_U_(0x1) << DEVEPTIDR_BLK_NAKINEC_Pos) /**< (DEVEPTIDR) NAKed IN Interrupt Clear Mask */ +#define DEVEPTIDR_BLK_STALLEDEC_Pos 6 /**< (DEVEPTIDR) STALLed Interrupt Clear Position */ +#define DEVEPTIDR_BLK_STALLEDEC (_U_(0x1) << DEVEPTIDR_BLK_STALLEDEC_Pos) /**< (DEVEPTIDR) STALLed Interrupt Clear Mask */ +#define DEVEPTIDR_BLK_NYETDISC_Pos 17 /**< (DEVEPTIDR) NYET Token Disable Clear Position */ +#define DEVEPTIDR_BLK_NYETDISC (_U_(0x1) << DEVEPTIDR_BLK_NYETDISC_Pos) /**< (DEVEPTIDR) NYET Token Disable Clear Mask */ +#define DEVEPTIDR_BLK_STALLRQC_Pos 19 /**< (DEVEPTIDR) STALL Request Clear Position */ +#define DEVEPTIDR_BLK_STALLRQC (_U_(0x1) << DEVEPTIDR_BLK_STALLRQC_Pos) /**< (DEVEPTIDR) STALL Request Clear Mask */ +#define DEVEPTIDR_BLK_Msk _U_(0xA005C) /**< (DEVEPTIDR_BLK) Register Mask */ + +/* INTRPT mode */ +#define DEVEPTIDR_INTRPT_RXSTPEC_Pos 2 /**< (DEVEPTIDR) Received SETUP Interrupt Clear Position */ +#define DEVEPTIDR_INTRPT_RXSTPEC (_U_(0x1) << DEVEPTIDR_INTRPT_RXSTPEC_Pos) /**< (DEVEPTIDR) Received SETUP Interrupt Clear Mask */ +#define DEVEPTIDR_INTRPT_NAKOUTEC_Pos 3 /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Position */ +#define DEVEPTIDR_INTRPT_NAKOUTEC (_U_(0x1) << DEVEPTIDR_INTRPT_NAKOUTEC_Pos) /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Mask */ +#define DEVEPTIDR_INTRPT_NAKINEC_Pos 4 /**< (DEVEPTIDR) NAKed IN Interrupt Clear Position */ +#define DEVEPTIDR_INTRPT_NAKINEC (_U_(0x1) << DEVEPTIDR_INTRPT_NAKINEC_Pos) /**< (DEVEPTIDR) NAKed IN Interrupt Clear Mask */ +#define DEVEPTIDR_INTRPT_STALLEDEC_Pos 6 /**< (DEVEPTIDR) STALLed Interrupt Clear Position */ +#define DEVEPTIDR_INTRPT_STALLEDEC (_U_(0x1) << DEVEPTIDR_INTRPT_STALLEDEC_Pos) /**< (DEVEPTIDR) STALLed Interrupt Clear Mask */ +#define DEVEPTIDR_INTRPT_NYETDISC_Pos 17 /**< (DEVEPTIDR) NYET Token Disable Clear Position */ +#define DEVEPTIDR_INTRPT_NYETDISC (_U_(0x1) << DEVEPTIDR_INTRPT_NYETDISC_Pos) /**< (DEVEPTIDR) NYET Token Disable Clear Mask */ +#define DEVEPTIDR_INTRPT_STALLRQC_Pos 19 /**< (DEVEPTIDR) STALL Request Clear Position */ +#define DEVEPTIDR_INTRPT_STALLRQC (_U_(0x1) << DEVEPTIDR_INTRPT_STALLRQC_Pos) /**< (DEVEPTIDR) STALL Request Clear Mask */ +#define DEVEPTIDR_INTRPT_Msk _U_(0xA005C) /**< (DEVEPTIDR_INTRPT) Register Mask */ + + +/* -------- HSTCTRL : (USBHS Offset: 0x400) (R/W 32) Host General Control Register -------- */ + +#define HSTCTRL_OFFSET (0x400) /**< (HSTCTRL) Host General Control Register Offset */ + +#define HSTCTRL_SOFE_Pos 8 /**< (HSTCTRL) Start of Frame Generation Enable Position */ +#define HSTCTRL_SOFE (_U_(0x1) << HSTCTRL_SOFE_Pos) /**< (HSTCTRL) Start of Frame Generation Enable Mask */ +#define HSTCTRL_RESET_Pos 9 /**< (HSTCTRL) Send USB Reset Position */ +#define HSTCTRL_RESET (_U_(0x1) << HSTCTRL_RESET_Pos) /**< (HSTCTRL) Send USB Reset Mask */ +#define HSTCTRL_RESUME_Pos 10 /**< (HSTCTRL) Send USB Resume Position */ +#define HSTCTRL_RESUME (_U_(0x1) << HSTCTRL_RESUME_Pos) /**< (HSTCTRL) Send USB Resume Mask */ +#define HSTCTRL_SPDCONF_Pos 12 /**< (HSTCTRL) Mode Configuration Position */ +#define HSTCTRL_SPDCONF (_U_(0x3) << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) Mode Configuration Mask */ +#define HSTCTRL_SPDCONF_NORMAL_Val _U_(0x0) /**< (HSTCTRL) The host starts in Full-speed mode and performs a high-speed reset to switch to High-speed mode if the downstream peripheral is high-speed capable. */ +#define HSTCTRL_SPDCONF_LOW_POWER_Val _U_(0x1) /**< (HSTCTRL) For a better consumption, if high speed is not needed. */ +#define HSTCTRL_SPDCONF_HIGH_SPEED_Val _U_(0x2) /**< (HSTCTRL) Forced high speed. */ +#define HSTCTRL_SPDCONF_FORCED_FS_Val _U_(0x3) /**< (HSTCTRL) The host remains in Full-speed mode whatever the peripheral speed capability. */ +#define HSTCTRL_SPDCONF_NORMAL (HSTCTRL_SPDCONF_NORMAL_Val << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) The host starts in Full-speed mode and performs a high-speed reset to switch to High-speed mode if the downstream peripheral is high-speed capable. Position */ +#define HSTCTRL_SPDCONF_LOW_POWER (HSTCTRL_SPDCONF_LOW_POWER_Val << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) For a better consumption, if high speed is not needed. Position */ +#define HSTCTRL_SPDCONF_HIGH_SPEED (HSTCTRL_SPDCONF_HIGH_SPEED_Val << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) Forced high speed. Position */ +#define HSTCTRL_SPDCONF_FORCED_FS (HSTCTRL_SPDCONF_FORCED_FS_Val << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) The host remains in Full-speed mode whatever the peripheral speed capability. Position */ +#define HSTCTRL_Msk _U_(0x3700) /**< (HSTCTRL) Register Mask */ + + +/* -------- HSTISR : (USBHS Offset: 0x404) (R/ 32) Host Global Interrupt Status Register -------- */ + +#define HSTISR_OFFSET (0x404) /**< (HSTISR) Host Global Interrupt Status Register Offset */ + +#define HSTISR_DCONNI_Pos 0 /**< (HSTISR) Device Connection Interrupt Position */ +#define HSTISR_DCONNI (_U_(0x1) << HSTISR_DCONNI_Pos) /**< (HSTISR) Device Connection Interrupt Mask */ +#define HSTISR_DDISCI_Pos 1 /**< (HSTISR) Device Disconnection Interrupt Position */ +#define HSTISR_DDISCI (_U_(0x1) << HSTISR_DDISCI_Pos) /**< (HSTISR) Device Disconnection Interrupt Mask */ +#define HSTISR_RSTI_Pos 2 /**< (HSTISR) USB Reset Sent Interrupt Position */ +#define HSTISR_RSTI (_U_(0x1) << HSTISR_RSTI_Pos) /**< (HSTISR) USB Reset Sent Interrupt Mask */ +#define HSTISR_RSMEDI_Pos 3 /**< (HSTISR) Downstream Resume Sent Interrupt Position */ +#define HSTISR_RSMEDI (_U_(0x1) << HSTISR_RSMEDI_Pos) /**< (HSTISR) Downstream Resume Sent Interrupt Mask */ +#define HSTISR_RXRSMI_Pos 4 /**< (HSTISR) Upstream Resume Received Interrupt Position */ +#define HSTISR_RXRSMI (_U_(0x1) << HSTISR_RXRSMI_Pos) /**< (HSTISR) Upstream Resume Received Interrupt Mask */ +#define HSTISR_HSOFI_Pos 5 /**< (HSTISR) Host Start of Frame Interrupt Position */ +#define HSTISR_HSOFI (_U_(0x1) << HSTISR_HSOFI_Pos) /**< (HSTISR) Host Start of Frame Interrupt Mask */ +#define HSTISR_HWUPI_Pos 6 /**< (HSTISR) Host Wake-Up Interrupt Position */ +#define HSTISR_HWUPI (_U_(0x1) << HSTISR_HWUPI_Pos) /**< (HSTISR) Host Wake-Up Interrupt Mask */ +#define HSTISR_PEP_0_Pos 8 /**< (HSTISR) Pipe 0 Interrupt Position */ +#define HSTISR_PEP_0 (_U_(0x1) << HSTISR_PEP_0_Pos) /**< (HSTISR) Pipe 0 Interrupt Mask */ +#define HSTISR_PEP_1_Pos 9 /**< (HSTISR) Pipe 1 Interrupt Position */ +#define HSTISR_PEP_1 (_U_(0x1) << HSTISR_PEP_1_Pos) /**< (HSTISR) Pipe 1 Interrupt Mask */ +#define HSTISR_PEP_2_Pos 10 /**< (HSTISR) Pipe 2 Interrupt Position */ +#define HSTISR_PEP_2 (_U_(0x1) << HSTISR_PEP_2_Pos) /**< (HSTISR) Pipe 2 Interrupt Mask */ +#define HSTISR_PEP_3_Pos 11 /**< (HSTISR) Pipe 3 Interrupt Position */ +#define HSTISR_PEP_3 (_U_(0x1) << HSTISR_PEP_3_Pos) /**< (HSTISR) Pipe 3 Interrupt Mask */ +#define HSTISR_PEP_4_Pos 12 /**< (HSTISR) Pipe 4 Interrupt Position */ +#define HSTISR_PEP_4 (_U_(0x1) << HSTISR_PEP_4_Pos) /**< (HSTISR) Pipe 4 Interrupt Mask */ +#define HSTISR_PEP_5_Pos 13 /**< (HSTISR) Pipe 5 Interrupt Position */ +#define HSTISR_PEP_5 (_U_(0x1) << HSTISR_PEP_5_Pos) /**< (HSTISR) Pipe 5 Interrupt Mask */ +#define HSTISR_PEP_6_Pos 14 /**< (HSTISR) Pipe 6 Interrupt Position */ +#define HSTISR_PEP_6 (_U_(0x1) << HSTISR_PEP_6_Pos) /**< (HSTISR) Pipe 6 Interrupt Mask */ +#define HSTISR_PEP_7_Pos 15 /**< (HSTISR) Pipe 7 Interrupt Position */ +#define HSTISR_PEP_7 (_U_(0x1) << HSTISR_PEP_7_Pos) /**< (HSTISR) Pipe 7 Interrupt Mask */ +#define HSTISR_PEP_8_Pos 16 /**< (HSTISR) Pipe 8 Interrupt Position */ +#define HSTISR_PEP_8 (_U_(0x1) << HSTISR_PEP_8_Pos) /**< (HSTISR) Pipe 8 Interrupt Mask */ +#define HSTISR_PEP_9_Pos 17 /**< (HSTISR) Pipe 9 Interrupt Position */ +#define HSTISR_PEP_9 (_U_(0x1) << HSTISR_PEP_9_Pos) /**< (HSTISR) Pipe 9 Interrupt Mask */ +#define HSTISR_DMA_0_Pos 25 /**< (HSTISR) DMA Channel 0 Interrupt Position */ +#define HSTISR_DMA_0 (_U_(0x1) << HSTISR_DMA_0_Pos) /**< (HSTISR) DMA Channel 0 Interrupt Mask */ +#define HSTISR_DMA_1_Pos 26 /**< (HSTISR) DMA Channel 1 Interrupt Position */ +#define HSTISR_DMA_1 (_U_(0x1) << HSTISR_DMA_1_Pos) /**< (HSTISR) DMA Channel 1 Interrupt Mask */ +#define HSTISR_DMA_2_Pos 27 /**< (HSTISR) DMA Channel 2 Interrupt Position */ +#define HSTISR_DMA_2 (_U_(0x1) << HSTISR_DMA_2_Pos) /**< (HSTISR) DMA Channel 2 Interrupt Mask */ +#define HSTISR_DMA_3_Pos 28 /**< (HSTISR) DMA Channel 3 Interrupt Position */ +#define HSTISR_DMA_3 (_U_(0x1) << HSTISR_DMA_3_Pos) /**< (HSTISR) DMA Channel 3 Interrupt Mask */ +#define HSTISR_DMA_4_Pos 29 /**< (HSTISR) DMA Channel 4 Interrupt Position */ +#define HSTISR_DMA_4 (_U_(0x1) << HSTISR_DMA_4_Pos) /**< (HSTISR) DMA Channel 4 Interrupt Mask */ +#define HSTISR_DMA_5_Pos 30 /**< (HSTISR) DMA Channel 5 Interrupt Position */ +#define HSTISR_DMA_5 (_U_(0x1) << HSTISR_DMA_5_Pos) /**< (HSTISR) DMA Channel 5 Interrupt Mask */ +#define HSTISR_DMA_6_Pos 31 /**< (HSTISR) DMA Channel 6 Interrupt Position */ +#define HSTISR_DMA_6 (_U_(0x1) << HSTISR_DMA_6_Pos) /**< (HSTISR) DMA Channel 6 Interrupt Mask */ +#define HSTISR_Msk _U_(0xFE03FF7F) /**< (HSTISR) Register Mask */ + +#define HSTISR_PEP__Pos 8 /**< (HSTISR Position) Pipe x Interrupt */ +#define HSTISR_PEP_ (_U_(0x3FF) << HSTISR_PEP__Pos) /**< (HSTISR Mask) PEP_ */ +#define HSTISR_DMA__Pos 25 /**< (HSTISR Position) DMA Channel 6 Interrupt */ +#define HSTISR_DMA_ (_U_(0x7F) << HSTISR_DMA__Pos) /**< (HSTISR Mask) DMA_ */ + +/* -------- HSTICR : (USBHS Offset: 0x408) (/W 32) Host Global Interrupt Clear Register -------- */ + +#define HSTICR_OFFSET (0x408) /**< (HSTICR) Host Global Interrupt Clear Register Offset */ + +#define HSTICR_DCONNIC_Pos 0 /**< (HSTICR) Device Connection Interrupt Clear Position */ +#define HSTICR_DCONNIC (_U_(0x1) << HSTICR_DCONNIC_Pos) /**< (HSTICR) Device Connection Interrupt Clear Mask */ +#define HSTICR_DDISCIC_Pos 1 /**< (HSTICR) Device Disconnection Interrupt Clear Position */ +#define HSTICR_DDISCIC (_U_(0x1) << HSTICR_DDISCIC_Pos) /**< (HSTICR) Device Disconnection Interrupt Clear Mask */ +#define HSTICR_RSTIC_Pos 2 /**< (HSTICR) USB Reset Sent Interrupt Clear Position */ +#define HSTICR_RSTIC (_U_(0x1) << HSTICR_RSTIC_Pos) /**< (HSTICR) USB Reset Sent Interrupt Clear Mask */ +#define HSTICR_RSMEDIC_Pos 3 /**< (HSTICR) Downstream Resume Sent Interrupt Clear Position */ +#define HSTICR_RSMEDIC (_U_(0x1) << HSTICR_RSMEDIC_Pos) /**< (HSTICR) Downstream Resume Sent Interrupt Clear Mask */ +#define HSTICR_RXRSMIC_Pos 4 /**< (HSTICR) Upstream Resume Received Interrupt Clear Position */ +#define HSTICR_RXRSMIC (_U_(0x1) << HSTICR_RXRSMIC_Pos) /**< (HSTICR) Upstream Resume Received Interrupt Clear Mask */ +#define HSTICR_HSOFIC_Pos 5 /**< (HSTICR) Host Start of Frame Interrupt Clear Position */ +#define HSTICR_HSOFIC (_U_(0x1) << HSTICR_HSOFIC_Pos) /**< (HSTICR) Host Start of Frame Interrupt Clear Mask */ +#define HSTICR_HWUPIC_Pos 6 /**< (HSTICR) Host Wake-Up Interrupt Clear Position */ +#define HSTICR_HWUPIC (_U_(0x1) << HSTICR_HWUPIC_Pos) /**< (HSTICR) Host Wake-Up Interrupt Clear Mask */ +#define HSTICR_Msk _U_(0x7F) /**< (HSTICR) Register Mask */ + + +/* -------- HSTIFR : (USBHS Offset: 0x40c) (/W 32) Host Global Interrupt Set Register -------- */ + +#define HSTIFR_OFFSET (0x40C) /**< (HSTIFR) Host Global Interrupt Set Register Offset */ + +#define HSTIFR_DCONNIS_Pos 0 /**< (HSTIFR) Device Connection Interrupt Set Position */ +#define HSTIFR_DCONNIS (_U_(0x1) << HSTIFR_DCONNIS_Pos) /**< (HSTIFR) Device Connection Interrupt Set Mask */ +#define HSTIFR_DDISCIS_Pos 1 /**< (HSTIFR) Device Disconnection Interrupt Set Position */ +#define HSTIFR_DDISCIS (_U_(0x1) << HSTIFR_DDISCIS_Pos) /**< (HSTIFR) Device Disconnection Interrupt Set Mask */ +#define HSTIFR_RSTIS_Pos 2 /**< (HSTIFR) USB Reset Sent Interrupt Set Position */ +#define HSTIFR_RSTIS (_U_(0x1) << HSTIFR_RSTIS_Pos) /**< (HSTIFR) USB Reset Sent Interrupt Set Mask */ +#define HSTIFR_RSMEDIS_Pos 3 /**< (HSTIFR) Downstream Resume Sent Interrupt Set Position */ +#define HSTIFR_RSMEDIS (_U_(0x1) << HSTIFR_RSMEDIS_Pos) /**< (HSTIFR) Downstream Resume Sent Interrupt Set Mask */ +#define HSTIFR_RXRSMIS_Pos 4 /**< (HSTIFR) Upstream Resume Received Interrupt Set Position */ +#define HSTIFR_RXRSMIS (_U_(0x1) << HSTIFR_RXRSMIS_Pos) /**< (HSTIFR) Upstream Resume Received Interrupt Set Mask */ +#define HSTIFR_HSOFIS_Pos 5 /**< (HSTIFR) Host Start of Frame Interrupt Set Position */ +#define HSTIFR_HSOFIS (_U_(0x1) << HSTIFR_HSOFIS_Pos) /**< (HSTIFR) Host Start of Frame Interrupt Set Mask */ +#define HSTIFR_HWUPIS_Pos 6 /**< (HSTIFR) Host Wake-Up Interrupt Set Position */ +#define HSTIFR_HWUPIS (_U_(0x1) << HSTIFR_HWUPIS_Pos) /**< (HSTIFR) Host Wake-Up Interrupt Set Mask */ +#define HSTIFR_DMA_0_Pos 25 /**< (HSTIFR) DMA Channel 0 Interrupt Set Position */ +#define HSTIFR_DMA_0 (_U_(0x1) << HSTIFR_DMA_0_Pos) /**< (HSTIFR) DMA Channel 0 Interrupt Set Mask */ +#define HSTIFR_DMA_1_Pos 26 /**< (HSTIFR) DMA Channel 1 Interrupt Set Position */ +#define HSTIFR_DMA_1 (_U_(0x1) << HSTIFR_DMA_1_Pos) /**< (HSTIFR) DMA Channel 1 Interrupt Set Mask */ +#define HSTIFR_DMA_2_Pos 27 /**< (HSTIFR) DMA Channel 2 Interrupt Set Position */ +#define HSTIFR_DMA_2 (_U_(0x1) << HSTIFR_DMA_2_Pos) /**< (HSTIFR) DMA Channel 2 Interrupt Set Mask */ +#define HSTIFR_DMA_3_Pos 28 /**< (HSTIFR) DMA Channel 3 Interrupt Set Position */ +#define HSTIFR_DMA_3 (_U_(0x1) << HSTIFR_DMA_3_Pos) /**< (HSTIFR) DMA Channel 3 Interrupt Set Mask */ +#define HSTIFR_DMA_4_Pos 29 /**< (HSTIFR) DMA Channel 4 Interrupt Set Position */ +#define HSTIFR_DMA_4 (_U_(0x1) << HSTIFR_DMA_4_Pos) /**< (HSTIFR) DMA Channel 4 Interrupt Set Mask */ +#define HSTIFR_DMA_5_Pos 30 /**< (HSTIFR) DMA Channel 5 Interrupt Set Position */ +#define HSTIFR_DMA_5 (_U_(0x1) << HSTIFR_DMA_5_Pos) /**< (HSTIFR) DMA Channel 5 Interrupt Set Mask */ +#define HSTIFR_DMA_6_Pos 31 /**< (HSTIFR) DMA Channel 6 Interrupt Set Position */ +#define HSTIFR_DMA_6 (_U_(0x1) << HSTIFR_DMA_6_Pos) /**< (HSTIFR) DMA Channel 6 Interrupt Set Mask */ +#define HSTIFR_Msk _U_(0xFE00007F) /**< (HSTIFR) Register Mask */ + +#define HSTIFR_DMA__Pos 25 /**< (HSTIFR Position) DMA Channel 6 Interrupt Set */ +#define HSTIFR_DMA_ (_U_(0x7F) << HSTIFR_DMA__Pos) /**< (HSTIFR Mask) DMA_ */ + +/* -------- HSTIMR : (USBHS Offset: 0x410) (R/ 32) Host Global Interrupt Mask Register -------- */ + +#define HSTIMR_OFFSET (0x410) /**< (HSTIMR) Host Global Interrupt Mask Register Offset */ + +#define HSTIMR_DCONNIE_Pos 0 /**< (HSTIMR) Device Connection Interrupt Enable Position */ +#define HSTIMR_DCONNIE (_U_(0x1) << HSTIMR_DCONNIE_Pos) /**< (HSTIMR) Device Connection Interrupt Enable Mask */ +#define HSTIMR_DDISCIE_Pos 1 /**< (HSTIMR) Device Disconnection Interrupt Enable Position */ +#define HSTIMR_DDISCIE (_U_(0x1) << HSTIMR_DDISCIE_Pos) /**< (HSTIMR) Device Disconnection Interrupt Enable Mask */ +#define HSTIMR_RSTIE_Pos 2 /**< (HSTIMR) USB Reset Sent Interrupt Enable Position */ +#define HSTIMR_RSTIE (_U_(0x1) << HSTIMR_RSTIE_Pos) /**< (HSTIMR) USB Reset Sent Interrupt Enable Mask */ +#define HSTIMR_RSMEDIE_Pos 3 /**< (HSTIMR) Downstream Resume Sent Interrupt Enable Position */ +#define HSTIMR_RSMEDIE (_U_(0x1) << HSTIMR_RSMEDIE_Pos) /**< (HSTIMR) Downstream Resume Sent Interrupt Enable Mask */ +#define HSTIMR_RXRSMIE_Pos 4 /**< (HSTIMR) Upstream Resume Received Interrupt Enable Position */ +#define HSTIMR_RXRSMIE (_U_(0x1) << HSTIMR_RXRSMIE_Pos) /**< (HSTIMR) Upstream Resume Received Interrupt Enable Mask */ +#define HSTIMR_HSOFIE_Pos 5 /**< (HSTIMR) Host Start of Frame Interrupt Enable Position */ +#define HSTIMR_HSOFIE (_U_(0x1) << HSTIMR_HSOFIE_Pos) /**< (HSTIMR) Host Start of Frame Interrupt Enable Mask */ +#define HSTIMR_HWUPIE_Pos 6 /**< (HSTIMR) Host Wake-Up Interrupt Enable Position */ +#define HSTIMR_HWUPIE (_U_(0x1) << HSTIMR_HWUPIE_Pos) /**< (HSTIMR) Host Wake-Up Interrupt Enable Mask */ +#define HSTIMR_PEP_0_Pos 8 /**< (HSTIMR) Pipe 0 Interrupt Enable Position */ +#define HSTIMR_PEP_0 (_U_(0x1) << HSTIMR_PEP_0_Pos) /**< (HSTIMR) Pipe 0 Interrupt Enable Mask */ +#define HSTIMR_PEP_1_Pos 9 /**< (HSTIMR) Pipe 1 Interrupt Enable Position */ +#define HSTIMR_PEP_1 (_U_(0x1) << HSTIMR_PEP_1_Pos) /**< (HSTIMR) Pipe 1 Interrupt Enable Mask */ +#define HSTIMR_PEP_2_Pos 10 /**< (HSTIMR) Pipe 2 Interrupt Enable Position */ +#define HSTIMR_PEP_2 (_U_(0x1) << HSTIMR_PEP_2_Pos) /**< (HSTIMR) Pipe 2 Interrupt Enable Mask */ +#define HSTIMR_PEP_3_Pos 11 /**< (HSTIMR) Pipe 3 Interrupt Enable Position */ +#define HSTIMR_PEP_3 (_U_(0x1) << HSTIMR_PEP_3_Pos) /**< (HSTIMR) Pipe 3 Interrupt Enable Mask */ +#define HSTIMR_PEP_4_Pos 12 /**< (HSTIMR) Pipe 4 Interrupt Enable Position */ +#define HSTIMR_PEP_4 (_U_(0x1) << HSTIMR_PEP_4_Pos) /**< (HSTIMR) Pipe 4 Interrupt Enable Mask */ +#define HSTIMR_PEP_5_Pos 13 /**< (HSTIMR) Pipe 5 Interrupt Enable Position */ +#define HSTIMR_PEP_5 (_U_(0x1) << HSTIMR_PEP_5_Pos) /**< (HSTIMR) Pipe 5 Interrupt Enable Mask */ +#define HSTIMR_PEP_6_Pos 14 /**< (HSTIMR) Pipe 6 Interrupt Enable Position */ +#define HSTIMR_PEP_6 (_U_(0x1) << HSTIMR_PEP_6_Pos) /**< (HSTIMR) Pipe 6 Interrupt Enable Mask */ +#define HSTIMR_PEP_7_Pos 15 /**< (HSTIMR) Pipe 7 Interrupt Enable Position */ +#define HSTIMR_PEP_7 (_U_(0x1) << HSTIMR_PEP_7_Pos) /**< (HSTIMR) Pipe 7 Interrupt Enable Mask */ +#define HSTIMR_PEP_8_Pos 16 /**< (HSTIMR) Pipe 8 Interrupt Enable Position */ +#define HSTIMR_PEP_8 (_U_(0x1) << HSTIMR_PEP_8_Pos) /**< (HSTIMR) Pipe 8 Interrupt Enable Mask */ +#define HSTIMR_PEP_9_Pos 17 /**< (HSTIMR) Pipe 9 Interrupt Enable Position */ +#define HSTIMR_PEP_9 (_U_(0x1) << HSTIMR_PEP_9_Pos) /**< (HSTIMR) Pipe 9 Interrupt Enable Mask */ +#define HSTIMR_DMA_0_Pos 25 /**< (HSTIMR) DMA Channel 0 Interrupt Enable Position */ +#define HSTIMR_DMA_0 (_U_(0x1) << HSTIMR_DMA_0_Pos) /**< (HSTIMR) DMA Channel 0 Interrupt Enable Mask */ +#define HSTIMR_DMA_1_Pos 26 /**< (HSTIMR) DMA Channel 1 Interrupt Enable Position */ +#define HSTIMR_DMA_1 (_U_(0x1) << HSTIMR_DMA_1_Pos) /**< (HSTIMR) DMA Channel 1 Interrupt Enable Mask */ +#define HSTIMR_DMA_2_Pos 27 /**< (HSTIMR) DMA Channel 2 Interrupt Enable Position */ +#define HSTIMR_DMA_2 (_U_(0x1) << HSTIMR_DMA_2_Pos) /**< (HSTIMR) DMA Channel 2 Interrupt Enable Mask */ +#define HSTIMR_DMA_3_Pos 28 /**< (HSTIMR) DMA Channel 3 Interrupt Enable Position */ +#define HSTIMR_DMA_3 (_U_(0x1) << HSTIMR_DMA_3_Pos) /**< (HSTIMR) DMA Channel 3 Interrupt Enable Mask */ +#define HSTIMR_DMA_4_Pos 29 /**< (HSTIMR) DMA Channel 4 Interrupt Enable Position */ +#define HSTIMR_DMA_4 (_U_(0x1) << HSTIMR_DMA_4_Pos) /**< (HSTIMR) DMA Channel 4 Interrupt Enable Mask */ +#define HSTIMR_DMA_5_Pos 30 /**< (HSTIMR) DMA Channel 5 Interrupt Enable Position */ +#define HSTIMR_DMA_5 (_U_(0x1) << HSTIMR_DMA_5_Pos) /**< (HSTIMR) DMA Channel 5 Interrupt Enable Mask */ +#define HSTIMR_DMA_6_Pos 31 /**< (HSTIMR) DMA Channel 6 Interrupt Enable Position */ +#define HSTIMR_DMA_6 (_U_(0x1) << HSTIMR_DMA_6_Pos) /**< (HSTIMR) DMA Channel 6 Interrupt Enable Mask */ +#define HSTIMR_Msk _U_(0xFE03FF7F) /**< (HSTIMR) Register Mask */ + +#define HSTIMR_PEP__Pos 8 /**< (HSTIMR Position) Pipe x Interrupt Enable */ +#define HSTIMR_PEP_ (_U_(0x3FF) << HSTIMR_PEP__Pos) /**< (HSTIMR Mask) PEP_ */ +#define HSTIMR_DMA__Pos 25 /**< (HSTIMR Position) DMA Channel 6 Interrupt Enable */ +#define HSTIMR_DMA_ (_U_(0x7F) << HSTIMR_DMA__Pos) /**< (HSTIMR Mask) DMA_ */ + +/* -------- HSTIDR : (USBHS Offset: 0x414) (/W 32) Host Global Interrupt Disable Register -------- */ + +#define HSTIDR_OFFSET (0x414) /**< (HSTIDR) Host Global Interrupt Disable Register Offset */ + +#define HSTIDR_DCONNIEC_Pos 0 /**< (HSTIDR) Device Connection Interrupt Disable Position */ +#define HSTIDR_DCONNIEC (_U_(0x1) << HSTIDR_DCONNIEC_Pos) /**< (HSTIDR) Device Connection Interrupt Disable Mask */ +#define HSTIDR_DDISCIEC_Pos 1 /**< (HSTIDR) Device Disconnection Interrupt Disable Position */ +#define HSTIDR_DDISCIEC (_U_(0x1) << HSTIDR_DDISCIEC_Pos) /**< (HSTIDR) Device Disconnection Interrupt Disable Mask */ +#define HSTIDR_RSTIEC_Pos 2 /**< (HSTIDR) USB Reset Sent Interrupt Disable Position */ +#define HSTIDR_RSTIEC (_U_(0x1) << HSTIDR_RSTIEC_Pos) /**< (HSTIDR) USB Reset Sent Interrupt Disable Mask */ +#define HSTIDR_RSMEDIEC_Pos 3 /**< (HSTIDR) Downstream Resume Sent Interrupt Disable Position */ +#define HSTIDR_RSMEDIEC (_U_(0x1) << HSTIDR_RSMEDIEC_Pos) /**< (HSTIDR) Downstream Resume Sent Interrupt Disable Mask */ +#define HSTIDR_RXRSMIEC_Pos 4 /**< (HSTIDR) Upstream Resume Received Interrupt Disable Position */ +#define HSTIDR_RXRSMIEC (_U_(0x1) << HSTIDR_RXRSMIEC_Pos) /**< (HSTIDR) Upstream Resume Received Interrupt Disable Mask */ +#define HSTIDR_HSOFIEC_Pos 5 /**< (HSTIDR) Host Start of Frame Interrupt Disable Position */ +#define HSTIDR_HSOFIEC (_U_(0x1) << HSTIDR_HSOFIEC_Pos) /**< (HSTIDR) Host Start of Frame Interrupt Disable Mask */ +#define HSTIDR_HWUPIEC_Pos 6 /**< (HSTIDR) Host Wake-Up Interrupt Disable Position */ +#define HSTIDR_HWUPIEC (_U_(0x1) << HSTIDR_HWUPIEC_Pos) /**< (HSTIDR) Host Wake-Up Interrupt Disable Mask */ +#define HSTIDR_PEP_0_Pos 8 /**< (HSTIDR) Pipe 0 Interrupt Disable Position */ +#define HSTIDR_PEP_0 (_U_(0x1) << HSTIDR_PEP_0_Pos) /**< (HSTIDR) Pipe 0 Interrupt Disable Mask */ +#define HSTIDR_PEP_1_Pos 9 /**< (HSTIDR) Pipe 1 Interrupt Disable Position */ +#define HSTIDR_PEP_1 (_U_(0x1) << HSTIDR_PEP_1_Pos) /**< (HSTIDR) Pipe 1 Interrupt Disable Mask */ +#define HSTIDR_PEP_2_Pos 10 /**< (HSTIDR) Pipe 2 Interrupt Disable Position */ +#define HSTIDR_PEP_2 (_U_(0x1) << HSTIDR_PEP_2_Pos) /**< (HSTIDR) Pipe 2 Interrupt Disable Mask */ +#define HSTIDR_PEP_3_Pos 11 /**< (HSTIDR) Pipe 3 Interrupt Disable Position */ +#define HSTIDR_PEP_3 (_U_(0x1) << HSTIDR_PEP_3_Pos) /**< (HSTIDR) Pipe 3 Interrupt Disable Mask */ +#define HSTIDR_PEP_4_Pos 12 /**< (HSTIDR) Pipe 4 Interrupt Disable Position */ +#define HSTIDR_PEP_4 (_U_(0x1) << HSTIDR_PEP_4_Pos) /**< (HSTIDR) Pipe 4 Interrupt Disable Mask */ +#define HSTIDR_PEP_5_Pos 13 /**< (HSTIDR) Pipe 5 Interrupt Disable Position */ +#define HSTIDR_PEP_5 (_U_(0x1) << HSTIDR_PEP_5_Pos) /**< (HSTIDR) Pipe 5 Interrupt Disable Mask */ +#define HSTIDR_PEP_6_Pos 14 /**< (HSTIDR) Pipe 6 Interrupt Disable Position */ +#define HSTIDR_PEP_6 (_U_(0x1) << HSTIDR_PEP_6_Pos) /**< (HSTIDR) Pipe 6 Interrupt Disable Mask */ +#define HSTIDR_PEP_7_Pos 15 /**< (HSTIDR) Pipe 7 Interrupt Disable Position */ +#define HSTIDR_PEP_7 (_U_(0x1) << HSTIDR_PEP_7_Pos) /**< (HSTIDR) Pipe 7 Interrupt Disable Mask */ +#define HSTIDR_PEP_8_Pos 16 /**< (HSTIDR) Pipe 8 Interrupt Disable Position */ +#define HSTIDR_PEP_8 (_U_(0x1) << HSTIDR_PEP_8_Pos) /**< (HSTIDR) Pipe 8 Interrupt Disable Mask */ +#define HSTIDR_PEP_9_Pos 17 /**< (HSTIDR) Pipe 9 Interrupt Disable Position */ +#define HSTIDR_PEP_9 (_U_(0x1) << HSTIDR_PEP_9_Pos) /**< (HSTIDR) Pipe 9 Interrupt Disable Mask */ +#define HSTIDR_DMA_0_Pos 25 /**< (HSTIDR) DMA Channel 0 Interrupt Disable Position */ +#define HSTIDR_DMA_0 (_U_(0x1) << HSTIDR_DMA_0_Pos) /**< (HSTIDR) DMA Channel 0 Interrupt Disable Mask */ +#define HSTIDR_DMA_1_Pos 26 /**< (HSTIDR) DMA Channel 1 Interrupt Disable Position */ +#define HSTIDR_DMA_1 (_U_(0x1) << HSTIDR_DMA_1_Pos) /**< (HSTIDR) DMA Channel 1 Interrupt Disable Mask */ +#define HSTIDR_DMA_2_Pos 27 /**< (HSTIDR) DMA Channel 2 Interrupt Disable Position */ +#define HSTIDR_DMA_2 (_U_(0x1) << HSTIDR_DMA_2_Pos) /**< (HSTIDR) DMA Channel 2 Interrupt Disable Mask */ +#define HSTIDR_DMA_3_Pos 28 /**< (HSTIDR) DMA Channel 3 Interrupt Disable Position */ +#define HSTIDR_DMA_3 (_U_(0x1) << HSTIDR_DMA_3_Pos) /**< (HSTIDR) DMA Channel 3 Interrupt Disable Mask */ +#define HSTIDR_DMA_4_Pos 29 /**< (HSTIDR) DMA Channel 4 Interrupt Disable Position */ +#define HSTIDR_DMA_4 (_U_(0x1) << HSTIDR_DMA_4_Pos) /**< (HSTIDR) DMA Channel 4 Interrupt Disable Mask */ +#define HSTIDR_DMA_5_Pos 30 /**< (HSTIDR) DMA Channel 5 Interrupt Disable Position */ +#define HSTIDR_DMA_5 (_U_(0x1) << HSTIDR_DMA_5_Pos) /**< (HSTIDR) DMA Channel 5 Interrupt Disable Mask */ +#define HSTIDR_DMA_6_Pos 31 /**< (HSTIDR) DMA Channel 6 Interrupt Disable Position */ +#define HSTIDR_DMA_6 (_U_(0x1) << HSTIDR_DMA_6_Pos) /**< (HSTIDR) DMA Channel 6 Interrupt Disable Mask */ +#define HSTIDR_Msk _U_(0xFE03FF7F) /**< (HSTIDR) Register Mask */ + +#define HSTIDR_PEP__Pos 8 /**< (HSTIDR Position) Pipe x Interrupt Disable */ +#define HSTIDR_PEP_ (_U_(0x3FF) << HSTIDR_PEP__Pos) /**< (HSTIDR Mask) PEP_ */ +#define HSTIDR_DMA__Pos 25 /**< (HSTIDR Position) DMA Channel 6 Interrupt Disable */ +#define HSTIDR_DMA_ (_U_(0x7F) << HSTIDR_DMA__Pos) /**< (HSTIDR Mask) DMA_ */ + +/* -------- HSTIER : (USBHS Offset: 0x418) (/W 32) Host Global Interrupt Enable Register -------- */ + +#define HSTIER_OFFSET (0x418) /**< (HSTIER) Host Global Interrupt Enable Register Offset */ + +#define HSTIER_DCONNIES_Pos 0 /**< (HSTIER) Device Connection Interrupt Enable Position */ +#define HSTIER_DCONNIES (_U_(0x1) << HSTIER_DCONNIES_Pos) /**< (HSTIER) Device Connection Interrupt Enable Mask */ +#define HSTIER_DDISCIES_Pos 1 /**< (HSTIER) Device Disconnection Interrupt Enable Position */ +#define HSTIER_DDISCIES (_U_(0x1) << HSTIER_DDISCIES_Pos) /**< (HSTIER) Device Disconnection Interrupt Enable Mask */ +#define HSTIER_RSTIES_Pos 2 /**< (HSTIER) USB Reset Sent Interrupt Enable Position */ +#define HSTIER_RSTIES (_U_(0x1) << HSTIER_RSTIES_Pos) /**< (HSTIER) USB Reset Sent Interrupt Enable Mask */ +#define HSTIER_RSMEDIES_Pos 3 /**< (HSTIER) Downstream Resume Sent Interrupt Enable Position */ +#define HSTIER_RSMEDIES (_U_(0x1) << HSTIER_RSMEDIES_Pos) /**< (HSTIER) Downstream Resume Sent Interrupt Enable Mask */ +#define HSTIER_RXRSMIES_Pos 4 /**< (HSTIER) Upstream Resume Received Interrupt Enable Position */ +#define HSTIER_RXRSMIES (_U_(0x1) << HSTIER_RXRSMIES_Pos) /**< (HSTIER) Upstream Resume Received Interrupt Enable Mask */ +#define HSTIER_HSOFIES_Pos 5 /**< (HSTIER) Host Start of Frame Interrupt Enable Position */ +#define HSTIER_HSOFIES (_U_(0x1) << HSTIER_HSOFIES_Pos) /**< (HSTIER) Host Start of Frame Interrupt Enable Mask */ +#define HSTIER_HWUPIES_Pos 6 /**< (HSTIER) Host Wake-Up Interrupt Enable Position */ +#define HSTIER_HWUPIES (_U_(0x1) << HSTIER_HWUPIES_Pos) /**< (HSTIER) Host Wake-Up Interrupt Enable Mask */ +#define HSTIER_PEP_0_Pos 8 /**< (HSTIER) Pipe 0 Interrupt Enable Position */ +#define HSTIER_PEP_0 (_U_(0x1) << HSTIER_PEP_0_Pos) /**< (HSTIER) Pipe 0 Interrupt Enable Mask */ +#define HSTIER_PEP_1_Pos 9 /**< (HSTIER) Pipe 1 Interrupt Enable Position */ +#define HSTIER_PEP_1 (_U_(0x1) << HSTIER_PEP_1_Pos) /**< (HSTIER) Pipe 1 Interrupt Enable Mask */ +#define HSTIER_PEP_2_Pos 10 /**< (HSTIER) Pipe 2 Interrupt Enable Position */ +#define HSTIER_PEP_2 (_U_(0x1) << HSTIER_PEP_2_Pos) /**< (HSTIER) Pipe 2 Interrupt Enable Mask */ +#define HSTIER_PEP_3_Pos 11 /**< (HSTIER) Pipe 3 Interrupt Enable Position */ +#define HSTIER_PEP_3 (_U_(0x1) << HSTIER_PEP_3_Pos) /**< (HSTIER) Pipe 3 Interrupt Enable Mask */ +#define HSTIER_PEP_4_Pos 12 /**< (HSTIER) Pipe 4 Interrupt Enable Position */ +#define HSTIER_PEP_4 (_U_(0x1) << HSTIER_PEP_4_Pos) /**< (HSTIER) Pipe 4 Interrupt Enable Mask */ +#define HSTIER_PEP_5_Pos 13 /**< (HSTIER) Pipe 5 Interrupt Enable Position */ +#define HSTIER_PEP_5 (_U_(0x1) << HSTIER_PEP_5_Pos) /**< (HSTIER) Pipe 5 Interrupt Enable Mask */ +#define HSTIER_PEP_6_Pos 14 /**< (HSTIER) Pipe 6 Interrupt Enable Position */ +#define HSTIER_PEP_6 (_U_(0x1) << HSTIER_PEP_6_Pos) /**< (HSTIER) Pipe 6 Interrupt Enable Mask */ +#define HSTIER_PEP_7_Pos 15 /**< (HSTIER) Pipe 7 Interrupt Enable Position */ +#define HSTIER_PEP_7 (_U_(0x1) << HSTIER_PEP_7_Pos) /**< (HSTIER) Pipe 7 Interrupt Enable Mask */ +#define HSTIER_PEP_8_Pos 16 /**< (HSTIER) Pipe 8 Interrupt Enable Position */ +#define HSTIER_PEP_8 (_U_(0x1) << HSTIER_PEP_8_Pos) /**< (HSTIER) Pipe 8 Interrupt Enable Mask */ +#define HSTIER_PEP_9_Pos 17 /**< (HSTIER) Pipe 9 Interrupt Enable Position */ +#define HSTIER_PEP_9 (_U_(0x1) << HSTIER_PEP_9_Pos) /**< (HSTIER) Pipe 9 Interrupt Enable Mask */ +#define HSTIER_DMA_0_Pos 25 /**< (HSTIER) DMA Channel 0 Interrupt Enable Position */ +#define HSTIER_DMA_0 (_U_(0x1) << HSTIER_DMA_0_Pos) /**< (HSTIER) DMA Channel 0 Interrupt Enable Mask */ +#define HSTIER_DMA_1_Pos 26 /**< (HSTIER) DMA Channel 1 Interrupt Enable Position */ +#define HSTIER_DMA_1 (_U_(0x1) << HSTIER_DMA_1_Pos) /**< (HSTIER) DMA Channel 1 Interrupt Enable Mask */ +#define HSTIER_DMA_2_Pos 27 /**< (HSTIER) DMA Channel 2 Interrupt Enable Position */ +#define HSTIER_DMA_2 (_U_(0x1) << HSTIER_DMA_2_Pos) /**< (HSTIER) DMA Channel 2 Interrupt Enable Mask */ +#define HSTIER_DMA_3_Pos 28 /**< (HSTIER) DMA Channel 3 Interrupt Enable Position */ +#define HSTIER_DMA_3 (_U_(0x1) << HSTIER_DMA_3_Pos) /**< (HSTIER) DMA Channel 3 Interrupt Enable Mask */ +#define HSTIER_DMA_4_Pos 29 /**< (HSTIER) DMA Channel 4 Interrupt Enable Position */ +#define HSTIER_DMA_4 (_U_(0x1) << HSTIER_DMA_4_Pos) /**< (HSTIER) DMA Channel 4 Interrupt Enable Mask */ +#define HSTIER_DMA_5_Pos 30 /**< (HSTIER) DMA Channel 5 Interrupt Enable Position */ +#define HSTIER_DMA_5 (_U_(0x1) << HSTIER_DMA_5_Pos) /**< (HSTIER) DMA Channel 5 Interrupt Enable Mask */ +#define HSTIER_DMA_6_Pos 31 /**< (HSTIER) DMA Channel 6 Interrupt Enable Position */ +#define HSTIER_DMA_6 (_U_(0x1) << HSTIER_DMA_6_Pos) /**< (HSTIER) DMA Channel 6 Interrupt Enable Mask */ +#define HSTIER_Msk _U_(0xFE03FF7F) /**< (HSTIER) Register Mask */ + +#define HSTIER_PEP__Pos 8 /**< (HSTIER Position) Pipe x Interrupt Enable */ +#define HSTIER_PEP_ (_U_(0x3FF) << HSTIER_PEP__Pos) /**< (HSTIER Mask) PEP_ */ +#define HSTIER_DMA__Pos 25 /**< (HSTIER Position) DMA Channel 6 Interrupt Enable */ +#define HSTIER_DMA_ (_U_(0x7F) << HSTIER_DMA__Pos) /**< (HSTIER Mask) DMA_ */ + +/* -------- HSTPIP : (USBHS Offset: 0x41c) (R/W 32) Host Pipe Register -------- */ + +#define HSTPIP_OFFSET (0x41C) /**< (HSTPIP) Host Pipe Register Offset */ + +#define HSTPIP_PEN0_Pos 0 /**< (HSTPIP) Pipe 0 Enable Position */ +#define HSTPIP_PEN0 (_U_(0x1) << HSTPIP_PEN0_Pos) /**< (HSTPIP) Pipe 0 Enable Mask */ +#define HSTPIP_PEN1_Pos 1 /**< (HSTPIP) Pipe 1 Enable Position */ +#define HSTPIP_PEN1 (_U_(0x1) << HSTPIP_PEN1_Pos) /**< (HSTPIP) Pipe 1 Enable Mask */ +#define HSTPIP_PEN2_Pos 2 /**< (HSTPIP) Pipe 2 Enable Position */ +#define HSTPIP_PEN2 (_U_(0x1) << HSTPIP_PEN2_Pos) /**< (HSTPIP) Pipe 2 Enable Mask */ +#define HSTPIP_PEN3_Pos 3 /**< (HSTPIP) Pipe 3 Enable Position */ +#define HSTPIP_PEN3 (_U_(0x1) << HSTPIP_PEN3_Pos) /**< (HSTPIP) Pipe 3 Enable Mask */ +#define HSTPIP_PEN4_Pos 4 /**< (HSTPIP) Pipe 4 Enable Position */ +#define HSTPIP_PEN4 (_U_(0x1) << HSTPIP_PEN4_Pos) /**< (HSTPIP) Pipe 4 Enable Mask */ +#define HSTPIP_PEN5_Pos 5 /**< (HSTPIP) Pipe 5 Enable Position */ +#define HSTPIP_PEN5 (_U_(0x1) << HSTPIP_PEN5_Pos) /**< (HSTPIP) Pipe 5 Enable Mask */ +#define HSTPIP_PEN6_Pos 6 /**< (HSTPIP) Pipe 6 Enable Position */ +#define HSTPIP_PEN6 (_U_(0x1) << HSTPIP_PEN6_Pos) /**< (HSTPIP) Pipe 6 Enable Mask */ +#define HSTPIP_PEN7_Pos 7 /**< (HSTPIP) Pipe 7 Enable Position */ +#define HSTPIP_PEN7 (_U_(0x1) << HSTPIP_PEN7_Pos) /**< (HSTPIP) Pipe 7 Enable Mask */ +#define HSTPIP_PEN8_Pos 8 /**< (HSTPIP) Pipe 8 Enable Position */ +#define HSTPIP_PEN8 (_U_(0x1) << HSTPIP_PEN8_Pos) /**< (HSTPIP) Pipe 8 Enable Mask */ +#define HSTPIP_PRST0_Pos 16 /**< (HSTPIP) Pipe 0 Reset Position */ +#define HSTPIP_PRST0 (_U_(0x1) << HSTPIP_PRST0_Pos) /**< (HSTPIP) Pipe 0 Reset Mask */ +#define HSTPIP_PRST1_Pos 17 /**< (HSTPIP) Pipe 1 Reset Position */ +#define HSTPIP_PRST1 (_U_(0x1) << HSTPIP_PRST1_Pos) /**< (HSTPIP) Pipe 1 Reset Mask */ +#define HSTPIP_PRST2_Pos 18 /**< (HSTPIP) Pipe 2 Reset Position */ +#define HSTPIP_PRST2 (_U_(0x1) << HSTPIP_PRST2_Pos) /**< (HSTPIP) Pipe 2 Reset Mask */ +#define HSTPIP_PRST3_Pos 19 /**< (HSTPIP) Pipe 3 Reset Position */ +#define HSTPIP_PRST3 (_U_(0x1) << HSTPIP_PRST3_Pos) /**< (HSTPIP) Pipe 3 Reset Mask */ +#define HSTPIP_PRST4_Pos 20 /**< (HSTPIP) Pipe 4 Reset Position */ +#define HSTPIP_PRST4 (_U_(0x1) << HSTPIP_PRST4_Pos) /**< (HSTPIP) Pipe 4 Reset Mask */ +#define HSTPIP_PRST5_Pos 21 /**< (HSTPIP) Pipe 5 Reset Position */ +#define HSTPIP_PRST5 (_U_(0x1) << HSTPIP_PRST5_Pos) /**< (HSTPIP) Pipe 5 Reset Mask */ +#define HSTPIP_PRST6_Pos 22 /**< (HSTPIP) Pipe 6 Reset Position */ +#define HSTPIP_PRST6 (_U_(0x1) << HSTPIP_PRST6_Pos) /**< (HSTPIP) Pipe 6 Reset Mask */ +#define HSTPIP_PRST7_Pos 23 /**< (HSTPIP) Pipe 7 Reset Position */ +#define HSTPIP_PRST7 (_U_(0x1) << HSTPIP_PRST7_Pos) /**< (HSTPIP) Pipe 7 Reset Mask */ +#define HSTPIP_PRST8_Pos 24 /**< (HSTPIP) Pipe 8 Reset Position */ +#define HSTPIP_PRST8 (_U_(0x1) << HSTPIP_PRST8_Pos) /**< (HSTPIP) Pipe 8 Reset Mask */ +#define HSTPIP_Msk _U_(0x1FF01FF) /**< (HSTPIP) Register Mask */ + +#define HSTPIP_PEN_Pos 0 /**< (HSTPIP Position) Pipe x Enable */ +#define HSTPIP_PEN (_U_(0x1FF) << HSTPIP_PEN_Pos) /**< (HSTPIP Mask) PEN */ +#define HSTPIP_PRST_Pos 16 /**< (HSTPIP Position) Pipe 8 Reset */ +#define HSTPIP_PRST (_U_(0x1FF) << HSTPIP_PRST_Pos) /**< (HSTPIP Mask) PRST */ + +/* -------- HSTFNUM : (USBHS Offset: 0x420) (R/W 32) Host Frame Number Register -------- */ + +#define HSTFNUM_OFFSET (0x420) /**< (HSTFNUM) Host Frame Number Register Offset */ + +#define HSTFNUM_MFNUM_Pos 0 /**< (HSTFNUM) Micro Frame Number Position */ +#define HSTFNUM_MFNUM (_U_(0x7) << HSTFNUM_MFNUM_Pos) /**< (HSTFNUM) Micro Frame Number Mask */ +#define HSTFNUM_FNUM_Pos 3 /**< (HSTFNUM) Frame Number Position */ +#define HSTFNUM_FNUM (_U_(0x7FF) << HSTFNUM_FNUM_Pos) /**< (HSTFNUM) Frame Number Mask */ +#define HSTFNUM_FLENHIGH_Pos 16 /**< (HSTFNUM) Frame Length Position */ +#define HSTFNUM_FLENHIGH (_U_(0xFF) << HSTFNUM_FLENHIGH_Pos) /**< (HSTFNUM) Frame Length Mask */ +#define HSTFNUM_Msk _U_(0xFF3FFF) /**< (HSTFNUM) Register Mask */ + + +/* -------- HSTADDR1 : (USBHS Offset: 0x424) (R/W 32) Host Address 1 Register -------- */ + +#define HSTADDR1_OFFSET (0x424) /**< (HSTADDR1) Host Address 1 Register Offset */ + +#define HSTADDR1_HSTADDRP0_Pos 0 /**< (HSTADDR1) USB Host Address Position */ +#define HSTADDR1_HSTADDRP0 (_U_(0x7F) << HSTADDR1_HSTADDRP0_Pos) /**< (HSTADDR1) USB Host Address Mask */ +#define HSTADDR1_HSTADDRP1_Pos 8 /**< (HSTADDR1) USB Host Address Position */ +#define HSTADDR1_HSTADDRP1 (_U_(0x7F) << HSTADDR1_HSTADDRP1_Pos) /**< (HSTADDR1) USB Host Address Mask */ +#define HSTADDR1_HSTADDRP2_Pos 16 /**< (HSTADDR1) USB Host Address Position */ +#define HSTADDR1_HSTADDRP2 (_U_(0x7F) << HSTADDR1_HSTADDRP2_Pos) /**< (HSTADDR1) USB Host Address Mask */ +#define HSTADDR1_HSTADDRP3_Pos 24 /**< (HSTADDR1) USB Host Address Position */ +#define HSTADDR1_HSTADDRP3 (_U_(0x7F) << HSTADDR1_HSTADDRP3_Pos) /**< (HSTADDR1) USB Host Address Mask */ +#define HSTADDR1_Msk _U_(0x7F7F7F7F) /**< (HSTADDR1) Register Mask */ + + +/* -------- HSTADDR2 : (USBHS Offset: 0x428) (R/W 32) Host Address 2 Register -------- */ + +#define HSTADDR2_OFFSET (0x428) /**< (HSTADDR2) Host Address 2 Register Offset */ + +#define HSTADDR2_HSTADDRP4_Pos 0 /**< (HSTADDR2) USB Host Address Position */ +#define HSTADDR2_HSTADDRP4 (_U_(0x7F) << HSTADDR2_HSTADDRP4_Pos) /**< (HSTADDR2) USB Host Address Mask */ +#define HSTADDR2_HSTADDRP5_Pos 8 /**< (HSTADDR2) USB Host Address Position */ +#define HSTADDR2_HSTADDRP5 (_U_(0x7F) << HSTADDR2_HSTADDRP5_Pos) /**< (HSTADDR2) USB Host Address Mask */ +#define HSTADDR2_HSTADDRP6_Pos 16 /**< (HSTADDR2) USB Host Address Position */ +#define HSTADDR2_HSTADDRP6 (_U_(0x7F) << HSTADDR2_HSTADDRP6_Pos) /**< (HSTADDR2) USB Host Address Mask */ +#define HSTADDR2_HSTADDRP7_Pos 24 /**< (HSTADDR2) USB Host Address Position */ +#define HSTADDR2_HSTADDRP7 (_U_(0x7F) << HSTADDR2_HSTADDRP7_Pos) /**< (HSTADDR2) USB Host Address Mask */ +#define HSTADDR2_Msk _U_(0x7F7F7F7F) /**< (HSTADDR2) Register Mask */ + + +/* -------- HSTADDR3 : (USBHS Offset: 0x42c) (R/W 32) Host Address 3 Register -------- */ + +#define HSTADDR3_OFFSET (0x42C) /**< (HSTADDR3) Host Address 3 Register Offset */ + +#define HSTADDR3_HSTADDRP8_Pos 0 /**< (HSTADDR3) USB Host Address Position */ +#define HSTADDR3_HSTADDRP8 (_U_(0x7F) << HSTADDR3_HSTADDRP8_Pos) /**< (HSTADDR3) USB Host Address Mask */ +#define HSTADDR3_HSTADDRP9_Pos 8 /**< (HSTADDR3) USB Host Address Position */ +#define HSTADDR3_HSTADDRP9 (_U_(0x7F) << HSTADDR3_HSTADDRP9_Pos) /**< (HSTADDR3) USB Host Address Mask */ +#define HSTADDR3_Msk _U_(0x7F7F) /**< (HSTADDR3) Register Mask */ + + +/* -------- HSTPIPCFG : (USBHS Offset: 0x500) (R/W 32) Host Pipe Configuration Register -------- */ + +#define HSTPIPCFG_OFFSET (0x500) /**< (HSTPIPCFG) Host Pipe Configuration Register Offset */ + +#define HSTPIPCFG_ALLOC_Pos 1 /**< (HSTPIPCFG) Pipe Memory Allocate Position */ +#define HSTPIPCFG_ALLOC (_U_(0x1) << HSTPIPCFG_ALLOC_Pos) /**< (HSTPIPCFG) Pipe Memory Allocate Mask */ +#define HSTPIPCFG_PBK_Pos 2 /**< (HSTPIPCFG) Pipe Banks Position */ +#define HSTPIPCFG_PBK (_U_(0x3) << HSTPIPCFG_PBK_Pos) /**< (HSTPIPCFG) Pipe Banks Mask */ +#define HSTPIPCFG_PBK_1_BANK_Val _U_(0x0) /**< (HSTPIPCFG) Single-bank pipe */ +#define HSTPIPCFG_PBK_2_BANK_Val _U_(0x1) /**< (HSTPIPCFG) Double-bank pipe */ +#define HSTPIPCFG_PBK_3_BANK_Val _U_(0x2) /**< (HSTPIPCFG) Triple-bank pipe */ +#define HSTPIPCFG_PBK_1_BANK (HSTPIPCFG_PBK_1_BANK_Val << HSTPIPCFG_PBK_Pos) /**< (HSTPIPCFG) Single-bank pipe Position */ +#define HSTPIPCFG_PBK_2_BANK (HSTPIPCFG_PBK_2_BANK_Val << HSTPIPCFG_PBK_Pos) /**< (HSTPIPCFG) Double-bank pipe Position */ +#define HSTPIPCFG_PBK_3_BANK (HSTPIPCFG_PBK_3_BANK_Val << HSTPIPCFG_PBK_Pos) /**< (HSTPIPCFG) Triple-bank pipe Position */ +#define HSTPIPCFG_PSIZE_Pos 4 /**< (HSTPIPCFG) Pipe Size Position */ +#define HSTPIPCFG_PSIZE (_U_(0x7) << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) Pipe Size Mask */ +#define HSTPIPCFG_PSIZE_8_BYTE_Val _U_(0x0) /**< (HSTPIPCFG) 8 bytes */ +#define HSTPIPCFG_PSIZE_16_BYTE_Val _U_(0x1) /**< (HSTPIPCFG) 16 bytes */ +#define HSTPIPCFG_PSIZE_32_BYTE_Val _U_(0x2) /**< (HSTPIPCFG) 32 bytes */ +#define HSTPIPCFG_PSIZE_64_BYTE_Val _U_(0x3) /**< (HSTPIPCFG) 64 bytes */ +#define HSTPIPCFG_PSIZE_128_BYTE_Val _U_(0x4) /**< (HSTPIPCFG) 128 bytes */ +#define HSTPIPCFG_PSIZE_256_BYTE_Val _U_(0x5) /**< (HSTPIPCFG) 256 bytes */ +#define HSTPIPCFG_PSIZE_512_BYTE_Val _U_(0x6) /**< (HSTPIPCFG) 512 bytes */ +#define HSTPIPCFG_PSIZE_1024_BYTE_Val _U_(0x7) /**< (HSTPIPCFG) 1024 bytes */ +#define HSTPIPCFG_PSIZE_8_BYTE (HSTPIPCFG_PSIZE_8_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 8 bytes Position */ +#define HSTPIPCFG_PSIZE_16_BYTE (HSTPIPCFG_PSIZE_16_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 16 bytes Position */ +#define HSTPIPCFG_PSIZE_32_BYTE (HSTPIPCFG_PSIZE_32_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 32 bytes Position */ +#define HSTPIPCFG_PSIZE_64_BYTE (HSTPIPCFG_PSIZE_64_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 64 bytes Position */ +#define HSTPIPCFG_PSIZE_128_BYTE (HSTPIPCFG_PSIZE_128_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 128 bytes Position */ +#define HSTPIPCFG_PSIZE_256_BYTE (HSTPIPCFG_PSIZE_256_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 256 bytes Position */ +#define HSTPIPCFG_PSIZE_512_BYTE (HSTPIPCFG_PSIZE_512_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 512 bytes Position */ +#define HSTPIPCFG_PSIZE_1024_BYTE (HSTPIPCFG_PSIZE_1024_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 1024 bytes Position */ +#define HSTPIPCFG_PTOKEN_Pos 8 /**< (HSTPIPCFG) Pipe Token Position */ +#define HSTPIPCFG_PTOKEN (_U_(0x3) << HSTPIPCFG_PTOKEN_Pos) /**< (HSTPIPCFG) Pipe Token Mask */ +#define HSTPIPCFG_PTOKEN_SETUP_Val _U_(0x0) /**< (HSTPIPCFG) SETUP */ +#define HSTPIPCFG_PTOKEN_IN_Val _U_(0x1) /**< (HSTPIPCFG) IN */ +#define HSTPIPCFG_PTOKEN_OUT_Val _U_(0x2) /**< (HSTPIPCFG) OUT */ +#define HSTPIPCFG_PTOKEN_SETUP (HSTPIPCFG_PTOKEN_SETUP_Val << HSTPIPCFG_PTOKEN_Pos) /**< (HSTPIPCFG) SETUP Position */ +#define HSTPIPCFG_PTOKEN_IN (HSTPIPCFG_PTOKEN_IN_Val << HSTPIPCFG_PTOKEN_Pos) /**< (HSTPIPCFG) IN Position */ +#define HSTPIPCFG_PTOKEN_OUT (HSTPIPCFG_PTOKEN_OUT_Val << HSTPIPCFG_PTOKEN_Pos) /**< (HSTPIPCFG) OUT Position */ +#define HSTPIPCFG_AUTOSW_Pos 10 /**< (HSTPIPCFG) Automatic Switch Position */ +#define HSTPIPCFG_AUTOSW (_U_(0x1) << HSTPIPCFG_AUTOSW_Pos) /**< (HSTPIPCFG) Automatic Switch Mask */ +#define HSTPIPCFG_PTYPE_Pos 12 /**< (HSTPIPCFG) Pipe Type Position */ +#define HSTPIPCFG_PTYPE (_U_(0x3) << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Pipe Type Mask */ +#define HSTPIPCFG_PTYPE_CTRL_Val _U_(0x0) /**< (HSTPIPCFG) Control */ +#define HSTPIPCFG_PTYPE_ISO_Val _U_(0x1) /**< (HSTPIPCFG) Isochronous */ +#define HSTPIPCFG_PTYPE_BLK_Val _U_(0x2) /**< (HSTPIPCFG) Bulk */ +#define HSTPIPCFG_PTYPE_INTRPT_Val _U_(0x3) /**< (HSTPIPCFG) Interrupt */ +#define HSTPIPCFG_PTYPE_CTRL (HSTPIPCFG_PTYPE_CTRL_Val << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Control Position */ +#define HSTPIPCFG_PTYPE_ISO (HSTPIPCFG_PTYPE_ISO_Val << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Isochronous Position */ +#define HSTPIPCFG_PTYPE_BLK (HSTPIPCFG_PTYPE_BLK_Val << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Bulk Position */ +#define HSTPIPCFG_PTYPE_INTRPT (HSTPIPCFG_PTYPE_INTRPT_Val << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Interrupt Position */ +#define HSTPIPCFG_PEPNUM_Pos 16 /**< (HSTPIPCFG) Pipe Endpoint Number Position */ +#define HSTPIPCFG_PEPNUM (_U_(0xF) << HSTPIPCFG_PEPNUM_Pos) /**< (HSTPIPCFG) Pipe Endpoint Number Mask */ +#define HSTPIPCFG_INTFRQ_Pos 24 /**< (HSTPIPCFG) Pipe Interrupt Request Frequency Position */ +#define HSTPIPCFG_INTFRQ (_U_(0xFF) << HSTPIPCFG_INTFRQ_Pos) /**< (HSTPIPCFG) Pipe Interrupt Request Frequency Mask */ +#define HSTPIPCFG_Msk _U_(0xFF0F377E) /**< (HSTPIPCFG) Register Mask */ + +/* CTRL_BULK mode */ +#define HSTPIPCFG_CTRL_BULK_PINGEN_Pos 20 /**< (HSTPIPCFG) Ping Enable Position */ +#define HSTPIPCFG_CTRL_BULK_PINGEN (_U_(0x1) << HSTPIPCFG_CTRL_BULK_PINGEN_Pos) /**< (HSTPIPCFG) Ping Enable Mask */ +#define HSTPIPCFG_CTRL_BULK_BINTERVAL_Pos 24 /**< (HSTPIPCFG) bInterval Parameter for the Bulk-Out/Ping Transaction Position */ +#define HSTPIPCFG_CTRL_BULK_BINTERVAL (_U_(0xFF) << HSTPIPCFG_CTRL_BULK_BINTERVAL_Pos) /**< (HSTPIPCFG) bInterval Parameter for the Bulk-Out/Ping Transaction Mask */ +#define HSTPIPCFG_CTRL_BULK_Msk _U_(0xFF100000) /**< (HSTPIPCFG_CTRL_BULK) Register Mask */ + + +/* -------- HSTPIPISR : (USBHS Offset: 0x530) (R/ 32) Host Pipe Status Register -------- */ + +#define HSTPIPISR_OFFSET (0x530) /**< (HSTPIPISR) Host Pipe Status Register Offset */ + +#define HSTPIPISR_RXINI_Pos 0 /**< (HSTPIPISR) Received IN Data Interrupt Position */ +#define HSTPIPISR_RXINI (_U_(0x1) << HSTPIPISR_RXINI_Pos) /**< (HSTPIPISR) Received IN Data Interrupt Mask */ +#define HSTPIPISR_TXOUTI_Pos 1 /**< (HSTPIPISR) Transmitted OUT Data Interrupt Position */ +#define HSTPIPISR_TXOUTI (_U_(0x1) << HSTPIPISR_TXOUTI_Pos) /**< (HSTPIPISR) Transmitted OUT Data Interrupt Mask */ +#define HSTPIPISR_PERRI_Pos 3 /**< (HSTPIPISR) Pipe Error Interrupt Position */ +#define HSTPIPISR_PERRI (_U_(0x1) << HSTPIPISR_PERRI_Pos) /**< (HSTPIPISR) Pipe Error Interrupt Mask */ +#define HSTPIPISR_NAKEDI_Pos 4 /**< (HSTPIPISR) NAKed Interrupt Position */ +#define HSTPIPISR_NAKEDI (_U_(0x1) << HSTPIPISR_NAKEDI_Pos) /**< (HSTPIPISR) NAKed Interrupt Mask */ +#define HSTPIPISR_OVERFI_Pos 5 /**< (HSTPIPISR) Overflow Interrupt Position */ +#define HSTPIPISR_OVERFI (_U_(0x1) << HSTPIPISR_OVERFI_Pos) /**< (HSTPIPISR) Overflow Interrupt Mask */ +#define HSTPIPISR_SHORTPACKETI_Pos 7 /**< (HSTPIPISR) Short Packet Interrupt Position */ +#define HSTPIPISR_SHORTPACKETI (_U_(0x1) << HSTPIPISR_SHORTPACKETI_Pos) /**< (HSTPIPISR) Short Packet Interrupt Mask */ +#define HSTPIPISR_DTSEQ_Pos 8 /**< (HSTPIPISR) Data Toggle Sequence Position */ +#define HSTPIPISR_DTSEQ (_U_(0x3) << HSTPIPISR_DTSEQ_Pos) /**< (HSTPIPISR) Data Toggle Sequence Mask */ +#define HSTPIPISR_DTSEQ_DATA0_Val _U_(0x0) /**< (HSTPIPISR) Data0 toggle sequence */ +#define HSTPIPISR_DTSEQ_DATA1_Val _U_(0x1) /**< (HSTPIPISR) Data1 toggle sequence */ +#define HSTPIPISR_DTSEQ_DATA0 (HSTPIPISR_DTSEQ_DATA0_Val << HSTPIPISR_DTSEQ_Pos) /**< (HSTPIPISR) Data0 toggle sequence Position */ +#define HSTPIPISR_DTSEQ_DATA1 (HSTPIPISR_DTSEQ_DATA1_Val << HSTPIPISR_DTSEQ_Pos) /**< (HSTPIPISR) Data1 toggle sequence Position */ +#define HSTPIPISR_NBUSYBK_Pos 12 /**< (HSTPIPISR) Number of Busy Banks Position */ +#define HSTPIPISR_NBUSYBK (_U_(0x3) << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) Number of Busy Banks Mask */ +#define HSTPIPISR_NBUSYBK_0_BUSY_Val _U_(0x0) /**< (HSTPIPISR) 0 busy bank (all banks free) */ +#define HSTPIPISR_NBUSYBK_1_BUSY_Val _U_(0x1) /**< (HSTPIPISR) 1 busy bank */ +#define HSTPIPISR_NBUSYBK_2_BUSY_Val _U_(0x2) /**< (HSTPIPISR) 2 busy banks */ +#define HSTPIPISR_NBUSYBK_3_BUSY_Val _U_(0x3) /**< (HSTPIPISR) 3 busy banks */ +#define HSTPIPISR_NBUSYBK_0_BUSY (HSTPIPISR_NBUSYBK_0_BUSY_Val << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) 0 busy bank (all banks free) Position */ +#define HSTPIPISR_NBUSYBK_1_BUSY (HSTPIPISR_NBUSYBK_1_BUSY_Val << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) 1 busy bank Position */ +#define HSTPIPISR_NBUSYBK_2_BUSY (HSTPIPISR_NBUSYBK_2_BUSY_Val << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) 2 busy banks Position */ +#define HSTPIPISR_NBUSYBK_3_BUSY (HSTPIPISR_NBUSYBK_3_BUSY_Val << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) 3 busy banks Position */ +#define HSTPIPISR_CURRBK_Pos 14 /**< (HSTPIPISR) Current Bank Position */ +#define HSTPIPISR_CURRBK (_U_(0x3) << HSTPIPISR_CURRBK_Pos) /**< (HSTPIPISR) Current Bank Mask */ +#define HSTPIPISR_CURRBK_BANK0_Val _U_(0x0) /**< (HSTPIPISR) Current bank is bank0 */ +#define HSTPIPISR_CURRBK_BANK1_Val _U_(0x1) /**< (HSTPIPISR) Current bank is bank1 */ +#define HSTPIPISR_CURRBK_BANK2_Val _U_(0x2) /**< (HSTPIPISR) Current bank is bank2 */ +#define HSTPIPISR_CURRBK_BANK0 (HSTPIPISR_CURRBK_BANK0_Val << HSTPIPISR_CURRBK_Pos) /**< (HSTPIPISR) Current bank is bank0 Position */ +#define HSTPIPISR_CURRBK_BANK1 (HSTPIPISR_CURRBK_BANK1_Val << HSTPIPISR_CURRBK_Pos) /**< (HSTPIPISR) Current bank is bank1 Position */ +#define HSTPIPISR_CURRBK_BANK2 (HSTPIPISR_CURRBK_BANK2_Val << HSTPIPISR_CURRBK_Pos) /**< (HSTPIPISR) Current bank is bank2 Position */ +#define HSTPIPISR_RWALL_Pos 16 /**< (HSTPIPISR) Read/Write Allowed Position */ +#define HSTPIPISR_RWALL (_U_(0x1) << HSTPIPISR_RWALL_Pos) /**< (HSTPIPISR) Read/Write Allowed Mask */ +#define HSTPIPISR_CFGOK_Pos 18 /**< (HSTPIPISR) Configuration OK Status Position */ +#define HSTPIPISR_CFGOK (_U_(0x1) << HSTPIPISR_CFGOK_Pos) /**< (HSTPIPISR) Configuration OK Status Mask */ +#define HSTPIPISR_PBYCT_Pos 20 /**< (HSTPIPISR) Pipe Byte Count Position */ +#define HSTPIPISR_PBYCT (_U_(0x7FF) << HSTPIPISR_PBYCT_Pos) /**< (HSTPIPISR) Pipe Byte Count Mask */ +#define HSTPIPISR_Msk _U_(0x7FF5F3BB) /**< (HSTPIPISR) Register Mask */ + +/* CTRL mode */ +#define HSTPIPISR_CTRL_TXSTPI_Pos 2 /**< (HSTPIPISR) Transmitted SETUP Interrupt Position */ +#define HSTPIPISR_CTRL_TXSTPI (_U_(0x1) << HSTPIPISR_CTRL_TXSTPI_Pos) /**< (HSTPIPISR) Transmitted SETUP Interrupt Mask */ +#define HSTPIPISR_CTRL_RXSTALLDI_Pos 6 /**< (HSTPIPISR) Received STALLed Interrupt Position */ +#define HSTPIPISR_CTRL_RXSTALLDI (_U_(0x1) << HSTPIPISR_CTRL_RXSTALLDI_Pos) /**< (HSTPIPISR) Received STALLed Interrupt Mask */ +#define HSTPIPISR_CTRL_Msk _U_(0x44) /**< (HSTPIPISR_CTRL) Register Mask */ + +/* ISO mode */ +#define HSTPIPISR_ISO_UNDERFI_Pos 2 /**< (HSTPIPISR) Underflow Interrupt Position */ +#define HSTPIPISR_ISO_UNDERFI (_U_(0x1) << HSTPIPISR_ISO_UNDERFI_Pos) /**< (HSTPIPISR) Underflow Interrupt Mask */ +#define HSTPIPISR_ISO_CRCERRI_Pos 6 /**< (HSTPIPISR) CRC Error Interrupt Position */ +#define HSTPIPISR_ISO_CRCERRI (_U_(0x1) << HSTPIPISR_ISO_CRCERRI_Pos) /**< (HSTPIPISR) CRC Error Interrupt Mask */ +#define HSTPIPISR_ISO_Msk _U_(0x44) /**< (HSTPIPISR_ISO) Register Mask */ + +/* BLK mode */ +#define HSTPIPISR_BLK_TXSTPI_Pos 2 /**< (HSTPIPISR) Transmitted SETUP Interrupt Position */ +#define HSTPIPISR_BLK_TXSTPI (_U_(0x1) << HSTPIPISR_BLK_TXSTPI_Pos) /**< (HSTPIPISR) Transmitted SETUP Interrupt Mask */ +#define HSTPIPISR_BLK_RXSTALLDI_Pos 6 /**< (HSTPIPISR) Received STALLed Interrupt Position */ +#define HSTPIPISR_BLK_RXSTALLDI (_U_(0x1) << HSTPIPISR_BLK_RXSTALLDI_Pos) /**< (HSTPIPISR) Received STALLed Interrupt Mask */ +#define HSTPIPISR_BLK_Msk _U_(0x44) /**< (HSTPIPISR_BLK) Register Mask */ + +/* INTRPT mode */ +#define HSTPIPISR_INTRPT_UNDERFI_Pos 2 /**< (HSTPIPISR) Underflow Interrupt Position */ +#define HSTPIPISR_INTRPT_UNDERFI (_U_(0x1) << HSTPIPISR_INTRPT_UNDERFI_Pos) /**< (HSTPIPISR) Underflow Interrupt Mask */ +#define HSTPIPISR_INTRPT_RXSTALLDI_Pos 6 /**< (HSTPIPISR) Received STALLed Interrupt Position */ +#define HSTPIPISR_INTRPT_RXSTALLDI (_U_(0x1) << HSTPIPISR_INTRPT_RXSTALLDI_Pos) /**< (HSTPIPISR) Received STALLed Interrupt Mask */ +#define HSTPIPISR_INTRPT_Msk _U_(0x44) /**< (HSTPIPISR_INTRPT) Register Mask */ + + +/* -------- HSTPIPICR : (USBHS Offset: 0x560) (/W 32) Host Pipe Clear Register -------- */ + +#define HSTPIPICR_OFFSET (0x560) /**< (HSTPIPICR) Host Pipe Clear Register Offset */ + +#define HSTPIPICR_RXINIC_Pos 0 /**< (HSTPIPICR) Received IN Data Interrupt Clear Position */ +#define HSTPIPICR_RXINIC (_U_(0x1) << HSTPIPICR_RXINIC_Pos) /**< (HSTPIPICR) Received IN Data Interrupt Clear Mask */ +#define HSTPIPICR_TXOUTIC_Pos 1 /**< (HSTPIPICR) Transmitted OUT Data Interrupt Clear Position */ +#define HSTPIPICR_TXOUTIC (_U_(0x1) << HSTPIPICR_TXOUTIC_Pos) /**< (HSTPIPICR) Transmitted OUT Data Interrupt Clear Mask */ +#define HSTPIPICR_NAKEDIC_Pos 4 /**< (HSTPIPICR) NAKed Interrupt Clear Position */ +#define HSTPIPICR_NAKEDIC (_U_(0x1) << HSTPIPICR_NAKEDIC_Pos) /**< (HSTPIPICR) NAKed Interrupt Clear Mask */ +#define HSTPIPICR_OVERFIC_Pos 5 /**< (HSTPIPICR) Overflow Interrupt Clear Position */ +#define HSTPIPICR_OVERFIC (_U_(0x1) << HSTPIPICR_OVERFIC_Pos) /**< (HSTPIPICR) Overflow Interrupt Clear Mask */ +#define HSTPIPICR_SHORTPACKETIC_Pos 7 /**< (HSTPIPICR) Short Packet Interrupt Clear Position */ +#define HSTPIPICR_SHORTPACKETIC (_U_(0x1) << HSTPIPICR_SHORTPACKETIC_Pos) /**< (HSTPIPICR) Short Packet Interrupt Clear Mask */ +#define HSTPIPICR_Msk _U_(0xB3) /**< (HSTPIPICR) Register Mask */ + +/* CTRL mode */ +#define HSTPIPICR_CTRL_TXSTPIC_Pos 2 /**< (HSTPIPICR) Transmitted SETUP Interrupt Clear Position */ +#define HSTPIPICR_CTRL_TXSTPIC (_U_(0x1) << HSTPIPICR_CTRL_TXSTPIC_Pos) /**< (HSTPIPICR) Transmitted SETUP Interrupt Clear Mask */ +#define HSTPIPICR_CTRL_RXSTALLDIC_Pos 6 /**< (HSTPIPICR) Received STALLed Interrupt Clear Position */ +#define HSTPIPICR_CTRL_RXSTALLDIC (_U_(0x1) << HSTPIPICR_CTRL_RXSTALLDIC_Pos) /**< (HSTPIPICR) Received STALLed Interrupt Clear Mask */ +#define HSTPIPICR_CTRL_Msk _U_(0x44) /**< (HSTPIPICR_CTRL) Register Mask */ + +/* ISO mode */ +#define HSTPIPICR_ISO_UNDERFIC_Pos 2 /**< (HSTPIPICR) Underflow Interrupt Clear Position */ +#define HSTPIPICR_ISO_UNDERFIC (_U_(0x1) << HSTPIPICR_ISO_UNDERFIC_Pos) /**< (HSTPIPICR) Underflow Interrupt Clear Mask */ +#define HSTPIPICR_ISO_CRCERRIC_Pos 6 /**< (HSTPIPICR) CRC Error Interrupt Clear Position */ +#define HSTPIPICR_ISO_CRCERRIC (_U_(0x1) << HSTPIPICR_ISO_CRCERRIC_Pos) /**< (HSTPIPICR) CRC Error Interrupt Clear Mask */ +#define HSTPIPICR_ISO_Msk _U_(0x44) /**< (HSTPIPICR_ISO) Register Mask */ + +/* BLK mode */ +#define HSTPIPICR_BLK_TXSTPIC_Pos 2 /**< (HSTPIPICR) Transmitted SETUP Interrupt Clear Position */ +#define HSTPIPICR_BLK_TXSTPIC (_U_(0x1) << HSTPIPICR_BLK_TXSTPIC_Pos) /**< (HSTPIPICR) Transmitted SETUP Interrupt Clear Mask */ +#define HSTPIPICR_BLK_RXSTALLDIC_Pos 6 /**< (HSTPIPICR) Received STALLed Interrupt Clear Position */ +#define HSTPIPICR_BLK_RXSTALLDIC (_U_(0x1) << HSTPIPICR_BLK_RXSTALLDIC_Pos) /**< (HSTPIPICR) Received STALLed Interrupt Clear Mask */ +#define HSTPIPICR_BLK_Msk _U_(0x44) /**< (HSTPIPICR_BLK) Register Mask */ + +/* INTRPT mode */ +#define HSTPIPICR_INTRPT_UNDERFIC_Pos 2 /**< (HSTPIPICR) Underflow Interrupt Clear Position */ +#define HSTPIPICR_INTRPT_UNDERFIC (_U_(0x1) << HSTPIPICR_INTRPT_UNDERFIC_Pos) /**< (HSTPIPICR) Underflow Interrupt Clear Mask */ +#define HSTPIPICR_INTRPT_RXSTALLDIC_Pos 6 /**< (HSTPIPICR) Received STALLed Interrupt Clear Position */ +#define HSTPIPICR_INTRPT_RXSTALLDIC (_U_(0x1) << HSTPIPICR_INTRPT_RXSTALLDIC_Pos) /**< (HSTPIPICR) Received STALLed Interrupt Clear Mask */ +#define HSTPIPICR_INTRPT_Msk _U_(0x44) /**< (HSTPIPICR_INTRPT) Register Mask */ + + +/* -------- HSTPIPIFR : (USBHS Offset: 0x590) (/W 32) Host Pipe Set Register -------- */ + +#define HSTPIPIFR_OFFSET (0x590) /**< (HSTPIPIFR) Host Pipe Set Register Offset */ + +#define HSTPIPIFR_RXINIS_Pos 0 /**< (HSTPIPIFR) Received IN Data Interrupt Set Position */ +#define HSTPIPIFR_RXINIS (_U_(0x1) << HSTPIPIFR_RXINIS_Pos) /**< (HSTPIPIFR) Received IN Data Interrupt Set Mask */ +#define HSTPIPIFR_TXOUTIS_Pos 1 /**< (HSTPIPIFR) Transmitted OUT Data Interrupt Set Position */ +#define HSTPIPIFR_TXOUTIS (_U_(0x1) << HSTPIPIFR_TXOUTIS_Pos) /**< (HSTPIPIFR) Transmitted OUT Data Interrupt Set Mask */ +#define HSTPIPIFR_PERRIS_Pos 3 /**< (HSTPIPIFR) Pipe Error Interrupt Set Position */ +#define HSTPIPIFR_PERRIS (_U_(0x1) << HSTPIPIFR_PERRIS_Pos) /**< (HSTPIPIFR) Pipe Error Interrupt Set Mask */ +#define HSTPIPIFR_NAKEDIS_Pos 4 /**< (HSTPIPIFR) NAKed Interrupt Set Position */ +#define HSTPIPIFR_NAKEDIS (_U_(0x1) << HSTPIPIFR_NAKEDIS_Pos) /**< (HSTPIPIFR) NAKed Interrupt Set Mask */ +#define HSTPIPIFR_OVERFIS_Pos 5 /**< (HSTPIPIFR) Overflow Interrupt Set Position */ +#define HSTPIPIFR_OVERFIS (_U_(0x1) << HSTPIPIFR_OVERFIS_Pos) /**< (HSTPIPIFR) Overflow Interrupt Set Mask */ +#define HSTPIPIFR_SHORTPACKETIS_Pos 7 /**< (HSTPIPIFR) Short Packet Interrupt Set Position */ +#define HSTPIPIFR_SHORTPACKETIS (_U_(0x1) << HSTPIPIFR_SHORTPACKETIS_Pos) /**< (HSTPIPIFR) Short Packet Interrupt Set Mask */ +#define HSTPIPIFR_NBUSYBKS_Pos 12 /**< (HSTPIPIFR) Number of Busy Banks Set Position */ +#define HSTPIPIFR_NBUSYBKS (_U_(0x1) << HSTPIPIFR_NBUSYBKS_Pos) /**< (HSTPIPIFR) Number of Busy Banks Set Mask */ +#define HSTPIPIFR_Msk _U_(0x10BB) /**< (HSTPIPIFR) Register Mask */ + +/* CTRL mode */ +#define HSTPIPIFR_CTRL_TXSTPIS_Pos 2 /**< (HSTPIPIFR) Transmitted SETUP Interrupt Set Position */ +#define HSTPIPIFR_CTRL_TXSTPIS (_U_(0x1) << HSTPIPIFR_CTRL_TXSTPIS_Pos) /**< (HSTPIPIFR) Transmitted SETUP Interrupt Set Mask */ +#define HSTPIPIFR_CTRL_RXSTALLDIS_Pos 6 /**< (HSTPIPIFR) Received STALLed Interrupt Set Position */ +#define HSTPIPIFR_CTRL_RXSTALLDIS (_U_(0x1) << HSTPIPIFR_CTRL_RXSTALLDIS_Pos) /**< (HSTPIPIFR) Received STALLed Interrupt Set Mask */ +#define HSTPIPIFR_CTRL_Msk _U_(0x44) /**< (HSTPIPIFR_CTRL) Register Mask */ + +/* ISO mode */ +#define HSTPIPIFR_ISO_UNDERFIS_Pos 2 /**< (HSTPIPIFR) Underflow Interrupt Set Position */ +#define HSTPIPIFR_ISO_UNDERFIS (_U_(0x1) << HSTPIPIFR_ISO_UNDERFIS_Pos) /**< (HSTPIPIFR) Underflow Interrupt Set Mask */ +#define HSTPIPIFR_ISO_CRCERRIS_Pos 6 /**< (HSTPIPIFR) CRC Error Interrupt Set Position */ +#define HSTPIPIFR_ISO_CRCERRIS (_U_(0x1) << HSTPIPIFR_ISO_CRCERRIS_Pos) /**< (HSTPIPIFR) CRC Error Interrupt Set Mask */ +#define HSTPIPIFR_ISO_Msk _U_(0x44) /**< (HSTPIPIFR_ISO) Register Mask */ + +/* BLK mode */ +#define HSTPIPIFR_BLK_TXSTPIS_Pos 2 /**< (HSTPIPIFR) Transmitted SETUP Interrupt Set Position */ +#define HSTPIPIFR_BLK_TXSTPIS (_U_(0x1) << HSTPIPIFR_BLK_TXSTPIS_Pos) /**< (HSTPIPIFR) Transmitted SETUP Interrupt Set Mask */ +#define HSTPIPIFR_BLK_RXSTALLDIS_Pos 6 /**< (HSTPIPIFR) Received STALLed Interrupt Set Position */ +#define HSTPIPIFR_BLK_RXSTALLDIS (_U_(0x1) << HSTPIPIFR_BLK_RXSTALLDIS_Pos) /**< (HSTPIPIFR) Received STALLed Interrupt Set Mask */ +#define HSTPIPIFR_BLK_Msk _U_(0x44) /**< (HSTPIPIFR_BLK) Register Mask */ + +/* INTRPT mode */ +#define HSTPIPIFR_INTRPT_UNDERFIS_Pos 2 /**< (HSTPIPIFR) Underflow Interrupt Set Position */ +#define HSTPIPIFR_INTRPT_UNDERFIS (_U_(0x1) << HSTPIPIFR_INTRPT_UNDERFIS_Pos) /**< (HSTPIPIFR) Underflow Interrupt Set Mask */ +#define HSTPIPIFR_INTRPT_RXSTALLDIS_Pos 6 /**< (HSTPIPIFR) Received STALLed Interrupt Set Position */ +#define HSTPIPIFR_INTRPT_RXSTALLDIS (_U_(0x1) << HSTPIPIFR_INTRPT_RXSTALLDIS_Pos) /**< (HSTPIPIFR) Received STALLed Interrupt Set Mask */ +#define HSTPIPIFR_INTRPT_Msk _U_(0x44) /**< (HSTPIPIFR_INTRPT) Register Mask */ + + +/* -------- HSTPIPIMR : (USBHS Offset: 0x5c0) (R/ 32) Host Pipe Mask Register -------- */ + +#define HSTPIPIMR_OFFSET (0x5C0) /**< (HSTPIPIMR) Host Pipe Mask Register Offset */ + +#define HSTPIPIMR_RXINE_Pos 0 /**< (HSTPIPIMR) Received IN Data Interrupt Enable Position */ +#define HSTPIPIMR_RXINE (_U_(0x1) << HSTPIPIMR_RXINE_Pos) /**< (HSTPIPIMR) Received IN Data Interrupt Enable Mask */ +#define HSTPIPIMR_TXOUTE_Pos 1 /**< (HSTPIPIMR) Transmitted OUT Data Interrupt Enable Position */ +#define HSTPIPIMR_TXOUTE (_U_(0x1) << HSTPIPIMR_TXOUTE_Pos) /**< (HSTPIPIMR) Transmitted OUT Data Interrupt Enable Mask */ +#define HSTPIPIMR_PERRE_Pos 3 /**< (HSTPIPIMR) Pipe Error Interrupt Enable Position */ +#define HSTPIPIMR_PERRE (_U_(0x1) << HSTPIPIMR_PERRE_Pos) /**< (HSTPIPIMR) Pipe Error Interrupt Enable Mask */ +#define HSTPIPIMR_NAKEDE_Pos 4 /**< (HSTPIPIMR) NAKed Interrupt Enable Position */ +#define HSTPIPIMR_NAKEDE (_U_(0x1) << HSTPIPIMR_NAKEDE_Pos) /**< (HSTPIPIMR) NAKed Interrupt Enable Mask */ +#define HSTPIPIMR_OVERFIE_Pos 5 /**< (HSTPIPIMR) Overflow Interrupt Enable Position */ +#define HSTPIPIMR_OVERFIE (_U_(0x1) << HSTPIPIMR_OVERFIE_Pos) /**< (HSTPIPIMR) Overflow Interrupt Enable Mask */ +#define HSTPIPIMR_SHORTPACKETIE_Pos 7 /**< (HSTPIPIMR) Short Packet Interrupt Enable Position */ +#define HSTPIPIMR_SHORTPACKETIE (_U_(0x1) << HSTPIPIMR_SHORTPACKETIE_Pos) /**< (HSTPIPIMR) Short Packet Interrupt Enable Mask */ +#define HSTPIPIMR_NBUSYBKE_Pos 12 /**< (HSTPIPIMR) Number of Busy Banks Interrupt Enable Position */ +#define HSTPIPIMR_NBUSYBKE (_U_(0x1) << HSTPIPIMR_NBUSYBKE_Pos) /**< (HSTPIPIMR) Number of Busy Banks Interrupt Enable Mask */ +#define HSTPIPIMR_FIFOCON_Pos 14 /**< (HSTPIPIMR) FIFO Control Position */ +#define HSTPIPIMR_FIFOCON (_U_(0x1) << HSTPIPIMR_FIFOCON_Pos) /**< (HSTPIPIMR) FIFO Control Mask */ +#define HSTPIPIMR_PDISHDMA_Pos 16 /**< (HSTPIPIMR) Pipe Interrupts Disable HDMA Request Enable Position */ +#define HSTPIPIMR_PDISHDMA (_U_(0x1) << HSTPIPIMR_PDISHDMA_Pos) /**< (HSTPIPIMR) Pipe Interrupts Disable HDMA Request Enable Mask */ +#define HSTPIPIMR_PFREEZE_Pos 17 /**< (HSTPIPIMR) Pipe Freeze Position */ +#define HSTPIPIMR_PFREEZE (_U_(0x1) << HSTPIPIMR_PFREEZE_Pos) /**< (HSTPIPIMR) Pipe Freeze Mask */ +#define HSTPIPIMR_RSTDT_Pos 18 /**< (HSTPIPIMR) Reset Data Toggle Position */ +#define HSTPIPIMR_RSTDT (_U_(0x1) << HSTPIPIMR_RSTDT_Pos) /**< (HSTPIPIMR) Reset Data Toggle Mask */ +#define HSTPIPIMR_Msk _U_(0x750BB) /**< (HSTPIPIMR) Register Mask */ + +/* CTRL mode */ +#define HSTPIPIMR_CTRL_TXSTPE_Pos 2 /**< (HSTPIPIMR) Transmitted SETUP Interrupt Enable Position */ +#define HSTPIPIMR_CTRL_TXSTPE (_U_(0x1) << HSTPIPIMR_CTRL_TXSTPE_Pos) /**< (HSTPIPIMR) Transmitted SETUP Interrupt Enable Mask */ +#define HSTPIPIMR_CTRL_RXSTALLDE_Pos 6 /**< (HSTPIPIMR) Received STALLed Interrupt Enable Position */ +#define HSTPIPIMR_CTRL_RXSTALLDE (_U_(0x1) << HSTPIPIMR_CTRL_RXSTALLDE_Pos) /**< (HSTPIPIMR) Received STALLed Interrupt Enable Mask */ +#define HSTPIPIMR_CTRL_Msk _U_(0x44) /**< (HSTPIPIMR_CTRL) Register Mask */ + +/* ISO mode */ +#define HSTPIPIMR_ISO_UNDERFIE_Pos 2 /**< (HSTPIPIMR) Underflow Interrupt Enable Position */ +#define HSTPIPIMR_ISO_UNDERFIE (_U_(0x1) << HSTPIPIMR_ISO_UNDERFIE_Pos) /**< (HSTPIPIMR) Underflow Interrupt Enable Mask */ +#define HSTPIPIMR_ISO_CRCERRE_Pos 6 /**< (HSTPIPIMR) CRC Error Interrupt Enable Position */ +#define HSTPIPIMR_ISO_CRCERRE (_U_(0x1) << HSTPIPIMR_ISO_CRCERRE_Pos) /**< (HSTPIPIMR) CRC Error Interrupt Enable Mask */ +#define HSTPIPIMR_ISO_Msk _U_(0x44) /**< (HSTPIPIMR_ISO) Register Mask */ + +/* BLK mode */ +#define HSTPIPIMR_BLK_TXSTPE_Pos 2 /**< (HSTPIPIMR) Transmitted SETUP Interrupt Enable Position */ +#define HSTPIPIMR_BLK_TXSTPE (_U_(0x1) << HSTPIPIMR_BLK_TXSTPE_Pos) /**< (HSTPIPIMR) Transmitted SETUP Interrupt Enable Mask */ +#define HSTPIPIMR_BLK_RXSTALLDE_Pos 6 /**< (HSTPIPIMR) Received STALLed Interrupt Enable Position */ +#define HSTPIPIMR_BLK_RXSTALLDE (_U_(0x1) << HSTPIPIMR_BLK_RXSTALLDE_Pos) /**< (HSTPIPIMR) Received STALLed Interrupt Enable Mask */ +#define HSTPIPIMR_BLK_Msk _U_(0x44) /**< (HSTPIPIMR_BLK) Register Mask */ + +/* INTRPT mode */ +#define HSTPIPIMR_INTRPT_UNDERFIE_Pos 2 /**< (HSTPIPIMR) Underflow Interrupt Enable Position */ +#define HSTPIPIMR_INTRPT_UNDERFIE (_U_(0x1) << HSTPIPIMR_INTRPT_UNDERFIE_Pos) /**< (HSTPIPIMR) Underflow Interrupt Enable Mask */ +#define HSTPIPIMR_INTRPT_RXSTALLDE_Pos 6 /**< (HSTPIPIMR) Received STALLed Interrupt Enable Position */ +#define HSTPIPIMR_INTRPT_RXSTALLDE (_U_(0x1) << HSTPIPIMR_INTRPT_RXSTALLDE_Pos) /**< (HSTPIPIMR) Received STALLed Interrupt Enable Mask */ +#define HSTPIPIMR_INTRPT_Msk _U_(0x44) /**< (HSTPIPIMR_INTRPT) Register Mask */ + + +/* -------- HSTPIPIER : (USBHS Offset: 0x5f0) (/W 32) Host Pipe Enable Register -------- */ + +#define HSTPIPIER_OFFSET (0x5F0) /**< (HSTPIPIER) Host Pipe Enable Register Offset */ + +#define HSTPIPIER_RXINES_Pos 0 /**< (HSTPIPIER) Received IN Data Interrupt Enable Position */ +#define HSTPIPIER_RXINES (_U_(0x1) << HSTPIPIER_RXINES_Pos) /**< (HSTPIPIER) Received IN Data Interrupt Enable Mask */ +#define HSTPIPIER_TXOUTES_Pos 1 /**< (HSTPIPIER) Transmitted OUT Data Interrupt Enable Position */ +#define HSTPIPIER_TXOUTES (_U_(0x1) << HSTPIPIER_TXOUTES_Pos) /**< (HSTPIPIER) Transmitted OUT Data Interrupt Enable Mask */ +#define HSTPIPIER_PERRES_Pos 3 /**< (HSTPIPIER) Pipe Error Interrupt Enable Position */ +#define HSTPIPIER_PERRES (_U_(0x1) << HSTPIPIER_PERRES_Pos) /**< (HSTPIPIER) Pipe Error Interrupt Enable Mask */ +#define HSTPIPIER_NAKEDES_Pos 4 /**< (HSTPIPIER) NAKed Interrupt Enable Position */ +#define HSTPIPIER_NAKEDES (_U_(0x1) << HSTPIPIER_NAKEDES_Pos) /**< (HSTPIPIER) NAKed Interrupt Enable Mask */ +#define HSTPIPIER_OVERFIES_Pos 5 /**< (HSTPIPIER) Overflow Interrupt Enable Position */ +#define HSTPIPIER_OVERFIES (_U_(0x1) << HSTPIPIER_OVERFIES_Pos) /**< (HSTPIPIER) Overflow Interrupt Enable Mask */ +#define HSTPIPIER_SHORTPACKETIES_Pos 7 /**< (HSTPIPIER) Short Packet Interrupt Enable Position */ +#define HSTPIPIER_SHORTPACKETIES (_U_(0x1) << HSTPIPIER_SHORTPACKETIES_Pos) /**< (HSTPIPIER) Short Packet Interrupt Enable Mask */ +#define HSTPIPIER_NBUSYBKES_Pos 12 /**< (HSTPIPIER) Number of Busy Banks Enable Position */ +#define HSTPIPIER_NBUSYBKES (_U_(0x1) << HSTPIPIER_NBUSYBKES_Pos) /**< (HSTPIPIER) Number of Busy Banks Enable Mask */ +#define HSTPIPIER_PDISHDMAS_Pos 16 /**< (HSTPIPIER) Pipe Interrupts Disable HDMA Request Enable Position */ +#define HSTPIPIER_PDISHDMAS (_U_(0x1) << HSTPIPIER_PDISHDMAS_Pos) /**< (HSTPIPIER) Pipe Interrupts Disable HDMA Request Enable Mask */ +#define HSTPIPIER_PFREEZES_Pos 17 /**< (HSTPIPIER) Pipe Freeze Enable Position */ +#define HSTPIPIER_PFREEZES (_U_(0x1) << HSTPIPIER_PFREEZES_Pos) /**< (HSTPIPIER) Pipe Freeze Enable Mask */ +#define HSTPIPIER_RSTDTS_Pos 18 /**< (HSTPIPIER) Reset Data Toggle Enable Position */ +#define HSTPIPIER_RSTDTS (_U_(0x1) << HSTPIPIER_RSTDTS_Pos) /**< (HSTPIPIER) Reset Data Toggle Enable Mask */ +#define HSTPIPIER_Msk _U_(0x710BB) /**< (HSTPIPIER) Register Mask */ + +/* CTRL mode */ +#define HSTPIPIER_CTRL_TXSTPES_Pos 2 /**< (HSTPIPIER) Transmitted SETUP Interrupt Enable Position */ +#define HSTPIPIER_CTRL_TXSTPES (_U_(0x1) << HSTPIPIER_CTRL_TXSTPES_Pos) /**< (HSTPIPIER) Transmitted SETUP Interrupt Enable Mask */ +#define HSTPIPIER_CTRL_RXSTALLDES_Pos 6 /**< (HSTPIPIER) Received STALLed Interrupt Enable Position */ +#define HSTPIPIER_CTRL_RXSTALLDES (_U_(0x1) << HSTPIPIER_CTRL_RXSTALLDES_Pos) /**< (HSTPIPIER) Received STALLed Interrupt Enable Mask */ +#define HSTPIPIER_CTRL_Msk _U_(0x44) /**< (HSTPIPIER_CTRL) Register Mask */ + +/* ISO mode */ +#define HSTPIPIER_ISO_UNDERFIES_Pos 2 /**< (HSTPIPIER) Underflow Interrupt Enable Position */ +#define HSTPIPIER_ISO_UNDERFIES (_U_(0x1) << HSTPIPIER_ISO_UNDERFIES_Pos) /**< (HSTPIPIER) Underflow Interrupt Enable Mask */ +#define HSTPIPIER_ISO_CRCERRES_Pos 6 /**< (HSTPIPIER) CRC Error Interrupt Enable Position */ +#define HSTPIPIER_ISO_CRCERRES (_U_(0x1) << HSTPIPIER_ISO_CRCERRES_Pos) /**< (HSTPIPIER) CRC Error Interrupt Enable Mask */ +#define HSTPIPIER_ISO_Msk _U_(0x44) /**< (HSTPIPIER_ISO) Register Mask */ + +/* BLK mode */ +#define HSTPIPIER_BLK_TXSTPES_Pos 2 /**< (HSTPIPIER) Transmitted SETUP Interrupt Enable Position */ +#define HSTPIPIER_BLK_TXSTPES (_U_(0x1) << HSTPIPIER_BLK_TXSTPES_Pos) /**< (HSTPIPIER) Transmitted SETUP Interrupt Enable Mask */ +#define HSTPIPIER_BLK_RXSTALLDES_Pos 6 /**< (HSTPIPIER) Received STALLed Interrupt Enable Position */ +#define HSTPIPIER_BLK_RXSTALLDES (_U_(0x1) << HSTPIPIER_BLK_RXSTALLDES_Pos) /**< (HSTPIPIER) Received STALLed Interrupt Enable Mask */ +#define HSTPIPIER_BLK_Msk _U_(0x44) /**< (HSTPIPIER_BLK) Register Mask */ + +/* INTRPT mode */ +#define HSTPIPIER_INTRPT_UNDERFIES_Pos 2 /**< (HSTPIPIER) Underflow Interrupt Enable Position */ +#define HSTPIPIER_INTRPT_UNDERFIES (_U_(0x1) << HSTPIPIER_INTRPT_UNDERFIES_Pos) /**< (HSTPIPIER) Underflow Interrupt Enable Mask */ +#define HSTPIPIER_INTRPT_RXSTALLDES_Pos 6 /**< (HSTPIPIER) Received STALLed Interrupt Enable Position */ +#define HSTPIPIER_INTRPT_RXSTALLDES (_U_(0x1) << HSTPIPIER_INTRPT_RXSTALLDES_Pos) /**< (HSTPIPIER) Received STALLed Interrupt Enable Mask */ +#define HSTPIPIER_INTRPT_Msk _U_(0x44) /**< (HSTPIPIER_INTRPT) Register Mask */ + + +/* -------- HSTPIPIDR : (USBHS Offset: 0x620) (/W 32) Host Pipe Disable Register -------- */ + +#define HSTPIPIDR_OFFSET (0x620) /**< (HSTPIPIDR) Host Pipe Disable Register Offset */ + +#define HSTPIPIDR_RXINEC_Pos 0 /**< (HSTPIPIDR) Received IN Data Interrupt Disable Position */ +#define HSTPIPIDR_RXINEC (_U_(0x1) << HSTPIPIDR_RXINEC_Pos) /**< (HSTPIPIDR) Received IN Data Interrupt Disable Mask */ +#define HSTPIPIDR_TXOUTEC_Pos 1 /**< (HSTPIPIDR) Transmitted OUT Data Interrupt Disable Position */ +#define HSTPIPIDR_TXOUTEC (_U_(0x1) << HSTPIPIDR_TXOUTEC_Pos) /**< (HSTPIPIDR) Transmitted OUT Data Interrupt Disable Mask */ +#define HSTPIPIDR_PERREC_Pos 3 /**< (HSTPIPIDR) Pipe Error Interrupt Disable Position */ +#define HSTPIPIDR_PERREC (_U_(0x1) << HSTPIPIDR_PERREC_Pos) /**< (HSTPIPIDR) Pipe Error Interrupt Disable Mask */ +#define HSTPIPIDR_NAKEDEC_Pos 4 /**< (HSTPIPIDR) NAKed Interrupt Disable Position */ +#define HSTPIPIDR_NAKEDEC (_U_(0x1) << HSTPIPIDR_NAKEDEC_Pos) /**< (HSTPIPIDR) NAKed Interrupt Disable Mask */ +#define HSTPIPIDR_OVERFIEC_Pos 5 /**< (HSTPIPIDR) Overflow Interrupt Disable Position */ +#define HSTPIPIDR_OVERFIEC (_U_(0x1) << HSTPIPIDR_OVERFIEC_Pos) /**< (HSTPIPIDR) Overflow Interrupt Disable Mask */ +#define HSTPIPIDR_SHORTPACKETIEC_Pos 7 /**< (HSTPIPIDR) Short Packet Interrupt Disable Position */ +#define HSTPIPIDR_SHORTPACKETIEC (_U_(0x1) << HSTPIPIDR_SHORTPACKETIEC_Pos) /**< (HSTPIPIDR) Short Packet Interrupt Disable Mask */ +#define HSTPIPIDR_NBUSYBKEC_Pos 12 /**< (HSTPIPIDR) Number of Busy Banks Disable Position */ +#define HSTPIPIDR_NBUSYBKEC (_U_(0x1) << HSTPIPIDR_NBUSYBKEC_Pos) /**< (HSTPIPIDR) Number of Busy Banks Disable Mask */ +#define HSTPIPIDR_FIFOCONC_Pos 14 /**< (HSTPIPIDR) FIFO Control Disable Position */ +#define HSTPIPIDR_FIFOCONC (_U_(0x1) << HSTPIPIDR_FIFOCONC_Pos) /**< (HSTPIPIDR) FIFO Control Disable Mask */ +#define HSTPIPIDR_PDISHDMAC_Pos 16 /**< (HSTPIPIDR) Pipe Interrupts Disable HDMA Request Disable Position */ +#define HSTPIPIDR_PDISHDMAC (_U_(0x1) << HSTPIPIDR_PDISHDMAC_Pos) /**< (HSTPIPIDR) Pipe Interrupts Disable HDMA Request Disable Mask */ +#define HSTPIPIDR_PFREEZEC_Pos 17 /**< (HSTPIPIDR) Pipe Freeze Disable Position */ +#define HSTPIPIDR_PFREEZEC (_U_(0x1) << HSTPIPIDR_PFREEZEC_Pos) /**< (HSTPIPIDR) Pipe Freeze Disable Mask */ +#define HSTPIPIDR_Msk _U_(0x350BB) /**< (HSTPIPIDR) Register Mask */ + +/* CTRL mode */ +#define HSTPIPIDR_CTRL_TXSTPEC_Pos 2 /**< (HSTPIPIDR) Transmitted SETUP Interrupt Disable Position */ +#define HSTPIPIDR_CTRL_TXSTPEC (_U_(0x1) << HSTPIPIDR_CTRL_TXSTPEC_Pos) /**< (HSTPIPIDR) Transmitted SETUP Interrupt Disable Mask */ +#define HSTPIPIDR_CTRL_RXSTALLDEC_Pos 6 /**< (HSTPIPIDR) Received STALLed Interrupt Disable Position */ +#define HSTPIPIDR_CTRL_RXSTALLDEC (_U_(0x1) << HSTPIPIDR_CTRL_RXSTALLDEC_Pos) /**< (HSTPIPIDR) Received STALLed Interrupt Disable Mask */ +#define HSTPIPIDR_CTRL_Msk _U_(0x44) /**< (HSTPIPIDR_CTRL) Register Mask */ + +/* ISO mode */ +#define HSTPIPIDR_ISO_UNDERFIEC_Pos 2 /**< (HSTPIPIDR) Underflow Interrupt Disable Position */ +#define HSTPIPIDR_ISO_UNDERFIEC (_U_(0x1) << HSTPIPIDR_ISO_UNDERFIEC_Pos) /**< (HSTPIPIDR) Underflow Interrupt Disable Mask */ +#define HSTPIPIDR_ISO_CRCERREC_Pos 6 /**< (HSTPIPIDR) CRC Error Interrupt Disable Position */ +#define HSTPIPIDR_ISO_CRCERREC (_U_(0x1) << HSTPIPIDR_ISO_CRCERREC_Pos) /**< (HSTPIPIDR) CRC Error Interrupt Disable Mask */ +#define HSTPIPIDR_ISO_Msk _U_(0x44) /**< (HSTPIPIDR_ISO) Register Mask */ + +/* BLK mode */ +#define HSTPIPIDR_BLK_TXSTPEC_Pos 2 /**< (HSTPIPIDR) Transmitted SETUP Interrupt Disable Position */ +#define HSTPIPIDR_BLK_TXSTPEC (_U_(0x1) << HSTPIPIDR_BLK_TXSTPEC_Pos) /**< (HSTPIPIDR) Transmitted SETUP Interrupt Disable Mask */ +#define HSTPIPIDR_BLK_RXSTALLDEC_Pos 6 /**< (HSTPIPIDR) Received STALLed Interrupt Disable Position */ +#define HSTPIPIDR_BLK_RXSTALLDEC (_U_(0x1) << HSTPIPIDR_BLK_RXSTALLDEC_Pos) /**< (HSTPIPIDR) Received STALLed Interrupt Disable Mask */ +#define HSTPIPIDR_BLK_Msk _U_(0x44) /**< (HSTPIPIDR_BLK) Register Mask */ + +/* INTRPT mode */ +#define HSTPIPIDR_INTRPT_UNDERFIEC_Pos 2 /**< (HSTPIPIDR) Underflow Interrupt Disable Position */ +#define HSTPIPIDR_INTRPT_UNDERFIEC (_U_(0x1) << HSTPIPIDR_INTRPT_UNDERFIEC_Pos) /**< (HSTPIPIDR) Underflow Interrupt Disable Mask */ +#define HSTPIPIDR_INTRPT_RXSTALLDEC_Pos 6 /**< (HSTPIPIDR) Received STALLed Interrupt Disable Position */ +#define HSTPIPIDR_INTRPT_RXSTALLDEC (_U_(0x1) << HSTPIPIDR_INTRPT_RXSTALLDEC_Pos) /**< (HSTPIPIDR) Received STALLed Interrupt Disable Mask */ +#define HSTPIPIDR_INTRPT_Msk _U_(0x44) /**< (HSTPIPIDR_INTRPT) Register Mask */ + + +/* -------- HSTPIPINRQ : (USBHS Offset: 0x650) (R/W 32) Host Pipe IN Request Register -------- */ + +#define HSTPIPINRQ_OFFSET (0x650) /**< (HSTPIPINRQ) Host Pipe IN Request Register Offset */ + +#define HSTPIPINRQ_INRQ_Pos 0 /**< (HSTPIPINRQ) IN Request Number before Freeze Position */ +#define HSTPIPINRQ_INRQ (_U_(0xFF) << HSTPIPINRQ_INRQ_Pos) /**< (HSTPIPINRQ) IN Request Number before Freeze Mask */ +#define HSTPIPINRQ_INMODE_Pos 8 /**< (HSTPIPINRQ) IN Request Mode Position */ +#define HSTPIPINRQ_INMODE (_U_(0x1) << HSTPIPINRQ_INMODE_Pos) /**< (HSTPIPINRQ) IN Request Mode Mask */ +#define HSTPIPINRQ_Msk _U_(0x1FF) /**< (HSTPIPINRQ) Register Mask */ + + +/* -------- HSTPIPERR : (USBHS Offset: 0x680) (R/W 32) Host Pipe Error Register -------- */ + +#define HSTPIPERR_OFFSET (0x680) /**< (HSTPIPERR) Host Pipe Error Register Offset */ + +#define HSTPIPERR_DATATGL_Pos 0 /**< (HSTPIPERR) Data Toggle Error Position */ +#define HSTPIPERR_DATATGL (_U_(0x1) << HSTPIPERR_DATATGL_Pos) /**< (HSTPIPERR) Data Toggle Error Mask */ +#define HSTPIPERR_DATAPID_Pos 1 /**< (HSTPIPERR) Data PID Error Position */ +#define HSTPIPERR_DATAPID (_U_(0x1) << HSTPIPERR_DATAPID_Pos) /**< (HSTPIPERR) Data PID Error Mask */ +#define HSTPIPERR_PID_Pos 2 /**< (HSTPIPERR) Data PID Error Position */ +#define HSTPIPERR_PID (_U_(0x1) << HSTPIPERR_PID_Pos) /**< (HSTPIPERR) Data PID Error Mask */ +#define HSTPIPERR_TIMEOUT_Pos 3 /**< (HSTPIPERR) Time-Out Error Position */ +#define HSTPIPERR_TIMEOUT (_U_(0x1) << HSTPIPERR_TIMEOUT_Pos) /**< (HSTPIPERR) Time-Out Error Mask */ +#define HSTPIPERR_CRC16_Pos 4 /**< (HSTPIPERR) CRC16 Error Position */ +#define HSTPIPERR_CRC16 (_U_(0x1) << HSTPIPERR_CRC16_Pos) /**< (HSTPIPERR) CRC16 Error Mask */ +#define HSTPIPERR_COUNTER_Pos 5 /**< (HSTPIPERR) Error Counter Position */ +#define HSTPIPERR_COUNTER (_U_(0x3) << HSTPIPERR_COUNTER_Pos) /**< (HSTPIPERR) Error Counter Mask */ +#define HSTPIPERR_Msk _U_(0x7F) /**< (HSTPIPERR) Register Mask */ + +#define HSTPIPERR_CRC_Pos 4 /**< (HSTPIPERR Position) CRCx6 Error */ +#define HSTPIPERR_CRC (_U_(0x1) << HSTPIPERR_CRC_Pos) /**< (HSTPIPERR Mask) CRC */ + +/* -------- CTRL : (USBHS Offset: 0x800) (R/W 32) General Control Register -------- */ + +#define CTRL_OFFSET (0x800) /**< (CTRL) General Control Register Offset */ + +#define CTRL_RDERRE_Pos 4 /**< (CTRL) Remote Device Connection Error Interrupt Enable Position */ +#define CTRL_RDERRE (_U_(0x1) << CTRL_RDERRE_Pos) /**< (CTRL) Remote Device Connection Error Interrupt Enable Mask */ +#define CTRL_VBUSHWC_Pos 8 /**< (CTRL) VBUS Hardware Control Position */ +#define CTRL_VBUSHWC (_U_(0x1) << CTRL_VBUSHWC_Pos) /**< (CTRL) VBUS Hardware Control Mask */ +#define CTRL_FRZCLK_Pos 14 /**< (CTRL) Freeze USB Clock Position */ +#define CTRL_FRZCLK (_U_(0x1) << CTRL_FRZCLK_Pos) /**< (CTRL) Freeze USB Clock Mask */ +#define CTRL_USBE_Pos 15 /**< (CTRL) USBHS Enable Position */ +#define CTRL_USBE (_U_(0x1) << CTRL_USBE_Pos) /**< (CTRL) USBHS Enable Mask */ +#define CTRL_UID_Pos 24 /**< (CTRL) UID Pin Enable Position */ +#define CTRL_UID (_U_(0x1) << CTRL_UID_Pos) /**< (CTRL) UID Pin Enable Mask */ +#define CTRL_UIMOD_Pos 25 /**< (CTRL) USBHS Mode Position */ +#define CTRL_UIMOD (_U_(0x1) << CTRL_UIMOD_Pos) /**< (CTRL) USBHS Mode Mask */ +#define CTRL_UIMOD_HOST_Val _U_(0x0) /**< (CTRL) The module is in USB Host mode. */ +#define CTRL_UIMOD_DEVICE_Val _U_(0x1) /**< (CTRL) The module is in USB Device mode. */ +#define CTRL_UIMOD_HOST (CTRL_UIMOD_HOST_Val << CTRL_UIMOD_Pos) /**< (CTRL) The module is in USB Host mode. Position */ +#define CTRL_UIMOD_DEVICE (CTRL_UIMOD_DEVICE_Val << CTRL_UIMOD_Pos) /**< (CTRL) The module is in USB Device mode. Position */ +#define CTRL_Msk _U_(0x300C110) /**< (CTRL) Register Mask */ + + +/* -------- SR : (USBHS Offset: 0x804) (R/ 32) General Status Register -------- */ + +#define SR_OFFSET (0x804) /**< (SR) General Status Register Offset */ + +#define SR_RDERRI_Pos 4 /**< (SR) Remote Device Connection Error Interrupt (Host mode only) Position */ +#define SR_RDERRI (_U_(0x1) << SR_RDERRI_Pos) /**< (SR) Remote Device Connection Error Interrupt (Host mode only) Mask */ +#define SR_SPEED_Pos 12 /**< (SR) Speed Status (Device mode only) Position */ +#define SR_SPEED (_U_(0x3) << SR_SPEED_Pos) /**< (SR) Speed Status (Device mode only) Mask */ +#define SR_SPEED_FULL_SPEED_Val _U_(0x0) /**< (SR) Full-Speed mode */ +#define SR_SPEED_HIGH_SPEED_Val _U_(0x1) /**< (SR) High-Speed mode */ +#define SR_SPEED_LOW_SPEED_Val _U_(0x2) /**< (SR) Low-Speed mode */ +#define SR_SPEED_FULL_SPEED (SR_SPEED_FULL_SPEED_Val << SR_SPEED_Pos) /**< (SR) Full-Speed mode Position */ +#define SR_SPEED_HIGH_SPEED (SR_SPEED_HIGH_SPEED_Val << SR_SPEED_Pos) /**< (SR) High-Speed mode Position */ +#define SR_SPEED_LOW_SPEED (SR_SPEED_LOW_SPEED_Val << SR_SPEED_Pos) /**< (SR) Low-Speed mode Position */ +#define SR_CLKUSABLE_Pos 14 /**< (SR) UTMI Clock Usable Position */ +#define SR_CLKUSABLE (_U_(0x1) << SR_CLKUSABLE_Pos) /**< (SR) UTMI Clock Usable Mask */ +#define SR_Msk _U_(0x7010) /**< (SR) Register Mask */ + + +/* -------- SCR : (USBHS Offset: 0x808) (/W 32) General Status Clear Register -------- */ + +#define SCR_OFFSET (0x808) /**< (SCR) General Status Clear Register Offset */ + +#define SCR_RDERRIC_Pos 4 /**< (SCR) Remote Device Connection Error Interrupt Clear Position */ +#define SCR_RDERRIC (_U_(0x1) << SCR_RDERRIC_Pos) /**< (SCR) Remote Device Connection Error Interrupt Clear Mask */ +#define SCR_Msk _U_(0x10) /**< (SCR) Register Mask */ + + +/* -------- SFR : (USBHS Offset: 0x80c) (/W 32) General Status Set Register -------- */ + +#define SFR_OFFSET (0x80C) /**< (SFR) General Status Set Register Offset */ + +#define SFR_RDERRIS_Pos 4 /**< (SFR) Remote Device Connection Error Interrupt Set Position */ +#define SFR_RDERRIS (_U_(0x1) << SFR_RDERRIS_Pos) /**< (SFR) Remote Device Connection Error Interrupt Set Mask */ +#define SFR_VBUSRQS_Pos 9 /**< (SFR) VBUS Request Set Position */ +#define SFR_VBUSRQS (_U_(0x1) << SFR_VBUSRQS_Pos) /**< (SFR) VBUS Request Set Mask */ +#define SFR_Msk _U_(0x210) /**< (SFR) Register Mask */ + + +/** \brief DEVDMA hardware registers */ +typedef struct +{ + __IO uint32_t DEVDMANXTDSC; /**< (DEVDMA Offset: 0x00) Device DMA Channel Next Descriptor Address Register */ + __IO uint32_t DEVDMAADDRESS; /**< (DEVDMA Offset: 0x04) Device DMA Channel Address Register */ + __IO uint32_t DEVDMACONTROL; /**< (DEVDMA Offset: 0x08) Device DMA Channel Control Register */ + __IO uint32_t DEVDMASTATUS; /**< (DEVDMA Offset: 0x0C) Device DMA Channel Status Register */ +} devdma_t; + +/** \brief HSTDMA hardware registers */ +typedef struct +{ + __IO uint32_t HSTDMANXTDSC; /**< (HSTDMA Offset: 0x00) Host DMA Channel Next Descriptor Address Register */ + __IO uint32_t HSTDMAADDRESS; /**< (HSTDMA Offset: 0x04) Host DMA Channel Address Register */ + __IO uint32_t HSTDMACONTROL; /**< (HSTDMA Offset: 0x08) Host DMA Channel Control Register */ + __IO uint32_t HSTDMASTATUS; /**< (HSTDMA Offset: 0x0C) Host DMA Channel Status Register */ +} hstdma_t; + +/** \brief USBHS hardware registers */ +typedef struct +{ + __IO uint32_t DEVCTRL; /**< (USBHS Offset: 0x00) Device General Control Register */ + __I uint32_t DEVISR; /**< (USBHS Offset: 0x04) Device Global Interrupt Status Register */ + __O uint32_t DEVICR; /**< (USBHS Offset: 0x08) Device Global Interrupt Clear Register */ + __O uint32_t DEVIFR; /**< (USBHS Offset: 0x0C) Device Global Interrupt Set Register */ + __I uint32_t DEVIMR; /**< (USBHS Offset: 0x10) Device Global Interrupt Mask Register */ + __O uint32_t DEVIDR; /**< (USBHS Offset: 0x14) Device Global Interrupt Disable Register */ + __O uint32_t DEVIER; /**< (USBHS Offset: 0x18) Device Global Interrupt Enable Register */ + __IO uint32_t DEVEPT; /**< (USBHS Offset: 0x1C) Device Endpoint Register */ + __I uint32_t DEVFNUM; /**< (USBHS Offset: 0x20) Device Frame Number Register */ + __I uint8_t Reserved1[220]; + __IO uint32_t DEVEPTCFG[10]; /**< (USBHS Offset: 0x100) Device Endpoint Configuration Register */ + __I uint8_t Reserved2[8]; + __I uint32_t DEVEPTISR[10]; /**< (USBHS Offset: 0x130) Device Endpoint Interrupt Status Register */ + __I uint8_t Reserved3[8]; + __O uint32_t DEVEPTICR[10]; /**< (USBHS Offset: 0x160) Device Endpoint Interrupt Clear Register */ + __I uint8_t Reserved4[8]; + __O uint32_t DEVEPTIFR[10]; /**< (USBHS Offset: 0x190) Device Endpoint Interrupt Set Register */ + __I uint8_t Reserved5[8]; + __I uint32_t DEVEPTIMR[10]; /**< (USBHS Offset: 0x1C0) Device Endpoint Interrupt Mask Register */ + __I uint8_t Reserved6[8]; + __O uint32_t DEVEPTIER[10]; /**< (USBHS Offset: 0x1F0) Device Endpoint Interrupt Enable Register */ + __I uint8_t Reserved7[8]; + __O uint32_t DEVEPTIDR[10]; /**< (USBHS Offset: 0x220) Device Endpoint Interrupt Disable Register */ + __I uint8_t Reserved8[200]; + devdma_t DEVDMA[7]; /**< Offset: 0x310 Device DMA Channel Next Descriptor Address Register */ + __I uint8_t Reserved9[128]; + __IO uint32_t HSTCTRL; /**< (USBHS Offset: 0x400) Host General Control Register */ + __I uint32_t HSTISR; /**< (USBHS Offset: 0x404) Host Global Interrupt Status Register */ + __O uint32_t HSTICR; /**< (USBHS Offset: 0x408) Host Global Interrupt Clear Register */ + __O uint32_t HSTIFR; /**< (USBHS Offset: 0x40C) Host Global Interrupt Set Register */ + __I uint32_t HSTIMR; /**< (USBHS Offset: 0x410) Host Global Interrupt Mask Register */ + __O uint32_t HSTIDR; /**< (USBHS Offset: 0x414) Host Global Interrupt Disable Register */ + __O uint32_t HSTIER; /**< (USBHS Offset: 0x418) Host Global Interrupt Enable Register */ + __IO uint32_t HSTPIP; /**< (USBHS Offset: 0x41C) Host Pipe Register */ + __IO uint32_t HSTFNUM; /**< (USBHS Offset: 0x420) Host Frame Number Register */ + __IO uint32_t HSTADDR1; /**< (USBHS Offset: 0x424) Host Address 1 Register */ + __IO uint32_t HSTADDR2; /**< (USBHS Offset: 0x428) Host Address 2 Register */ + __IO uint32_t HSTADDR3; /**< (USBHS Offset: 0x42C) Host Address 3 Register */ + __I uint8_t Reserved10[208]; + __IO uint32_t HSTPIPCFG[10]; /**< (USBHS Offset: 0x500) Host Pipe Configuration Register */ + __I uint8_t Reserved11[8]; + __I uint32_t HSTPIPISR[10]; /**< (USBHS Offset: 0x530) Host Pipe Status Register */ + __I uint8_t Reserved12[8]; + __O uint32_t HSTPIPICR[10]; /**< (USBHS Offset: 0x560) Host Pipe Clear Register */ + __I uint8_t Reserved13[8]; + __O uint32_t HSTPIPIFR[10]; /**< (USBHS Offset: 0x590) Host Pipe Set Register */ + __I uint8_t Reserved14[8]; + __I uint32_t HSTPIPIMR[10]; /**< (USBHS Offset: 0x5C0) Host Pipe Mask Register */ + __I uint8_t Reserved15[8]; + __O uint32_t HSTPIPIER[10]; /**< (USBHS Offset: 0x5F0) Host Pipe Enable Register */ + __I uint8_t Reserved16[8]; + __O uint32_t HSTPIPIDR[10]; /**< (USBHS Offset: 0x620) Host Pipe Disable Register */ + __I uint8_t Reserved17[8]; + __IO uint32_t HSTPIPINRQ[10]; /**< (USBHS Offset: 0x650) Host Pipe IN Request Register */ + __I uint8_t Reserved18[8]; + __IO uint32_t HSTPIPERR[10]; /**< (USBHS Offset: 0x680) Host Pipe Error Register */ + __I uint8_t Reserved19[104]; + hstdma_t HSTDMA[7]; /**< Offset: 0x710 Host DMA Channel Next Descriptor Address Register */ + __I uint8_t Reserved20[128]; + __IO uint32_t CTRL; /**< (USBHS Offset: 0x800) General Control Register */ + __I uint32_t SR; /**< (USBHS Offset: 0x804) General Status Register */ + __O uint32_t SCR; /**< (USBHS Offset: 0x808) General Status Clear Register */ + __O uint32_t SFR; /**< (USBHS Offset: 0x80C) General Status Set Register */ +} dcd_registers_t; + +#define USB_REG ((dcd_registers_t *)0x40038000U) /**< \brief (USBHS) Base Address */ + +#define EP_MAX 10 + +#define FIFO_RAM_ADDR 0xA0100000u + +// Errata: The DMA feature is not available for Pipe/Endpoint 7 +#define EP_DMA_SUPPORT(epnum) (epnum >= 1 && epnum <= 6 && CFG_TUD_SAMX7X_DMA_ENABLE) + +//------------- DCache -------------// +#if CFG_TUD_MEM_DCACHE_ENABLE || CFG_TUH_MEM_DCACHE_ENABLE + +typedef struct { + uintptr_t start; + uintptr_t end; +} mem_region_t; + +// Can be used to define additional uncached regions +#ifndef CFG_SAMX7X_MEM_UNCACHED_REGIONS +#define CFG_SAMX7X_MEM_UNCACHED_REGIONS +#endif + +static mem_region_t uncached_regions[] = { + // DTCM + {.start = 0x20000000, .end = 0x203fffff}, + CFG_SAMX7X_MEM_UNCACHED_REGIONS +}; + +TU_ATTR_ALWAYS_INLINE static inline uint32_t round_up_to_cache_line_size(uint32_t size) { + if (size & (CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT-1)) { + size = (size & ~(CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT-1)) + CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT; + } + return size; +} + +TU_ATTR_ALWAYS_INLINE static inline bool is_cache_mem(uintptr_t addr) { + if (0 == (SCB->CCR & SCB_CCR_DC_Msk)) { + return false; // D-Cache is disabled + } + for (unsigned int i = 0; i < TU_ARRAY_SIZE(uncached_regions); i++) { + if (uncached_regions[i].start <= addr && addr <= uncached_regions[i].end) { return false; } + } + return true; +} + +TU_ATTR_ALWAYS_INLINE static inline bool samx7x_dcache_clean(void const* addr, uint32_t data_size) { + const uintptr_t addr32 = (uintptr_t) addr; + if (is_cache_mem(addr32)) { + data_size = round_up_to_cache_line_size(data_size); + SCB_CleanDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size); + } + return true; +} + +TU_ATTR_ALWAYS_INLINE static inline bool samx7x_dcache_invalidate(void const* addr, uint32_t data_size) { + const uintptr_t addr32 = (uintptr_t) addr; + if (is_cache_mem(addr32)) { + data_size = round_up_to_cache_line_size(data_size); + SCB_InvalidateDCache_by_Addr((void*) addr32, (int32_t) data_size); + } + return true; +} + +TU_ATTR_ALWAYS_INLINE static inline bool samx7x_dcache_clean_invalidate(void const* addr, uint32_t data_size) { + const uintptr_t addr32 = (uintptr_t) addr; + if (is_cache_mem(addr32)) { + data_size = round_up_to_cache_line_size(data_size); + SCB_CleanInvalidateDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size); + } + return true; +} + +#endif + +#else // TODO : SAM3U + + +#endif + +#endif /* _COMMON_USB_REGS_H_ */ diff --git a/src/tusb_option.h b/src/tusb_option.h index d87c2dc8b..8b4d3dcd5 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -394,6 +394,24 @@ // odd byte with byte access #endif +//------- Microchip SAMX7X -------// +// DMA mode for device +#ifndef CFG_TUD_SAMX7X_DMA_ENABLE + #ifndef CFG_TUD_SAMX7X_DMA_ENABLE_DEFAULT + #define CFG_TUD_SAMX7X_DMA_ENABLE_DEFAULT 0 + #endif + + #define CFG_TUD_SAMX7X_DMA_ENABLE CFG_TUD_SAMX7X_DMA_ENABLE_DEFAULT +#endif + +#if (CFG_TUSB_MCU == OPT_MCU_SAMX7X) + #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4 + #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 4 + #define CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS + #define CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS + #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 +#endif + //-------------------------------------------------------------------- // RootHub Mode detection //-------------------------------------------------------------------- -- cgit v1.3.1 From eca8b0050ffef13a534d08e8c648f18c7d654e3e Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 27 Feb 2026 11:31:10 +0100 Subject: dcd/samx7x: remove buggy DMA FIFO transfer Signed-off-by: HiFiPhile --- src/portable/microchip/samx7x/dcd_samx7x.c | 70 ++---------------------------- 1 file changed, 3 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c index 979d08fe9..c1cc95d8c 100644 --- a/src/portable/microchip/samx7x/dcd_samx7x.c +++ b/src/portable/microchip/samx7x/dcd_samx7x.c @@ -76,9 +76,6 @@ typedef struct { static tusb_speed_t get_speed(void); static void dcd_transmit_packet(xfer_ctl_t * xfer, uint8_t ep_ix); -// DMA descriptors shouldn't be placed in ITCM ! -CFG_TUD_MEM_SECTION static dma_desc_t dma_desc[6]; - static xfer_ctl_t xfer_status[EP_MAX]; static const tusb_desc_endpoint_t ep0_desc = @@ -673,73 +670,12 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_ xfer->queued_len = 0; xfer->fifo = ff; - if (EP_DMA_SUPPORT(epnum) && total_bytes != 0) + if (dir == TUSB_DIR_OUT) { - tu_fifo_buffer_info_t info; - uint32_t udd_dma_ctrl_lin = DEVDMACONTROL_CHANN_ENB; - uint32_t udd_dma_ctrl_wrap = DEVDMACONTROL_CHANN_ENB | DEVDMACONTROL_END_BUFFIT; - if (dir == TUSB_DIR_OUT) - { - tu_fifo_get_write_info(ff, &info); - udd_dma_ctrl_lin |= DEVDMACONTROL_END_TR_IT | DEVDMACONTROL_END_TR_EN; - udd_dma_ctrl_wrap |= DEVDMACONTROL_END_TR_IT | DEVDMACONTROL_END_TR_EN; - } else { - tu_fifo_get_read_info(ff, &info); - if(info.wrapped.len == 0) - { - udd_dma_ctrl_lin |= DEVDMACONTROL_END_B_EN; - } - udd_dma_ctrl_wrap |= DEVDMACONTROL_END_B_EN; - } - - // Clean invalidate cache of linear part - CleanInValidateCache((uint32_t*) tu_align((uint32_t) info.linear.ptr, 4), info.linear.len + 31); - - USB_REG->DEVDMA[epnum - 1].DEVDMAADDRESS = (uint32_t)info.linear.ptr; - if (info.wrapped.len) - { - // Clean invalidate cache of wrapped part - CleanInValidateCache((uint32_t*) tu_align((uint32_t) info.wrapped.ptr, 4), info.wrapped.len + 31); - - dma_desc[epnum - 1].next_desc = 0; - dma_desc[epnum - 1].buff_addr = (uint32_t)info.wrapped.ptr; - dma_desc[epnum - 1].chnl_ctrl = - udd_dma_ctrl_wrap | (info.wrapped.len << DEVDMACONTROL_BUFF_LENGTH_Pos); - // Clean cache of wrapped DMA descriptor - CleanInValidateCache((uint32_t*)&dma_desc[epnum - 1], sizeof(dma_desc_t)); - - udd_dma_ctrl_lin |= DEVDMASTATUS_DESC_LDST; - USB_REG->DEVDMA[epnum - 1].DEVDMANXTDSC = (uint32_t)&dma_desc[epnum - 1]; - } else { - udd_dma_ctrl_lin |= DEVDMACONTROL_END_BUFFIT; - } - udd_dma_ctrl_lin |= (info.linear.len << DEVDMACONTROL_BUFF_LENGTH_Pos); - // Disable IRQs to have a short sequence - // between read of EOT_STA and DMA enable - uint32_t irq_state = __get_PRIMASK(); - __disable_irq(); - if (!(USB_REG->DEVDMA[epnum - 1].DEVDMASTATUS & DEVDMASTATUS_END_TR_ST)) - { - USB_REG->DEVDMA[epnum - 1].DEVDMACONTROL = udd_dma_ctrl_lin; - USB_REG->DEVIER = DEVIER_DMA_1 << (epnum - 1); - __set_PRIMASK(irq_state); - return true; - } - __set_PRIMASK(irq_state); - - // Here a ZLP has been received - // and the DMA transfer must be not started. - // It is the end of transfer - return false; + USB_REG->DEVEPTIER[epnum] = DEVEPTIER_RXOUTES; } else { - if (dir == TUSB_DIR_OUT) - { - USB_REG->DEVEPTIER[epnum] = DEVEPTIER_RXOUTES; - } else - { - dcd_transmit_packet(xfer,epnum); - } + dcd_transmit_packet(xfer,epnum); } return true; } -- cgit v1.3.1 From 84f214d33cf4f1cb2c8a6cf485d135ac2347c24b Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 27 Feb 2026 11:34:55 +0100 Subject: dcd/samx7x: reformat code Signed-off-by: HiFiPhile --- src/portable/microchip/samx7x/dcd_samx7x.c | 568 ++++++++++++----------------- 1 file changed, 236 insertions(+), 332 deletions(-) (limited to 'src') diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c index c1cc95d8c..8dd333e0f 100644 --- a/src/portable/microchip/samx7x/dcd_samx7x.c +++ b/src/portable/microchip/samx7x/dcd_samx7x.c @@ -1,134 +1,125 @@ /* -* The MIT License (MIT) -* -* Copyright (c) 2018, hathach (tinyusb.org) -* Copyright (c) 2021, HiFiPhile -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -* -* This file is part of the TinyUSB stack. -*/ + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (tinyusb.org) + * Copyright (c) 2021, HiFiPhile + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ #include "tusb_option.h" #if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_SAMX7X -#include "device/dcd.h" -#include "sam.h" -#include "samx7x_common.h" -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ - -// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) -// We disable SOF for now until needed later on -#ifndef USE_SOF -# define USE_SOF 0 -#endif - -// Dual bank can improve performance, but need 2 times bigger packet buffer -// As SAM7x has only 4KB packet buffer, use with caution ! -// Enable in FS mode as packets are smaller -#ifndef USE_DUAL_BANK -# if TUD_OPT_HIGH_SPEED -# define USE_DUAL_BANK 0 -# else -# define USE_DUAL_BANK 1 -# endif -#endif - -#define EP_GET_FIFO_PTR(ep, scale) (((TU_XSTRCAT(TU_STRCAT(uint, scale),_t) (*)[0x8000 / ((scale) / 8)])FIFO_RAM_ADDR)[(ep)]) + #include "device/dcd.h" + #include "sam.h" + #include "samx7x_common.h" + //--------------------------------------------------------------------+ + // MACRO TYPEDEF CONSTANT ENUM DECLARATION + //--------------------------------------------------------------------+ + + // Dual bank can improve performance, but need 2 times bigger packet buffer + // As SAM7x has only 4KB packet buffer, use with caution ! + // Enable in FS mode as packets are smaller + #ifndef USE_DUAL_BANK + #if TUD_OPT_HIGH_SPEED + #define USE_DUAL_BANK 0 + #else + #define USE_DUAL_BANK 1 + #endif + #endif + + #define EP_GET_FIFO_PTR(ep, scale) \ + (((TU_XSTRCAT(TU_STRCAT(uint, scale), _t)(*)[0x8000 / ((scale) / 8)]) FIFO_RAM_ADDR)[(ep)]) // DMA Channel Transfer Descriptor typedef struct { volatile uint32_t next_desc; volatile uint32_t buff_addr; volatile uint32_t chnl_ctrl; - uint32_t padding; + uint32_t padding; } dma_desc_t; // Transfer control context typedef struct { - uint8_t * buffer; - uint16_t total_len; - uint16_t queued_len; - uint16_t max_packet_size; - uint8_t interval; - tu_fifo_t * fifo; + uint8_t *buffer; + uint16_t total_len; + uint16_t queued_len; + uint16_t max_packet_size; + uint8_t interval; + tu_fifo_t *fifo; } xfer_ctl_t; static tusb_speed_t get_speed(void); -static void dcd_transmit_packet(xfer_ctl_t * xfer, uint8_t ep_ix); +static void dcd_transmit_packet(xfer_ctl_t *xfer, uint8_t ep_ix); static xfer_ctl_t xfer_status[EP_MAX]; -static const tusb_desc_endpoint_t ep0_desc = -{ +static const tusb_desc_endpoint_t ep0_desc = { .bEndpointAddress = 0x00, .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, }; -#if CFG_TUD_MEM_DCACHE_ENABLE -bool dcd_dcache_clean(const void* addr, uint32_t data_size) { + #if CFG_TUD_MEM_DCACHE_ENABLE +bool dcd_dcache_clean(const void *addr, uint32_t data_size) { TU_VERIFY(addr && data_size); return samx7x_dcache_clean(addr, data_size); } -bool dcd_dcache_invalidate(const void* addr, uint32_t data_size) { +bool dcd_dcache_invalidate(const void *addr, uint32_t data_size) { TU_VERIFY(addr && data_size); return samx7x_dcache_invalidate(addr, data_size); } -bool dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size) { +bool dcd_dcache_clean_invalidate(const void *addr, uint32_t data_size) { TU_VERIFY(addr && data_size); return samx7x_dcache_clean_invalidate(addr, data_size); } -#endif + #endif //------------------------------------------------------------------ // Device API //------------------------------------------------------------------ // Initialize controller to device mode -bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { - (void) rh_init; +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { + (void)rh_init; dcd_connect(rhport); return true; } // Enable device interrupt -void dcd_int_enable (uint8_t rhport) -{ - (void) rhport; - NVIC_EnableIRQ((IRQn_Type) ID_USBHS); +void dcd_int_enable(uint8_t rhport) { + (void)rhport; + NVIC_EnableIRQ((IRQn_Type)ID_USBHS); } // Disable device interrupt -void dcd_int_disable (uint8_t rhport) -{ - (void) rhport; - NVIC_DisableIRQ((IRQn_Type) ID_USBHS); +void dcd_int_disable(uint8_t rhport) { + (void)rhport; + NVIC_DisableIRQ((IRQn_Type)ID_USBHS); } // Receive Set Address request, mcu port must also include status IN response -void dcd_set_address (uint8_t rhport, uint8_t dev_addr) -{ - (void) dev_addr; +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { + (void)dev_addr; // DCD can only set address after status for this request is complete // do it at dcd_edpt0_status_complete() @@ -137,30 +128,26 @@ void dcd_set_address (uint8_t rhport, uint8_t dev_addr) } // Wake up host -void dcd_remote_wakeup (uint8_t rhport) -{ - (void) rhport; +void dcd_remote_wakeup(uint8_t rhport) { + (void)rhport; USB_REG->DEVCTRL |= DEVCTRL_RMWKUP; } // Connect by enabling internal pull-up resistor on D+/D- -void dcd_connect(uint8_t rhport) -{ - (void) rhport; +void dcd_connect(uint8_t rhport) { + (void)rhport; dcd_int_disable(rhport); // Enable the USB controller in device mode USB_REG->CTRL = CTRL_UIMOD | CTRL_USBE; - while (!(USB_REG->SR & SR_CLKUSABLE)); -#if TUD_OPT_HIGH_SPEED + while (!(USB_REG->SR & SR_CLKUSABLE)) + ; + #if TUD_OPT_HIGH_SPEED USB_REG->DEVCTRL &= ~DEVCTRL_SPDCONF; -#else + #else USB_REG->DEVCTRL |= DEVCTRL_SPDCONF_LOW_POWER; -#endif + #endif // Enable the End Of Reset, Suspend & Wakeup interrupts USB_REG->DEVIER = (DEVIER_EORSTES | DEVIER_SUSPES | DEVIER_WAKEUPES); -#if USE_SOF - USB_REG->DEVIER = DEVIER_SOFES; -#endif // Clear the End Of Reset, SOF & Wakeup interrupts USB_REG->DEVICR = (DEVICR_EORSTC | DEVICR_SOFC | DEVICR_WAKEUPC); // Manually set the Suspend Interrupt @@ -174,15 +161,15 @@ void dcd_connect(uint8_t rhport) } // Disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(uint8_t rhport) -{ - (void) rhport; +void dcd_disconnect(uint8_t rhport) { + (void)rhport; dcd_int_disable(rhport); // Disable all endpoints USB_REG->DEVEPT &= ~(0x3FF << DEVEPT_EPEN0_Pos); // Unfreeze USB clock USB_REG->CTRL &= ~CTRL_FRZCLK; - while (!(USB_REG->SR & SR_CLKUSABLE)); + while (!(USB_REG->SR & SR_CLKUSABLE)) + ; // Clear all the pending interrupts USB_REG->DEVICR = DEVICR_Msk; // Disable all interrupts @@ -190,124 +177,103 @@ void dcd_disconnect(uint8_t rhport) // Detach the device USB_REG->DEVCTRL |= DEVCTRL_DETACH; // Disable the device address - USB_REG->DEVCTRL &=~(DEVCTRL_ADDEN | DEVCTRL_UADD); + USB_REG->DEVCTRL &= ~(DEVCTRL_ADDEN | DEVCTRL_UADD); } -void dcd_sof_enable(uint8_t rhport, bool en) -{ - (void) rhport; - (void) en; - - // TODO implement later +void dcd_sof_enable(uint8_t rhport, bool en) { + (void)rhport; + if (en) { + USB_REG->DEVIER = DEVIER_SOFES; + } else { + USB_REG->DEVIDR = DEVIDR_SOFEC; + } } -static tusb_speed_t get_speed(void) -{ +static tusb_speed_t get_speed(void) { switch (USB_REG->SR & SR_SPEED) { - case SR_SPEED_FULL_SPEED: - default: - return TUSB_SPEED_FULL; - case SR_SPEED_HIGH_SPEED: - return TUSB_SPEED_HIGH; - case SR_SPEED_LOW_SPEED: - return TUSB_SPEED_LOW; + case SR_SPEED_FULL_SPEED: + default: + return TUSB_SPEED_FULL; + case SR_SPEED_HIGH_SPEED: + return TUSB_SPEED_HIGH; + case SR_SPEED_LOW_SPEED: + return TUSB_SPEED_LOW; } } -static void dcd_ep_handler(uint8_t ep_ix) -{ +static void dcd_ep_handler(uint8_t ep_ix) { uint32_t int_status = USB_REG->DEVEPTISR[ep_ix]; int_status &= USB_REG->DEVEPTIMR[ep_ix]; - uint16_t count = (USB_REG->DEVEPTISR[ep_ix] & - DEVEPTISR_BYCT) >> DEVEPTISR_BYCT_Pos; - xfer_ctl_t *xfer = &xfer_status[ep_ix]; + uint16_t count = (USB_REG->DEVEPTISR[ep_ix] & DEVEPTISR_BYCT) >> DEVEPTISR_BYCT_Pos; + xfer_ctl_t *xfer = &xfer_status[ep_ix]; - if (ep_ix == 0U) - { + if (ep_ix == 0U) { static uint8_t ctrl_dir; - if (int_status & DEVEPTISR_CTRL_RXSTPI) - { + if (int_status & DEVEPTISR_CTRL_RXSTPI) { ctrl_dir = (USB_REG->DEVEPTISR[0] & DEVEPTISR_CTRL_CTRLDIR) >> DEVEPTISR_CTRL_CTRLDIR_Pos; // Setup packet should always be 8 bytes. If not, ignore it, and try again. - if (count == 8) - { - uint8_t *ptr = EP_GET_FIFO_PTR(0,8); + if (count == 8) { + uint8_t *ptr = EP_GET_FIFO_PTR(0, 8); dcd_event_setup_received(0, ptr, true); } // Ack and disable SETUP interrupt USB_REG->DEVEPTICR[0] = DEVEPTICR_CTRL_RXSTPIC; USB_REG->DEVEPTIDR[0] = DEVEPTIDR_CTRL_RXSTPEC; } - if (int_status & DEVEPTISR_RXOUTI) - { - uint8_t *ptr = EP_GET_FIFO_PTR(0,8); + if (int_status & DEVEPTISR_RXOUTI) { + uint8_t *ptr = EP_GET_FIFO_PTR(0, 8); - if (count && xfer->total_len) - { + if (count && xfer->total_len) { uint16_t remain = xfer->total_len - xfer->queued_len; - if (count > remain) - { + if (count > remain) { count = remain; } - if (xfer->buffer) - { + if (xfer->buffer) { memcpy(xfer->buffer + xfer->queued_len, ptr, count); - } else - { + } else { tu_hwfifo_read_to_fifo(ptr, xfer->fifo, count, NULL); } xfer->queued_len = (uint16_t)(xfer->queued_len + count); } // Acknowledge the interrupt USB_REG->DEVEPTICR[0] = DEVEPTICR_RXOUTIC; - if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) - { + if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { // RX COMPLETE dcd_event_xfer_complete(0, 0, xfer->queued_len, XFER_RESULT_SUCCESS, true); // Disable the interrupt USB_REG->DEVEPTIDR[0] = DEVEPTIDR_RXOUTEC; // Re-enable SETUP interrupt - if (ctrl_dir == 1) - { + if (ctrl_dir == 1) { USB_REG->DEVEPTIER[0] = DEVEPTIER_CTRL_RXSTPES; } } } - if (int_status & DEVEPTISR_TXINI) - { + if (int_status & DEVEPTISR_TXINI) { // Disable the interrupt USB_REG->DEVEPTIDR[0] = DEVEPTIDR_TXINEC; - if ((xfer->total_len != xfer->queued_len)) - { + if ((xfer->total_len != xfer->queued_len)) { // TX not complete dcd_transmit_packet(xfer, 0); - } else - { + } else { // TX complete dcd_event_xfer_complete(0, 0x80 + 0, xfer->total_len, XFER_RESULT_SUCCESS, true); // Re-enable SETUP interrupt - if (ctrl_dir == 0) - { + if (ctrl_dir == 0) { USB_REG->DEVEPTIER[0] = DEVEPTIER_CTRL_RXSTPES; } } } - } else - { - if (int_status & DEVEPTISR_RXOUTI) - { - if (count && xfer->total_len) - { + } else { + if (int_status & DEVEPTISR_RXOUTI) { + if (count && xfer->total_len) { uint16_t remain = xfer->total_len - xfer->queued_len; - if (count > remain) - { + if (count > remain) { count = remain; } - uint8_t *ptr = EP_GET_FIFO_PTR(ep_ix,8); - if (xfer->buffer) - { + uint8_t *ptr = EP_GET_FIFO_PTR(ep_ix, 8); + if (xfer->buffer) { memcpy(xfer->buffer + xfer->queued_len, ptr, count); } else { tu_hwfifo_read_to_fifo(ptr, xfer->fifo, count, NULL); @@ -318,8 +284,7 @@ static void dcd_ep_handler(uint8_t ep_ix) USB_REG->DEVEPTIDR[ep_ix] = DEVEPTIDR_FIFOCONC; // Acknowledge the interrupt USB_REG->DEVEPTICR[ep_ix] = DEVEPTICR_RXOUTIC; - if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) - { + if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { // RX COMPLETE dcd_event_xfer_complete(0, ep_ix, xfer->queued_len, XFER_RESULT_SUCCESS, true); // Disable the interrupt @@ -327,16 +292,13 @@ static void dcd_ep_handler(uint8_t ep_ix) // Though the host could still send, we don't know. } } - if (int_status & DEVEPTISR_TXINI) - { + if (int_status & DEVEPTISR_TXINI) { // Acknowledge the interrupt USB_REG->DEVEPTICR[ep_ix] = DEVEPTICR_TXINIC; - if ((xfer->total_len != xfer->queued_len)) - { + if ((xfer->total_len != xfer->queued_len)) { // TX not complete dcd_transmit_packet(xfer, ep_ix); - } else - { + } else { // TX complete dcd_event_xfer_complete(0, 0x80 + ep_ix, xfer->total_len, XFER_RESULT_SUCCESS, true); // Disable the interrupt @@ -346,46 +308,40 @@ static void dcd_ep_handler(uint8_t ep_ix) } } -static void dcd_dma_handler(uint8_t ep_ix) -{ +static void dcd_dma_handler(uint8_t ep_ix) { uint32_t status = USB_REG->DEVDMA[ep_ix - 1].DEVDMASTATUS; - if (status & DEVDMASTATUS_CHANN_ENB) - { + if (status & DEVDMASTATUS_CHANN_ENB) { return; // Ignore EOT_STA interrupt } // Disable DMA interrupt USB_REG->DEVIDR = DEVIDR_DMA_1 << (ep_ix - 1); - xfer_ctl_t *xfer = &xfer_status[ep_ix]; - uint16_t count = xfer->total_len - ((status & DEVDMASTATUS_BUFF_COUNT) >> DEVDMASTATUS_BUFF_COUNT_Pos); - if(USB_REG->DEVEPTCFG[ep_ix] & DEVEPTCFG_EPDIR) - { + xfer_ctl_t *xfer = &xfer_status[ep_ix]; + uint16_t count = xfer->total_len - ((status & DEVDMASTATUS_BUFF_COUNT) >> DEVDMASTATUS_BUFF_COUNT_Pos); + if (USB_REG->DEVEPTCFG[ep_ix] & DEVEPTCFG_EPDIR) { dcd_event_xfer_complete(0, 0x80 + ep_ix, count, XFER_RESULT_SUCCESS, true); - } else - { + } else { dcd_dcache_invalidate(xfer->buffer, xfer->total_len); dcd_event_xfer_complete(0, ep_ix, count, XFER_RESULT_SUCCESS, true); } } -void dcd_int_handler(uint8_t rhport) -{ - (void) rhport; +void dcd_int_handler(uint8_t rhport) { + (void)rhport; uint32_t int_status = USB_REG->DEVISR; int_status &= USB_REG->DEVIMR; // End of reset interrupt - if (int_status & DEVISR_EORST) - { + if (int_status & DEVISR_EORST) { // Unfreeze USB clock USB_REG->CTRL &= ~CTRL_FRZCLK; - while(!(USB_REG->SR & SR_CLKUSABLE)); + while (!(USB_REG->SR & SR_CLKUSABLE)) + ; // Reset all endpoints - for (int ep_ix = 1; ep_ix < EP_MAX; ep_ix++) - { + for (int ep_ix = 1; ep_ix < EP_MAX; ep_ix++) { USB_REG->DEVEPT |= 1 << (DEVEPT_EPRST0_Pos + ep_ix); - USB_REG->DEVEPT &=~(1 << (DEVEPT_EPRST0_Pos + ep_ix)); + USB_REG->DEVEPT &= ~(1 << (DEVEPT_EPRST0_Pos + ep_ix)); } - dcd_edpt_open (0, &ep0_desc); + dcd_edpt_open(0, &ep0_desc); USB_REG->DEVICR = DEVICR_EORSTC; USB_REG->DEVICR = DEVICR_WAKEUPC; USB_REG->DEVICR = DEVICR_SUSPC; @@ -394,10 +350,10 @@ void dcd_int_handler(uint8_t rhport) dcd_event_bus_reset(rhport, get_speed(), true); } // End of Wakeup interrupt - if (int_status & DEVISR_WAKEUP) - { + if (int_status & DEVISR_WAKEUP) { USB_REG->CTRL &= ~CTRL_FRZCLK; - while (!(USB_REG->SR & SR_CLKUSABLE)); + while (!(USB_REG->SR & SR_CLKUSABLE)) + ; USB_REG->DEVICR = DEVICR_WAKEUPC; USB_REG->DEVIDR = DEVIDR_WAKEUPEC; USB_REG->DEVIER = DEVIER_SUSPES; @@ -405,11 +361,11 @@ void dcd_int_handler(uint8_t rhport) dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } // Suspend interrupt - if (int_status & DEVISR_SUSP) - { + if (int_status & DEVISR_SUSP) { // Unfreeze USB clock USB_REG->CTRL &= ~CTRL_FRZCLK; - while (!(USB_REG->SR & SR_CLKUSABLE)); + while (!(USB_REG->SR & SR_CLKUSABLE)) + ; USB_REG->DEVICR = DEVICR_SUSPC; USB_REG->DEVIDR = DEVIDR_SUSPEC; USB_REG->DEVIER = DEVIER_WAKEUPES; @@ -417,29 +373,21 @@ void dcd_int_handler(uint8_t rhport) dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } -#if USE_SOF - if(int_status & DEVISR_SOF) - { + if (int_status & DEVISR_SOF) { USB_REG->DEVICR = DEVICR_SOFC; dcd_event_bus_signal(0, DCD_EVENT_SOF, true); } -#endif // Endpoints interrupt - for (int ep_ix = 0; ep_ix < EP_MAX; ep_ix++) - { - if (int_status & (DEVISR_PEP_0 << ep_ix)) - { + for (int ep_ix = 0; ep_ix < EP_MAX; ep_ix++) { + if (int_status & (DEVISR_PEP_0 << ep_ix)) { dcd_ep_handler(ep_ix); } } // Endpoints DMA interrupt - for (int ep_ix = 0; ep_ix < EP_MAX; ep_ix++) - { - if (EP_DMA_SUPPORT(ep_ix)) - { - if (int_status & (DEVISR_DMA_1 << (ep_ix - 1))) - { + for (int ep_ix = 0; ep_ix < EP_MAX; ep_ix++) { + if (EP_DMA_SUPPORT(ep_ix)) { + if (int_status & (DEVISR_DMA_1 << (ep_ix - 1))) { dcd_dma_handler(ep_ix); } } @@ -451,35 +399,29 @@ void dcd_int_handler(uint8_t rhport) //--------------------------------------------------------------------+ // Invoked when a control transfer's status stage is complete. // May help DCD to prepare for next control transfer, this API is optional. -void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) -{ - (void) rhport; +void dcd_edpt0_status_complete(uint8_t rhport, const tusb_control_request_t *request) { + (void)rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && - request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && - request->bRequest == TUSB_REQ_SET_ADDRESS ) - { - uint8_t const dev_addr = (uint8_t) request->wValue; + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) { + const uint8_t dev_addr = (uint8_t)request->wValue; USB_REG->DEVCTRL |= dev_addr | DEVCTRL_ADDEN; } } // Configure endpoint's registers according to descriptor -bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) -{ - (void) rhport; - uint8_t const epnum = tu_edpt_number(ep_desc->bEndpointAddress); - uint8_t const dir = tu_edpt_dir(ep_desc->bEndpointAddress); - uint16_t const epMaxPktSize = tu_edpt_packet_size(ep_desc); - tusb_xfer_type_t const eptype = (tusb_xfer_type_t)ep_desc->bmAttributes.xfer; - uint8_t fifoSize = 0; // FIFO size - uint16_t defaultEndpointSize = 8; // Default size of Endpoint +bool dcd_edpt_open(uint8_t rhport, const tusb_desc_endpoint_t *ep_desc) { + (void)rhport; + const uint8_t epnum = tu_edpt_number(ep_desc->bEndpointAddress); + const uint8_t dir = tu_edpt_dir(ep_desc->bEndpointAddress); + const uint16_t epMaxPktSize = tu_edpt_packet_size(ep_desc); + const tusb_xfer_type_t eptype = (tusb_xfer_type_t)ep_desc->bmAttributes.xfer; + uint8_t fifoSize = 0; // FIFO size + uint16_t defaultEndpointSize = 8; // Default size of Endpoint // Find upper 2 power number of epMaxPktSize - if (epMaxPktSize) - { - while (defaultEndpointSize < epMaxPktSize) - { + if (epMaxPktSize) { + while (defaultEndpointSize < epMaxPktSize) { fifoSize++; defaultEndpointSize <<= 1; } @@ -487,121 +429,94 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) xfer_status[epnum].max_packet_size = epMaxPktSize; USB_REG->DEVEPT |= 1 << (DEVEPT_EPRST0_Pos + epnum); - USB_REG->DEVEPT &=~(1 << (DEVEPT_EPRST0_Pos + epnum)); + USB_REG->DEVEPT &= ~(1 << (DEVEPT_EPRST0_Pos + epnum)); - if (epnum == 0) - { + if (epnum == 0) { // Enable the control endpoint - Endpoint 0 USB_REG->DEVEPT |= DEVEPT_EPEN0; // Configure the Endpoint 0 configuration register - USB_REG->DEVEPTCFG[0] = - ( - (fifoSize << DEVEPTCFG_EPSIZE_Pos) | - (TUSB_XFER_CONTROL << DEVEPTCFG_EPTYPE_Pos) | - (DEVEPTCFG_EPBK_1_BANK << DEVEPTCFG_EPBK_Pos) | - DEVEPTCFG_ALLOC - ); + USB_REG->DEVEPTCFG[0] = ((fifoSize << DEVEPTCFG_EPSIZE_Pos) | (TUSB_XFER_CONTROL << DEVEPTCFG_EPTYPE_Pos) | + (DEVEPTCFG_EPBK_1_BANK << DEVEPTCFG_EPBK_Pos) | DEVEPTCFG_ALLOC); USB_REG->DEVEPTIER[0] = DEVEPTIER_RSTDTS; USB_REG->DEVEPTIDR[0] = DEVEPTIDR_CTRL_STALLRQC; - if (DEVEPTISR_CFGOK == (USB_REG->DEVEPTISR[0] & DEVEPTISR_CFGOK)) - { + if (DEVEPTISR_CFGOK == (USB_REG->DEVEPTISR[0] & DEVEPTISR_CFGOK)) { // Endpoint configuration is successful USB_REG->DEVEPTIER[0] = DEVEPTIER_CTRL_RXSTPES; // Enable Endpoint 0 Interrupts USB_REG->DEVIER = DEVIER_PEP_0; return true; - } else - { + } else { // Endpoint configuration is not successful return false; } - } else - { + } else { // Enable the endpoint USB_REG->DEVEPT |= ((0x01 << epnum) << DEVEPT_EPEN0_Pos); // Set up the maxpacket size, fifo start address fifosize // and enable the interrupt. CLear the data toggle. // AUTOSW is needed for DMA ack ! USB_REG->DEVEPTCFG[epnum] = - ( - (fifoSize << DEVEPTCFG_EPSIZE_Pos) | - (eptype << DEVEPTCFG_EPTYPE_Pos) | - (DEVEPTCFG_EPBK_1_BANK << DEVEPTCFG_EPBK_Pos) | - DEVEPTCFG_AUTOSW | - ((dir & 0x01) << DEVEPTCFG_EPDIR_Pos) - ); - if (eptype == TUSB_XFER_ISOCHRONOUS) - { + ((fifoSize << DEVEPTCFG_EPSIZE_Pos) | (eptype << DEVEPTCFG_EPTYPE_Pos) | + (DEVEPTCFG_EPBK_1_BANK << DEVEPTCFG_EPBK_Pos) | DEVEPTCFG_AUTOSW | ((dir & 0x01) << DEVEPTCFG_EPDIR_Pos)); + if (eptype == TUSB_XFER_ISOCHRONOUS) { USB_REG->DEVEPTCFG[epnum] |= DEVEPTCFG_NBTRANS_1_TRANS; } -#if USE_DUAL_BANK - if (eptype == TUSB_XFER_ISOCHRONOUS || eptype == TUSB_XFER_BULK) - { + #if USE_DUAL_BANK + if (eptype == TUSB_XFER_ISOCHRONOUS || eptype == TUSB_XFER_BULK) { USB_REG->DEVEPTCFG[epnum] |= DEVEPTCFG_EPBK_2_BANK; } -#endif + #endif USB_REG->DEVEPTCFG[epnum] |= DEVEPTCFG_ALLOC; USB_REG->DEVEPTIER[epnum] = DEVEPTIER_RSTDTS; USB_REG->DEVEPTIDR[epnum] = DEVEPTIDR_CTRL_STALLRQC; - if (DEVEPTISR_CFGOK == (USB_REG->DEVEPTISR[epnum] & DEVEPTISR_CFGOK)) - { + if (DEVEPTISR_CFGOK == (USB_REG->DEVEPTISR[epnum] & DEVEPTISR_CFGOK)) { USB_REG->DEVIER = ((0x01 << epnum) << DEVIER_PEP_0_Pos); return true; - } else - { + } else { // Endpoint configuration is not successful return false; } } } -void dcd_edpt_close_all (uint8_t rhport) -{ - (void) rhport; +void dcd_edpt_close_all(uint8_t rhport) { + (void)rhport; // TODO implement dcd_edpt_close_all() } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { - (void) rhport; - (void) ep_addr; - (void) largest_packet_size; + (void)rhport; + (void)ep_addr; + (void)largest_packet_size; return false; } -bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { - (void) rhport; - (void) desc_ep; +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { + (void)rhport; + (void)desc_ep; return false; } -static void dcd_transmit_packet(xfer_ctl_t * xfer, uint8_t ep_ix) -{ +static void dcd_transmit_packet(xfer_ctl_t *xfer, uint8_t ep_ix) { uint16_t len = (uint16_t)(xfer->total_len - xfer->queued_len); - if (len) - { - if (len > xfer->max_packet_size) - { + if (len) { + if (len > xfer->max_packet_size) { len = xfer->max_packet_size; } - uint8_t *ptr = EP_GET_FIFO_PTR(ep_ix,8); - if(xfer->buffer) - { + uint8_t *ptr = EP_GET_FIFO_PTR(ep_ix, 8); + if (xfer->buffer) { memcpy(ptr, xfer->buffer + xfer->queued_len, len); - } - else - { + } else { tu_hwfifo_write_from_fifo(ptr, xfer->fifo, len, NULL); } __DSB(); __ISB(); xfer->queued_len = (uint16_t)(xfer->queued_len + len); } - if (ep_ix == 0U) - { + if (ep_ix == 0U) { // Control endpoint: clear the interrupt flag to send the data USB_REG->DEVEPTICR[0] = DEVEPTICR_TXINIC; - } else - { + } else { // Other endpoint types: clear the FIFO control flag to send the data USB_REG->DEVEPTIDR[ep_ix] = DEVEPTIDR_FIFOCONC; } @@ -609,25 +524,22 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint8_t ep_ix) } // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) -{ - (void) is_isr; - (void) rhport; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes, bool is_isr) { + (void)is_isr; + (void)rhport; + const uint8_t epnum = tu_edpt_number(ep_addr); + const uint8_t dir = tu_edpt_dir(ep_addr); - xfer_ctl_t * xfer = &xfer_status[epnum]; + xfer_ctl_t *xfer = &xfer_status[epnum]; - xfer->buffer = buffer; - xfer->total_len = total_bytes; + xfer->buffer = buffer; + xfer->total_len = total_bytes; xfer->queued_len = 0; - xfer->fifo = NULL; + xfer->fifo = NULL; - if (EP_DMA_SUPPORT(epnum) && total_bytes != 0) - { + if (EP_DMA_SUPPORT(epnum) && total_bytes != 0) { uint32_t udd_dma_ctrl = total_bytes << DEVDMACONTROL_BUFF_LENGTH_Pos; - if (dir == TUSB_DIR_OUT) - { + if (dir == TUSB_DIR_OUT) { udd_dma_ctrl |= DEVDMACONTROL_END_TR_IT | DEVDMACONTROL_END_TR_EN; } else { udd_dma_ctrl |= DEVDMACONTROL_END_B_EN; @@ -636,15 +548,12 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t USB_REG->DEVDMA[epnum - 1].DEVDMAADDRESS = (uint32_t)buffer; udd_dma_ctrl |= DEVDMACONTROL_END_BUFFIT | DEVDMACONTROL_CHANN_ENB; USB_REG->DEVDMA[epnum - 1].DEVDMACONTROL = udd_dma_ctrl; - USB_REG->DEVIER = DEVIER_DMA_1 << (epnum - 1); - } else - { - if (dir == TUSB_DIR_OUT) - { + USB_REG->DEVIER = DEVIER_DMA_1 << (epnum - 1); + } else { + if (dir == TUSB_DIR_OUT) { USB_REG->DEVEPTIER[epnum] = DEVEPTIER_RXOUTES; - } else - { - dcd_transmit_packet(xfer,epnum); + } else { + dcd_transmit_packet(xfer, epnum); } } return true; @@ -654,50 +563,45 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t // bytes should be written and second to keep the return value free to give back a boolean // success message. If total_bytes is too big, the FIFO will copy only what is available // into the USB buffer! -bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr) -{ - (void) is_isr; - (void) rhport; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - xfer_ctl_t * xfer = &xfer_status[epnum]; - if(epnum == 0x80) +bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes, bool is_isr) { + (void)is_isr; + (void)rhport; + const uint8_t epnum = tu_edpt_number(ep_addr); + const uint8_t dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t *xfer = &xfer_status[epnum]; + if (epnum == 0x80) { xfer = &xfer_status[EP_MAX]; + } - xfer->buffer = NULL; - xfer->total_len = total_bytes; + xfer->buffer = NULL; + xfer->total_len = total_bytes; xfer->queued_len = 0; - xfer->fifo = ff; + xfer->fifo = ff; - if (dir == TUSB_DIR_OUT) - { + if (dir == TUSB_DIR_OUT) { USB_REG->DEVEPTIER[epnum] = DEVEPTIER_RXOUTES; - } else - { - dcd_transmit_packet(xfer,epnum); + } else { + dcd_transmit_packet(xfer, epnum); } return true; } // Stall endpoint -void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) -{ - (void) rhport; - uint8_t const epnum = tu_edpt_number(ep_addr); +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { + (void)rhport; + const uint8_t epnum = tu_edpt_number(ep_addr); USB_REG->DEVEPTIER[epnum] = DEVEPTIER_CTRL_STALLRQS; // Re-enable SETUP interrupt - if (epnum == 0) - { + if (epnum == 0) { USB_REG->DEVEPTIER[0] = DEVEPTIER_CTRL_RXSTPES; } } // clear stall, data toggle is also reset to DATA0 -void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) -{ - (void) rhport; - uint8_t const epnum = tu_edpt_number(ep_addr); +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { + (void)rhport; + const uint8_t epnum = tu_edpt_number(ep_addr); USB_REG->DEVEPTIDR[epnum] = DEVEPTIDR_CTRL_STALLRQC; USB_REG->DEVEPTIER[epnum] = HSTPIPIER_RSTDTS; } -- cgit v1.3.1 From a3fd3071c17bdc7392db1361f3a97019351af337 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 15 Dec 2025 23:01:36 +0100 Subject: Fix IAR warnings Signed-off-by: HiFiPhile --- src/common/tusb_fifo.h | 10 ++++++++++ src/tusb.c | 6 ++++++ 2 files changed, 16 insertions(+) (limited to 'src') diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 86ba59059..a3829e38e 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -289,6 +289,12 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_fifo_empty(const tu_fifo_t *f) { return wr_idx == rd_idx; } +// Suppress IAR warning +// Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement +#if defined(__ICCARM__) +#pragma diag_suppress = Pa082 +#endif + // return number of items in fifo, capped to fifo's depth TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_count(const tu_fifo_t *f) { return tu_min16(tu_ff_overflow_count(f->depth, f->wr_idx, f->rd_idx), f->depth); @@ -303,6 +309,10 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_remaining(const tu_fifo_t * return tu_ff_remaining_local(f->depth, f->wr_idx, f->rd_idx); } +#if defined(__ICCARM__) + #pragma diag_default=Pa082 +#endif + #ifdef __cplusplus } #endif diff --git a/src/tusb.c b/src/tusb.c index ed254a10b..803803ca2 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -39,6 +39,12 @@ #include "host/usbh_pvt.h" #endif +// Suppress IAR warning +// Warning[Pe111]: statement is unreachable +#if defined(__ICCARM__) +#pragma diag_suppress = Pe111 +#endif + tusb_role_t _tusb_rhport_role[TUP_USBIP_CONTROLLER_NUM] = { TUSB_ROLE_INVALID }; //-------------------------------------------------------------------- -- cgit v1.3.1 From 22acfb62672b4eae27f8d6db49ac205a38c18f9e Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 27 Feb 2026 11:53:02 +0100 Subject: cleanup Signed-off-by: HiFiPhile --- src/portable/synopsys/dwc2/hcd_dwc2.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index 1bdab6a45..420b3fe4b 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -416,11 +416,6 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { // force host mode and wait for mode switch dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_FDMOD) | GUSBCFG_FHMOD; - #if CFG_TUSB_MCU == OPT_MCU_STM32N6 - // No hardware detection of Vbus B-session is available on the STM32N6 - dwc2->stm32_gccfg &= ~STM32_GCCFG_VBVALOVAL; - #endif - while ((dwc2->gintsts & GINTSTS_CMOD) != GINTSTS_CMODE_HOST) {} #ifdef TUP_USBIP_DWC2_STM32 -- cgit v1.3.1 From 66c4d470eb70b781f0ebdd995aadf44633ce95a4 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 Feb 2026 22:39:42 +0700 Subject: add back deferred attachment queue, retry get hub port status if reset change not set after 20ms --- src/host/hcd.h | 3 +- src/host/usbh.c | 117 ++++++++++++++++++++++++++++++++++++--------------- src/osal/osal_none.h | 4 +- 3 files changed, 86 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/host/hcd.h b/src/host/hcd.h index 36a7f5da5..47d672f9e 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -59,7 +59,7 @@ typedef enum { HCD_EVENT_XFER_COMPLETE, USBH_EVENT_FUNC_CALL, // Not an HCD event - HCD_EVENT_COUNT + HCD_EVENT_INVALID } hcd_eventid_t; typedef struct { @@ -72,7 +72,6 @@ typedef struct { struct { uint8_t hub_addr; uint8_t hub_port; - uint8_t speed; } connection; // XFER_COMPLETE diff --git a/src/host/usbh.c b/src/host/usbh.c index 76269eb2f..60d78605f 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -169,6 +169,12 @@ static OSAL_SPINLOCK_DEF(_usbh_spin, usbh_int_set); OSAL_QUEUE_DEF(usbh_int_set, _usbh_qdef, CFG_TUH_TASK_QUEUE_SZ, hcd_event_t); static osal_queue_t _usbh_q; + #if CFG_TUH_HUB +// Deferred attachment queue, only needed when using hub +OSAL_QUEUE_DEF(usbh_int_set, _usbh_daqdef, CFG_TUH_HUB, hcd_event_t); +static osal_queue_t _usbh_daq; + #endif + // Control transfers: since most controllers do not support multiple control transfers // on multiple devices concurrently and control transfers are not used much except for // enumeration, we will only execute control transfers one at a time. @@ -387,9 +393,6 @@ TU_ATTR_ALWAYS_INLINE static inline void usbh_device_close(uint8_t rhport, uint8 // invalidate if enumerating if (daddr == _usbh_data.enumerating_daddr) { _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8; - #if CFG_TUSB_OS_HAS_SCHEDULER == 0 - _usbh_data.call_after.func = NULL; - #endif } } @@ -523,11 +526,17 @@ bool tuh_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { _usbh_q = osal_queue_create(&_usbh_qdef); TU_ASSERT(_usbh_q != NULL); -#if OSAL_MUTEX_REQUIRED + #if CFG_TUH_HUB + // Deferred attachment queue + _usbh_daq = osal_queue_create(&_usbh_daqdef); + TU_ASSERT(_usbh_daq != NULL); + #endif + + #if OSAL_MUTEX_REQUIRED // Init mutex _usbh_mutex = osal_mutex_create(&_usbh_mutexdef); TU_ASSERT(_usbh_mutex); -#endif + #endif // Get application driver if available _app_driver = usbh_app_driver_get_cb(&_app_driver_count); @@ -588,11 +597,16 @@ bool tuh_deinit(uint8_t rhport) { osal_queue_delete(_usbh_q); _usbh_q = NULL; -#if OSAL_MUTEX_REQUIRED + #if CFG_TUH_HUB + osal_queue_delete(_usbh_daq); + _usbh_daq = NULL; + #endif + + #if OSAL_MUTEX_REQUIRED // TODO make sure there is no task waiting on this mutex osal_mutex_delete(_usbh_mutex); _usbh_mutex = NULL; -#endif + #endif } return true; @@ -600,9 +614,19 @@ bool tuh_deinit(uint8_t rhport) { bool tuh_task_event_ready(void) { if (!tuh_inited()) { - return false; // Skip if stack is not initialized + return false; // Skip if tusb stack is not initialized + } + if (!osal_queue_empty(_usbh_q)) { + return true; } - return !osal_queue_empty(_usbh_q); + + #if CFG_TUH_HUB + if (!osal_queue_empty(_usbh_daq)) { + return true; + } + #endif + + return false; } /* USB Host Driver task @@ -652,12 +676,27 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { #endif hcd_event_t event; - if (!osal_queue_receive(_usbh_q, &event, timeout_ms)) { return; } + + #if CFG_TUH_HUB + // Get deferred device attachments if none is enumerating + bool has_deferred_attach = false; + if (_usbh_data.enumerating_daddr == TUSB_INDEX_INVALID_8) { + // zero wait to avoid blocking the main event queue + has_deferred_attach = osal_queue_receive(_usbh_daq, &event, 0); + } + + if (!has_deferred_attach) // skip event queue to process deferred at + #endif + { + if (!osal_queue_receive(_usbh_q, &event, timeout_ms)) { + return; + } + } switch (event.event_id) { case HCD_EVENT_DEVICE_ATTACH: // Should we miss the hub detach event due to high traffic, Or due to physical debouncing, some devices can - // cause multiple attaches (actually reset) without detach event. + // cause multiple attaches (actually reset) without a detached event. // Force remove currently mounted with the same bus info (rhport, hub addr, hub port) if exists process_remove_event(&event); @@ -667,15 +706,13 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { TU_LOG_USBH("[%u:] USBH Device Attach\r\n", event.rhport); _usbh_data.enumerating_daddr = 0; // enumerate new device with address 0 enum_new_device(&event); - } else { - // currently enumerating another device + } + #if CFG_TUH_HUB + else { TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport); - const bool is_empty = osal_queue_empty(_usbh_q); - queue_event(&event, in_isr); - if (is_empty) { - return; // Exit if this is the only event in the queue, otherwise we loop forever - } + TU_ASSERT(osal_queue_send(_usbh_daq, &event, in_isr), ); } + #endif break; case HCD_EVENT_DEVICE_REMOVE: @@ -753,8 +790,12 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { } #if CFG_TUSB_OS_HAS_SCHEDULER - // return if there are no more events, for application to run other backgrounds - if (osal_queue_empty(_usbh_q)) { + // return if there are no more events, to allow application to run other backgrounds + if (osal_queue_empty(_usbh_q) + #if CFG_TUH_HUB + && osal_queue_empty(_usbh_daq) + #endif + ) { return; } #endif @@ -1468,6 +1509,7 @@ enum { ENUM_HUB_RERSET, ENUM_HUB_RESET_COMPLETE, ENUM_HUB_CLEAR_RESET, + ENUM_HUB_CLEAR_RESET_RETRY, // 2nd attempt waiting for hub reset ENUM_HUB_CLEAR_RESET_COMPLETE, ENUM_ADDR0_DEVICE_DESC, ENUM_SET_ADDR, @@ -1496,6 +1538,7 @@ enum { ENUM_AFTER_RESET_ROOT_DELAY, ENUM_AFTER_RESET_ROOT_POST_DELAY, ENUM_AFTER_RESET_HUB_DELAY, + ENUM_AFTER_RESET_HUB_DELAY_RETRY, ENUM_AFTER_RESET_RECOVERY_DELAY, ENUM_AFTER_SET_ADDRESS_RECOVERY_DELAY, }; @@ -1561,9 +1604,11 @@ static void enum_async_delay(uintptr_t state) { #if CFG_TUH_HUB case ENUM_AFTER_RESET_HUB_DELAY: + case ENUM_AFTER_RESET_HUB_DELAY_RETRY: // get status after reset complete to check for reset change TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, NULL, process_enumeration, - ENUM_HUB_CLEAR_RESET), ); + state == ENUM_AFTER_RESET_HUB_DELAY ? ENUM_HUB_CLEAR_RESET + : ENUM_HUB_CLEAR_RESET_RETRY), ); break; #endif @@ -1646,18 +1691,22 @@ static void process_enumeration(tuh_xfer_t *xfer) { usbh_call_after_ms(ENUM_RESET_HUB_DELAY_MS, enum_async_delay, ENUM_AFTER_RESET_HUB_DELAY); break; - case ENUM_HUB_CLEAR_RESET: { + case ENUM_HUB_CLEAR_RESET: + case ENUM_HUB_CLEAR_RESET_RETRY: { hub_port_status_response_t port_status; hub_port_get_status_local(dev0_bus->hub_addr, dev0_bus->hub_port, &port_status); if (1 == port_status.change.reset) { // Acknowledge Port Reset Change - TU_ASSERT(hub_port_clear_reset_change(dev0_bus->hub_addr, dev0_bus->hub_port, process_enumeration, ENUM_HUB_CLEAR_RESET_COMPLETE),); + TU_ASSERT(hub_port_clear_reset_change(dev0_bus->hub_addr, dev0_bus->hub_port, process_enumeration, + ENUM_HUB_CLEAR_RESET_COMPLETE), ); + } else if (state == ENUM_HUB_CLEAR_RESET) { + // retry one more time if reset change not set yet + usbh_call_after_ms(ENUM_RESET_HUB_DELAY_MS, enum_async_delay, ENUM_AFTER_RESET_HUB_DELAY_RETRY); } else { - // maybe retry if reset change not set but we need timeout to prevent infinite loop - // TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, NULL, process_enumeration, ENUM_HUB_CLEAR_RESET_COMPLETE),); + // retry but still not set --> failed + enum_full_complete(false); } - break; } @@ -1855,11 +1904,12 @@ static void process_enumeration(tuh_xfer_t *xfer) { TU_LOG_USBH("Device configured\r\n"); dev->configured = 1; - #if CFG_TUH_HUB + #if CFG_TUH_HUB + // get next hub status now since device can be unplugged before set_configure() is complete if (_usbh_data.dev0_bus.hub_addr != 0) { - hub_edpt_status_xfer(_usbh_data.dev0_bus.hub_addr); // get next hub status + hub_edpt_status_xfer(_usbh_data.dev0_bus.hub_addr); } - #endif + #endif // Parse configuration & set up drivers // driver_open() must not make any usb transfer @@ -1981,7 +2031,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) { } } - // all interface are configured + // all interfaces are configured if (itf_num == CFG_TUH_INTERFACE_MAX) { enum_full_complete(true); @@ -2004,11 +2054,10 @@ static void enum_full_complete(bool success) { #if CFG_TUH_HUB // Hub status is already requested in case of successful enumeration - if (_usbh_data.dev0_bus.hub_addr != 0 && !success) { - hub_edpt_status_xfer(_usbh_data.dev0_bus.hub_addr); // get next hub status + if (!success && _usbh_data.dev0_bus.hub_addr != 0) { + hub_edpt_status_xfer(_usbh_data.dev0_bus.hub_addr); } -#endif - + #endif } #endif diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 6ab18ace8..bba42716d 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -184,7 +184,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, v (void) msec; // not used, always behave as msec = 0 qhdl->interrupt_set(false); - const bool success = tu_fifo_read_n(&qhdl->ff, data, qhdl->item_size); + const bool success = (tu_fifo_read_n(&qhdl->ff, data, qhdl->item_size) > 0); qhdl->interrupt_set(true); return success; @@ -195,7 +195,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void qhdl->interrupt_set(false); } - const bool success = tu_fifo_write_n(&qhdl->ff, data, qhdl->item_size); + const bool success = (tu_fifo_write_n(&qhdl->ff, data, qhdl->item_size) > 0); if (!in_isr) { qhdl->interrupt_set(true); -- cgit v1.3.1 From 7ea02fd6c9e376679bc1fe025bb73e43664e17c6 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 Feb 2026 23:34:48 +0700 Subject: add osal_time_millis() to osal requirement implement tusb_time_millis_api() with osal_time_millis() when OS is not NONE --- src/common/tusb_common.h | 6 ------ src/osal/osal.h | 2 ++ src/osal/osal_freertos.h | 4 ++++ src/osal/osal_mynewt.h | 4 ++++ src/osal/osal_none.h | 2 ++ src/osal/osal_pico.h | 4 ++++ src/osal/osal_rtthread.h | 4 ++++ src/osal/osal_rtx4.h | 4 ++++ src/osal/osal_zephyr.h | 4 ++++ src/tusb.c | 10 ++++++++-- src/tusb.h | 12 +++++++++++- 11 files changed, 47 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 6ac1405f3..9eb0a9337 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -90,12 +90,6 @@ // TODO move to a more obvious place/file //--------------------------------------------------------------------+ -// Get current milliseconds, required by some port/configuration without RTOS -extern uint32_t tusb_time_millis_api(void); - -// Delay in milliseconds, use tusb_time_millis_api() by default. required by some port/configuration with no RTOS -extern void tusb_time_delay_ms_api(uint32_t ms); - // flush data cache extern void tusb_app_dcache_flush(uintptr_t addr, uint32_t data_size); diff --git a/src/osal/osal.h b/src/osal/osal.h index 44521620f..c0292a008 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -74,6 +74,8 @@ typedef void (*osal_task_func_t)(void* param); /*-------------------------------------------------------------------- OSAL Porting API Should be implemented as static inline function in osal_port.h header + uint32_t osal_time_millis(void); + void osal_spin_init(osal_spinlock_t *ctx); void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr); diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index 9aeda4d01..32ee2d55c 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -99,6 +99,10 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { vTaskDelay(pdMS_TO_TICKS(msec)); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t osal_time_millis(void) { + return pdTICKS_TO_MS(xTaskGetTickCount()); +} + //--------------------------------------------------------------------+ // Spinlock API //--------------------------------------------------------------------+ diff --git a/src/osal/osal_mynewt.h b/src/osal/osal_mynewt.h index 6d51f8ec3..94124ca81 100644 --- a/src/osal/osal_mynewt.h +++ b/src/osal/osal_mynewt.h @@ -40,6 +40,10 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { os_time_delay( os_time_ms_to_ticks32(msec) ); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t osal_time_millis(void) { + return os_time_ticks_to_ms32(os_time_get()); +} + //--------------------------------------------------------------------+ // Spinlock API //--------------------------------------------------------------------+ diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index bba42716d..7bf6029d6 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -31,6 +31,8 @@ extern "C" { #endif +// osal_time_millis() is not provided, tusb_time_millis_api() must be implemented by user application + //--------------------------------------------------------------------+ // Spinlock API //--------------------------------------------------------------------+ diff --git a/src/osal/osal_pico.h b/src/osal/osal_pico.h index 79b728e9a..6a0a21bb3 100644 --- a/src/osal/osal_pico.h +++ b/src/osal/osal_pico.h @@ -43,6 +43,10 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { sleep_ms(msec); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t osal_time_millis(void) { + return to_ms_since_boot(get_absolute_time()); +} + //--------------------------------------------------------------------+ // Spinlock API //--------------------------------------------------------------------+ diff --git a/src/osal/osal_rtthread.h b/src/osal/osal_rtthread.h index a778f5425..f560281c5 100644 --- a/src/osal/osal_rtthread.h +++ b/src/osal/osal_rtthread.h @@ -42,6 +42,10 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { rt_thread_mdelay(msec); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t osal_time_millis(void) { + return (uint32_t)((((uint64_t)rt_tick_get()) * 1000) / RT_TICK_PER_SECOND); +} + //--------------------------------------------------------------------+ // Spinlock API //--------------------------------------------------------------------+ diff --git a/src/osal/osal_rtx4.h b/src/osal/osal_rtx4.h index 35860ddd5..e1930c96c 100644 --- a/src/osal/osal_rtx4.h +++ b/src/osal/osal_rtx4.h @@ -46,6 +46,10 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { os_dly_wait(lo); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t osal_time_millis(void) { + return os_time_get(); +} + TU_ATTR_ALWAYS_INLINE static inline uint16_t msec2wait(uint32_t msec) { if (msec == OSAL_TIMEOUT_WAIT_FOREVER) { return 0xFFFF; diff --git a/src/osal/osal_zephyr.h b/src/osal/osal_zephyr.h index 91f225f79..900ac786c 100644 --- a/src/osal/osal_zephyr.h +++ b/src/osal/osal_zephyr.h @@ -35,6 +35,10 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { k_msleep(msec); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t osal_time_millis(void) { + return k_uptime_get_32(); +} + //--------------------------------------------------------------------+ // Spinlock API //--------------------------------------------------------------------+ diff --git a/src/tusb.c b/src/tusb.c index 6075e9db4..40d0e8adf 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -45,17 +45,23 @@ tusb_role_t _tusb_rhport_role[TUP_USBIP_CONTROLLER_NUM] = { TUSB_ROLE_INVALID }; // Weak/Default API, can be overwritten by Application //-------------------------------------------------------------------- + #if CFG_TUSB_OS != OPT_OS_NONE +uint32_t tusb_time_millis_api(void) { + return osal_time_millis(); +} + #endif + TU_ATTR_WEAK void tusb_time_delay_ms_api(uint32_t ms) { #if CFG_TUSB_OS != OPT_OS_NONE osal_task_delay(ms); #else - // delay using millis() (if implemented) and/or frame number if possible + // delay using millis() const uint32_t time_ms = tusb_time_millis_api(); while ((tusb_time_millis_api() - time_ms) < ms) {} #endif } -TU_ATTR_WEAK void* tusb_app_virt_to_phys(void *virt_addr) { +TU_ATTR_WEAK void *tusb_app_virt_to_phys(void *virt_addr) { return virt_addr; } diff --git a/src/tusb.h b/src/tusb.h index 62b3b9783..742009a2e 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -135,7 +135,7 @@ //--------------------------------------------------------------------+ -// User API +// Application API //--------------------------------------------------------------------+ #if CFG_TUH_ENABLED || CFG_TUD_ENABLED @@ -174,6 +174,16 @@ bool tusb_deinit(uint8_t rhport); #endif +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +// Get current milliseconds, required by some port/configuration without RTOS +extern uint32_t tusb_time_millis_api(void); + +// Delay in milliseconds, use tusb_time_millis_api() by default. required by some port/configuration with no RTOS +extern void tusb_time_delay_ms_api(uint32_t ms); + #ifdef __cplusplus } #endif -- cgit v1.3.1 From 8444c25ab6bc841bad81fd04afc1e66a9d57a115 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 Feb 2026 23:51:36 +0700 Subject: replace board_millis() with tusb_time_millis_api() --- examples/device/audio_4_channel_mic/src/main.c | 4 +-- examples/device/audio_test/src/main.c | 4 +-- examples/device/audio_test_multi_rate/src/main.c | 4 +-- examples/device/board_test/src/main.c | 4 +-- examples/device/cdc_dual_ports/src/main.c | 2 +- examples/device/cdc_msc/src/main.c | 2 +- examples/device/cdc_uac2/src/uac2_app.c | 4 +-- examples/device/dfu/src/main.c | 2 +- examples/device/dfu_runtime/src/main.c | 2 +- examples/device/dynamic_configuration/src/main.c | 4 +-- examples/device/hid_boot_interface/src/main.c | 4 +-- examples/device/hid_composite/src/main.c | 4 +-- examples/device/hid_generic_inout/src/main.c | 2 +- examples/device/hid_multiple_interface/src/main.c | 4 +-- examples/device/midi_test/src/main.c | 4 +-- examples/device/msc_dual_lun/src/main.c | 2 +- examples/device/mtp/src/main.c | 2 +- examples/device/net_lwip_webserver/src/main.c | 2 +- examples/device/uac2_headset/src/main.c | 6 ++-- examples/device/uac2_speaker_fb/src/main.c | 6 ++-- examples/device/usbtmc/src/main.c | 6 ++-- examples/device/usbtmc/src/usbtmc_app.c | 8 ++--- examples/device/video_capture/src/main.c | 6 ++-- examples/device/video_capture_2ch/src/main.c | 6 ++-- examples/device/webusb_serial/src/main.c | 2 +- examples/dual/host_hid_to_device_cdc/src/main.c | 2 +- examples/dual/host_info_to_device_cdc/src/main.c | 6 ++-- examples/host/bare_api/src/main.c | 2 +- examples/host/cdc_msc_hid/src/main.c | 2 +- examples/host/device_info/src/main.c | 2 +- examples/host/hid_controller/src/hid_app.c | 2 +- examples/host/hid_controller/src/main.c | 2 +- examples/host/midi_rx/src/main.c | 2 +- examples/host/msc_file_explorer/src/main.c | 2 +- examples/typec/power_delivery/src/main.c | 2 +- hw/bsp/at32f402_405/family.c | 2 +- hw/bsp/at32f403a_407/family.c | 2 +- hw/bsp/at32f413/family.c | 2 +- hw/bsp/at32f415/family.c | 2 +- hw/bsp/at32f423/family.c | 2 +- hw/bsp/at32f425/family.c | 2 +- hw/bsp/at32f435_437/family.c | 2 +- hw/bsp/at32f45x/family.c | 2 +- hw/bsp/board.c | 4 --- hw/bsp/board_api.h | 41 ++--------------------- hw/bsp/broadcom_32bit/family.c | 2 +- hw/bsp/broadcom_64bit/family.c | 2 +- hw/bsp/brtmm90x/family.c | 2 +- hw/bsp/ch32f20x/family.c | 2 +- hw/bsp/ch32v10x/family.c | 2 +- hw/bsp/ch32v20x/family.c | 2 +- hw/bsp/ch32v30x/family.c | 2 +- hw/bsp/cxd56/family.c | 2 +- hw/bsp/da1469x/family.c | 2 +- hw/bsp/efm32/family.c | 2 +- hw/bsp/f1c100s/family.c | 2 +- hw/bsp/fomu/family.c | 2 +- hw/bsp/gd32vf103/family.c | 2 +- hw/bsp/hpmicro/family.c | 2 +- hw/bsp/imxrt/family.c | 2 +- hw/bsp/kinetis_k/family.c | 2 +- hw/bsp/kinetis_k32l2/family.c | 2 +- hw/bsp/kinetis_kl/family.c | 2 +- hw/bsp/lpc11/family.c | 2 +- hw/bsp/lpc13/family.c | 2 +- hw/bsp/lpc15/family.c | 2 +- hw/bsp/lpc17/family.c | 2 +- hw/bsp/lpc18/family.c | 2 +- hw/bsp/lpc40/family.c | 2 +- hw/bsp/lpc43/family.c | 2 +- hw/bsp/lpc51/family.c | 2 +- hw/bsp/lpc54/family.c | 2 +- hw/bsp/lpc55/family.c | 2 +- hw/bsp/maxim/family.c | 2 +- hw/bsp/mcx/family.c | 2 +- hw/bsp/mm32/family.c | 2 +- hw/bsp/msp430/family.c | 10 +++--- hw/bsp/msp432e4/family.c | 2 +- hw/bsp/nrf/family.c | 2 +- hw/bsp/nuc100_120/family.c | 2 +- hw/bsp/nuc121_125/family.c | 2 +- hw/bsp/nuc126/family.c | 2 +- hw/bsp/nuc505/family.c | 2 +- hw/bsp/pic32mz/family.c | 2 +- hw/bsp/ra/family.c | 2 +- hw/bsp/rw61x/family.c | 2 +- hw/bsp/rx/boards/gr_citrus/gr_citrus.c | 2 +- hw/bsp/rx/boards/rx65n_target/rx65n_target.c | 2 +- hw/bsp/samd11/family.c | 2 +- hw/bsp/samd2x_l2x/family.c | 2 +- hw/bsp/samd5x_e5x/family.c | 2 +- hw/bsp/same7x/family.c | 2 +- hw/bsp/samg/family.c | 2 +- hw/bsp/stm32c0/family.c | 2 +- hw/bsp/stm32f0/family.c | 2 +- hw/bsp/stm32f1/family.c | 2 +- hw/bsp/stm32f2/family.c | 2 +- hw/bsp/stm32f3/family.c | 2 +- hw/bsp/stm32f4/family.c | 2 +- hw/bsp/stm32f7/family.c | 2 +- hw/bsp/stm32g0/family.c | 2 +- hw/bsp/stm32g4/family.c | 2 +- hw/bsp/stm32h5/family.c | 2 +- hw/bsp/stm32h7/family.c | 2 +- hw/bsp/stm32h7rs/family.c | 2 +- hw/bsp/stm32l0/family.c | 2 +- hw/bsp/stm32l4/family.c | 2 +- hw/bsp/stm32n6/family.c | 2 +- hw/bsp/stm32u0/family.c | 2 +- hw/bsp/stm32u5/family.c | 2 +- hw/bsp/stm32wb/family.c | 2 +- hw/bsp/stm32wba/family.c | 2 +- hw/bsp/tm4c/family.c | 2 +- hw/bsp/xmc4000/family.c | 2 +- src/common/tusb_common.h | 6 ++++ src/host/usbh.c | 2 +- src/portable/sunxi/dcd_sunxi_musb.c | 3 -- src/tusb.c | 13 ++++--- src/tusb.h | 10 ------ 119 files changed, 158 insertions(+), 203 deletions(-) (limited to 'src') diff --git a/examples/device/audio_4_channel_mic/src/main.c b/examples/device/audio_4_channel_mic/src/main.c index 5767c7453..c9c6dd46c 100644 --- a/examples/device/audio_4_channel_mic/src/main.c +++ b/examples/device/audio_4_channel_mic/src/main.c @@ -155,7 +155,7 @@ void tud_resume_cb(void) { // In a real application, this would be replaced with actual I2S receive callback. void audio_task(void) { static uint32_t start_ms = 0; - uint32_t curr_ms = board_millis(); + uint32_t curr_ms = tusb_time_millis_api(); if (start_ms == curr_ms) { return; // not enough time } @@ -408,7 +408,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) { + if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; diff --git a/examples/device/audio_test/src/main.c b/examples/device/audio_test/src/main.c index 2441eefbc..876a41d06 100644 --- a/examples/device/audio_test/src/main.c +++ b/examples/device/audio_test/src/main.c @@ -138,7 +138,7 @@ void tud_resume_cb(void) { // In a real application, this would be replaced with actual I2S receive callback. void audio_task(void) { static uint32_t start_ms = 0; - uint32_t curr_ms = board_millis(); + uint32_t curr_ms = tusb_time_millis_api(); if (start_ms == curr_ms) { return; // not enough time } @@ -402,7 +402,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) { + if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; diff --git a/examples/device/audio_test_multi_rate/src/main.c b/examples/device/audio_test_multi_rate/src/main.c index baeec870f..952176997 100644 --- a/examples/device/audio_test_multi_rate/src/main.c +++ b/examples/device/audio_test_multi_rate/src/main.c @@ -146,7 +146,7 @@ void tud_resume_cb(void) { // In a real application, this would be replaced with actual I2S receive callback. void audio_task(void) { static uint32_t start_ms = 0; - uint32_t curr_ms = board_millis(); + uint32_t curr_ms = tusb_time_millis_api(); if (start_ms == curr_ms) { return; // not enough time } @@ -614,7 +614,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) { + if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; diff --git a/examples/device/board_test/src/main.c b/examples/device/board_test/src/main.c index ee0829e5b..757876ac8 100644 --- a/examples/device/board_test/src/main.c +++ b/examples/device/board_test/src/main.c @@ -58,8 +58,8 @@ int main(void) { } // Blink and print every interval ms - if (!(board_millis() - start_ms < interval_ms)) { - start_ms = board_millis(); + if (!(tusb_time_millis_api() - start_ms < interval_ms)) { + start_ms = tusb_time_millis_api(); if (ch < 0) { // skip if echoing diff --git a/examples/device/cdc_dual_ports/src/main.c b/examples/device/cdc_dual_ports/src/main.c index 5ccb06a8a..6f918218d 100644 --- a/examples/device/cdc_dual_ports/src/main.c +++ b/examples/device/cdc_dual_ports/src/main.c @@ -157,7 +157,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) { + if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; diff --git a/examples/device/cdc_msc/src/main.c b/examples/device/cdc_msc/src/main.c index 06a4f732f..b00a0e3a9 100644 --- a/examples/device/cdc_msc/src/main.c +++ b/examples/device/cdc_msc/src/main.c @@ -160,7 +160,7 @@ void led_blinking_task(void) { if (blink_enable) { // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) { + if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; diff --git a/examples/device/cdc_uac2/src/uac2_app.c b/examples/device/cdc_uac2/src/uac2_app.c index 73a262d0c..7760c402b 100644 --- a/examples/device/cdc_uac2/src/uac2_app.c +++ b/examples/device/cdc_uac2/src/uac2_app.c @@ -66,7 +66,7 @@ uint8_t current_resolution; // In a real application, this would be replaced with actual I2S send/receive callback. void audio_task(void) { static uint32_t start_ms = 0; - uint32_t curr_ms = board_millis(); + uint32_t curr_ms = tusb_time_millis_api(); if (start_ms == curr_ms) { return; // not enough time } @@ -303,7 +303,7 @@ void led_blinking_task(void) static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) { + if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; } start_ms += blink_interval_ms; diff --git a/examples/device/dfu/src/main.c b/examples/device/dfu/src/main.c index 77632bf1a..fb3c22630 100644 --- a/examples/device/dfu/src/main.c +++ b/examples/device/dfu/src/main.c @@ -199,7 +199,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) { + if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; diff --git a/examples/device/dfu_runtime/src/main.c b/examples/device/dfu_runtime/src/main.c index 5de651bcd..6f412e8de 100644 --- a/examples/device/dfu_runtime/src/main.c +++ b/examples/device/dfu_runtime/src/main.c @@ -132,7 +132,7 @@ void led_blinking_task(void) static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) { + if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; diff --git a/examples/device/dynamic_configuration/src/main.c b/examples/device/dynamic_configuration/src/main.c index dac74bb7a..8ebb42f9a 100644 --- a/examples/device/dynamic_configuration/src/main.c +++ b/examples/device/dynamic_configuration/src/main.c @@ -170,7 +170,7 @@ void midi_task(void) { while( tud_midi_available() ) tud_midi_packet_read(packet); // send note every 1000 ms - if (board_millis() - start_ms < 286) { + if (tusb_time_millis_api() - start_ms < 286) { return; // not enough time } start_ms += 286; @@ -209,7 +209,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) { + if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return;// not enough time } start_ms += blink_interval_ms; diff --git a/examples/device/hid_boot_interface/src/main.c b/examples/device/hid_boot_interface/src/main.c index 44a91db67..4de319f52 100644 --- a/examples/device/hid_boot_interface/src/main.c +++ b/examples/device/hid_boot_interface/src/main.c @@ -109,7 +109,7 @@ void hid_task(void) { const uint32_t interval_ms = 10; static uint32_t start_ms = 0; - if (board_millis() - start_ms < interval_ms) { + if (tusb_time_millis_api() - start_ms < interval_ms) { return; // not enough time } start_ms += interval_ms; @@ -238,7 +238,7 @@ void led_blinking_task(void) { } // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) { + if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; diff --git a/examples/device/hid_composite/src/main.c b/examples/device/hid_composite/src/main.c index 9693d564d..7c9d5af8d 100644 --- a/examples/device/hid_composite/src/main.c +++ b/examples/device/hid_composite/src/main.c @@ -209,7 +209,7 @@ void hid_task(void) { const uint32_t interval_ms = 10; static uint32_t start_ms = 0; - if (board_millis() - start_ms < interval_ms) { + if (tusb_time_millis_api() - start_ms < interval_ms) { return; // not enough time } start_ms += interval_ms; @@ -298,7 +298,7 @@ void led_blinking_task(void) { } // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) { + if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; diff --git a/examples/device/hid_generic_inout/src/main.c b/examples/device/hid_generic_inout/src/main.c index 9837a47d9..2a6b91a8a 100644 --- a/examples/device/hid_generic_inout/src/main.c +++ b/examples/device/hid_generic_inout/src/main.c @@ -168,7 +168,7 @@ void led_blinking_task(void) static bool led_state = false; // Blink every interval ms - if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + if ( tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/hid_multiple_interface/src/main.c b/examples/device/hid_multiple_interface/src/main.c index 0bccd13c1..c71a9cbad 100644 --- a/examples/device/hid_multiple_interface/src/main.c +++ b/examples/device/hid_multiple_interface/src/main.c @@ -120,7 +120,7 @@ void hid_task(void) const uint32_t interval_ms = 10; static uint32_t start_ms = 0; - if ( board_millis() - start_ms < interval_ms) return; // not enough time + if ( tusb_time_millis_api() - start_ms < interval_ms) return; // not enough time start_ms += interval_ms; uint32_t const btn = board_button_read(); @@ -205,7 +205,7 @@ void led_blinking_task(void) static bool led_state = false; // Blink every interval ms - if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + if ( tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/midi_test/src/main.c b/examples/device/midi_test/src/main.c index fd58e3021..1154c1d60 100644 --- a/examples/device/midi_test/src/main.c +++ b/examples/device/midi_test/src/main.c @@ -134,7 +134,7 @@ void midi_task(void) } // send note periodically - if (board_millis() - start_ms < 286) { + if (tusb_time_millis_api() - start_ms < 286) { return; // not enough time } start_ms += 286; @@ -174,7 +174,7 @@ void led_blinking_task(void) static bool led_state = false; // Blink every interval ms - if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + if ( tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/msc_dual_lun/src/main.c b/examples/device/msc_dual_lun/src/main.c index 62b1c872a..b459871f7 100644 --- a/examples/device/msc_dual_lun/src/main.c +++ b/examples/device/msc_dual_lun/src/main.c @@ -103,7 +103,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) return; // not enough time + if (tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/mtp/src/main.c b/examples/device/mtp/src/main.c index 57d1535b2..6ffa435d1 100644 --- a/examples/device/mtp/src/main.c +++ b/examples/device/mtp/src/main.c @@ -102,7 +102,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) return; // not enough time + if (tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/net_lwip_webserver/src/main.c b/examples/device/net_lwip_webserver/src/main.c index 867cf2812..9f26da2ba 100644 --- a/examples/device/net_lwip_webserver/src/main.c +++ b/examples/device/net_lwip_webserver/src/main.c @@ -291,5 +291,5 @@ void sys_arch_unprotect(sys_prot_t pval) { /* lwip needs a millisecond time source, and the TinyUSB board support code has one available */ uint32_t sys_now(void) { - return board_millis(); + return tusb_time_millis_api(); } diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index 96fa66f1e..0ea63d8f7 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -559,7 +559,7 @@ bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_reques // In a real application, this would be replaced with actual I2S send/receive callback. void audio_task(void) { static uint32_t start_ms = 0; - uint32_t curr_ms = board_millis(); + uint32_t curr_ms = tusb_time_millis_api(); if (start_ms == curr_ms) return;// not enough time start_ms = curr_ms; // When new data arrived, copy data from speaker buffer, to microphone buffer @@ -605,7 +605,7 @@ void audio_control_task(void) { static uint32_t start_ms = 0; static uint32_t btn_prev = 0; - if (board_millis() - start_ms < interval_ms) return;// not enough time + if (tusb_time_millis_api() - start_ms < interval_ms) return;// not enough time start_ms += interval_ms; uint32_t btn = board_button_read(); @@ -644,7 +644,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) return; + if (tusb_time_millis_api() - start_ms < blink_interval_ms) return; start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/uac2_speaker_fb/src/main.c b/examples/device/uac2_speaker_fb/src/main.c index 7b4e2d64c..8323d82e8 100644 --- a/examples/device/uac2_speaker_fb/src/main.c +++ b/examples/device/uac2_speaker_fb/src/main.c @@ -583,7 +583,7 @@ bool tud_audio_rx_done_isr(uint8_t rhport, uint16_t n_bytes_received, uint8_t fu // In a real application, this would be replaced with actual I2S transmit callback. void audio_task(void) { static uint32_t start_ms = 0; - uint32_t curr_ms = board_millis(); + uint32_t curr_ms = tusb_time_millis_api(); if (start_ms == curr_ms) return;// not enough time start_ms = curr_ms; @@ -610,7 +610,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) return; + if (tusb_time_millis_api() - start_ms < blink_interval_ms) return; start_ms += blink_interval_ms; board_led_write(led_state); @@ -624,7 +624,7 @@ void led_blinking_task(void) { // Every 1ms, we will sent 1 debug information report void audio_debug_task(void) { static uint32_t start_ms = 0; - uint32_t curr_ms = board_millis(); + uint32_t curr_ms = tusb_time_millis_api(); if (start_ms == curr_ms) return;// not enough time start_ms = curr_ms; diff --git a/examples/device/usbtmc/src/main.c b/examples/device/usbtmc/src/main.c index 5cbbb85ef..b1269b117 100644 --- a/examples/device/usbtmc/src/main.c +++ b/examples/device/usbtmc/src/main.c @@ -124,12 +124,12 @@ void led_blinking_task(void) { led_state = true; board_led_write(true); - start_ms = board_millis(); + start_ms = tusb_time_millis_api(); doPulse = false; } else if (led_state == true) { - if ( board_millis() - start_ms < 750) //Spec says blink must be between 500 and 1000 ms. + if ( tusb_time_millis_api() - start_ms < 750) //Spec says blink must be between 500 and 1000 ms. { return; // not enough time } @@ -140,7 +140,7 @@ void led_blinking_task(void) else { // Blink every interval ms - if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + if ( tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index 4c3724ac4..35e8618f5 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -209,19 +209,19 @@ void usbtmc_app_task_iter(void) { case 0: break; case 1: - queryDelayStart = board_millis(); + queryDelayStart = tusb_time_millis_api(); queryState = 2; break; case 2: - if( (board_millis() - queryDelayStart) > resp_delay) { - queryDelayStart = board_millis(); + if( (tusb_time_millis_api() - queryDelayStart) > resp_delay) { + queryDelayStart = tusb_time_millis_api(); queryState=3; status |= 0x10u; // MAV status |= 0x40u; // SRQ } break; case 3: - if( (board_millis() - queryDelayStart) > resp_delay) { + if( (tusb_time_millis_api() - queryDelayStart) > resp_delay) { queryState = 4; } break; diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c index ffa2a7afa..df9f77a1c 100644 --- a/examples/device/video_capture/src/main.c +++ b/examples/device/video_capture/src/main.c @@ -231,7 +231,7 @@ static void video_send_frame(void) { if (!already_sent) { already_sent = 1; tx_busy = 1; - start_ms = board_millis(); + start_ms = tusb_time_millis_api(); #if defined(CFG_EXAMPLE_VIDEO_BUFFERLESS) tud_video_n_frame_xfer(0, 0, NULL, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); #elif defined (CFG_EXAMPLE_VIDEO_READONLY) @@ -247,7 +247,7 @@ static void video_send_frame(void) { #endif } - unsigned cur = board_millis(); + unsigned cur = tusb_time_millis_api(); if (cur - start_ms < interval_ms) { return; // not enough time } @@ -316,7 +316,7 @@ void led_blinking_task(void* param) { #if CFG_TUSB_OS == OPT_OS_FREERTOS vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); #else - if (board_millis() - start_ms < blink_interval_ms) { + if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } #endif diff --git a/examples/device/video_capture_2ch/src/main.c b/examples/device/video_capture_2ch/src/main.c index 79b149f2b..debd336fd 100644 --- a/examples/device/video_capture_2ch/src/main.c +++ b/examples/device/video_capture_2ch/src/main.c @@ -221,13 +221,13 @@ static void video_send_frame(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { if (!(already_sent & (1u << idx))) { already_sent |= 1u << idx; tx_busy |= 1u << idx; - start_ms[idx] = board_millis(); + start_ms[idx] = tusb_time_millis_api(); fb_size = get_framebuf(ctl_idx, stm_idx, frame_num[idx], &fp); tud_video_n_frame_xfer(ctl_idx, stm_idx, fp, fb_size); } - unsigned cur = board_millis(); + unsigned cur = tusb_time_millis_api(); if (cur - start_ms[idx] < interval_ms[idx]) return; // not enough time if (tx_busy & (1u << idx)) return; start_ms[idx] += interval_ms[idx]; @@ -280,7 +280,7 @@ void led_blinking_task(void* param) { #if CFG_TUSB_OS == OPT_OS_FREERTOS vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); #else - if (board_millis() - start_ms < blink_interval_ms) return; // not enough time + if (tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time #endif start_ms += blink_interval_ms; diff --git a/examples/device/webusb_serial/src/main.c b/examples/device/webusb_serial/src/main.c index 155768b76..4be5e4db4 100644 --- a/examples/device/webusb_serial/src/main.c +++ b/examples/device/webusb_serial/src/main.c @@ -257,7 +257,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) { + if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; diff --git a/examples/dual/host_hid_to_device_cdc/src/main.c b/examples/dual/host_hid_to_device_cdc/src/main.c index 8c53588c3..ba8ba019a 100644 --- a/examples/dual/host_hid_to_device_cdc/src/main.c +++ b/examples/dual/host_hid_to_device_cdc/src/main.c @@ -284,7 +284,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) return; // not enough time + if (tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/dual/host_info_to_device_cdc/src/main.c b/examples/dual/host_info_to_device_cdc/src/main.c index fffb54d58..7cf43aef3 100644 --- a/examples/dual/host_info_to_device_cdc/src/main.c +++ b/examples/dual/host_info_to_device_cdc/src/main.c @@ -213,13 +213,13 @@ void cdc_task(void) { static uint32_t connected_ms = 0; if (!tud_cdc_connected()) { - connected_ms = board_millis(); + connected_ms = tusb_time_millis_api(); return; } // delay a bit otherwise we can outpace host's terminal. Linux will set LineState (DTR) then Line Coding. // If we send data before Linux's terminal set Line Coding, it can be ignored --> missing data with hardware test loop - if (board_millis() - connected_ms < 100) { + if (tusb_time_millis_api() - connected_ms < 100) { return; // wait for stable connection } @@ -309,7 +309,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) { + if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return;// not enough time } start_ms += blink_interval_ms; diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index c693d6b00..ced2eaa32 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -335,7 +335,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < interval_ms) { + if (tusb_time_millis_api() - start_ms < interval_ms) { return; // not enough time } start_ms += interval_ms; diff --git a/examples/host/cdc_msc_hid/src/main.c b/examples/host/cdc_msc_hid/src/main.c index c309a7cae..c27ad93fe 100644 --- a/examples/host/cdc_msc_hid/src/main.c +++ b/examples/host/cdc_msc_hid/src/main.c @@ -92,7 +92,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < interval_ms) { + if (tusb_time_millis_api() - start_ms < interval_ms) { return;// not enough time } start_ms += interval_ms; diff --git a/examples/host/device_info/src/main.c b/examples/host/device_info/src/main.c index ab617e989..fd4e9c3ed 100644 --- a/examples/host/device_info/src/main.c +++ b/examples/host/device_info/src/main.c @@ -246,7 +246,7 @@ void led_blinking_task(void* param) { #if CFG_TUSB_OS == OPT_OS_FREERTOS vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); #else - if (board_millis() - start_ms < blink_interval_ms) { + if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } #endif diff --git a/examples/host/hid_controller/src/hid_app.c b/examples/host/hid_controller/src/hid_app.c index f8c3d029b..5417811f0 100644 --- a/examples/host/hid_controller/src/hid_app.c +++ b/examples/host/hid_controller/src/hid_app.c @@ -168,7 +168,7 @@ void hid_app_task(void) const uint32_t interval_ms = 200; static uint32_t start_ms = 0; - uint32_t current_time_ms = board_millis(); + uint32_t current_time_ms = tusb_time_millis_api(); if ( current_time_ms - start_ms >= interval_ms) { start_ms = current_time_ms; diff --git a/examples/host/hid_controller/src/main.c b/examples/host/hid_controller/src/main.c index fa70d7d1a..a9eebc90b 100644 --- a/examples/host/hid_controller/src/main.c +++ b/examples/host/hid_controller/src/main.c @@ -79,7 +79,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if ( board_millis() - start_ms < interval_ms) return; // not enough time + if ( tusb_time_millis_api() - start_ms < interval_ms) return; // not enough time start_ms += interval_ms; board_led_write(led_state); diff --git a/examples/host/midi_rx/src/main.c b/examples/host/midi_rx/src/main.c index 78b1a11b9..f189e0864 100644 --- a/examples/host/midi_rx/src/main.c +++ b/examples/host/midi_rx/src/main.c @@ -72,7 +72,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < interval_ms) return;// not enough time + if (tusb_time_millis_api() - start_ms < interval_ms) return;// not enough time start_ms += interval_ms; board_led_write(led_state); diff --git a/examples/host/msc_file_explorer/src/main.c b/examples/host/msc_file_explorer/src/main.c index f9ec0ff5f..0a8967380 100644 --- a/examples/host/msc_file_explorer/src/main.c +++ b/examples/host/msc_file_explorer/src/main.c @@ -118,7 +118,7 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < interval_ms) return; // not enough time + if (tusb_time_millis_api() - start_ms < interval_ms) return; // not enough time start_ms += interval_ms; board_led_write(led_state); diff --git a/examples/typec/power_delivery/src/main.c b/examples/typec/power_delivery/src/main.c index de0db4721..f6191bfe8 100644 --- a/examples/typec/power_delivery/src/main.c +++ b/examples/typec/power_delivery/src/main.c @@ -184,7 +184,7 @@ void led_blinking_task(void) static bool led_state = false; // Blink every interval ms - if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + if ( tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/hw/bsp/at32f402_405/family.c b/hw/bsp/at32f402_405/family.c index a6c2217fe..b7dbcbd98 100644 --- a/hw/bsp/at32f402_405/family.c +++ b/hw/bsp/at32f402_405/family.c @@ -258,7 +258,7 @@ size_t board_get_unique_id(uint8_t id[], size_t max_len) { system_ticks++; } - uint32_t board_millis(void) + uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/at32f403a_407/family.c b/hw/bsp/at32f403a_407/family.c index dd9b85dc5..d4a7e446d 100644 --- a/hw/bsp/at32f403a_407/family.c +++ b/hw/bsp/at32f403a_407/family.c @@ -250,7 +250,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/at32f413/family.c b/hw/bsp/at32f413/family.c index bdaed523c..adf29e097 100644 --- a/hw/bsp/at32f413/family.c +++ b/hw/bsp/at32f413/family.c @@ -250,7 +250,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/at32f415/family.c b/hw/bsp/at32f415/family.c index 2fbd4c821..b592bf6c5 100644 --- a/hw/bsp/at32f415/family.c +++ b/hw/bsp/at32f415/family.c @@ -246,7 +246,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/at32f423/family.c b/hw/bsp/at32f423/family.c index f30c6a83f..71cb559dc 100644 --- a/hw/bsp/at32f423/family.c +++ b/hw/bsp/at32f423/family.c @@ -250,7 +250,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/at32f425/family.c b/hw/bsp/at32f425/family.c index 4ff4c8d6a..7f443509e 100644 --- a/hw/bsp/at32f425/family.c +++ b/hw/bsp/at32f425/family.c @@ -254,7 +254,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/at32f435_437/family.c b/hw/bsp/at32f435_437/family.c index 01dd429f8..6c6bc4d72 100644 --- a/hw/bsp/at32f435_437/family.c +++ b/hw/bsp/at32f435_437/family.c @@ -320,7 +320,7 @@ volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } void SVC_Handler(void) { diff --git a/hw/bsp/at32f45x/family.c b/hw/bsp/at32f45x/family.c index 0593e5115..fa0c1139f 100644 --- a/hw/bsp/at32f45x/family.c +++ b/hw/bsp/at32f45x/family.c @@ -227,7 +227,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/board.c b/hw/bsp/board.c index 483d9dc28..91e7de9fe 100644 --- a/hw/bsp/board.c +++ b/hw/bsp/board.c @@ -161,10 +161,6 @@ void board_putchar(int c) { (void) sys_write(0, (const char*)&c, 1); } -uint32_t tusb_time_millis_api(void) { - return board_millis(); -} - //-------------------------------------------------------------------- // FreeRTOS hooks //-------------------------------------------------------------------- diff --git a/hw/bsp/board_api.h b/hw/bsp/board_api.h index 606ac484f..4487871eb 100644 --- a/hw/bsp/board_api.h +++ b/hw/bsp/board_api.h @@ -98,43 +98,6 @@ int board_uart_read(uint8_t *buf, int len); // Send characters to UART. Return number of sent bytes int board_uart_write(void const *buf, int len); -#if CFG_TUSB_OS == OPT_OS_NONE -// Get current milliseconds, must be implemented when no RTOS is used -uint32_t board_millis(void); - -#elif CFG_TUSB_OS == OPT_OS_FREERTOS -static inline uint32_t board_millis(void) { - return ( ( ((uint64_t) xTaskGetTickCount()) * 1000) / configTICK_RATE_HZ ); -} - -#elif CFG_TUSB_OS == OPT_OS_MYNEWT -static inline uint32_t board_millis(void) { - return os_time_ticks_to_ms32( os_time_get() ); -} - -#elif CFG_TUSB_OS == OPT_OS_PICO -#include "pico/time.h" -static inline uint32_t board_millis(void) { - return to_ms_since_boot(get_absolute_time()); -} - -#elif CFG_TUSB_OS == OPT_OS_RTTHREAD -static inline uint32_t board_millis(void) { - return (((uint64_t)rt_tick_get()) * 1000 / RT_TICK_PER_SECOND); -} - -#elif CFG_TUSB_OS == OPT_OS_CUSTOM -// Implement your own board_millis() in any of .c file -uint32_t board_millis(void); - -#elif CFG_TUSB_OS == OPT_OS_ZEPHYR -static inline uint32_t board_millis(void) { - return k_uptime_get_32(); -} -#else - #error "board_millis() is not implemented for this OS" -#endif - //--------------------------------------------------------------------+ // Helper functions //--------------------------------------------------------------------+ @@ -175,8 +138,8 @@ static inline size_t board_usb_get_serial(uint16_t desc_str1[], size_t max_chars // TODO remove static inline void board_delay(uint32_t ms) { - uint32_t start_ms = board_millis(); - while ( board_millis() - start_ms < ms ) { + uint32_t start_ms = tusb_time_millis_api(); + while ( tusb_time_millis_api() - start_ms < ms ) { // take chance to run usb background #if CFG_TUD_ENABLED tud_task(); diff --git a/hw/bsp/broadcom_32bit/family.c b/hw/bsp/broadcom_32bit/family.c index f8f3b0b70..399397bb4 100644 --- a/hw/bsp/broadcom_32bit/family.c +++ b/hw/bsp/broadcom_32bit/family.c @@ -146,7 +146,7 @@ void TIMER_1_IRQHandler(void) { SYSTMR->CS_b.M1 = 1; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/broadcom_64bit/family.c b/hw/bsp/broadcom_64bit/family.c index f8f3b0b70..399397bb4 100644 --- a/hw/bsp/broadcom_64bit/family.c +++ b/hw/bsp/broadcom_64bit/family.c @@ -146,7 +146,7 @@ void TIMER_1_IRQHandler(void) { SYSTMR->CS_b.M1 = 1; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/brtmm90x/family.c b/hw/bsp/brtmm90x/family.c index 15ff4b8ee..ff24cfe89 100644 --- a/hw/bsp/brtmm90x/family.c +++ b/hw/bsp/brtmm90x/family.c @@ -234,7 +234,7 @@ int board_uart_write(void const *buf, int len) } // Get current milliseconds -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { uint32_t safe_ms; diff --git a/hw/bsp/ch32f20x/family.c b/hw/bsp/ch32f20x/family.c index 7eae62fa4..dd84b7c77 100644 --- a/hw/bsp/ch32f20x/family.c +++ b/hw/bsp/ch32f20x/family.c @@ -101,7 +101,7 @@ void SysTick_Handler(void) system_ticks++; } -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/ch32v10x/family.c b/hw/bsp/ch32v10x/family.c index dfc041462..344dcaf0b 100644 --- a/hw/bsp/ch32v10x/family.c +++ b/hw/bsp/ch32v10x/family.c @@ -61,7 +61,7 @@ static uint32_t SysTick_Config(uint32_t ticks) { return 0; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/ch32v20x/family.c b/hw/bsp/ch32v20x/family.c index 690acee1e..4c22450f9 100644 --- a/hw/bsp/ch32v20x/family.c +++ b/hw/bsp/ch32v20x/family.c @@ -85,7 +85,7 @@ static uint32_t SysTick_Config(uint32_t ticks) { return 0; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/ch32v30x/family.c b/hw/bsp/ch32v30x/family.c index c694f1a08..6295f7723 100644 --- a/hw/bsp/ch32v30x/family.c +++ b/hw/bsp/ch32v30x/family.c @@ -144,7 +144,7 @@ __attribute__((interrupt)) void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/cxd56/family.c b/hw/bsp/cxd56/family.c index a8e2fd52b..fd92bb9d9 100644 --- a/hw/bsp/cxd56/family.c +++ b/hw/bsp/cxd56/family.c @@ -96,7 +96,7 @@ int board_uart_write(void const *buf, int len) } // Get current milliseconds -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { struct timespec tp; diff --git a/hw/bsp/da1469x/family.c b/hw/bsp/da1469x/family.c index a64ffce67..a4f7f2e8d 100644 --- a/hw/bsp/da1469x/family.c +++ b/hw/bsp/da1469x/family.c @@ -140,7 +140,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/efm32/family.c b/hw/bsp/efm32/family.c index 39166bc4d..d318e20d6 100644 --- a/hw/bsp/efm32/family.c +++ b/hw/bsp/efm32/family.c @@ -689,7 +689,7 @@ void SysTick_Handler(void) system_ticks++; } -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/f1c100s/family.c b/hw/bsp/f1c100s/family.c index 9e864363f..1e71333d4 100644 --- a/hw/bsp/f1c100s/family.c +++ b/hw/bsp/f1c100s/family.c @@ -79,7 +79,7 @@ int board_uart_write(void const* buf, int len) { #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/fomu/family.c b/hw/bsp/fomu/family.c index 9d7977bea..cf04a1f6f 100644 --- a/hw/bsp/fomu/family.c +++ b/hw/bsp/fomu/family.c @@ -117,7 +117,7 @@ int board_uart_write(void const * buf, int len) } #if CFG_TUSB_OS == OPT_OS_NONE -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/gd32vf103/family.c b/hw/bsp/gd32vf103/family.c index 9d15755fc..4c1099317 100644 --- a/hw/bsp/gd32vf103/family.c +++ b/hw/bsp/gd32vf103/family.c @@ -179,7 +179,7 @@ void eclic_mtip_handler(void) { system_ticks++; SysTick_Reload(TIMER_TICKS); } -uint32_t board_millis(void) { return system_ticks; } +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif #ifdef USE_FULL_ASSERT diff --git a/hw/bsp/hpmicro/family.c b/hw/bsp/hpmicro/family.c index ffec2523a..a80a8d913 100644 --- a/hw/bsp/hpmicro/family.c +++ b/hw/bsp/hpmicro/family.c @@ -108,7 +108,7 @@ int board_uart_write(void const *buf, int len) { #if CFG_TUSB_OS == OPT_OS_NONE // Get current milliseconds, must be implemented when no RTOS is used -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return (hpm_csr_get_core_cycle() / clock_get_core_clock_ticks_per_ms()); } diff --git a/hw/bsp/imxrt/family.c b/hw/bsp/imxrt/family.c index d54b41bdb..c1ee34b1a 100644 --- a/hw/bsp/imxrt/family.c +++ b/hw/bsp/imxrt/family.c @@ -239,7 +239,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/kinetis_k/family.c b/hw/bsp/kinetis_k/family.c index 98ef52739..1505defe0 100644 --- a/hw/bsp/kinetis_k/family.c +++ b/hw/bsp/kinetis_k/family.c @@ -143,7 +143,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/kinetis_k32l2/family.c b/hw/bsp/kinetis_k32l2/family.c index 2062b8b18..ec8dc6ecf 100644 --- a/hw/bsp/kinetis_k32l2/family.c +++ b/hw/bsp/kinetis_k32l2/family.c @@ -148,7 +148,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/kinetis_kl/family.c b/hw/bsp/kinetis_kl/family.c index c257f4b2b..f89434d06 100644 --- a/hw/bsp/kinetis_kl/family.c +++ b/hw/bsp/kinetis_kl/family.c @@ -142,7 +142,7 @@ void SysTick_Handler(void) system_ticks++; } -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/lpc11/family.c b/hw/bsp/lpc11/family.c index c9f18bd2f..76c2bd17c 100644 --- a/hw/bsp/lpc11/family.c +++ b/hw/bsp/lpc11/family.c @@ -130,7 +130,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/lpc13/family.c b/hw/bsp/lpc13/family.c index e212c6a63..8513f4df4 100644 --- a/hw/bsp/lpc13/family.c +++ b/hw/bsp/lpc13/family.c @@ -83,7 +83,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/lpc15/family.c b/hw/bsp/lpc15/family.c index 5f22df175..0d092d3a9 100644 --- a/hw/bsp/lpc15/family.c +++ b/hw/bsp/lpc15/family.c @@ -140,7 +140,7 @@ void SysTick_Handler (void) system_ticks++; } -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/lpc17/family.c b/hw/bsp/lpc17/family.c index ba59fccca..f398f7e3c 100644 --- a/hw/bsp/lpc17/family.c +++ b/hw/bsp/lpc17/family.c @@ -145,7 +145,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/lpc18/family.c b/hw/bsp/lpc18/family.c index 6c02c711f..2043cef99 100644 --- a/hw/bsp/lpc18/family.c +++ b/hw/bsp/lpc18/family.c @@ -143,7 +143,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/lpc40/family.c b/hw/bsp/lpc40/family.c index 5ea95e9b8..237cd996b 100644 --- a/hw/bsp/lpc40/family.c +++ b/hw/bsp/lpc40/family.c @@ -156,7 +156,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/lpc43/family.c b/hw/bsp/lpc43/family.c index f440fb119..bade53b07 100644 --- a/hw/bsp/lpc43/family.c +++ b/hw/bsp/lpc43/family.c @@ -257,7 +257,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/lpc51/family.c b/hw/bsp/lpc51/family.c index bec86f87f..847972350 100644 --- a/hw/bsp/lpc51/family.c +++ b/hw/bsp/lpc51/family.c @@ -122,7 +122,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/lpc54/family.c b/hw/bsp/lpc54/family.c index 7bb73afbc..945e27154 100644 --- a/hw/bsp/lpc54/family.c +++ b/hw/bsp/lpc54/family.c @@ -217,7 +217,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/lpc55/family.c b/hw/bsp/lpc55/family.c index ad0e502b5..7485ed4d5 100644 --- a/hw/bsp/lpc55/family.c +++ b/hw/bsp/lpc55/family.c @@ -350,7 +350,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/maxim/family.c b/hw/bsp/maxim/family.c index 7ad7d6ff9..6ef4c12c1 100644 --- a/hw/bsp/maxim/family.c +++ b/hw/bsp/maxim/family.c @@ -202,7 +202,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/mcx/family.c b/hw/bsp/mcx/family.c index 3b91678b1..a3969c217 100644 --- a/hw/bsp/mcx/family.c +++ b/hw/bsp/mcx/family.c @@ -219,7 +219,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/mm32/family.c b/hw/bsp/mm32/family.c index 663c30818..330b01f6d 100644 --- a/hw/bsp/mm32/family.c +++ b/hw/bsp/mm32/family.c @@ -175,7 +175,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/msp430/family.c b/hw/bsp/msp430/family.c index 390a9915e..413ad7db6 100644 --- a/hw/bsp/msp430/family.c +++ b/hw/bsp/msp430/family.c @@ -102,10 +102,10 @@ static void SystemClock_Config(void) // VUSB enabled automatically. // Wait two milliseconds to stabilize, per manual recommendation. - uint32_t ms_elapsed = board_millis(); + uint32_t ms_elapsed = tusb_time_millis_api(); do { - while((board_millis() - ms_elapsed) < 2); + while((tusb_time_millis_api() - ms_elapsed) < 2); }while(!(USBPWRCTL & USBBGVBV)); // USB uses XT2 (4 MHz) directly. Enable the PLL. @@ -113,11 +113,11 @@ static void SystemClock_Config(void) USBPLLCTL |= (UPFDEN | UPLLEN); // Wait until PLL locks. Check every 2ms, per manual. - ms_elapsed = board_millis(); + ms_elapsed = tusb_time_millis_api(); do { USBPLLIR &= ~USBOOLIFG; - while((board_millis() - ms_elapsed) < 2); + while((tusb_time_millis_api() - ms_elapsed) < 2); }while(USBPLLIR & USBOOLIFG); USBKEYPID = 0; @@ -207,7 +207,7 @@ void TIMER0_A0_ISR (void) { // TAxCCR0 CCIFG resets itself as soon as interrupt is invoked. } -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { uint32_t systick_mirror; diff --git a/hw/bsp/msp432e4/family.c b/hw/bsp/msp432e4/family.c index 0e1b0528a..90eb945f4 100644 --- a/hw/bsp/msp432e4/family.c +++ b/hw/bsp/msp432e4/family.c @@ -202,7 +202,7 @@ void SysTick_Handler(void) system_ticks++; } -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index ee3ac61e2..04bfbf320 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -296,7 +296,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/nuc100_120/family.c b/hw/bsp/nuc100_120/family.c index 752af2a56..cfe60121c 100644 --- a/hw/bsp/nuc100_120/family.c +++ b/hw/bsp/nuc100_120/family.c @@ -87,7 +87,7 @@ void SysTick_Handler (void) system_ticks++; } -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/nuc121_125/family.c b/hw/bsp/nuc121_125/family.c index 089855207..dce5b4d62 100644 --- a/hw/bsp/nuc121_125/family.c +++ b/hw/bsp/nuc121_125/family.c @@ -86,7 +86,7 @@ void SysTick_Handler (void) system_ticks++; } -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/nuc126/family.c b/hw/bsp/nuc126/family.c index f992fcab4..3343064e5 100644 --- a/hw/bsp/nuc126/family.c +++ b/hw/bsp/nuc126/family.c @@ -111,7 +111,7 @@ void SysTick_Handler (void) system_ticks++; } -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/nuc505/family.c b/hw/bsp/nuc505/family.c index 00ed92310..f1a77e4a5 100644 --- a/hw/bsp/nuc505/family.c +++ b/hw/bsp/nuc505/family.c @@ -88,7 +88,7 @@ void SysTick_Handler (void) system_ticks++; } -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/pic32mz/family.c b/hw/bsp/pic32mz/family.c index da97f67a9..2bfc876e1 100644 --- a/hw/bsp/pic32mz/family.c +++ b/hw/bsp/pic32mz/family.c @@ -106,7 +106,7 @@ TU_ATTR_WEAK int board_uart_write(void const * buf, int len) } #if CFG_TUSB_OS == OPT_OS_NONE -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { // COUNTER is system clock (200MHz / 2 = 100MHz) convert to ms) return _CP0_GET_COUNT() / (100000000 / 1000); diff --git a/hw/bsp/ra/family.c b/hw/bsp/ra/family.c index 1f75b47c1..f371e694b 100644 --- a/hw/bsp/ra/family.c +++ b/hw/bsp/ra/family.c @@ -169,7 +169,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/rw61x/family.c b/hw/bsp/rw61x/family.c index 265d5fcc0..fcc7fb262 100644 --- a/hw/bsp/rw61x/family.c +++ b/hw/bsp/rw61x/family.c @@ -128,7 +128,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/rx/boards/gr_citrus/gr_citrus.c b/hw/bsp/rx/boards/gr_citrus/gr_citrus.c index 26ad4a6aa..e5b24bf69 100644 --- a/hw/bsp/rx/boards/gr_citrus/gr_citrus.c +++ b/hw/bsp/rx/boards/gr_citrus/gr_citrus.c @@ -248,7 +248,7 @@ void INT_Excep_CMT0_CMI0(void) ++system_ticks; } -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c index 66a319541..d5c2de05a 100644 --- a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c +++ b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c @@ -299,7 +299,7 @@ void INT_Excep_CMT0_CMI0(void) ++system_ticks; } -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/samd11/family.c b/hw/bsp/samd11/family.c index 6cbf02412..bccbac8ea 100644 --- a/hw/bsp/samd11/family.c +++ b/hw/bsp/samd11/family.c @@ -155,7 +155,7 @@ void SysTick_Handler (void) system_ticks++; } -uint32_t board_millis(void) +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/samd2x_l2x/family.c b/hw/bsp/samd2x_l2x/family.c index a2dc8a8d4..737219b6c 100644 --- a/hw/bsp/samd2x_l2x/family.c +++ b/hw/bsp/samd2x_l2x/family.c @@ -361,7 +361,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/samd5x_e5x/family.c b/hw/bsp/samd5x_e5x/family.c index 5a7105894..c008b9719 100644 --- a/hw/bsp/samd5x_e5x/family.c +++ b/hw/bsp/samd5x_e5x/family.c @@ -210,7 +210,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/same7x/family.c b/hw/bsp/same7x/family.c index 6feefa3b5..ff6ecf277 100644 --- a/hw/bsp/same7x/family.c +++ b/hw/bsp/same7x/family.c @@ -192,7 +192,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/samg/family.c b/hw/bsp/samg/family.c index 5c5fc3c14..b27134305 100644 --- a/hw/bsp/samg/family.c +++ b/hw/bsp/samg/family.c @@ -148,7 +148,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/stm32c0/family.c b/hw/bsp/stm32c0/family.c index e2ba47f45..e20c0ee15 100644 --- a/hw/bsp/stm32c0/family.c +++ b/hw/bsp/stm32c0/family.c @@ -173,7 +173,7 @@ void SysTick_Handler(void) { HAL_IncTick(); } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/stm32f0/family.c b/hw/bsp/stm32f0/family.c index b99b0a8cc..5a35a3e50 100644 --- a/hw/bsp/stm32f0/family.c +++ b/hw/bsp/stm32f0/family.c @@ -160,7 +160,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/stm32f1/family.c b/hw/bsp/stm32f1/family.c index 3147061cf..fae61ca9e 100644 --- a/hw/bsp/stm32f1/family.c +++ b/hw/bsp/stm32f1/family.c @@ -202,7 +202,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/stm32f2/family.c b/hw/bsp/stm32f2/family.c index f95128040..b901bf4cc 100644 --- a/hw/bsp/stm32f2/family.c +++ b/hw/bsp/stm32f2/family.c @@ -145,7 +145,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/stm32f3/family.c b/hw/bsp/stm32f3/family.c index 95bcc7882..fde1e9f6d 100644 --- a/hw/bsp/stm32f3/family.c +++ b/hw/bsp/stm32f3/family.c @@ -156,7 +156,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/stm32f4/family.c b/hw/bsp/stm32f4/family.c index f0e9620f2..665ea114a 100644 --- a/hw/bsp/stm32f4/family.c +++ b/hw/bsp/stm32f4/family.c @@ -251,7 +251,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/stm32f7/family.c b/hw/bsp/stm32f7/family.c index d8f0da201..ce9049abe 100644 --- a/hw/bsp/stm32f7/family.c +++ b/hw/bsp/stm32f7/family.c @@ -312,7 +312,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/stm32g0/family.c b/hw/bsp/stm32g0/family.c index 4b175b0ec..b25897264 100644 --- a/hw/bsp/stm32g0/family.c +++ b/hw/bsp/stm32g0/family.c @@ -181,7 +181,7 @@ void SysTick_Handler(void) { HAL_IncTick(); } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/stm32g4/family.c b/hw/bsp/stm32g4/family.c index d8afa0f95..2e13a1d4b 100644 --- a/hw/bsp/stm32g4/family.c +++ b/hw/bsp/stm32g4/family.c @@ -211,7 +211,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/stm32h5/family.c b/hw/bsp/stm32h5/family.c index fdb12e44f..1e8acd502 100644 --- a/hw/bsp/stm32h5/family.c +++ b/hw/bsp/stm32h5/family.c @@ -207,7 +207,7 @@ void SysTick_Handler(void) { HAL_IncTick(); } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/stm32h7/family.c b/hw/bsp/stm32h7/family.c index a320a7e72..2759dac63 100644 --- a/hw/bsp/stm32h7/family.c +++ b/hw/bsp/stm32h7/family.c @@ -295,7 +295,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/stm32h7rs/family.c b/hw/bsp/stm32h7rs/family.c index 2cc39b7ac..3bf75ba97 100644 --- a/hw/bsp/stm32h7rs/family.c +++ b/hw/bsp/stm32h7rs/family.c @@ -468,7 +468,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/stm32l0/family.c b/hw/bsp/stm32l0/family.c index 6aeab1259..192f014f4 100644 --- a/hw/bsp/stm32l0/family.c +++ b/hw/bsp/stm32l0/family.c @@ -168,7 +168,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/stm32l4/family.c b/hw/bsp/stm32l4/family.c index 65f6b9ab3..c87b643b8 100644 --- a/hw/bsp/stm32l4/family.c +++ b/hw/bsp/stm32l4/family.c @@ -231,7 +231,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/stm32n6/family.c b/hw/bsp/stm32n6/family.c index c839e6b3e..4354616c3 100644 --- a/hw/bsp/stm32n6/family.c +++ b/hw/bsp/stm32n6/family.c @@ -366,7 +366,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/stm32u0/family.c b/hw/bsp/stm32u0/family.c index 50b513d8f..0f91d1f30 100644 --- a/hw/bsp/stm32u0/family.c +++ b/hw/bsp/stm32u0/family.c @@ -174,7 +174,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif diff --git a/hw/bsp/stm32u5/family.c b/hw/bsp/stm32u5/family.c index dfcf5c537..55ca25d58 100644 --- a/hw/bsp/stm32u5/family.c +++ b/hw/bsp/stm32u5/family.c @@ -270,7 +270,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/stm32wb/family.c b/hw/bsp/stm32wb/family.c index 153d10a09..de503c072 100644 --- a/hw/bsp/stm32wb/family.c +++ b/hw/bsp/stm32wb/family.c @@ -174,7 +174,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/stm32wba/family.c b/hw/bsp/stm32wba/family.c index d05415755..e058a80a1 100644 --- a/hw/bsp/stm32wba/family.c +++ b/hw/bsp/stm32wba/family.c @@ -198,7 +198,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { return system_ticks; } +uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { asm( "bkpt 1" ); } diff --git a/hw/bsp/tm4c/family.c b/hw/bsp/tm4c/family.c index ae7f22f00..503d0a8c9 100644 --- a/hw/bsp/tm4c/family.c +++ b/hw/bsp/tm4c/family.c @@ -211,7 +211,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/hw/bsp/xmc4000/family.c b/hw/bsp/xmc4000/family.c index 6fef53025..d0acd04cb 100644 --- a/hw/bsp/xmc4000/family.c +++ b/hw/bsp/xmc4000/family.c @@ -147,7 +147,7 @@ void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) { +uint32_t tusb_time_millis_api(void) { return system_ticks; } diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 9eb0a9337..6ac1405f3 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -90,6 +90,12 @@ // TODO move to a more obvious place/file //--------------------------------------------------------------------+ +// Get current milliseconds, required by some port/configuration without RTOS +extern uint32_t tusb_time_millis_api(void); + +// Delay in milliseconds, use tusb_time_millis_api() by default. required by some port/configuration with no RTOS +extern void tusb_time_delay_ms_api(uint32_t ms); + // flush data cache extern void tusb_app_dcache_flush(uintptr_t addr, uint32_t data_size); diff --git a/src/host/usbh.c b/src/host/usbh.c index 60d78605f..0da5166c2 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -685,7 +685,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { has_deferred_attach = osal_queue_receive(_usbh_daq, &event, 0); } - if (!has_deferred_attach) // skip event queue to process deferred at + if (!has_deferred_attach) // skip event queue to process deferred attach #endif { if (!osal_queue_receive(_usbh_q, &event, timeout_ms)) { diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index b413121a5..9fac0bc1c 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -36,9 +36,6 @@ #include #include "musb_def.h" -//#include "bsp/board_api.h" -extern uint32_t board_millis(void); // TODO remove - typedef uint32_t u32; typedef uint16_t u16; typedef uint8_t u8; diff --git a/src/tusb.c b/src/tusb.c index 40d0e8adf..37aecf693 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -45,21 +45,24 @@ tusb_role_t _tusb_rhport_role[TUP_USBIP_CONTROLLER_NUM] = { TUSB_ROLE_INVALID }; // Weak/Default API, can be overwritten by Application //-------------------------------------------------------------------- - #if CFG_TUSB_OS != OPT_OS_NONE -uint32_t tusb_time_millis_api(void) { +#if CFG_TUSB_OS != OPT_OS_NONE +TU_ATTR_WEAK uint32_t tusb_time_millis_api(void) { return osal_time_millis(); } - #endif TU_ATTR_WEAK void tusb_time_delay_ms_api(uint32_t ms) { -#if CFG_TUSB_OS != OPT_OS_NONE osal_task_delay(ms); +} + #else +// tusb_time_millis_api() must be implemented by user application. + +TU_ATTR_WEAK void tusb_time_delay_ms_api(uint32_t ms) { // delay using millis() const uint32_t time_ms = tusb_time_millis_api(); while ((tusb_time_millis_api() - time_ms) < ms) {} -#endif } +#endif TU_ATTR_WEAK void *tusb_app_virt_to_phys(void *virt_addr) { return virt_addr; diff --git a/src/tusb.h b/src/tusb.h index 742009a2e..3876bf863 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -174,16 +174,6 @@ bool tusb_deinit(uint8_t rhport); #endif -//--------------------------------------------------------------------+ -// -//--------------------------------------------------------------------+ - -// Get current milliseconds, required by some port/configuration without RTOS -extern uint32_t tusb_time_millis_api(void); - -// Delay in milliseconds, use tusb_time_millis_api() by default. required by some port/configuration with no RTOS -extern void tusb_time_delay_ms_api(uint32_t ms); - #ifdef __cplusplus } #endif -- cgit v1.3.1 From 0daa444a9b337262c25fe2a2b4598bd3401464e5 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 2 Mar 2026 15:05:28 +0700 Subject: - rename to usbh_defer_func_ms_async() - call after (enum non-blocking delay) also support rtos now --- src/host/usbh.c | 65 +++++++++++++++++++++-------------------------------- src/host/usbh_pvt.h | 3 +++ 2 files changed, 28 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/host/usbh.c b/src/host/usbh.c index 0da5166c2..a674b040e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -201,10 +201,7 @@ typedef struct { uint8_t attach_debouncing_bm; // bitmask for roothub port attach debouncing tuh_bus_info_t dev0_bus; // bus info for dev0 in enumeration usbh_ctrl_xfer_info_t ctrl_xfer_info; // control transfer - - #if CFG_TUSB_OS_HAS_SCHEDULER == 0 // call after only needed for non-scheduler OS usbh_call_after_t call_after; - #endif } usbh_data_t; static usbh_data_t _usbh_data = { @@ -328,6 +325,7 @@ TU_ATTR_ALWAYS_INLINE static inline usbh_class_driver_t const *get_driver(uint8_ // Function Inline and Prototypes //--------------------------------------------------------------------+ static void enum_new_device(hcd_event_t* event); +static void enum_delay_async(uintptr_t state); static void process_remove_event(hcd_event_t *event); static void remove_device_tree(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port); static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size); @@ -366,19 +364,12 @@ TU_ATTR_ALWAYS_INLINE static inline bool usbh_setup_send(uint8_t daddr, const ui } // For non-scheduler deferred callback. For scheduler OS: blocking delay then callback -static bool usbh_call_after_ms(uint32_t ms, tusb_defer_func_t func, uintptr_t param) { - #if CFG_TUSB_OS_HAS_SCHEDULER - TU_LOG_USBH("USBH sleep for %u ms\r\n", (unsigned int)ms); - osal_task_delay(ms); - func(param); - #else +bool usbh_defer_func_ms_async(uint32_t ms, tusb_defer_func_t func, uintptr_t param) { TU_ASSERT(_usbh_data.call_after.func == NULL); - TU_LOG_USBH("USBH start timer for %u ms\r\n", (unsigned int)ms); + TU_LOG_USBH("USBH schedule function after %u ms\r\n", (unsigned int)ms); _usbh_data.call_after.func = func; _usbh_data.call_after.arg = param; _usbh_data.call_after.at_ms = tusb_time_millis_api() + ms; - #endif - return true; } @@ -393,6 +384,10 @@ TU_ATTR_ALWAYS_INLINE static inline void usbh_device_close(uint8_t rhport, uint8 // invalidate if enumerating if (daddr == _usbh_data.enumerating_daddr) { _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8; + // clear enum delay function of the device being removed + if (_usbh_data.call_after.func == enum_delay_async) { + _usbh_data.call_after.func = NULL; + } } } @@ -662,18 +657,20 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { } #endif - #if CFG_TUSB_OS_HAS_SCHEDULER == 0 // Process call_after_ms function if ms is reached tusb_defer_func_t after_cb = _usbh_data.call_after.func; if (after_cb) { - uint32_t ms = tusb_time_millis_api(); - if (ms >= _usbh_data.call_after.at_ms) { - TU_LOG_USBH("USBH run timer callback\r\n"); + int32_t ms = (int32_t)(_usbh_data.call_after.at_ms - tusb_time_millis_api()); + if (ms <= 0) { + // delay expired, run callback now + TU_LOG_USBH("USBH invoke scheduled function\r\n"); _usbh_data.call_after.func = NULL; after_cb(_usbh_data.call_after.arg); + } else if (timeout_ms > (uint32_t)ms) { + // reduce main event timeout to make sure we don't blocking more than call_after timeout + timeout_ms = (uint32_t)ms; } } - #endif hcd_event_t event; @@ -716,7 +713,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { break; case HCD_EVENT_DEVICE_REMOVE: - TU_LOG_USBH("[%u:%u:%u] USBH DEVICE REMOVED\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port); + TU_LOG_USBH("[%u:%u:%u] USBH Device Removed\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port); process_remove_event(&event); break; @@ -1543,19 +1540,8 @@ enum { ENUM_AFTER_SET_ADDRESS_RECOVERY_DELAY, }; - // fallthrough to avoid recursive call of enum_async_delay() - #if CFG_TUSB_OS_HAS_SCHEDULER - #define ENUM_ASYNC_DELAY_OR_FALLTHROUGH(_ms, _state) \ - osal_task_delay(_ms); \ - TU_ATTR_FALLTHROUGH - #else - #define ENUM_ASYNC_DELAY_OR_FALLTHROUGH(_ms, _state) \ - usbh_call_after_ms(_ms, enum_async_delay, _state); \ - break - #endif - // process async delay in enumeration -static void enum_async_delay(uintptr_t state) { +static void enum_delay_async(uintptr_t state) { tuh_bus_info_t *dev0_bus = &_usbh_data.dev0_bus; switch (state) { case ENUM_AFTER_DEBOUNCING_DELAY: @@ -1565,7 +1551,6 @@ static void enum_async_delay(uintptr_t state) { TU_VERIFY(dev0_bus->hub_port != 0, ); TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, NULL, process_enumeration, ENUM_HUB_RERSET), ); - break; } else #endif { @@ -1577,12 +1562,14 @@ static void enum_async_delay(uintptr_t state) { return; } hcd_port_reset(dev0_bus->rhport); // reset port - ENUM_ASYNC_DELAY_OR_FALLTHROUGH(ENUM_RESET_ROOT_DELAY_MS, ENUM_AFTER_RESET_ROOT_DELAY); + usbh_defer_func_ms_async(ENUM_RESET_ROOT_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_ROOT_DELAY); } + break; case ENUM_AFTER_RESET_ROOT_DELAY: hcd_port_reset_end(dev0_bus->rhport); - ENUM_ASYNC_DELAY_OR_FALLTHROUGH(ENUM_RESET_ROOT_POST_DELAY_MS, ENUM_AFTER_RESET_ROOT_POST_DELAY); + usbh_defer_func_ms_async(ENUM_RESET_ROOT_POST_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_ROOT_POST_DELAY); + break; case ENUM_AFTER_RESET_ROOT_POST_DELAY: if (!hcd_port_connect_status(dev0_bus->rhport)) { @@ -1651,7 +1638,7 @@ static void enum_new_device(hcd_event_t *event) { dev0_bus->rhport = event->rhport; dev0_bus->hub_addr = event->connection.hub_addr; dev0_bus->hub_port = event->connection.hub_port; - usbh_call_after_ms(ENUM_DEBOUNCING_DELAY_MS, enum_async_delay, ENUM_AFTER_DEBOUNCING_DELAY); + usbh_defer_func_ms_async(ENUM_DEBOUNCING_DELAY_MS, enum_delay_async, ENUM_AFTER_DEBOUNCING_DELAY); } // process device enumeration @@ -1688,7 +1675,7 @@ static void process_enumeration(tuh_xfer_t *xfer) { case ENUM_HUB_RESET_COMPLETE: // wait for reset to take effect - usbh_call_after_ms(ENUM_RESET_HUB_DELAY_MS, enum_async_delay, ENUM_AFTER_RESET_HUB_DELAY); + usbh_defer_func_ms_async(ENUM_RESET_HUB_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_HUB_DELAY); break; case ENUM_HUB_CLEAR_RESET: @@ -1702,7 +1689,7 @@ static void process_enumeration(tuh_xfer_t *xfer) { ENUM_HUB_CLEAR_RESET_COMPLETE), ); } else if (state == ENUM_HUB_CLEAR_RESET) { // retry one more time if reset change not set yet - usbh_call_after_ms(ENUM_RESET_HUB_DELAY_MS, enum_async_delay, ENUM_AFTER_RESET_HUB_DELAY_RETRY); + usbh_defer_func_ms_async(ENUM_RESET_HUB_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_HUB_DELAY_RETRY); } else { // retry but still not set --> failed enum_full_complete(false); @@ -1729,7 +1716,7 @@ static void process_enumeration(tuh_xfer_t *xfer) { #endif case ENUM_ADDR0_DEVICE_DESC: - usbh_call_after_ms(ENUM_RESET_RECOVERY_DELAY_MS, enum_async_delay, ENUM_AFTER_RESET_RECOVERY_DELAY); + usbh_defer_func_ms_async(ENUM_RESET_RECOVERY_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_RECOVERY_DELAY); break; case ENUM_SET_ADDR: { @@ -1754,7 +1741,7 @@ static void process_enumeration(tuh_xfer_t *xfer) { _usbh_data.enumerating_daddr = new_addr; usbh_device_close(dev0_bus->rhport, 0); // close dev0 - usbh_call_after_ms(ENUM_SET_ADDRESS_RECOVERY_DELAY_MS, enum_async_delay, ENUM_AFTER_SET_ADDRESS_RECOVERY_DELAY); + usbh_defer_func_ms_async(ENUM_SET_ADDRESS_RECOVERY_DELAY_MS, enum_delay_async, ENUM_AFTER_SET_ADDRESS_RECOVERY_DELAY); break; } @@ -2048,9 +2035,7 @@ static void enum_full_complete(bool success) { (void)success; _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8; // mark enumeration as complete - #if CFG_TUSB_OS_HAS_SCHEDULER == 0 _usbh_data.call_after.func = NULL; - #endif #if CFG_TUH_HUB // Hub status is already requested in case of successful enumeration diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h index ecb692e9d..bc8658b9a 100644 --- a/src/host/usbh_pvt.h +++ b/src/host/usbh_pvt.h @@ -71,6 +71,9 @@ void usbh_int_set(bool enabled); // Invoke this function later in tuh_task() by putting it into task queue void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr); +// Schedules a function to be called after certain time in async manner +bool usbh_defer_func_ms_async(uint32_t ms, tusb_defer_func_t func, uintptr_t param); + void usbh_spin_lock(bool in_isr); void usbh_spin_unlock(bool in_isr); -- cgit v1.3.1 From 4df7ef54396e1695aa9504aef9dfe4263569c3f6 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 2 Mar 2026 17:51:48 +0700 Subject: fix call_after timeout adjustment with rtos --- hw/bsp/stm32h7/boards/stm32h743eval/board.h | 4 ++-- src/host/usbh.c | 10 +++++++--- src/host/usbh_pvt.h | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/hw/bsp/stm32h7/boards/stm32h743eval/board.h b/hw/bsp/stm32h7/boards/stm32h743eval/board.h index 0f0eb4ed3..d2f61a5ce 100644 --- a/hw/bsp/stm32h7/boards/stm32h743eval/board.h +++ b/hw/bsp/stm32h7/boards/stm32h743eval/board.h @@ -120,10 +120,10 @@ static inline void SystemClock_Config(void) { // From H743 eval manual ETM can only work at 50 MHz clock by default because ETM signals // are shared with other peripherals. Trace CLK = PLL1R. RCC_OscInitStruct.PLL.PLLM = 5; - RCC_OscInitStruct.PLL.PLLN = 160; // May reduce to 200 Mhz when tracing to avoid overflowing trace buffer + RCC_OscInitStruct.PLL.PLLN = 160; // May reduce to 100/200 Mhz when tracing to avoid overflowing trace buffer RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLQ = 4; - RCC_OscInitStruct.PLL.PLLR = 16; // Trace clock is limit to 50 Mhz to meet board requirement + RCC_OscInitStruct.PLL.PLLR = RCC_OscInitStruct.PLL.PLLN/10; // Trace clock is limit to 50 Mhz to meet board requirement RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM; RCC_OscInitStruct.PLL.PLLFRACN = 0; diff --git a/src/host/usbh.c b/src/host/usbh.c index a674b040e..5cf0096f2 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -363,7 +363,6 @@ TU_ATTR_ALWAYS_INLINE static inline bool usbh_setup_send(uint8_t daddr, const ui return ret; } -// For non-scheduler deferred callback. For scheduler OS: blocking delay then callback bool usbh_defer_func_ms_async(uint32_t ms, tusb_defer_func_t func, uintptr_t param) { TU_ASSERT(_usbh_data.call_after.func == NULL); TU_LOG_USBH("USBH schedule function after %u ms\r\n", (unsigned int)ms); @@ -666,8 +665,12 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { TU_LOG_USBH("USBH invoke scheduled function\r\n"); _usbh_data.call_after.func = NULL; after_cb(_usbh_data.call_after.arg); - } else if (timeout_ms > (uint32_t)ms) { - // reduce main event timeout to make sure we don't blocking more than call_after timeout + } + + // above after_cb() can re-schedule another function, we need to re-check and reduce timeout of + // the main event timeout to make sure we aren't blocking more than call_after timeout. + if (_usbh_data.call_after.func != NULL && + timeout_ms > (uint32_t)(_usbh_data.call_after.at_ms - tusb_time_millis_api())) { timeout_ms = (uint32_t)ms; } } @@ -2033,6 +2036,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) { static void enum_full_complete(bool success) { (void)success; + TU_LOG_USBH("Enumeration complete: success = %u\r\n", success); _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8; // mark enumeration as complete _usbh_data.call_after.func = NULL; diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h index bc8658b9a..adb6a8c44 100644 --- a/src/host/usbh_pvt.h +++ b/src/host/usbh_pvt.h @@ -71,7 +71,7 @@ void usbh_int_set(bool enabled); // Invoke this function later in tuh_task() by putting it into task queue void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr); -// Schedules a function to be called after certain time in async manner +// Schedules a function to be called after certain time asynchronously bool usbh_defer_func_ms_async(uint32_t ms, tusb_defer_func_t func, uintptr_t param); void usbh_spin_lock(bool in_isr); -- cgit v1.3.1 From 4fa4d39883a6328d4628525cfc163516fd919aba Mon Sep 17 00:00:00 2001 From: Tomas Rezucha Date: Mon, 2 Mar 2026 12:29:09 +0100 Subject: fix(dcd/dwc2): Do not modify FS PHY registers on HS PHY ESP32-P4 --- src/portable/synopsys/dwc2/dcd_dwc2.c | 36 +++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 2e2b050bc..b52646a5d 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -527,34 +527,38 @@ void dcd_remote_wakeup(uint8_t rhport) { } void dcd_connect(uint8_t rhport) { - (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); #ifdef TUP_USBIP_DWC2_ESP32 - usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf; - conf.pad_pull_override = 0; - conf.dp_pullup = 0; - conf.dp_pulldown = 0; - conf.dm_pullup = 0; - conf.dm_pulldown = 0; - USB_WRAP.otg_conf = conf; + // On ESP32-P4 HS PHY, do not write to USB_WRAP register which belongs to FS PHY + if (rhport == 0) { + usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf; + conf.pad_pull_override = 0; + conf.dp_pullup = 0; + conf.dp_pulldown = 0; + conf.dm_pullup = 0; + conf.dm_pulldown = 0; + USB_WRAP.otg_conf = conf; + } #endif dwc2->dctl &= ~DCTL_SDIS; } void dcd_disconnect(uint8_t rhport) { - (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); #ifdef TUP_USBIP_DWC2_ESP32 - usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf; - conf.pad_pull_override = 1; - conf.dp_pullup = 0; - conf.dp_pulldown = 1; - conf.dm_pullup = 0; - conf.dm_pulldown = 1; - USB_WRAP.otg_conf = conf; + // On ESP32-P4 HS PHY, do not write to USB_WRAP register which belongs to FS PHY + if (rhport == 0) { + usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf; + conf.pad_pull_override = 1; + conf.dp_pullup = 0; + conf.dp_pulldown = 1; + conf.dm_pullup = 0; + conf.dm_pulldown = 1; + USB_WRAP.otg_conf = conf; + } #endif dwc2->dctl |= DCTL_SDIS; -- cgit v1.3.1 From d9a7d1023c1fd38981ecbfc9fbb37bc14c4f85a1 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 2 Mar 2026 20:07:16 +0700 Subject: improve timeout adjustment, exit tuh_task() by timeout_ms = 0 --- src/host/usbh.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/host/usbh.c b/src/host/usbh.c index 5cf0096f2..e161d212e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -659,8 +659,8 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { // Process call_after_ms function if ms is reached tusb_defer_func_t after_cb = _usbh_data.call_after.func; if (after_cb) { - int32_t ms = (int32_t)(_usbh_data.call_after.at_ms - tusb_time_millis_api()); - if (ms <= 0) { + int32_t remain_ms = (int32_t)(_usbh_data.call_after.at_ms - tusb_time_millis_api()); + if (remain_ms <= 0) { // delay expired, run callback now TU_LOG_USBH("USBH invoke scheduled function\r\n"); _usbh_data.call_after.func = NULL; @@ -669,9 +669,11 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { // above after_cb() can re-schedule another function, we need to re-check and reduce timeout of // the main event timeout to make sure we aren't blocking more than call_after timeout. - if (_usbh_data.call_after.func != NULL && - timeout_ms > (uint32_t)(_usbh_data.call_after.at_ms - tusb_time_millis_api())) { - timeout_ms = (uint32_t)ms; + if (_usbh_data.call_after.func != NULL) { + remain_ms = (int32_t) (_usbh_data.call_after.at_ms - tusb_time_millis_api()); + if (remain_ms > 0 && timeout_ms > (uint32_t)remain_ms) { + timeout_ms = (uint32_t)remain_ms; + } } } @@ -789,16 +791,8 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { break; } - #if CFG_TUSB_OS_HAS_SCHEDULER - // return if there are no more events, to allow application to run other backgrounds - if (osal_queue_empty(_usbh_q) - #if CFG_TUH_HUB - && osal_queue_empty(_usbh_daq) - #endif - ) { - return; - } - #endif + // allow to exit tuh_task() if there is no event in the next run + timeout_ms = 0; } } -- cgit v1.3.1 From 2a27bd9db0f97f2d5034336626accbe2bb6bd330 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 2 Mar 2026 22:32:15 +0700 Subject: more call_after timeout adjustment with rtos --- src/host/usbh.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/host/usbh.c b/src/host/usbh.c index e161d212e..20791340e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -668,10 +668,12 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { } // above after_cb() can re-schedule another function, we need to re-check and reduce timeout of - // the main event timeout to make sure we aren't blocking more than call_after timeout. + // the main event timeout to make sure we aren't blocking more than call_after remaining ms. if (_usbh_data.call_after.func != NULL) { remain_ms = (int32_t) (_usbh_data.call_after.at_ms - tusb_time_millis_api()); - if (remain_ms > 0 && timeout_ms > (uint32_t)remain_ms) { + if (remain_ms <= 0) { + timeout_ms = 0; // expired already + } else if (timeout_ms > (uint32_t)remain_ms) { timeout_ms = (uint32_t)remain_ms; } } -- cgit v1.3.1 From 30af158af9ada161d31e02d08548f78390183920 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 4 Mar 2026 17:30:40 +0700 Subject: add PHY deinitialization support for DWC2 driver across all MCUs --- src/portable/synopsys/dwc2/dcd_dwc2.c | 6 ------ src/portable/synopsys/dwc2/dwc2_at32.h | 5 +++++ src/portable/synopsys/dwc2/dwc2_bcm.h | 6 ++++++ src/portable/synopsys/dwc2/dwc2_common.c | 27 +++++++++++++-------------- src/portable/synopsys/dwc2/dwc2_common.h | 1 + src/portable/synopsys/dwc2/dwc2_efm32.h | 8 ++++++++ src/portable/synopsys/dwc2/dwc2_esp32.h | 6 ++++++ src/portable/synopsys/dwc2/dwc2_gd32.h | 6 ++++++ src/portable/synopsys/dwc2/dwc2_nrf.h | 5 +++++ src/portable/synopsys/dwc2/dwc2_stm32.h | 14 ++++++++++++++ src/portable/synopsys/dwc2/dwc2_xmc.h | 7 +++++++ src/portable/synopsys/dwc2/hcd_dwc2.c | 16 ++++++++++++++-- 12 files changed, 85 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 2c76098a4..8685ec6dc 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -493,13 +493,7 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { } bool dcd_deinit(uint8_t rhport) { - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - - // Disable global interrupt - dwc2->gahbcfg &= ~GAHBCFG_GINT; - dcd_disconnect(rhport); - dwc2_core_deinit(rhport); return true; } diff --git a/src/portable/synopsys/dwc2/dwc2_at32.h b/src/portable/synopsys/dwc2/dwc2_at32.h index 10824ae92..95ee8a8e1 100644 --- a/src/portable/synopsys/dwc2/dwc2_at32.h +++ b/src/portable/synopsys/dwc2/dwc2_at32.h @@ -112,6 +112,11 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t *dwc2, uint8_ } } +// MCU specific PHY deinit, disable PHY power +TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_deinit(dwc2_regs_t *dwc2) { + dwc2->stm32_gccfg &= ~(STM32_GCCFG_PWRDWN | STM32_GCCFG_DCDEN | STM32_GCCFG_PDEN); +} + // MCU specific PHY update, it is called AFTER init() and core reset TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t *dwc2, uint8_t hs_phy_type) { (void) dwc2; diff --git a/src/portable/synopsys/dwc2/dwc2_bcm.h b/src/portable/synopsys/dwc2/dwc2_bcm.h index df6d4a852..852db15e5 100644 --- a/src/portable/synopsys/dwc2/dwc2_bcm.h +++ b/src/portable/synopsys/dwc2/dwc2_bcm.h @@ -73,6 +73,12 @@ static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) // nothing to do } +// MCU specific PHY deinit, disable PHY power +static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2) { + (void) dwc2; + // nothing to do +} + // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index a6afc3154..4e8e1ff04 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -39,14 +39,11 @@ static void reset_core(dwc2_regs_t* dwc2) { while (!(dwc2->grstctl & GRSTCTL_AHBIDL)) { } - // load gsnpsid (it is not readable after reset is asserted) - const uint32_t gsnpsid = dwc2->gsnpsid; - - // reset core - dwc2->grstctl |= GRSTCTL_CSRST; + const uint32_t gsnpsid = dwc2->gsnpsid; // preload gsnpsid which is not readable while resetting + dwc2->grstctl |= GRSTCTL_CSRST; // reset core if ((gsnpsid & DWC2_CORE_REV_MASK) < (DWC2_CORE_REV_4_20a & DWC2_CORE_REV_MASK)) { - // prior v4.20a: CSRST is self-clearing and the core clears this bit after all the necessary logic is reset in + // prior v4.20a: CSRST is self-clearing, and the core clears this bit after all the necessary logic is reset in // the core, which can take several clocks, depending on the current state of the core. Once this bit has been // cleared, the software must wait at least 3 PHY clocks before accessing the PHY domain (synchronization delay). while (dwc2->grstctl & GRSTCTL_CSRST) {} @@ -88,8 +85,7 @@ static void phy_fs_init(dwc2_regs_t* dwc2) { } /* dwc2 has 2 highspeed PHYs options - * - UTMI+ is internal highspeed PHY, can be clocked at 30/60 Mhz for fullspeed or 60 Mhz for highspeed. Can be either - * 8 or 16-bit interface. + * - UTMI+ is internal highspeed PHY, can be clocked at 30 Mhz (8-bit) or 60 Mhz (16-bit). * - ULPI is external highspeed PHY, clocked at 60Mhz with 8-bit interface. * * In addition, UTMI+/ULPI can be shared to run at fullspeed mode with 48Mhz @@ -250,14 +246,17 @@ bool dwc2_core_init(uint8_t rhport, bool is_hs_phy, bool is_dma) { void dwc2_core_deinit(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); - // Soft disconnect - dwc2->dctl |= DCTL_SDIS; - - // Reset global registers - dwc2->gotgctl = 0; + // Disable global interrupt + dwc2->gahbcfg &= ~GAHBCFG_GINT; - // Reset core + // Reset core: this also flushes FIFOs and clears all interrupt registers reset_core(dwc2); + + // Stop PHY clock and gate HCLK for power saving (per databook chapter 14) + dwc2->pcgcctl |= PCGCCTL_STOPPCLK | PCGCCTL_GATEHCLK; + + // MCU-specific PHY deinit (disable PHY power) + dwc2_phy_deinit(dwc2); } // void dwc2_core_handle_common_irq(uint8_t rhport, bool in_isr) { diff --git a/src/portable/synopsys/dwc2/dwc2_common.h b/src/portable/synopsys/dwc2/dwc2_common.h index c74ad2233..ac97ab3d5 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.h +++ b/src/portable/synopsys/dwc2/dwc2_common.h @@ -42,6 +42,7 @@ // - _dwc2_controller[]: array of controllers // - DWC2_EP_MAX: largest EP counts of all controllers // - dwc2_phy_init/dwc2_phy_update: phy init called before and after core reset +// - dwc2_phy_deinit: phy deinit to disable PHY power // - dwc2_dcd_int_enable/dwc2_dcd_int_disable // - dwc2_remote_wakeup_delay diff --git a/src/portable/synopsys/dwc2/dwc2_efm32.h b/src/portable/synopsys/dwc2/dwc2_efm32.h index 0e3570cbb..f808b567c 100644 --- a/src/portable/synopsys/dwc2/dwc2_efm32.h +++ b/src/portable/synopsys/dwc2/dwc2_efm32.h @@ -72,6 +72,14 @@ static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) USB->ROUTE = USB_ROUTE_PHYPEN; } +// MCU specific PHY deinit, disable PHY power +static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2) { + (void) dwc2; + + // Disable PHY pin + USB->ROUTE = 0; +} + // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index a4e0d1770..f4fa0bf8b 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -121,6 +121,12 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_ } +// MCU specific PHY deinit, disable PHY power +TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_deinit(dwc2_regs_t* dwc2) { + (void)dwc2; + // PHY managed by ESP-IDF +} + // MCU specific PHY update, it is called AFTER init() and core reset TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { (void)dwc2; diff --git a/src/portable/synopsys/dwc2/dwc2_gd32.h b/src/portable/synopsys/dwc2/dwc2_gd32.h index 0375fffe4..26b924161 100644 --- a/src/portable/synopsys/dwc2/dwc2_gd32.h +++ b/src/portable/synopsys/dwc2/dwc2_gd32.h @@ -85,6 +85,12 @@ static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) // nothing to do } +// MCU specific PHY deinit, disable PHY power +static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2) { + (void) dwc2; + // nothing to do +} + // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { diff --git a/src/portable/synopsys/dwc2/dwc2_nrf.h b/src/portable/synopsys/dwc2/dwc2_nrf.h index b93571f16..17d21518b 100644 --- a/src/portable/synopsys/dwc2/dwc2_nrf.h +++ b/src/portable/synopsys/dwc2/dwc2_nrf.h @@ -52,6 +52,11 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_ (void)hs_phy_type; } +// MCU specific PHY deinit, disable PHY power +TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_deinit(dwc2_regs_t* dwc2) { + (void)dwc2; +} + // MCU specific PHY update, it is called AFTER init() and core reset TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { (void)dwc2; diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 753917a20..cc972e957 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -264,6 +264,20 @@ static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { } } +// MCU specific PHY deinit, disable PHY power +static inline void dwc2_phy_deinit(dwc2_regs_t* dwc2) { + // Disable on-chip FS PHY + dwc2->stm32_gccfg &= ~STM32_GCCFG_PWRDWN; + + // Disable HS PHY if present + #ifdef USB_HS_PHYC + dwc2->stm32_gccfg &= ~STM32_GCCFG_PHYHSEN; + // Disable PLL and LDO + USB_HS_PHYC->USB_HS_PHYC_PLL &= ~USB_HS_PHYC_PLL_PLLEN; + USB_HS_PHYC->USB_HS_PHYC_LDO &= ~USB_HS_PHYC_LDO_ENABLE; + #endif +} + // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { // used to set turnaround time for fullspeed, nothing to do in highspeed mode diff --git a/src/portable/synopsys/dwc2/dwc2_xmc.h b/src/portable/synopsys/dwc2/dwc2_xmc.h index 63419abf7..e38935e9c 100644 --- a/src/portable/synopsys/dwc2/dwc2_xmc.h +++ b/src/portable/synopsys/dwc2/dwc2_xmc.h @@ -71,6 +71,13 @@ static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) //USB->ROUTE = USB_ROUTE_PHYPEN; } +// MCU specific PHY deinit, disable PHY power +static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2) { + (void) dwc2; + + // nothing to do +} + // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index 420b3fe4b..e12e44a41 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -448,8 +448,9 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { bool hcd_deinit(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); - // Disable global interrupt - dwc2->gahbcfg &= ~GAHBCFG_GINT; + // Turn off VBUS + dwc2->hprt = HPRT_W1_MASK; // clear w1c bits without side effects + // HPRT_POWER is not set -> VBUS off dwc2_core_deinit(rhport); return true; @@ -1359,6 +1360,17 @@ static bool handle_sof_irq(uint8_t rhport, bool in_isr) { } // Config HCFG FS/LS clock and HFIR for SOF interval according to link speed (value is in PHY clock unit) +// Databook Table 2-2: System Clock Speeds +// +-----------+------------------+----------+-----------+-------------------+ +// | PHY | PHY Clock (MHz) | Width | HCFG.Sel | HFIR (clk cycles) | +// +-----------+------------------+----------+-----------+-------------------+ +// | HS UTMI+ | 30 | 16-bit | 30_60 | HS:3749 FS:29999 | +// | HS UTMI+ | 60 | 8-bit | 30_60 | HS:7499 FS:59999 | +// | HS ULPI | 60 | 8-bit | 30_60 | HS:7499 FS:59999 | +// | FS (dead.) | 48 | internal | 48 | FS:47999 | +// | LS via FS | 48 (6 effective) | internal | 6 | LS:47999 | +// +-----------+------------------+----------+-----------+-------------------+ +// HFIR = (interval_us * phy_clock) - 1, where interval is 125us (HS) or 1000us (FS/LS) static void port0_enable(dwc2_regs_t* dwc2, tusb_speed_t speed) { uint32_t hcfg = dwc2->hcfg & ~HCFG_FSLS_PHYCLK_SEL; -- cgit v1.3.1 From 1efe4cd0e84e965db7c5056f4339c83102e997ab Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 5 Mar 2026 10:01:40 +0700 Subject: add hs_phy_type parameter to dwc2_phy_deinit for selective PHY deinitialization across all MCUs --- src/portable/synopsys/dwc2/dwc2_at32.h | 3 ++- src/portable/synopsys/dwc2/dwc2_bcm.h | 3 ++- src/portable/synopsys/dwc2/dwc2_common.c | 4 +++- src/portable/synopsys/dwc2/dwc2_common.h | 2 +- src/portable/synopsys/dwc2/dwc2_efm32.h | 4 ++-- src/portable/synopsys/dwc2/dwc2_esp32.h | 3 ++- src/portable/synopsys/dwc2/dwc2_gd32.h | 3 ++- src/portable/synopsys/dwc2/dwc2_nrf.h | 3 ++- src/portable/synopsys/dwc2/dwc2_stm32.h | 24 +++++++++++++----------- src/portable/synopsys/dwc2/dwc2_xmc.h | 4 ++-- 10 files changed, 31 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/dwc2_at32.h b/src/portable/synopsys/dwc2/dwc2_at32.h index 95ee8a8e1..fa6d10c12 100644 --- a/src/portable/synopsys/dwc2/dwc2_at32.h +++ b/src/portable/synopsys/dwc2/dwc2_at32.h @@ -113,7 +113,8 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t *dwc2, uint8_ } // MCU specific PHY deinit, disable PHY power -TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_deinit(dwc2_regs_t *dwc2) { +TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_deinit(dwc2_regs_t *dwc2, uint8_t hs_phy_type) { + (void) hs_phy_type; dwc2->stm32_gccfg &= ~(STM32_GCCFG_PWRDWN | STM32_GCCFG_DCDEN | STM32_GCCFG_PDEN); } diff --git a/src/portable/synopsys/dwc2/dwc2_bcm.h b/src/portable/synopsys/dwc2/dwc2_bcm.h index 852db15e5..00842bba2 100644 --- a/src/portable/synopsys/dwc2/dwc2_bcm.h +++ b/src/portable/synopsys/dwc2/dwc2_bcm.h @@ -74,8 +74,9 @@ static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) } // MCU specific PHY deinit, disable PHY power -static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2) { +static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { (void) dwc2; + (void) hs_phy_type; // nothing to do } diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index 4e8e1ff04..33eabaeab 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -256,7 +256,9 @@ void dwc2_core_deinit(uint8_t rhport) { dwc2->pcgcctl |= PCGCCTL_STOPPCLK | PCGCCTL_GATEHCLK; // MCU-specific PHY deinit (disable PHY power) - dwc2_phy_deinit(dwc2); + const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; + const uint8_t hs_phy_type = (dwc2->gusbcfg & GUSBCFG_PHYSEL) ? GHWCFG2_HSPHY_NOT_SUPPORTED : ghwcfg2.hs_phy_type; + dwc2_phy_deinit(dwc2, hs_phy_type); } // void dwc2_core_handle_common_irq(uint8_t rhport, bool in_isr) { diff --git a/src/portable/synopsys/dwc2/dwc2_common.h b/src/portable/synopsys/dwc2/dwc2_common.h index ac97ab3d5..9f28ab2e0 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.h +++ b/src/portable/synopsys/dwc2/dwc2_common.h @@ -42,7 +42,7 @@ // - _dwc2_controller[]: array of controllers // - DWC2_EP_MAX: largest EP counts of all controllers // - dwc2_phy_init/dwc2_phy_update: phy init called before and after core reset -// - dwc2_phy_deinit: phy deinit to disable PHY power +// - dwc2_phy_deinit(dwc2, hs_phy_type): phy deinit to disable PHY power, only deinit the phy used by core // - dwc2_dcd_int_enable/dwc2_dcd_int_disable // - dwc2_remote_wakeup_delay diff --git a/src/portable/synopsys/dwc2/dwc2_efm32.h b/src/portable/synopsys/dwc2/dwc2_efm32.h index f808b567c..e1cb7c769 100644 --- a/src/portable/synopsys/dwc2/dwc2_efm32.h +++ b/src/portable/synopsys/dwc2/dwc2_efm32.h @@ -73,9 +73,9 @@ static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) } // MCU specific PHY deinit, disable PHY power -static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2) { +static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { (void) dwc2; - + (void) hs_phy_type; // Disable PHY pin USB->ROUTE = 0; } diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index f4fa0bf8b..ff9f216bd 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -122,8 +122,9 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_ } // MCU specific PHY deinit, disable PHY power -TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_deinit(dwc2_regs_t* dwc2) { +TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_deinit(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { (void)dwc2; + (void)hs_phy_type; // PHY managed by ESP-IDF } diff --git a/src/portable/synopsys/dwc2/dwc2_gd32.h b/src/portable/synopsys/dwc2/dwc2_gd32.h index 26b924161..ccbf93a76 100644 --- a/src/portable/synopsys/dwc2/dwc2_gd32.h +++ b/src/portable/synopsys/dwc2/dwc2_gd32.h @@ -86,8 +86,9 @@ static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) } // MCU specific PHY deinit, disable PHY power -static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2) { +static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { (void) dwc2; + (void) hs_phy_type; // nothing to do } diff --git a/src/portable/synopsys/dwc2/dwc2_nrf.h b/src/portable/synopsys/dwc2/dwc2_nrf.h index 17d21518b..51f2d684f 100644 --- a/src/portable/synopsys/dwc2/dwc2_nrf.h +++ b/src/portable/synopsys/dwc2/dwc2_nrf.h @@ -53,8 +53,9 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_ } // MCU specific PHY deinit, disable PHY power -TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_deinit(dwc2_regs_t* dwc2) { +TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_deinit(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { (void)dwc2; + (void)hs_phy_type; } // MCU specific PHY update, it is called AFTER init() and core reset diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index cc972e957..259ad21b9 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -265,17 +265,19 @@ static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { } // MCU specific PHY deinit, disable PHY power -static inline void dwc2_phy_deinit(dwc2_regs_t* dwc2) { - // Disable on-chip FS PHY - dwc2->stm32_gccfg &= ~STM32_GCCFG_PWRDWN; - - // Disable HS PHY if present - #ifdef USB_HS_PHYC - dwc2->stm32_gccfg &= ~STM32_GCCFG_PHYHSEN; - // Disable PLL and LDO - USB_HS_PHYC->USB_HS_PHYC_PLL &= ~USB_HS_PHYC_PLL_PLLEN; - USB_HS_PHYC->USB_HS_PHYC_LDO &= ~USB_HS_PHYC_LDO_ENABLE; - #endif +static inline void dwc2_phy_deinit(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { + if (hs_phy_type == GHWCFG2_HSPHY_NOT_SUPPORTED) { + // Disable on-chip FS PHY + dwc2->stm32_gccfg &= ~STM32_GCCFG_PWRDWN; + } else { + // Disable HS PHY + #ifdef USB_HS_PHYC + dwc2->stm32_gccfg &= ~STM32_GCCFG_PHYHSEN; + // Disable PLL and LDO + USB_HS_PHYC->USB_HS_PHYC_PLL &= ~USB_HS_PHYC_PLL_PLLEN; + USB_HS_PHYC->USB_HS_PHYC_LDO &= ~USB_HS_PHYC_LDO_ENABLE; + #endif + } } // MCU specific PHY update, it is called AFTER init() and core reset diff --git a/src/portable/synopsys/dwc2/dwc2_xmc.h b/src/portable/synopsys/dwc2/dwc2_xmc.h index e38935e9c..aca3873df 100644 --- a/src/portable/synopsys/dwc2/dwc2_xmc.h +++ b/src/portable/synopsys/dwc2/dwc2_xmc.h @@ -72,9 +72,9 @@ static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) } // MCU specific PHY deinit, disable PHY power -static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2) { +static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { (void) dwc2; - + (void) hs_phy_type; // nothing to do } -- cgit v1.3.1 From 70c93adc2f6264015cae597a9abe58ad2e1aaee6 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 5 Mar 2026 17:51:57 +0700 Subject: improve threadx support, add multi ROTS support for board_test and msc_dual_lun --- AGENTS.md | 57 +++++++++++- examples/device/board_test/src/main.c | 80 +++++++++++++++- examples/device/msc_dual_lun/src/main.c | 160 ++++++++++++++++++++++++++------ hw/bsp/board.c | 55 +++++++++++ hw/bsp/family_support.cmake | 20 ++++ hw/bsp/stm32h7/family.c | 9 ++ src/osal/osal_threadx.h | 27 ++++-- tools/get_deps.py | 3 + 8 files changed, 370 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/AGENTS.md b/AGENTS.md index b4f87e98c..34fc57cb8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -114,13 +114,65 @@ Use `-DBOARD=...` with any supported board under `hw/bsp/espressif/boards/`. NEV - `cd examples/device/cdc_msc_freertos` - `idf.py -DBOARD=espressif_s3_devkitc monitor` -## J-Link GDB Server + RTT Logging +## GDB Debugging + +Look up the board's `JLINK_DEVICE` and `OPENOCD_OPTION` from `hw/bsp/*/boards/*/board.cmake` (or `board.mk`). + +### JLinkGDBServer + +**Terminal 1 – start the GDB server:** +```bash +JLinkGDBServer -device stm32h743xi -if SWD -speed 4000 \ + -port 2331 -swoport 2332 -telnetport 2333 -nogui +``` + +**Terminal 2 – connect GDB:** +```bash +arm-none-eabi-gdb /tmp/build/firmware.elf +(gdb) target remote :2331 +(gdb) monitor reset halt +(gdb) load +(gdb) continue +``` + +To break on entry instead of running immediately: +```bash +(gdb) monitor reset halt +(gdb) load +(gdb) break main +(gdb) continue +``` + +### OpenOCD + +**Terminal 1 – start the GDB server:** +```bash +openocd -f interface/stlink.cfg -f target/stm32h7x.cfg +# or with J-Link probe: +openocd -f interface/jlink.cfg -f target/stm32h7x.cfg +``` + +For boards that define `OPENOCD_OPTION` in `board.cmake`, use those options directly: +```bash +openocd $(cat hw/bsp/FAMILY/boards/BOARD/board.cmake | grep OPENOCD_OPTION | ...) +``` + +**Terminal 2 – connect GDB (OpenOCD default port is 3333):** +```bash +arm-none-eabi-gdb /tmp/build/firmware.elf +(gdb) target remote :3333 +(gdb) monitor reset halt +(gdb) load +(gdb) continue +``` + +### RTT Logging with JLinkGDBServer - Build with RTT logging enabled (example): `cd examples/device/cdc_msc && make BOARD=stm32h743eval LOG=2 LOGGER=rtt all` - Flash with J-Link: `cd examples/device/cdc_msc && make BOARD=stm32h743eval LOG=2 LOGGER=rtt flash-jlink` -- Launch GDB server (keep this running in terminal 1): +- Launch GDB server with RTT port (keep this running in terminal 1): `JLinkGDBServer -device stm32h743xi -if SWD -speed 4000 -port 2331 -swoport 2332 -telnetport 2333 -RTTTelnetPort 19021 -nogui` - Read RTT output (terminal 2): `JLinkRTTClient` @@ -128,7 +180,6 @@ Use `-DBOARD=...` with any supported board under `hw/bsp/espressif/boards/`. NEV `JLinkRTTClient | tee rtt.log` - For non-interactive capture: `timeout 20s JLinkRTTClient > rtt.log` -- Use the board-specific `JLINK_DEVICE` from `hw/bsp/*/boards/*/board.mk` if you are not using `stm32h743eval`. ## Unit Testing diff --git a/examples/device/board_test/src/main.c b/examples/device/board_test/src/main.c index 757876ac8..ddc9bba6b 100644 --- a/examples/device/board_test/src/main.c +++ b/examples/device/board_test/src/main.c @@ -39,10 +39,7 @@ enum { #define HELLO_STR "Hello from TinyUSB\r\n" -int main(void) { - board_init(); - board_led_write(true); - +static void board_test_loop(void) { uint32_t start_ms = 0; bool led_state = false; @@ -76,8 +73,83 @@ int main(void) { } } +#if CFG_TUSB_OS == OPT_OS_FREERTOS +static void freertos_init(void); +#endif + +int main(void) { + board_init(); + board_led_write(true); + +#if CFG_TUSB_OS == OPT_OS_FREERTOS + freertos_init(); +#elif CFG_TUSB_OS == OPT_OS_THREADX + tx_kernel_enter(); +#else + board_test_loop(); +#endif + + return 0; +} + #ifdef ESP_PLATFORM void app_main(void) { main(); } #endif + +//--------------------------------------------------------------------+ +// FreeRTOS +//--------------------------------------------------------------------+ +#if CFG_TUSB_OS == OPT_OS_FREERTOS + +#ifdef ESP_PLATFORM +#define MAIN_STACK_SIZE 4096 +#else +#define MAIN_STACK_SIZE configMINIMAL_STACK_SIZE +#endif + +#if configSUPPORT_STATIC_ALLOCATION +static StackType_t _main_stack[MAIN_STACK_SIZE]; +static StaticTask_t _main_taskdef; +#endif + +static void board_test_task(void* param) { + (void) param; + board_test_loop(); +} + +static void freertos_init(void) { + #if configSUPPORT_STATIC_ALLOCATION + xTaskCreateStatic(board_test_task, "main", MAIN_STACK_SIZE, NULL, 1, _main_stack, &_main_taskdef); + #else + xTaskCreate(board_test_task, "main", MAIN_STACK_SIZE, NULL, 1, NULL); + #endif + #ifndef ESP_PLATFORM + vTaskStartScheduler(); + #endif +} + +//--------------------------------------------------------------------+ +// ThreadX +//--------------------------------------------------------------------+ +#elif CFG_TUSB_OS == OPT_OS_THREADX + +#define MAIN_TASK_STACK_SIZE 1024 +static TX_THREAD _main_thread; +static ULONG _main_thread_stack[MAIN_TASK_STACK_SIZE / sizeof(ULONG)]; +static void main_thread_entry(ULONG arg); + +static void main_thread_entry(ULONG arg) { + (void) arg; + board_test_loop(); +} + +void tx_application_define(void *first_unused_memory) { + (void) first_unused_memory; + static CHAR main_thread_name[] = "main"; + tx_thread_create(&_main_thread, main_thread_name, main_thread_entry, 0, + _main_thread_stack, MAIN_TASK_STACK_SIZE, + 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); +} +#endif diff --git a/examples/device/msc_dual_lun/src/main.c b/examples/device/msc_dual_lun/src/main.c index b459871f7..9ca3a1f34 100644 --- a/examples/device/msc_dual_lun/src/main.c +++ b/examples/device/msc_dual_lun/src/main.c @@ -31,7 +31,7 @@ #include "tusb.h" //--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF PROTYPES +// MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ /* Blink pattern @@ -41,71 +41,179 @@ */ enum { BLINK_NOT_MOUNTED = 250, - BLINK_MOUNTED = 1000, - BLINK_SUSPENDED = 2500, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; -void led_blinking_task(void); +// Task parameter type: ULONG for ThreadX, void* for FreeRTOS and noos +#if CFG_TUSB_OS == OPT_OS_THREADX + #define RTOS_PARAM ULONG +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + #define RTOS_PARAM void* + static void freertos_init(void); +#else + #define RTOS_PARAM void* +#endif -/*------------- MAIN -------------*/ -int main(void) { - board_init(); +void led_blinking_task(RTOS_PARAM param); - // init device stack on configured roothub port +//--------------------------------------------------------------------+ +// USB Device Task +//--------------------------------------------------------------------+ +static void usb_device_init(void) { tusb_rhport_init_t dev_init = { - .role = TUSB_ROLE_DEVICE, + .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); - board_init_after_tusb(); +} + +#if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO +static void usb_device_task(RTOS_PARAM param) { + (void) param; + usb_device_init(); while (1) { - tud_task(); // tinyusb device task - led_blinking_task(); + tud_task(); } } +#endif //--------------------------------------------------------------------+ -// Device callbacks +// Main //--------------------------------------------------------------------+ +int main(void) { + board_init(); + +#if CFG_TUSB_OS == OPT_OS_FREERTOS + freertos_init(); + +#elif CFG_TUSB_OS == OPT_OS_THREADX + tx_kernel_enter(); + +#else + // noos + pico-sdk: init USB then run polling loop + usb_device_init(); -// Invoked when device is mounted + while (1) { + tud_task(); + led_blinking_task(NULL); + } +#endif + + return 0; +} + +#ifdef ESP_PLATFORM +void app_main(void) { + main(); +} +#endif + +//--------------------------------------------------------------------+ +// Device callbacks +//--------------------------------------------------------------------+ void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } -// Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } -// Invoked when usb bus is suspended -// remote_wakeup_en : if host allow us to perform remote wakeup -// Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } -// Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ -// BLINKING TASK +// Blinking Task //--------------------------------------------------------------------+ -void led_blinking_task(void) { +void led_blinking_task(RTOS_PARAM param) { + (void) param; static uint32_t start_ms = 0; static bool led_state = false; - // Blink every interval ms - if (tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time - start_ms += blink_interval_ms; + while (1) { +#if CFG_TUSB_OS == OPT_OS_FREERTOS + vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); +#elif CFG_TUSB_OS == OPT_OS_THREADX + tx_thread_sleep(_osal_ms2tick(blink_interval_ms)); +#else + if (tusb_time_millis_api() - start_ms < blink_interval_ms) { + return; // not enough time + } +#endif + + start_ms += blink_interval_ms; + board_led_write(led_state); + led_state = 1 - led_state; // toggle + } +} + +//--------------------------------------------------------------------+ +// FreeRTOS +//--------------------------------------------------------------------+ +#if CFG_TUSB_OS == OPT_OS_FREERTOS + +#ifdef ESP_PLATFORM +#define USBD_STACK_SIZE 4096 +#else +#define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2 * (CFG_TUSB_DEBUG ? 2 : 1)) +#endif +#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE + +#if configSUPPORT_STATIC_ALLOCATION +static StackType_t _usb_device_stack[USBD_STACK_SIZE]; +static StaticTask_t _usb_device_taskdef; +static StackType_t _blinky_stack[BLINKY_STACK_SIZE]; +static StaticTask_t _blinky_taskdef; +#endif + + +static void freertos_init(void) { + #if configSUPPORT_STATIC_ALLOCATION + xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, _usb_device_stack, &_usb_device_taskdef); + xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, _blinky_stack, &_blinky_taskdef); + #else + xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); + xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); + #endif + #ifndef ESP_PLATFORM + vTaskStartScheduler(); + #endif +} - board_led_write(led_state); - led_state = 1 - led_state; // toggle +//--------------------------------------------------------------------+ +// ThreadX +//--------------------------------------------------------------------+ +#elif CFG_TUSB_OS == OPT_OS_THREADX + +#define USBD_STACK_SIZE 4096 +#define BLINKY_STACK_SIZE 1024 + +static TX_THREAD _usb_device_thread; +static ULONG _usb_device_stack[USBD_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD _blinky_thread; +static ULONG _blinky_stack[BLINKY_STACK_SIZE / sizeof(ULONG)]; + +void tx_application_define(void *first_unused_memory) { + (void) first_unused_memory; + static CHAR usbd_name[] = "usbd"; + static CHAR blinky_name[] = "blinky"; + tx_thread_create(&_usb_device_thread, usbd_name, usb_device_task, 0, + _usb_device_stack, USBD_STACK_SIZE, + 0, 0, TX_NO_TIME_SLICE, TX_AUTO_START); + tx_thread_create(&_blinky_thread, blinky_name, led_blinking_task, 0, + _blinky_stack, BLINKY_STACK_SIZE, + 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); } + +#endif diff --git a/hw/bsp/board.c b/hw/bsp/board.c index 91e7de9fe..0553a7eb7 100644 --- a/hw/bsp/board.c +++ b/hw/bsp/board.c @@ -251,3 +251,58 @@ void vApplicationSetupTimerInterrupt(void) { #endif #endif + +//-------------------------------------------------------------------- +// ThreadX hooks for ARM Cortex-M +//-------------------------------------------------------------------- +#if CFG_TUSB_OS == OPT_OS_THREADX && defined(__ARM_ARCH) + +#include "tx_api.h" +#include "tx_initialize.h" + +// Newlib linker symbol: end of statically allocated RAM (start of heap) +extern ULONG _end; + +// CMSIS standard variable for system clock frequency +extern uint32_t SystemCoreClock; + +// Cortex-M SysTick registers (fixed addresses on all Cortex-M) +#define _TX_SYST_CSR (*((volatile uint32_t *)0xE000E010U)) +#define _TX_SYST_RVR (*((volatile uint32_t *)0xE000E014U)) +#define _TX_SYST_CVR (*((volatile uint32_t *)0xE000E018U)) +// SCB->SHP[10] = PendSV priority, [11] = SysTick priority (byte access at SCB base + 0xD22) +#define _TX_SCB_SHPR3 (*((volatile uint32_t *)0xE000ED20U)) + +VOID _tx_initialize_low_level(VOID) { + // Set the first available memory address for tx_application_define + _tx_initialize_unused_memory = (VOID *)(&_end); + + // Configure SysTick for ThreadX tick rate: enable with processor clock + interrupt + _TX_SYST_RVR = (SystemCoreClock / TX_TIMER_TICKS_PER_SECOND) - 1u; + _TX_SYST_CVR = 0u; + _TX_SYST_CSR = 0x07u; // CLKSOURCE=1, TICKINT=1, ENABLE=1 + + // SHPR3 bits[31:24] = SysTick priority, bits[23:16] = PendSV priority + // PendSV must be lowest priority (0xFF). SysTick must be higher than PendSV (0x40) + // so SysTick can preempt the PendSV scheduler idle loop (__tx_ts_wait) to tick the timer. + _TX_SCB_SHPR3 = (_TX_SCB_SHPR3 & 0x0000FFFFU) | 0x40FF0000U; +} + +// Weak callback for board-specific SysTick work (e.g. HAL_IncTick on STM32) +void osal_threadx_tick_cb(void); +TU_ATTR_WEAK void osal_threadx_tick_cb(void) { } + +// SysTick drives the ThreadX timer tick +extern void _tx_timer_interrupt(void); +void SysTick_Handler(void); +void SysTick_Handler(void) { + osal_threadx_tick_cb(); + _tx_timer_interrupt(); +} + +// tusb_time_millis_api() based on ThreadX tick counter +uint32_t tusb_time_millis_api(void) { + return (uint32_t)((uint64_t) tx_time_get() * 1000u / TX_TIMER_TICKS_PER_SECOND); +} + +#endif diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 699afda92..4299ad44e 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -380,6 +380,26 @@ function(family_add_rtos TARGET RTOS) target_link_libraries(${TARGET} PUBLIC freertos_kernel) target_compile_definitions(${TARGET} PUBLIC CFG_TUSB_OS=OPT_OS_FREERTOS) + elseif (RTOS STREQUAL "threadx") + if (NOT TARGET threadx) + # Derive THREADX_ARCH from CMAKE_SYSTEM_CPU if not explicitly set + if (NOT DEFINED THREADX_ARCH) + string(REPLACE "-" "_" THREADX_ARCH ${CMAKE_SYSTEM_CPU}) + endif () + # Derive THREADX_TOOLCHAIN from TOOLCHAIN if not explicitly set + if (NOT DEFINED THREADX_TOOLCHAIN) + if (TOOLCHAIN STREQUAL "iar") + set(THREADX_TOOLCHAIN "iar") + elseif (TOOLCHAIN STREQUAL "clang") + set(THREADX_TOOLCHAIN "ac6") + else () + set(THREADX_TOOLCHAIN "gnu") + endif () + endif () + add_subdirectory(${TOP}/lib/threadx ${CMAKE_BINARY_DIR}/lib/threadx) + endif () + target_link_libraries(${TARGET} PUBLIC threadx) + target_compile_definitions(${TARGET} PUBLIC CFG_TUSB_OS=OPT_OS_THREADX) elseif (RTOS STREQUAL "zephyr") target_compile_definitions(${TARGET} PUBLIC CFG_TUSB_OS=OPT_OS_ZEPHYR) target_include_directories(${TARGET} PUBLIC ${ZEPHYR_BASE}/include) diff --git a/hw/bsp/stm32h7/family.c b/hw/bsp/stm32h7/family.c index 2759dac63..c94c2e755 100644 --- a/hw/bsp/stm32h7/family.c +++ b/hw/bsp/stm32h7/family.c @@ -139,6 +139,10 @@ void board_init(void) { #endif NVIC_SetPriority(OTG_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + +#elif CFG_TUSB_OS == OPT_OS_THREADX + // Disable SysTick before kernel entry; _tx_initialize_low_level() will re-configure it + SysTick->CTRL &= ~1UL; #endif GPIO_InitTypeDef GPIO_InitStruct; @@ -299,6 +303,11 @@ uint32_t tusb_time_millis_api(void) { return system_ticks; } +#elif CFG_TUSB_OS == OPT_OS_THREADX +// Keep HAL_GetTick() working for HAL functions called from board_init() +void osal_threadx_tick_cb(void) { + HAL_IncTick(); +} #endif void HardFault_Handler(void) { diff --git a/src/osal/osal_threadx.h b/src/osal/osal_threadx.h index 4f05ef535..6bcf9c5ab 100644 --- a/src/osal/osal_threadx.h +++ b/src/osal/osal_threadx.h @@ -39,18 +39,28 @@ extern "C" { //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline uint32_t _osal_ms2tick(uint32_t msec) { - if ( msec == TX_WAIT_FOREVER ) return TX_WAIT_FOREVER; - if ( msec == 0 ) return 0; + if ( msec == TX_WAIT_FOREVER ) { + return TX_WAIT_FOREVER; + } + if ( msec == 0 ) { + return 0; + } uint32_t ticks = msec * TX_TIMER_TICKS_PER_SECOND / 1000; // TX_TIMER_TICKS_PER_SECOND is less than 1000 and 1 tick > 1 ms // we still need to delay at least 1 tick - if ( ticks == 0 ) ticks = 1; + if ( ticks == 0 ) { + ticks = 1; + } return ticks; } +TU_ATTR_ALWAYS_INLINE static inline uint32_t osal_time_millis(void) { + return (uint32_t)((uint64_t) tx_time_get() * 1000u / TX_TIMER_TICKS_PER_SECOND); +} + TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { tx_thread_sleep(_osal_ms2tick(msec)); } @@ -94,7 +104,7 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, typedef TX_SEMAPHORE osal_semaphore_def_t, * osal_semaphore_t; TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t *semdef) { - tx_semaphore_create(semdef->semaphore, semdef->name, 0); + tx_semaphore_create(semdef, TX_NULL, 0); return semdef; } @@ -113,6 +123,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t se } TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { + (void) sem_hdl; } //--------------------------------------------------------------------+ @@ -152,10 +163,10 @@ typedef TX_QUEUE osal_queue_def_t, * osal_queue_t; #define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ static _type _name##_buf[_depth]; \ osal_queue_def_t _name = { \ - .tx_queue_name = #_name, \ + .tx_queue_name = (CHAR*)(uintptr_t)#_name, \ .tx_queue_message_size = (sizeof(_type) + 3) / 4, \ .tx_queue_capacity = _depth, \ - .tx_queue_start = _name##_buf } + .tx_queue_start = (ULONG *) _name##_buf } TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { @@ -173,8 +184,8 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, v return 0 == tx_queue_receive(qhdl, data, _osal_ms2tick(msec)); } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void *data, bool in_isr) { - return 0 == tx_queue_send(qhdl, data, in_isr ? TX_NO_WAIT : TX_WAIT_FOREVER); +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) { + return 0 == tx_queue_send(qhdl, (VOID *)(uintptr_t) data, in_isr ? TX_NO_WAIT : TX_WAIT_FOREVER); } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { diff --git a/tools/get_deps.py b/tools/get_deps.py index 1d596469b..696914251 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -14,6 +14,9 @@ deps_mandatory = { 'lib/lwip': ['https://github.com/lwip-tcpip/lwip.git', '159e31b689577dbf69cf0683bbaffbd71fa5ee10', 'all'], + 'lib/threadx': ['https://github.com/eclipse-threadx/threadx.git', + '4b6e8100d932a3a67b34c6eb17f84f3bffb9e2ae', + 'all'], 'tools/linkermap': ['https://github.com/hathach/linkermap.git', '8e1f440fa15c567aceb5aa0d14f6d18c329cc67f', 'all'], -- cgit v1.3.1 From 7088dc528bd5a89a77e06798d8b5384962748828 Mon Sep 17 00:00:00 2001 From: Zixun LI Date: Wed, 3 Dec 2025 16:26:56 +0100 Subject: ci_hs: add deinit support Signed-off-by: Zixun LI --- examples/dual/dynamic_switch/only.txt | 2 ++ hw/bsp/lpc43/family.c | 2 ++ src/portable/chipidea/ci_hs/dcd_ci_hs.c | 17 +++++++++++++++++ src/portable/chipidea/ci_hs/hcd_ci_hs.c | 12 ++++++++---- src/portable/ehci/ehci.c | 11 ++++++++--- src/portable/ehci/ehci_api.h | 3 +++ 6 files changed, 40 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/examples/dual/dynamic_switch/only.txt b/examples/dual/dynamic_switch/only.txt index 8508780e6..70be49b28 100644 --- a/examples/dual/dynamic_switch/only.txt +++ b/examples/dual/dynamic_switch/only.txt @@ -1,4 +1,6 @@ family:espressif +mcu:LPC43XX +mcu:MIMXRT1XXX mcu:STM32C0 mcu:STM32G0 mcu:STM32H5 diff --git a/hw/bsp/lpc43/family.c b/hw/bsp/lpc43/family.c index bade53b07..56834a1b0 100644 --- a/hw/bsp/lpc43/family.c +++ b/hw/bsp/lpc43/family.c @@ -185,8 +185,10 @@ void board_init(void) */ Chip_USB1_Init(); +#ifdef _BOARD_EA4357_H // USB0 Vbus Power: P2_3 on EA4357 channel B U20 GPIO26 active low (base board) Chip_SCU_PinMuxSet(2, 3, SCU_MODE_PULLUP | SCU_MODE_INBUFF_EN | SCU_MODE_FUNC7); +#endif #if defined(BOARD_TUD_RHPORT) && BOARD_TUD_RHPORT == 0 // P9_5 (GPIO5[18]) (GPIO28 on oem base) as USB connect, active low. diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index 2bba32ada..b9f6a8a7b 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -285,6 +285,23 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { return true; } +bool dcd_deinit(uint8_t rhport) { + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + + // disable all interrupt + dcd_reg->USBINTR = 0; + + // unattach from bus + dcd_reg->USBCMD &= ~USBCMD_RUN_STOP; + + // flush all endpoints + while (dcd_reg->ENDPTPRIME) {} + dcd_reg->ENDPTFLUSH = 0xFFFFFFFF; + while (dcd_reg->ENDPTFLUSH) {} + + return true; +} + void dcd_int_enable(uint8_t rhport) { CI_DCD_INT_ENABLE(rhport); } diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c index 29ce0cd7f..91adc06b1 100644 --- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -93,14 +93,14 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { hcd_reg->USBCMD |= USBCMD_RESET; while (hcd_reg->USBCMD & USBCMD_RESET) {} - // Set mode to device, must be set immediately after reset + // Set mode to host, must be set immediately after reset #if CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX // LPC18XX/43XX need to set VBUS Power Select to HIGH // RHPORT1 is fullspeed only (need external PHY for Highspeed) hcd_reg->USBMODE = USBMODE_CM_HOST | USBMODE_VBUS_POWER_SELECT; - if (rhport == 1) { - hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED; - } + #if !TUH_OPT_HIGH_SPEED + hcd_reg->PORTSC1 = PORTSC1_FORCE_FULL_SPEED; + #endif #else hcd_reg->USBMODE = USBMODE_CM_HOST; #endif @@ -108,6 +108,10 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { return ehci_init(rhport, (uint32_t)&hcd_reg->CAPLENGTH, (uint32_t)&hcd_reg->USBCMD); } +bool hcd_deinit(uint8_t rhport) { + return ehci_deinit(rhport); +} + void hcd_int_enable(uint8_t rhport) { CI_HCD_INT_ENABLE(rhport); } diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 9b2cf98be..03c3b91fd 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -411,17 +411,22 @@ bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg) return true; } -#if 0 -static void ehci_stop(uint8_t rhport) { +bool ehci_deinit(uint8_t rhport) { (void) rhport; ehci_registers_t* regs = ehci_data.regs; + + // Disable all the interrupt + regs->inten = 0; + + // Disable schedules regs->command_bm.run_stop = 0; // USB Spec: controller has to stop within 16 uframe = 2 frames while( regs->status_bm.hc_halted == 0 ) {} + + return true; } -#endif //--------------------------------------------------------------------+ // Endpoint API diff --git a/src/portable/ehci/ehci_api.h b/src/portable/ehci/ehci_api.h index 79fbe702a..e9018639f 100644 --- a/src/portable/ehci/ehci_api.h +++ b/src/portable/ehci/ehci_api.h @@ -38,6 +38,9 @@ // Initialize EHCI driver bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg); +// De-initialize EHCI driver +bool ehci_deinit(uint8_t rhport); + #ifdef __cplusplus } #endif -- cgit v1.3.1 From 4ed45cf9bc866750492210b0a14bf751d43421ab Mon Sep 17 00:00:00 2001 From: Zixun LI Date: Thu, 5 Mar 2026 16:23:24 +0100 Subject: update PORTSC1 Signed-off-by: Zixun LI --- src/portable/chipidea/ci_hs/hcd_ci_hs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c index 91adc06b1..c0d14fe57 100644 --- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -96,15 +96,15 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { // Set mode to host, must be set immediately after reset #if CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX // LPC18XX/43XX need to set VBUS Power Select to HIGH - // RHPORT1 is fullspeed only (need external PHY for Highspeed) hcd_reg->USBMODE = USBMODE_CM_HOST | USBMODE_VBUS_POWER_SELECT; - #if !TUH_OPT_HIGH_SPEED - hcd_reg->PORTSC1 = PORTSC1_FORCE_FULL_SPEED; - #endif #else hcd_reg->USBMODE = USBMODE_CM_HOST; #endif + #if !TUH_OPT_HIGH_SPEED + hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED; + #endif + return ehci_init(rhport, (uint32_t)&hcd_reg->CAPLENGTH, (uint32_t)&hcd_reg->USBCMD); } -- cgit v1.3.1 From 61e4b9ce3fba2fea731396c56eee1c7b5a2f5338 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 5 Mar 2026 23:24:14 +0700 Subject: add IAR warning flags to cmake build and fix them --- examples/device/cdc_msc/src/msc_disk.c | 2 +- examples/device/cdc_msc_freertos/src/msc_disk.c | 15 +++++-------- examples/device/cdc_uac2/src/main.c | 2 -- .../device/dynamic_configuration/src/msc_disk.c | 15 +++++-------- examples/device/hid_boot_interface/src/main.c | 2 -- examples/device/msc_dual_lun/src/main.c | 2 -- examples/device/net_lwip_webserver/src/main.c | 2 -- examples/device/uac2_speaker_fb/src/main.c | 6 +++-- examples/dual/host_hid_to_device_cdc/src/main.c | 2 -- examples/host/bare_api/src/main.c | 2 -- examples/host/device_info/src/main.c | 1 - examples/host/midi_rx/src/main.c | 2 -- examples/host/msc_file_explorer/src/main.c | 2 -- examples/host/msc_file_explorer/src/msc_app.c | 2 -- hw/bsp/family_support.cmake | 7 ++++++ src/class/dfu/dfu_device.c | 6 ++--- src/common/tusb_fifo.c | 19 ++++++++-------- src/common/tusb_fifo.h | 26 +++++++++------------- src/osal/osal_freertos.h | 18 ++++++++------- 19 files changed, 58 insertions(+), 75 deletions(-) (limited to 'src') diff --git a/examples/device/cdc_msc/src/msc_disk.c b/examples/device/cdc_msc/src/msc_disk.c index e091c2985..017acd039 100644 --- a/examples/device/cdc_msc/src/msc_disk.c +++ b/examples/device/cdc_msc/src/msc_disk.c @@ -238,7 +238,7 @@ int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, u (void) buffer; (void) bufsize; - // currently no other commands is supported + // currently no other commands are supported // Set Sense = Invalid Command Operation (void) tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); diff --git a/examples/device/cdc_msc_freertos/src/msc_disk.c b/examples/device/cdc_msc_freertos/src/msc_disk.c index 29ff86281..ff918205e 100644 --- a/examples/device/cdc_msc_freertos/src/msc_disk.c +++ b/examples/device/cdc_msc_freertos/src/msc_disk.c @@ -324,20 +324,17 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* // - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE // - READ10 and WRITE10 has their own callbacks int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) { - // read10 & write10 has their own callback and MUST not be handled here + (void) lun; + (void) scsi_cmd; (void) buffer; (void) bufsize; - switch (scsi_cmd[0]) { - default: - // Set Sense = Invalid Command Operation - tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); + // currently no other commands are supported - // negative means error -> tinyusb could stall and/or response with failed status - return -1; - } + // Set Sense = Invalid Command Operation + (void) tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); - return -1; + return -1; // stall/failed command request; } #endif diff --git a/examples/device/cdc_uac2/src/main.c b/examples/device/cdc_uac2/src/main.c index 22c462be7..cb7b3a142 100644 --- a/examples/device/cdc_uac2/src/main.c +++ b/examples/device/cdc_uac2/src/main.c @@ -65,8 +65,6 @@ int main(void) // printf("Hello, world!\r\n"); #endif } - - return 0; } //--------------------------------------------------------------------+ diff --git a/examples/device/dynamic_configuration/src/msc_disk.c b/examples/device/dynamic_configuration/src/msc_disk.c index e95b2e197..b545e4652 100644 --- a/examples/device/dynamic_configuration/src/msc_disk.c +++ b/examples/device/dynamic_configuration/src/msc_disk.c @@ -215,20 +215,17 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* // - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE // - READ10 and WRITE10 has their own callbacks int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) { - // read10 & write10 has their own callback and MUST not be handled here + (void) lun; + (void) scsi_cmd; (void) buffer; (void) bufsize; - switch (scsi_cmd[0]) { - default: - // Set Sense = Invalid Command Operation - tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); + // currently no other commands are supported - // negative means error -> tinyusb could stall and/or response with failed status - return -1; - } + // Set Sense = Invalid Command Operation + (void) tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); - return -1; + return -1; // stall/failed command request; } #endif diff --git a/examples/device/hid_boot_interface/src/main.c b/examples/device/hid_boot_interface/src/main.c index 4de319f52..7f2153ae9 100644 --- a/examples/device/hid_boot_interface/src/main.c +++ b/examples/device/hid_boot_interface/src/main.c @@ -67,8 +67,6 @@ int main(void) { hid_task(); } - - return 0; } //--------------------------------------------------------------------+ diff --git a/examples/device/msc_dual_lun/src/main.c b/examples/device/msc_dual_lun/src/main.c index 74a60aa6b..a4ade6f9b 100644 --- a/examples/device/msc_dual_lun/src/main.c +++ b/examples/device/msc_dual_lun/src/main.c @@ -103,8 +103,6 @@ int main(void) { led_blinking_task(NULL); } #endif - - return 0; } #ifdef ESP_PLATFORM diff --git a/examples/device/net_lwip_webserver/src/main.c b/examples/device/net_lwip_webserver/src/main.c index 9f26da2ba..8bd8a8c21 100644 --- a/examples/device/net_lwip_webserver/src/main.c +++ b/examples/device/net_lwip_webserver/src/main.c @@ -276,8 +276,6 @@ int main(void) { sys_check_timeouts(); // service lwip handle_link_state_switch(); } - - return 0; } /* lwip has provision for using a mutex, when applicable */ diff --git a/examples/device/uac2_speaker_fb/src/main.c b/examples/device/uac2_speaker_fb/src/main.c index 8323d82e8..c3e97bb28 100644 --- a/examples/device/uac2_speaker_fb/src/main.c +++ b/examples/device/uac2_speaker_fb/src/main.c @@ -534,8 +534,9 @@ bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); - if (ITF_NUM_AUDIO_STREAMING == itf && alt == 0) + if (ITF_NUM_AUDIO_STREAMING == itf && alt == 0) { blink_interval_ms = BLINK_MOUNTED; + } return true; } @@ -569,7 +570,8 @@ bool tud_audio_rx_done_isr(uint8_t rhport, uint16_t n_bytes_received, uint8_t fu fifo_count = tud_audio_available(); // Same averaging method used in UAC2 class - fifo_count_avg = (uint32_t) (((uint64_t) fifo_count_avg * 63 + ((uint32_t) fifo_count << 16)) >> 6); + const uint32_t ff_count32 = (uint32_t) fifo_count << 16; + fifo_count_avg = (uint32_t) (((uint64_t) fifo_count_avg * 63 + ff_count32) >> 6); return true; } diff --git a/examples/dual/host_hid_to_device_cdc/src/main.c b/examples/dual/host_hid_to_device_cdc/src/main.c index ba8ba019a..c8fca48f8 100644 --- a/examples/dual/host_hid_to_device_cdc/src/main.c +++ b/examples/dual/host_hid_to_device_cdc/src/main.c @@ -98,8 +98,6 @@ int main(void) { tuh_task(); // tinyusb host task led_blinking_task(); } - - return 0; } //--------------------------------------------------------------------+ diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index ced2eaa32..81d4d8731 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -74,8 +74,6 @@ int main(void) { tuh_task(); led_blinking_task(); } - - return 0; } /*------------- TinyUSB Callbacks -------------*/ diff --git a/examples/host/device_info/src/main.c b/examples/host/device_info/src/main.c index fd4e9c3ed..b0e38dd6b 100644 --- a/examples/host/device_info/src/main.c +++ b/examples/host/device_info/src/main.c @@ -105,7 +105,6 @@ int main(void) { tuh_task(); // tinyusb host task led_blinking_task(NULL); } - return 0; #endif } diff --git a/examples/host/midi_rx/src/main.c b/examples/host/midi_rx/src/main.c index f189e0864..fb36906c6 100644 --- a/examples/host/midi_rx/src/main.c +++ b/examples/host/midi_rx/src/main.c @@ -58,8 +58,6 @@ int main(void) { led_blinking_task(); midi_host_rx_task(); } - - return 0; } //--------------------------------------------------------------------+ diff --git a/examples/host/msc_file_explorer/src/main.c b/examples/host/msc_file_explorer/src/main.c index 0a8967380..f6bf9a60a 100644 --- a/examples/host/msc_file_explorer/src/main.c +++ b/examples/host/msc_file_explorer/src/main.c @@ -92,8 +92,6 @@ int main(void) { msc_app_task(); led_blinking_task(); } - - return 0; } //--------------------------------------------------------------------+ diff --git a/examples/host/msc_file_explorer/src/msc_app.c b/examples/host/msc_file_explorer/src/msc_app.c index 40a9ef57e..7e019818a 100644 --- a/examples/host/msc_file_explorer/src/msc_app.c +++ b/examples/host/msc_file_explorer/src/msc_app.c @@ -282,8 +282,6 @@ DRESULT disk_ioctl ( default: return RES_PARERR; } - - return RES_OK; } //--------------------------------------------------------------------+ diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 4299ad44e..c166a0618 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -105,6 +105,12 @@ set(WARN_FLAGS_GNU ) set(WARN_FLAGS_Clang ${WARN_FLAGS_GNU}) +set(WARN_FLAGS_IAR + --warnings_are_errors + --diag_suppress=Pa089 + --diag_suppress=Pe236 + ) + # Optimization if (NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Build type" FORCE) @@ -467,6 +473,7 @@ function(family_configure_common TARGET RTOS) target_link_options(${TARGET} PUBLIC "LINKER:--no-warn-rwx-segments") endif () elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_compile_options(${TARGET} PRIVATE $<$,$>:${WARN_FLAGS_IAR}>) target_link_options(${TARGET} PUBLIC "LINKER:--map=$.map") if (IAR_CSTAT) diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index d3cc53918..a09c53b7e 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -327,7 +327,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control default: if (stage == CONTROL_STAGE_SETUP) { - return reply_getstatus(rhport, request, _dfu_ctx.state, _dfu_ctx.status, 0); + return reply_getstatus(rhport, request, (dfu_state_t) _dfu_ctx.state, (dfu_status_t) _dfu_ctx.status, 0); } break; } @@ -376,7 +376,7 @@ static bool process_download_get_status(uint8_t rhport, uint8_t stage, const tus timeout = 0; } - return reply_getstatus(rhport, request, next_state, _dfu_ctx.status, timeout); + return reply_getstatus(rhport, request, next_state, (dfu_status_t) _dfu_ctx.status, timeout); } else if (stage == CONTROL_STAGE_ACK) { if (_dfu_ctx.flashing_in_progress) { _dfu_ctx.state = DFU_DNBUSY; @@ -405,7 +405,7 @@ static bool process_manifest_get_status(uint8_t rhport, uint8_t stage, const tus timeout = 0; } - return reply_getstatus(rhport, request, next_state, _dfu_ctx.status, timeout); + return reply_getstatus(rhport, request, next_state, (dfu_status_t) _dfu_ctx.status, timeout); } else if (stage == CONTROL_STAGE_ACK) { if (_dfu_ctx.flashing_in_progress) { _dfu_ctx.state = DFU_MANIFEST; diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 9f188f296..8bd79e56d 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -30,11 +30,6 @@ #define TU_FIFO_DBG 0 -// Suppress IAR warning -// Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement -#if defined(__ICCARM__) - #pragma diag_suppress = Pa082 -#endif #if OSAL_MUTEX_REQUIRED @@ -496,7 +491,9 @@ uint16_t tu_fifo_peek_n_access_mode(tu_fifo_t *f, void *p_buffer, uint16_t n, ui // Read n items without removing it from the FIFO, correct read pointer if overflowed uint16_t tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n) { ff_lock(f->mutex_rd); - const uint16_t ret = tu_fifo_peek_n_access_mode(f, p_buffer, n, f->wr_idx, f->rd_idx, NULL); + const uint16_t wr_idx = f->wr_idx; + const uint16_t rd_idx = f->rd_idx; + const uint16_t ret = tu_fifo_peek_n_access_mode(f, p_buffer, n, wr_idx, rd_idx, NULL); ff_unlock(f->mutex_rd); return ret; } @@ -506,7 +503,8 @@ uint16_t tu_fifo_read_n_access_mode(tu_fifo_t *f, void *buffer, uint16_t n, cons ff_lock(f->mutex_rd); // Peek the data: f->rd_idx might get modified in case of an overflow so we can not use a local variable - n = tu_fifo_peek_n_access_mode(f, buffer, n, f->wr_idx, f->rd_idx, access_mode); + const uint16_t wr_idx = f->wr_idx; + n = tu_fifo_peek_n_access_mode(f, buffer, n, wr_idx, f->rd_idx, access_mode); f->rd_idx = advance_index(f->depth, f->rd_idx, n); ff_unlock(f->mutex_rd); @@ -633,7 +631,8 @@ static bool ff_peek_local(tu_fifo_t *f, void *buf, uint16_t wr_idx, uint16_t rd_ bool tu_fifo_read(tu_fifo_t *f, void *buffer) { // Peek the data // f->rd_idx might get modified in case of an overflow so we can not use a local variable - const bool ret = ff_peek_local(f, buffer, f->wr_idx, f->rd_idx); + const uint16_t wr_idx = f->wr_idx; + const bool ret = ff_peek_local(f, buffer, wr_idx, f->rd_idx); if (ret) { ff_lock(f->mutex_rd); f->rd_idx = advance_index(f->depth, f->rd_idx, 1); @@ -645,7 +644,9 @@ bool tu_fifo_read(tu_fifo_t *f, void *buffer) { // Read one item without removing it from the FIFO, correct read index if overflowed bool tu_fifo_peek(tu_fifo_t *f, void *p_buffer) { - return ff_peek_local(f, p_buffer, f->wr_idx, f->rd_idx); + const uint16_t wr_idx = f->wr_idx; + const uint16_t rd_idx = f->rd_idx; + return ff_peek_local(f, p_buffer, wr_idx, rd_idx); } // Write one element into the buffer diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index a3829e38e..b31a0802e 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -120,9 +120,9 @@ typedef struct { uint8_t *buffer; // buffer pointer uint16_t depth; // max items bool overwritable; // overwritable when full - // 1 byte padding here + // 1 byte padding here - volatile uint16_t wr_idx; // write index TODO maybe can drop volatile + volatile uint16_t wr_idx; // write index volatile uint16_t rd_idx; // read index #if OSAL_MUTEX_REQUIRED @@ -289,30 +289,26 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_fifo_empty(const tu_fifo_t *f) { return wr_idx == rd_idx; } -// Suppress IAR warning -// Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement -#if defined(__ICCARM__) -#pragma diag_suppress = Pa082 -#endif - // return number of items in fifo, capped to fifo's depth TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_count(const tu_fifo_t *f) { - return tu_min16(tu_ff_overflow_count(f->depth, f->wr_idx, f->rd_idx), f->depth); + const uint16_t wr_idx = f->wr_idx; + const uint16_t rd_idx = f->rd_idx; + return tu_min16(tu_ff_overflow_count(f->depth, wr_idx, rd_idx), f->depth); } // check if fifo is full TU_ATTR_ALWAYS_INLINE static inline bool tu_fifo_full(const tu_fifo_t *f) { - return tu_ff_overflow_count(f->depth, f->wr_idx, f->rd_idx) >= f->depth; + const uint16_t wr_idx = f->wr_idx; + const uint16_t rd_idx = f->rd_idx; + return tu_ff_overflow_count(f->depth, wr_idx, rd_idx) >= f->depth; } TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_remaining(const tu_fifo_t *f) { - return tu_ff_remaining_local(f->depth, f->wr_idx, f->rd_idx); + const uint16_t wr_idx = f->wr_idx; + const uint16_t rd_idx = f->rd_idx; + return tu_ff_remaining_local(f->depth, wr_idx, rd_idx); } -#if defined(__ICCARM__) - #pragma diag_default=Pa082 -#endif - #ifdef __cplusplus } #endif diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index 32ee2d55c..db724179d 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -141,11 +141,12 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) { TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) { if (in_isr) { - if (TUP_MCU_MULTIPLE_CORE == 0) { - (void) ctx; - return; // single core MCU does not need to lock in ISR - } + #if TUP_MCU_MULTIPLE_CORE *ctx = taskENTER_CRITICAL_FROM_ISR(); + #else + (void) ctx; + return; // single core MCU does not need to lock in ISR + #endif } else { taskENTER_CRITICAL(); } @@ -153,11 +154,12 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bo TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) { if (in_isr) { - if (TUP_MCU_MULTIPLE_CORE == 0) { - (void) ctx; - return; // single core MCU does not need to lock in ISR - } + #if TUP_MCU_MULTIPLE_CORE taskEXIT_CRITICAL_FROM_ISR(*ctx); + #else + (void) ctx; + return; // single core MCU does not need to lock in ISR + #endif } else { taskEXIT_CRITICAL(); } -- cgit v1.3.1 From 94baf394686f92d9edaf109dcae30fa7b531fefc Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 6 Mar 2026 10:59:32 +0700 Subject: fix warnings --- hw/bsp/stm32f1/family.c | 4 ++-- hw/bsp/stm32l0/family.c | 3 ++- hw/bsp/stm32wba/family.c | 5 ++++- lib/networking/rndis_reports.c | 2 +- src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h | 8 ++++---- 5 files changed, 13 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/hw/bsp/stm32f1/family.c b/hw/bsp/stm32f1/family.c index fae61ca9e..78a425453 100644 --- a/hw/bsp/stm32f1/family.c +++ b/hw/bsp/stm32f1/family.c @@ -148,12 +148,12 @@ void board_init(void) { #ifdef USB_CONNECT_PIN void dcd_disconnect(uint8_t rhport) { (void)rhport; - HAL_GPIO_WritePin(USB_CONNECT_PORT, USB_CONNECT_PIN, 1-USB_CONNECT_STATE); + HAL_GPIO_WritePin(USB_CONNECT_PORT, USB_CONNECT_PIN, (GPIO_PinState)(1 - USB_CONNECT_STATE)); } void dcd_connect(uint8_t rhport) { (void)rhport; - HAL_GPIO_WritePin(USB_CONNECT_PORT, USB_CONNECT_PIN, USB_CONNECT_STATE); + HAL_GPIO_WritePin(USB_CONNECT_PORT, USB_CONNECT_PIN, (GPIO_PinState)USB_CONNECT_STATE); } #endif diff --git a/hw/bsp/stm32l0/family.c b/hw/bsp/stm32l0/family.c index 192f014f4..7fd076dbd 100644 --- a/hw/bsp/stm32l0/family.c +++ b/hw/bsp/stm32l0/family.c @@ -123,7 +123,8 @@ void board_init(void) { //--------------------------------------------------------------------+ void board_led_write(bool state) { - HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); + GPIO_PinState pin_state = (GPIO_PinState)(state ? LED_STATE_ON : (1 - LED_STATE_ON)); + HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { diff --git a/hw/bsp/stm32wba/family.c b/hw/bsp/stm32wba/family.c index e058a80a1..878355b48 100644 --- a/hw/bsp/stm32wba/family.c +++ b/hw/bsp/stm32wba/family.c @@ -175,7 +175,10 @@ void board_init(void) { #endif // USB_OTG_HS } -void board_led_write(bool state) { HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } +void board_led_write(bool state) { + GPIO_PinState pin_state = (GPIO_PinState)(state ? LED_STATE_ON : (1 - LED_STATE_ON)); + HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); +} uint32_t board_button_read(void) { return HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN) == BUTTON_STATE_ACTIVE; } diff --git a/lib/networking/rndis_reports.c b/lib/networking/rndis_reports.c index e2849fb10..5e824d5a5 100644 --- a/lib/networking/rndis_reports.c +++ b/lib/networking/rndis_reports.c @@ -44,7 +44,7 @@ static const uint8_t *const permanent_hwaddr = tud_network_mac_address; static usb_eth_stat_t usb_eth_stat = { 0, 0, 0, 0 }; static uint32_t oid_packet_filter = 0x0000000; -static rndis_state_t rndis_state; +TU_ATTR_UNUSED static rndis_state_t rndis_state; static const uint32_t OIDSupportedList[] = { diff --git a/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h b/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h index 178eec419..c22aea887 100644 --- a/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h +++ b/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h @@ -47,10 +47,10 @@ static const ci_hs_controller_t _ci_controller[] = #define CI_HS_REG(_port) ((ci_hs_regs_t*) _ci_controller[_port].reg_base) -#define CI_DCD_INT_ENABLE(_p) NVIC_EnableIRQ (_ci_controller[_p].irqnum) -#define CI_DCD_INT_DISABLE(_p) NVIC_DisableIRQ(_ci_controller[_p].irqnum) +#define CI_DCD_INT_ENABLE(_p) NVIC_EnableIRQ ((IRQn_Type)_ci_controller[_p].irqnum) +#define CI_DCD_INT_DISABLE(_p) NVIC_DisableIRQ((IRQn_Type)_ci_controller[_p].irqnum) -#define CI_HCD_INT_ENABLE(_p) NVIC_EnableIRQ (_ci_controller[_p].irqnum) -#define CI_HCD_INT_DISABLE(_p) NVIC_DisableIRQ(_ci_controller[_p].irqnum) +#define CI_HCD_INT_ENABLE(_p) NVIC_EnableIRQ ((IRQn_Type)_ci_controller[_p].irqnum) +#define CI_HCD_INT_DISABLE(_p) NVIC_DisableIRQ((IRQn_Type)_ci_controller[_p].irqnum) #endif -- cgit v1.3.1 From 5838c7f09dda8921fe6f350871211f8bd5a97208 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 6 Mar 2026 15:11:59 +0700 Subject: update printer class: enhance descriptors, buffer sizes, and callbacks --- AGENTS.md | 3 + examples/device/CMakeLists.txt | 1 + examples/device/printer_to_hid/src/main.c | 18 +- examples/device/printer_to_hid/src/tusb_config.h | 10 +- .../device/printer_to_hid/src/usb_descriptors.c | 243 +++++++++++++-------- .../device/printer_to_hid/src/usb_descriptors.h | 47 +--- src/class/printer/printer.h | 29 ++- src/class/printer/printer_device.c | 105 +++++---- src/class/printer/printer_device.h | 22 +- src/device/usbd.h | 15 -- src/tusb.h | 4 - 11 files changed, 284 insertions(+), 213 deletions(-) (limited to 'src') diff --git a/AGENTS.md b/AGENTS.md index 34fc57cb8..bbbd7c36d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -332,6 +332,9 @@ take 2-5 minutes. NEVER CANCEL. Set timeout to 20+ minutes. - `examples/device/cdc_msc/`: Most commonly used example for testing - `test/unit-test/project.yml`: Ceedling test configuration +#### MCU Reference Manuals and Datasheets +- Look in `$HOME/Documents/Calibre Library` for all MCU reference manuals, datasheets and board schematics. + #### Debugging Build Issues - **Missing compiler**: Install `gcc-arm-none-eabi` package - **Missing dependencies**: Run `python3 tools/get_deps.py FAMILY` diff --git a/examples/device/CMakeLists.txt b/examples/device/CMakeLists.txt index 660df67cb..dbcb8df6a 100644 --- a/examples/device/CMakeLists.txt +++ b/examples/device/CMakeLists.txt @@ -30,6 +30,7 @@ set(EXAMPLE_LIST msc_dual_lun mtp net_lwip_webserver + printer_to_hid uac2_headset uac2_speaker_fb usbtmc diff --git a/examples/device/printer_to_hid/src/main.c b/examples/device/printer_to_hid/src/main.c index 765d1e653..02b54c7d0 100644 --- a/examples/device/printer_to_hid/src/main.c +++ b/examples/device/printer_to_hid/src/main.c @@ -81,7 +81,7 @@ static void hid_tx_task(void) { return; } - if (board_millis() - start_ms < interval_ms) { + if (tusb_time_millis_api() - start_ms < interval_ms) { return; // not enough time } start_ms += interval_ms; @@ -208,6 +208,22 @@ void tud_printer_rx_cb(uint8_t itf, size_t n) { pending_bytes_on_usb_ep += n; // count pending bytes, counter must decrement when reading from the endpoint buffer } +// IEEE 1284 Device ID: first 2 bytes are big-endian total length (including the 2 length bytes). +// The rest is the Device ID string using standard abbreviated keys. +static const char printer_device_id[] = + "\x00\x34" // total length = 52 = 0x0034 (big-endian) + "MFG:TinyUSB;" + "MDL:Printer to HID;" + "CMD:PS;" + "CLS:PRINTER;"; + +TU_VERIFY_STATIC(sizeof(printer_device_id) - 1 == 52, "device ID length mismatch"); + +uint8_t const *tud_printer_get_device_id_cb(uint8_t itf) { + (void)itf; + return (uint8_t const *)printer_device_id; +} + //--------------------------------------------------------------------+ // HID callbacks diff --git a/examples/device/printer_to_hid/src/tusb_config.h b/examples/device/printer_to_hid/src/tusb_config.h index a8dbac89d..0988be166 100644 --- a/examples/device/printer_to_hid/src/tusb_config.h +++ b/examples/device/printer_to_hid/src/tusb_config.h @@ -34,8 +34,6 @@ extern "C" { // Board Specific Configuration //--------------------------------------------------------------------+ -#define BOARD_DEVICE_RHPORT_NUM 3 - // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 @@ -103,10 +101,10 @@ extern "C" { // HID buffer size Should be sufficient to hold ID (if any) + Data #define CFG_TUD_HID_EP_BUFSIZE 16 -// Printer buffer size Should be sufficient to hold data -#define CFG_TUD_PRINTER_RX_BUFSIZE 16 -#define CFG_TUD_PRINTER_TX_BUFSIZE 16 -#define CFG_TUD_PRINTER_EP_BUFSIZE 16 +// Printer buffer sizes +#define CFG_TUD_PRINTER_RX_BUFSIZE 512 +#define CFG_TUD_PRINTER_TX_BUFSIZE 512 +#define CFG_TUD_PRINTER_EP_BUFSIZE 512 #ifdef __cplusplus } diff --git a/examples/device/printer_to_hid/src/usb_descriptors.c b/examples/device/printer_to_hid/src/usb_descriptors.c index 9a88cb891..1cbabb02e 100644 --- a/examples/device/printer_to_hid/src/usb_descriptors.c +++ b/examples/device/printer_to_hid/src/usb_descriptors.c @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2026 Ha Thach (tinyusb.org) + * Copyright (c) 2019 Ha Thach (tinyusb.org) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,117 +28,188 @@ #include "usb_descriptors.h" +#define USB_VID 0xCafe +#define USB_PID 0x4004 +#define USB_BCD 0x0200 //--------------------------------------------------------------------+ -// Report definitions +// Device Descriptors //--------------------------------------------------------------------+ +static tusb_desc_device_t const desc_device = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = USB_BCD, + .bDeviceClass = 0x00, + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = USB_VID, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, -// Values of the string descriptors. Order must match the order defined by STRING_DESCRIPTOR_INDICES. -const char *STRING_DESCRIPTOR_VALUES[] = { - (const char[]){0x09, 0x04}, // 0: Supported language is English (0x0409) - "TinyUSB", // 1: Manufacturer - "TinyUSB Device", // 2: Product - NULL, // 3: Serial number, will use unique ID from the Pi Pico board hardware - "Config1", // 4: Configuration - "Hid1", // 5: HID interface - "Print1", // 6: Printer interface + .bNumConfigurations = 0x01 }; -uint8_t HID_REPORT_DESCRIPTOR[] = {TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(REPORT_ID_KEYBOARD))}; +uint8_t const *tud_descriptor_device_cb(void) { + return (uint8_t const *) &desc_device; +} + +//--------------------------------------------------------------------+ +// HID Report Descriptor +//--------------------------------------------------------------------+ +static uint8_t const desc_hid_report[] = { + TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(REPORT_ID_KEYBOARD)) +}; -uint8_t CONFIG_INTERFACE_ENDPOINT_DESCRIPTOR[] = { +uint8_t const *tud_hid_descriptor_report_cb(uint8_t instance) { + (void)instance; + return desc_hid_report; +} + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ + +// Endpoint numbers +#if defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) + #define EPNUM_HID 0x81 + #define EPNUM_PRINTER_OUT 0x02 + #define EPNUM_PRINTER_IN 0x83 +#else + #define EPNUM_HID 0x81 + #define EPNUM_PRINTER_OUT 0x02 + #define EPNUM_PRINTER_IN 0x82 +#endif + +// full speed configuration +static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(1, ITF_COUNT, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), - // HID: // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval - TUD_HID_DESCRIPTOR(ITF_HID, 0, HID_ITF_PROTOCOL_NONE, sizeof(HID_REPORT_DESCRIPTOR), EPADDR_HID, + TUD_HID_DESCRIPTOR(ITF_NUM_HID, 4, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 5), - // Printer: // Interface number, string index, EP Bulk Out address, EP Bulk In address, EP size - TUD_PRINTER_DESCRIPTOR(ITF_PRINTER, 0, EPADDR_PRINTER_OUT, EPADDR_PRINTER_IN, CFG_TUD_PRINTER_EP_BUFSIZE)}; - -static const tusb_desc_device_t DEVICE_DESCRIPTOR = { - .bLength = sizeof(tusb_desc_device_t), - .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = USB_BCD, - .bDeviceClass = 0x00, // Define class at interface level - .bDeviceSubClass = 0x00, - .bDeviceProtocol = 0x00, - .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + TUD_PRINTER_DESCRIPTOR(ITF_NUM_PRINTER, 5, EPNUM_PRINTER_OUT, EPNUM_PRINTER_IN, 64), +}; - .idVendor = USB_VID, - .idProduct = USB_PID, - .bcdDevice = 0x0100, +#if TUD_OPT_HIGH_SPEED +// high speed configuration +static uint8_t const desc_hs_configuration[] = { + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), - .iManufacturer = STR_MANUFACTURER, - .iProduct = STR_PRODUCT, - .iSerialNumber = STR_SERIAL, + TUD_HID_DESCRIPTOR(ITF_NUM_HID, 4, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, + CFG_TUD_HID_EP_BUFSIZE, 5), - .bNumConfigurations = 0x01 + TUD_PRINTER_DESCRIPTOR(ITF_NUM_PRINTER, 5, EPNUM_PRINTER_OUT, EPNUM_PRINTER_IN, 512), }; +// other speed configuration +static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; -//--------------------------------------------------------------------+ -// TinyUSB callbacks (descriptor requests) -//--------------------------------------------------------------------+ +// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed +static tusb_desc_device_qualifier_t const desc_device_qualifier = { + .bLength = sizeof(tusb_desc_device_qualifier_t), + .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, + .bcdUSB = USB_BCD, -// TinyUSB GET HID REPORT DESCRIPTOR callback. -const uint8_t *tud_hid_descriptor_report_cb(uint8_t instance) { - (void)instance; - return HID_REPORT_DESCRIPTOR; + .bDeviceClass = 0x00, + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + .bNumConfigurations = 0x01, + .bReserved = 0x00 +}; + +uint8_t const *tud_descriptor_device_qualifier_cb(void) { + return (uint8_t const *) &desc_device_qualifier; } -// TinyUSB GET CONFIGURATION DESCRIPTOR callback. -const uint8_t *tud_descriptor_configuration_cb(uint8_t index) { - (void)index; - return CONFIG_INTERFACE_ENDPOINT_DESCRIPTOR; +uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { + (void) index; + + // if link speed is high return fullspeed config, and vice versa + memcpy(desc_other_speed_config, + (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration, + CONFIG_TOTAL_LEN); + + desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; + + return desc_other_speed_config; } -// TinyUSB GET DEVICE DESCRIPTOR callback. -const uint8_t *tud_descriptor_device_cb(void) { - return (const uint8_t *)&DEVICE_DESCRIPTOR; +#endif // TUD_OPT_HIGH_SPEED + +uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { + (void) index; + +#if TUD_OPT_HIGH_SPEED + return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; +#else + return desc_fs_configuration; +#endif } -// Storage buffer array for string descriptor to be sent to host. -static uint16_t string_descriptor_buffer[STRING_DESCRIPTOR_MAX_LENGTH + 1]; - -// TinyUSB GET STRING DESCRIPTOR callback. -const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { - (void)langid; - size_t utf16_string_length; - - if (index == LANGID) { - // langid is not a string as in a series of characters: language ID code is binary, 2 bytes - memcpy(string_descriptor_buffer + 1, STRING_DESCRIPTOR_VALUES[LANGID], 2); - utf16_string_length = 1; // 2 bytes = 1 UTF16 word - - } else if (index == STR_SERIAL) { - // serialnumber is generated from pi pico: see note in STRING_DESCRIPTOR_VALUES definition - utf16_string_length = board_usb_get_serial(string_descriptor_buffer + 1, STRING_DESCRIPTOR_MAX_LENGTH); - - } else if (index < STRING_COUNT) { - // Get adequate descriptor string - const char *str = STRING_DESCRIPTOR_VALUES[index]; - utf16_string_length = strlen(str); - if (utf16_string_length > STRING_DESCRIPTOR_MAX_LENGTH) { - utf16_string_length = STRING_DESCRIPTOR_MAX_LENGTH; - } - // Convert ASCII string from memory (char*) to UTF16 (for buffer), - // store in buffer with 1 UTF16 word offset (2 bytes, for buffer header) - for (size_t i = 0; i < utf16_string_length; i++) { - string_descriptor_buffer[i + 1] = str[i]; - } - - } else { - return NULL; - } +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, + STRID_HID, + STRID_PRINTER, +}; - // Set buffer header: - // byte 1 - buffer length in bytes (including header) - // byte 0 - string descriptor type (0x03). - string_descriptor_buffer[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * utf16_string_length + 2)); +static char const *string_desc_arr[] = { + (const char[]) { 0x09, 0x04 }, // 0: supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + NULL, // 3: Serial, use unique ID if possible + "TinyUSB HID", // 4: HID Interface + "TinyUSB Printer", // 5: Printer Interface +}; + +static uint16_t _desc_str[32 + 1]; + +uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { + (void) langid; + size_t chr_count; + + switch (index) { + case STRID_LANGID: + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + break; + + case STRID_SERIAL: + chr_count = board_usb_get_serial(_desc_str + 1, 32); + break; + + default: + if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } + + const char *str = string_desc_arr[index]; + + chr_count = strlen(str); + size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; + if (chr_count > max_count) { chr_count = max_count; } + + for (size_t i = 0; i < chr_count; i++) { + _desc_str[1 + i] = str[i]; + } + break; + } - return string_descriptor_buffer; + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); + return _desc_str; } diff --git a/examples/device/printer_to_hid/src/usb_descriptors.h b/examples/device/printer_to_hid/src/usb_descriptors.h index 0d9793a9c..20c34f151 100644 --- a/examples/device/printer_to_hid/src/usb_descriptors.h +++ b/examples/device/printer_to_hid/src/usb_descriptors.h @@ -25,52 +25,17 @@ #ifndef USB_DESCRIPTORS_H_ #define USB_DESCRIPTORS_H_ -#include "bsp/board_api.h" -#include "tusb.h" - -#define USB_VID 0xCafe // unassigned vendor id -#define USB_PID 0x4004 // random product id -#define USB_BCD 0x0200 // binary coded version: 2.00 - -// Configuration -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN + TUD_PRINTER_DESC_LEN) - -// HID interface endpoints -#define EPADDR_HID 0x81 // Interrupt In, MSB must be 1 -// Printer interface endpoints -#define EPADDR_PRINTER_OUT 0x01 // Bulk Out, MSB must be 0 -#define EPADDR_PRINTER_IN 0x82 // Bulk In, MSB must be 1 - // HID report ID -#define REPORT_ID_KEYBOARD 1 - -// The maximum length of the string that will be sent to the host via the STRING DESCRIPTOR. Note that the -// string descriptor itself is two bytes wider than the string. -#define STRING_DESCRIPTOR_MAX_LENGTH 32 - -//--------------------------------------------------------------------+ -// Configuration, interface, endpoint descriptors -//--------------------------------------------------------------------+ - enum { - ITF_HID, - ITF_PRINTER, - ITF_COUNT, + REPORT_ID_KEYBOARD = 1, }; -//--------------------------------------------------------------------+ -// String Descriptors -//--------------------------------------------------------------------+ - enum { - LANGID = 0, - STR_MANUFACTURER, - STR_PRODUCT, - STR_SERIAL, - STR_CONFIGURATION, - STR_HID_INTERFACE, - STR_PRINTER_INTERFACE, - STRING_COUNT, + ITF_NUM_HID, + ITF_NUM_PRINTER, + ITF_NUM_TOTAL, }; +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN + TUD_PRINTER_DESC_LEN) + #endif /* USB_DESCRIPTORS_H_ */ diff --git a/src/class/printer/printer.h b/src/class/printer/printer.h index c9ed3cebc..b32543077 100644 --- a/src/class/printer/printer.h +++ b/src/class/printer/printer.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_PRINTER_H_ -#define _TUSB_PRINTER_H_ +#ifndef TUSB_PRINTER_H_ +#define TUSB_PRINTER_H_ #include "common/tusb_common.h" @@ -35,13 +35,28 @@ extern "C" { /// Printer Class Specific Control Request typedef enum { - PRINTER_REQ_CONTROL_GET_DEVICE_ID = 0x01, ///< Get device ID - PRINTER_REQ_CONTROL_GET_PORT_STATUS = 0x02, ///< Get port status - PRINTER_REQ_CONTROL_SOFT_RESET = 0x03, ///< Soft reset -} printer_request_enum_t; + TUSB_PRINTER_REQUEST_GET_DEVICE_ID = 0x01, ///< Get device ID + TUSB_PRINTER_REQUEST_GET_PORT_STATUS = 0x02, ///< Get port status + TUSB_PRINTER_REQUEST_SOFT_RESET = 0x03, ///< Soft reset +} tusb_printer_request_type_t; + +/// Printer Port Status (returned by GET_PORT_STATUS request) +/// USB Printer Class spec 1.1, Section 4.2 +typedef union TU_ATTR_PACKED { + uint8_t status; + struct TU_ATTR_PACKED { + uint8_t reserved0 : 3; ///< Reserved (bits 0-2) + uint8_t not_error : 1; ///< 1 = no error, 0 = error + uint8_t selected : 1; ///< 1 = selected (online), 0 = not selected + uint8_t paper_empty : 1; ///< 1 = paper empty, 0 = paper not empty + uint8_t reserved6 : 2; ///< Reserved (bits 6-7) + } status_bm; +} tusb_printer_port_status_t; + +TU_VERIFY_STATIC(sizeof(tusb_printer_port_status_t) == 1, "size is not correct"); #ifdef __cplusplus } #endif -#endif /* _TUSB_PRINTER_H__ */ +#endif diff --git a/src/class/printer/printer_device.c b/src/class/printer/printer_device.c index aaea4c988..d288014a1 100644 --- a/src/class/printer/printer_device.c +++ b/src/class/printer/printer_device.c @@ -28,13 +28,13 @@ #if (CFG_TUD_ENABLED && CFG_TUD_PRINTER) - //--------------------------------------------------------------------+ - // INCLUDE - //--------------------------------------------------------------------+ - #include "device/usbd.h" - #include "device/usbd_pvt.h" +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "device/usbd.h" +#include "device/usbd_pvt.h" - #include "printer_device.h" +#include "printer_device.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF @@ -63,6 +63,8 @@ typedef struct { TUD_EPBUF_DEF(epin, CFG_TUD_PRINTER_EP_BUFSIZE); } printer_epbuf_t; +#define ITF_MEM_RESET_SIZE offsetof(printer_interface_t, rx_ff) + static printer_interface_t _printer_itf[CFG_TUD_PRINTER]; CFG_TUD_MEM_SECTION static printer_epbuf_t _printer_epbuf[CFG_TUD_PRINTER]; @@ -70,9 +72,6 @@ CFG_TUD_MEM_SECTION static printer_epbuf_t _printer_epbuf[CFG_TUD_PRINTER]; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ - -static tud_printer_configure_fifo_t _printer_fifo_cfg; - static bool _prep_out_transaction(uint8_t itf) { const uint8_t rhport = 0; printer_interface_t *p_printer = &_printer_itf[itf]; @@ -112,6 +111,25 @@ TU_ATTR_WEAK void tud_printer_rx_cb(uint8_t itf, size_t n) { (void)n; } +TU_ATTR_WEAK void tud_printer_request_complete_cb(uint8_t itf, tusb_control_request_t const *request) { + (void)itf; + (void)request; +} + +TU_ATTR_WEAK uint8_t const *tud_printer_get_device_id_cb(uint8_t itf) { + (void)itf; + return NULL; +} + +TU_ATTR_WEAK uint8_t tud_printer_get_port_status_cb(uint8_t itf) { + (void)itf; + return 0x18; // not error, selected, paper not empty +} + +TU_ATTR_WEAK void tud_printer_soft_reset_cb(uint8_t itf) { + (void)itf; +} + //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ @@ -142,7 +160,6 @@ void tud_printer_n_read_flush(uint8_t itf) { //--------------------------------------------------------------------+ void printerd_init(void) { tu_memclr(_printer_itf, sizeof(_printer_itf)); - tu_memclr(&_printer_fifo_cfg, sizeof(_printer_fifo_cfg)); for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { printer_interface_t *p_printer = &_printer_itf[i]; @@ -166,7 +183,7 @@ bool printerd_deinit(void) { for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { printer_interface_t *p_printer = &_printer_itf[i]; osal_mutex_t mutex_rd = p_printer->rx_ff.mutex_rd; - osal_mutex_t mutex_wr = p_printer->tx_ff.mutex_rd; + osal_mutex_t mutex_wr = p_printer->tx_ff.mutex_wr; if (mutex_rd) { osal_mutex_delete(mutex_rd); @@ -189,15 +206,9 @@ void printerd_reset(uint8_t rhport) { for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { printer_interface_t *p_printer = &_printer_itf[i]; - tu_memclr(p_printer, sizeof(&p_printer)); - if (!_printer_fifo_cfg.rx_persistent) { - tu_fifo_clear(&p_printer->rx_ff); - } - if (!_printer_fifo_cfg.tx_persistent) { - tu_fifo_clear(&p_printer->tx_ff); - } - // tu_fifo_set_overwritable(&p_printer->rx_ff, true); - tu_fifo_set_overwritable(&p_printer->tx_ff, true); + tu_memclr(p_printer, ITF_MEM_RESET_SIZE); + tu_fifo_clear(&p_printer->rx_ff); + tu_fifo_clear(&p_printer->tx_ff); } } @@ -222,7 +233,7 @@ uint16_t printerd_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, ui //------------- Endpoints -------------// TU_ASSERT(itf_desc->bNumEndpoints == 2); drv_len += 2 * sizeof(tusb_desc_endpoint_t); - p_printer->itf_num = 2; + p_printer->itf_num = itf_desc->bInterfaceNumber; const uint8_t *p_desc = tu_desc_next(itf_desc); TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_printer->ep_out, &p_printer->ep_in), 0); @@ -233,6 +244,7 @@ uint16_t printerd_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, ui bool printerd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t *request) { TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); + uint8_t const itf_num = (uint8_t)request->wIndex; if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) { //------------- STD Request -------------// @@ -240,39 +252,38 @@ bool printerd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_ return true; } } else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) { - switch (request->bRequest) { - // https://www.usb.org/sites/default/files/usbprint11a021811.pdf - case PRINTER_REQ_CONTROL_GET_DEVICE_ID: - if (stage == CONTROL_STAGE_SETUP) { - const char deviceId[] = "MANUFACTURER:ACME Manufacturing;" - "MODEL:LaserBeam 9;" - "COMMAND SET:PS;" - "COMMENT:Anything you like;" - "ACTIVE COMMAND SET:PS;"; - char buffer[256]; - strcpy(buffer + 2, deviceId); - buffer[0] = 0x00; - buffer[1] = strlen(deviceId); - return tud_control_xfer(rhport, request, buffer, strlen(deviceId) + 2); + // https://www.usb.org/sites/default/files/usbprint11a021811.pdf + if (stage == CONTROL_STAGE_SETUP) { + switch (request->bRequest) { + case TUSB_PRINTER_REQUEST_GET_DEVICE_ID: { + // App provides buffer with IEEE 1284 format (first 2 bytes = big-endian length) + const uint8_t *device_id = tud_printer_get_device_id_cb(itf_num); + TU_VERIFY(device_id); + const uint16_t total_len = (uint16_t)((device_id[0] << 8) | device_id[1]); + return tud_control_xfer(rhport, request, (void *)(uintptr_t)device_id, total_len); } - break; - case PRINTER_REQ_CONTROL_GET_PORT_STATUS: - if (stage == CONTROL_STAGE_SETUP) { - static uint8_t port_status = 0b00011000; // paper not empty, selected, no error + + case TUSB_PRINTER_REQUEST_GET_PORT_STATUS: { + static uint8_t port_status; + port_status = tud_printer_get_port_status_cb(itf_num); return tud_control_xfer(rhport, request, &port_status, sizeof(port_status)); } - break; - case PRINTER_REQ_CONTROL_SOFT_RESET: - if (stage == CONTROL_STAGE_SETUP) { - return false; // TODO: reset buffers, reset Bulk In and Out endpoints, clear stall conditions - } - break; - default: - return false; + + case TUSB_PRINTER_REQUEST_SOFT_RESET: + tud_printer_soft_reset_cb(itf_num); + tud_control_status(rhport, request); + return true; + + default: + return false; + } + } else if (stage == CONTROL_STAGE_ACK) { + tud_printer_request_complete_cb(itf_num, request); } } else { return false; } + return true; } diff --git a/src/class/printer/printer_device.h b/src/class/printer/printer_device.h index 8c21e39ce..aeff1ffc5 100644 --- a/src/class/printer/printer_device.h +++ b/src/class/printer/printer_device.h @@ -33,11 +33,6 @@ extern "C" { #endif -typedef struct TU_ATTR_PACKED { - uint8_t rx_persistent : 1; // keep rx fifo on bus reset or disconnect - uint8_t tx_persistent : 1; // keep tx fifo on bus reset or disconnect -} tud_printer_configure_fifo_t; - //--------------------------------------------------------------------+ // Application API (Multiple Ports) i.e. CFG_TUD_PRINTER > 1 //--------------------------------------------------------------------+ @@ -59,7 +54,22 @@ bool tud_printer_n_peek(uint8_t itf, uint8_t *ui8); //--------------------------------------------------------------------+ // Invoked when received new data -TU_ATTR_WEAK void tud_printer_rx_cb(uint8_t itf, size_t n); +void tud_printer_rx_cb(uint8_t itf, size_t n); + +// Invoked when host requests device ID string (IEEE 1284). +// Application returns pointer to device ID buffer (must remain valid until transfer completes). +// First 2 bytes of returned buffer must contain big-endian length (including the 2 length bytes). +const uint8_t *tud_printer_get_device_id_cb(uint8_t itf); + +// Invoked when host requests port status. +uint8_t tud_printer_get_port_status_cb(uint8_t itf); + +// Invoked when host requests soft reset. +void tud_printer_soft_reset_cb(uint8_t itf); + +// Invoked when a control request is completed (GET_DEVICE_ID, GET_PORT_STATUS, etc.) +void tud_printer_request_complete_cb(uint8_t itf, tusb_control_request_t const *request); + //--------------------------------------------------------------------+ // Internal Class Driver API diff --git a/src/device/usbd.h b/src/device/usbd.h index c6e7d31c8..d3a6dccbb 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -330,21 +330,6 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 -//--------------------------------------------------------------------+ -// Printer Descriptor Templates -//--------------------------------------------------------------------+ - -#define TUD_PRINTER_DESC_LEN (9 + 7 + 7) // one interface, two endpoints - -#define TUD_PRINTER_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \ - /* Interface */\ - 9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_PRINTER, 1, 2, _stridx,\ - /* Endpoint Out */\ - 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ - /* Endpoint In */\ - 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 - - //--------------------------------------------------------------------+ // HID Descriptor Templates //--------------------------------------------------------------------+ diff --git a/src/tusb.h b/src/tusb.h index 4f76397cc..c80c8433c 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -96,10 +96,6 @@ #include "class/mtp/mtp_device.h" #endif - #if CFG_TUD_PRINTER - #include "class/printer/printer_device.h" - #endif - #if CFG_TUD_AUDIO #include "class/audio/audio_device.h" #endif -- cgit v1.3.1 From 988b18a40a4276eb731c80bc4cec3bf5750523f9 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 6 Mar 2026 16:06:42 +0700 Subject: add full read/write() API, use edpt stream for printer class --- examples/device/printer_to_hid/src/main.c | 137 ++++------------ src/class/printer/printer_device.c | 250 +++++++++++++++--------------- src/class/printer/printer_device.h | 55 ++++++- 3 files changed, 208 insertions(+), 234 deletions(-) (limited to 'src') diff --git a/examples/device/printer_to_hid/src/main.c b/examples/device/printer_to_hid/src/main.c index 02b54c7d0..0d14147b4 100644 --- a/examples/device/printer_to_hid/src/main.c +++ b/examples/device/printer_to_hid/src/main.c @@ -33,34 +33,15 @@ #include "usb_descriptors.h" // -------------------------------------------------------------------+ -// Variables controlled with USB endpoint callbacks +// Variables // -------------------------------------------------------------------+ -// usb interface pointer -uint8_t printer_itf = 0; -// pendings bytes in usb endpoint buffer ; must process these bytes -size_t pending_bytes_on_usb_ep = 0; - - -// -------------------------------------------------------------------+ -// Variables controlled locally -// -------------------------------------------------------------------+ - -// local data buffer (copy data from usb endpoint into this buffer) ; acts as fifo -uint8_t data_buffer[16] = {0}; -// write offset for usb/printer incoming data to data_buffer -size_t data_rx_offset = 0; -// read offset for usb/hid outgoing data from data_buffer -size_t data_tx_offset = 0; -// available space in data_buffer -size_t data_available = sizeof(data_buffer); - // next keycode to send on usb/hid -uint8_t next_keycode = 0; +static uint8_t next_keycode = 0; // next key modifiers to send on usb/hid -uint8_t next_modifiers = 0; +static uint8_t next_modifiers = 0; // whether the next usb/hid report must be NULL to release the last keystroke -uint8_t next_keycode_is_release = false; +static bool next_keycode_is_release = false; // -------------------------------------------------------------------+ @@ -99,83 +80,34 @@ static void hid_tx_task(void) { next_keycode = 0; } -// Whenever there are pendings bytes on the USB endpoint, we will pull them from the -// endpoint buffer and write then in the local data buffer. We must take care to not -// overwrite local data that is not processed yet, so we use data_buffer as a fifo. -// We do not have to take care of reading correctly from the endpoint buffer, as all -// is done well by tud_printer_n_read(). -static void printer_rx_task(void) { - - if (pending_bytes_on_usb_ep == 0) { - return; +// Read one byte from printer FIFO and translate to HID keycode. +// Only a-zA-Z0-9 are translated; everything else becomes space. +static void printer_to_hid_task(void) { + if (next_keycode != 0) { + return; // previous key not yet sent } - size_t len1 = data_available; - size_t len2 = 0; - if (data_rx_offset + len1 > sizeof(data_buffer)) { - len2 = len1 - (sizeof(data_buffer) - data_rx_offset); - len1 = sizeof(data_buffer) - data_rx_offset; - } - uint32_t count = tud_printer_n_read(printer_itf, data_buffer + data_rx_offset, len1); - if (len2 > 0) { - count += tud_printer_n_read(printer_itf, data_buffer, len2); + uint8_t ch; + if (tud_printer_read(&ch, 1) == 0) { + return; // no data available } - if (count == 0) { - return; + uint8_t m = 0; + if ('a' <= ch && ch <= 'z') { + ch = (uint8_t)(ch - 'a' + HID_KEY_A); + } else if ('A' <= ch && ch <= 'Z') { + ch = (uint8_t)(ch - 'A' + HID_KEY_A); + m = KEYBOARD_MODIFIER_LEFTSHIFT; + } else if ('1' <= ch && ch <= '9') { + ch = (uint8_t)(ch - '1' + HID_KEY_1); + } else if (ch == '0') { + ch = HID_KEY_0; + } else { + ch = HID_KEY_SPACE; } - data_available -= count; - pending_bytes_on_usb_ep -= count; - data_rx_offset = (data_rx_offset + count) % sizeof(data_buffer); -} - -// The HID keycodes are not binary mapped like UTF8 codes. If we want to send the -// data received as a usb/printer, we have to translate the binary data for the -// usb/hid interface. Note that the simple mapping below will be valid only for -// hosts expecting hid data from a QWERTY keyboard. Also note that only a-zA-Z0-9 -// characters are converted, for simplicity of the example. Other characters are -// converted to spaces. -static void translation_task(void) { - if (data_tx_offset != data_rx_offset || data_available == 0) { - // If data_tx_offset and data_rx_offset have different values, then we - // can proceed: translate, prepare for TX, and advance data_tx_offset. - // - // If the buffer is full (data_available == 0), then we must also - // translate data and prepare it for TX. But the data_tx_offset and - // data_rx_offset will have the same value, since RX caught up to TX. - // Hence the OR. - - // Translate UTF8 to HID keystroke - char c = data_buffer[data_tx_offset]; - uint8_t m = 0; - if ('a' <= c && c <= 'z') { - c -= 'a'; - c += HID_KEY_A; - } else if ('A' <= c && c <= 'Z') { - c -= 'A'; - c += HID_KEY_A; - m = KEYBOARD_MODIFIER_LEFTSHIFT; - } else if ('1' <= c && c <= '9') { - c -= '1'; - c += HID_KEY_1; - } else if (c == '0') { - c = HID_KEY_0; - } else { - c = HID_KEY_SPACE; - } - - // Proceed only if there are no characters pending for TX - if (next_keycode == 0) { - // Prepare next keystroke with translated data - next_keycode = c; - next_modifiers = m; - // Increment read offset - data_tx_offset += 1; - data_tx_offset %= sizeof(data_buffer); - data_available += 1; - } - } + next_keycode = ch; + next_modifiers = m; } int main(void) { @@ -186,15 +118,9 @@ int main(void) { board_init_after_tusb(); while (1) { - tud_task(); // tinyusb device task - printer_rx_task(); // read data sent by host on our printer interface - translation_task(); // translate printer's UTF8 to HID keycodes - hid_tx_task(); // send data to host with our HID interface - if (pending_bytes_on_usb_ep > 0) { - board_led_on(); - } else { - board_led_off(); - } + tud_task(); // tinyusb device task + printer_to_hid_task(); // read printer data and translate to HID keycodes + hid_tx_task(); // send keycodes to host via HID } } @@ -203,9 +129,8 @@ int main(void) { // Printer callbacks //--------------------------------------------------------------------+ -void tud_printer_rx_cb(uint8_t itf, size_t n) { - printer_itf = itf; // get interface from which to read endpoint buffer - pending_bytes_on_usb_ep += n; // count pending bytes, counter must decrement when reading from the endpoint buffer +void tud_printer_rx_cb(uint8_t itf) { + (void)itf; } // IEEE 1284 Device ID: first 2 bytes are big-endian total length (including the 2 length bytes). diff --git a/src/class/printer/printer_device.c b/src/class/printer/printer_device.c index d288014a1..05d3f28eb 100644 --- a/src/class/printer/printer_device.c +++ b/src/class/printer/printer_device.c @@ -28,9 +28,6 @@ #if (CFG_TUD_ENABLED && CFG_TUD_PRINTER) -//--------------------------------------------------------------------+ -// INCLUDE -//--------------------------------------------------------------------+ #include "device/usbd.h" #include "device/usbd_pvt.h" @@ -42,73 +39,52 @@ typedef struct { uint8_t itf_num; - uint8_t ep_out; // Bulk Out endpoint - uint8_t ep_in; // optional Bulk In endpoint /*------------- From this point, data is not cleared by bus reset -------------*/ - // FIFO - tu_fifo_t rx_ff; - tu_fifo_t tx_ff; + tu_edpt_stream_t rx_stream; + tu_edpt_stream_t tx_stream; uint8_t rx_ff_buf[CFG_TUD_PRINTER_RX_BUFSIZE]; uint8_t tx_ff_buf[CFG_TUD_PRINTER_TX_BUFSIZE]; - - OSAL_MUTEX_DEF(rx_ff_mutex); - OSAL_MUTEX_DEF(tx_ff_mutex); } printer_interface_t; +#define ITF_MEM_RESET_SIZE offsetof(printer_interface_t, rx_stream) + +#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 typedef struct { TUD_EPBUF_DEF(epout, CFG_TUD_PRINTER_EP_BUFSIZE); TUD_EPBUF_DEF(epin, CFG_TUD_PRINTER_EP_BUFSIZE); } printer_epbuf_t; -#define ITF_MEM_RESET_SIZE offsetof(printer_interface_t, rx_ff) - -static printer_interface_t _printer_itf[CFG_TUD_PRINTER]; CFG_TUD_MEM_SECTION static printer_epbuf_t _printer_epbuf[CFG_TUD_PRINTER]; +#endif +static printer_interface_t _printer_itf[CFG_TUD_PRINTER]; //--------------------------------------------------------------------+ -// INTERNAL OBJECT & FUNCTION DECLARATION +// INTERNAL HELPERS //--------------------------------------------------------------------+ -static bool _prep_out_transaction(uint8_t itf) { - const uint8_t rhport = 0; - printer_interface_t *p_printer = &_printer_itf[itf]; - printer_epbuf_t *p_epbuf = &_printer_epbuf[itf]; - - // Skip if usb is not ready yet - TU_VERIFY(tud_ready() && p_printer->ep_out); - uint16_t available = tu_fifo_remaining(&p_printer->rx_ff); - - // Prepare for incoming data but only allow what we can store in the ring buffer. - // TODO Actually we can still carry out the transfer, keeping count of received bytes - // and slowly move it to the FIFO when read(). - // This pre-check reduces endpoint claiming - TU_VERIFY(available >= CFG_TUD_PRINTER_EP_BUFSIZE); - - // claim endpoint - TU_VERIFY(usbd_edpt_claim(rhport, p_printer->ep_out)); - - // fifo can be changed before endpoint is claimed - available = tu_fifo_remaining(&p_printer->rx_ff); - - if (available >= CFG_TUD_PRINTER_EP_BUFSIZE) { - return usbd_edpt_xfer(rhport, p_printer->ep_out, p_epbuf->epout, CFG_TUD_PRINTER_EP_BUFSIZE, false); - } else { - // Release endpoint since we don't make any transfer - usbd_edpt_release(rhport, p_printer->ep_out); - return false; +TU_ATTR_ALWAYS_INLINE static inline uint8_t _find_itf(uint8_t ep_addr) { + for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { + const printer_interface_t *p = &_printer_itf[i]; + if (ep_addr == p->rx_stream.ep_addr || ep_addr == p->tx_stream.ep_addr) { + return i; + } } + return TUSB_INDEX_INVALID_8; } //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ -TU_ATTR_WEAK void tud_printer_rx_cb(uint8_t itf, size_t n) { +TU_ATTR_WEAK void tud_printer_rx_cb(uint8_t itf) { + (void)itf; +} + +TU_ATTR_WEAK void tud_printer_tx_complete_cb(uint8_t itf) { (void)itf; - (void)n; } TU_ATTR_WEAK void tud_printer_request_complete_cb(uint8_t itf, tusb_control_request_t const *request) { @@ -131,29 +107,53 @@ TU_ATTR_WEAK void tud_printer_soft_reset_cb(uint8_t itf) { } //--------------------------------------------------------------------+ -// APPLICATION API +// READ API //--------------------------------------------------------------------+ -uint32_t tud_printer_n_available(uint8_t itf) { - return tu_fifo_count(&_printer_itf[itf].rx_ff); +uint32_t tud_printer_n_read_available(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_PRINTER, 0); + return tu_edpt_stream_read_available(&_printer_itf[itf].rx_stream); } uint32_t tud_printer_n_read(uint8_t itf, void *buffer, uint32_t bufsize) { - printer_interface_t *p_printer = &_printer_itf[itf]; - uint32_t num_read = tu_fifo_read_n(&p_printer->rx_ff, buffer, (uint16_t)TU_MIN(bufsize, UINT16_MAX)); - _prep_out_transaction(itf); - return num_read; + TU_VERIFY(itf < CFG_TUD_PRINTER, 0); + return tu_edpt_stream_read(&_printer_itf[itf].rx_stream, buffer, bufsize); } bool tud_printer_n_peek(uint8_t itf, uint8_t *chr) { - return tu_fifo_peek(&_printer_itf[itf].rx_ff, chr); + TU_VERIFY(itf < CFG_TUD_PRINTER); + return tu_edpt_stream_peek(&_printer_itf[itf].rx_stream, chr); } void tud_printer_n_read_flush(uint8_t itf) { - printer_interface_t *p_printer = &_printer_itf[itf]; - tu_fifo_clear(&p_printer->rx_ff); - _prep_out_transaction(itf); + TU_VERIFY(itf < CFG_TUD_PRINTER, ); + printer_interface_t *p = &_printer_itf[itf]; + tu_edpt_stream_clear(&p->rx_stream); + tu_edpt_stream_read_xfer(&p->rx_stream); } +//--------------------------------------------------------------------+ +// WRITE API +//--------------------------------------------------------------------+ +uint32_t tud_printer_n_write(uint8_t itf, const void *buffer, uint32_t bufsize) { + TU_VERIFY(itf < CFG_TUD_PRINTER, 0); + return tu_edpt_stream_write(&_printer_itf[itf].tx_stream, buffer, bufsize); +} + +uint32_t tud_printer_n_write_flush(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_PRINTER, 0); + return tu_edpt_stream_write_xfer(&_printer_itf[itf].tx_stream); +} + +uint32_t tud_printer_n_write_available(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_PRINTER, 0); + return tu_edpt_stream_write_available(&_printer_itf[itf].tx_stream); +} + +bool tud_printer_n_write_clear(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_PRINTER); + tu_edpt_stream_clear(&_printer_itf[itf].tx_stream); + return true; +} //--------------------------------------------------------------------+ // USBD-CLASS API @@ -162,41 +162,32 @@ void printerd_init(void) { tu_memclr(_printer_itf, sizeof(_printer_itf)); for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { - printer_interface_t *p_printer = &_printer_itf[i]; - - tu_fifo_config(&p_printer->rx_ff, p_printer->rx_ff_buf, TU_ARRAY_SIZE(p_printer->rx_ff_buf), false); - tu_fifo_config(&p_printer->tx_ff, p_printer->tx_ff_buf, TU_ARRAY_SIZE(p_printer->tx_ff_buf), true); + printer_interface_t *p = &_printer_itf[i]; + + #if CFG_TUD_EDPT_DEDICATED_HWFIFO + uint8_t *epout_buf = NULL; + uint8_t *epin_buf = NULL; + #else + uint8_t *epout_buf = _printer_epbuf[i].epout; + uint8_t *epin_buf = _printer_epbuf[i].epin; + #endif - #if OSAL_MUTEX_REQUIRED - osal_mutex_t mutex_rd = osal_mutex_create(&p_printer->rx_ff_mutex); - osal_mutex_t mutex_wr = osal_mutex_create(&p_printer->tx_ff_mutex); - TU_ASSERT(mutex_rd != NULL && mutex_wr != NULL, ); + tu_edpt_stream_init(&p->rx_stream, false, false, false, + p->rx_ff_buf, CFG_TUD_PRINTER_RX_BUFSIZE, + epout_buf, CFG_TUD_PRINTER_EP_BUFSIZE); - tu_fifo_config_mutex(&p_printer->rx_ff, NULL, mutex_rd); - tu_fifo_config_mutex(&p_printer->tx_ff, mutex_wr, NULL); - #endif + tu_edpt_stream_init(&p->tx_stream, false, true, true, + p->tx_ff_buf, CFG_TUD_PRINTER_TX_BUFSIZE, + epin_buf, CFG_TUD_PRINTER_EP_BUFSIZE); } } bool printerd_deinit(void) { - #if OSAL_MUTEX_REQUIRED for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { - printer_interface_t *p_printer = &_printer_itf[i]; - osal_mutex_t mutex_rd = p_printer->rx_ff.mutex_rd; - osal_mutex_t mutex_wr = p_printer->tx_ff.mutex_wr; - - if (mutex_rd) { - osal_mutex_delete(mutex_rd); - tu_fifo_config_mutex(&p_printer->rx_ff, NULL, NULL); - } - - if (mutex_wr) { - osal_mutex_delete(mutex_wr); - tu_fifo_config_mutex(&p_printer->tx_ff, NULL, NULL); - } + printer_interface_t *p = &_printer_itf[i]; + tu_edpt_stream_deinit(&p->rx_stream); + tu_edpt_stream_deinit(&p->tx_stream); } - #endif - return true; } @@ -204,40 +195,48 @@ void printerd_reset(uint8_t rhport) { (void)rhport; for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { - printer_interface_t *p_printer = &_printer_itf[i]; - - tu_memclr(p_printer, ITF_MEM_RESET_SIZE); - tu_fifo_clear(&p_printer->rx_ff); - tu_fifo_clear(&p_printer->tx_ff); + printer_interface_t *p = &_printer_itf[i]; + tu_memclr(p, ITF_MEM_RESET_SIZE); + tu_edpt_stream_close(&p->rx_stream); + tu_edpt_stream_close(&p->tx_stream); } } uint16_t printerd_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { - (void)max_len; TU_VERIFY(TUSB_CLASS_PRINTER == itf_desc->bInterfaceClass, 0); - // Identify available interface to open - printer_interface_t *p_printer; - uint8_t printer_id; - for (printer_id = 0; printer_id < CFG_TUD_PRINTER; printer_id++) { - p_printer = &_printer_itf[printer_id]; - if (p_printer->ep_out == 0) { - break; - } - } - TU_ASSERT(printer_id < CFG_TUD_PRINTER); + // Find available interface slot + uint8_t const printer_id = _find_itf(0); + TU_ASSERT(printer_id < CFG_TUD_PRINTER, 0); + printer_interface_t *p = &_printer_itf[printer_id]; - //------------- Interface -------------// - uint16_t drv_len = sizeof(tusb_desc_interface_t); + p->itf_num = itf_desc->bInterfaceNumber; //------------- Endpoints -------------// - TU_ASSERT(itf_desc->bNumEndpoints == 2); - drv_len += 2 * sizeof(tusb_desc_endpoint_t); - p_printer->itf_num = itf_desc->bInterfaceNumber; - const uint8_t *p_desc = tu_desc_next(itf_desc); - TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_printer->ep_out, &p_printer->ep_in), 0); + const uint8_t *p_desc = (const uint8_t *)itf_desc; + const uint8_t *desc_end = p_desc + max_len; + uint16_t drv_len = sizeof(tusb_desc_interface_t); + + p_desc = tu_desc_next(itf_desc); + for (uint8_t e = 0; e < itf_desc->bNumEndpoints; e++) { + TU_VERIFY(tu_desc_in_bounds(p_desc, desc_end), 0); + const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc; + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer, 0); + + TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); + + if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { + tu_edpt_stream_open(&p->tx_stream, rhport, desc_ep); + tu_edpt_stream_clear(&p->tx_stream); + } else { + tu_edpt_stream_open(&p->rx_stream, rhport, desc_ep); + tu_edpt_stream_clear(&p->rx_stream); + TU_ASSERT(tu_edpt_stream_read_xfer(&p->rx_stream) > 0, 0); + } - _prep_out_transaction(printer_id); + drv_len += sizeof(tusb_desc_endpoint_t); + p_desc = tu_desc_next(p_desc); + } return drv_len; } @@ -247,7 +246,6 @@ bool printerd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_ uint8_t const itf_num = (uint8_t)request->wIndex; if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) { - //------------- STD Request -------------// if (stage != CONTROL_STAGE_SETUP) { return true; } @@ -256,7 +254,6 @@ bool printerd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_ if (stage == CONTROL_STAGE_SETUP) { switch (request->bRequest) { case TUSB_PRINTER_REQUEST_GET_DEVICE_ID: { - // App provides buffer with IEEE 1284 format (first 2 bytes = big-endian length) const uint8_t *device_id = tud_printer_get_device_id_cb(itf_num); TU_VERIFY(device_id); const uint16_t total_len = (uint16_t)((device_id[0] << 8) | device_id[1]); @@ -290,28 +287,29 @@ bool printerd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_ bool printerd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void)rhport; (void)result; - uint8_t itf; - printer_interface_t *p_printer; - - // Identify which interface to use - for (itf = 0; itf < CFG_TUD_PRINTER; itf++) { - p_printer = &_printer_itf[itf]; - if (ep_addr == p_printer->ep_out) { - break; - } - } + + uint8_t const itf = _find_itf(ep_addr); TU_ASSERT(itf < CFG_TUD_PRINTER); - printer_epbuf_t *p_epbuf = &_printer_epbuf[itf]; + printer_interface_t *p = &_printer_itf[itf]; // Received new data - if (ep_addr == p_printer->ep_out) { - tu_fifo_write_n(&p_printer->rx_ff, p_epbuf->epout, (uint16_t)xferred_bytes); - // invoke receive callback (if there is still data) - if (!tu_fifo_empty(&p_printer->rx_ff)) { - tud_printer_rx_cb(itf, xferred_bytes); + if (ep_addr == p->rx_stream.ep_addr) { + tu_edpt_stream_read_xfer_complete(&p->rx_stream, xferred_bytes); + + if (!tu_edpt_stream_empty(&p->rx_stream)) { + tud_printer_rx_cb(itf); + } + + tu_edpt_stream_read_xfer(&p->rx_stream); + } + + // Data sent to host + if (ep_addr == p->tx_stream.ep_addr) { + tud_printer_tx_complete_cb(itf); + + if (0 == tu_edpt_stream_write_xfer(&p->tx_stream)) { + tu_edpt_stream_write_zlp_if_needed(&p->tx_stream, xferred_bytes); } - // prepare for OUT transaction - _prep_out_transaction(itf); } return true; diff --git a/src/class/printer/printer_device.h b/src/class/printer/printer_device.h index aeff1ffc5..a6b7052cb 100644 --- a/src/class/printer/printer_device.h +++ b/src/class/printer/printer_device.h @@ -38,23 +38,74 @@ extern "C" { //--------------------------------------------------------------------+ // Get the number of bytes available for reading -uint32_t tud_printer_n_available(uint8_t itf); +uint32_t tud_printer_n_read_available(uint8_t itf); // Read received bytes uint32_t tud_printer_n_read(uint8_t itf, void *buffer, uint32_t bufsize); +// Get the number of bytes available for writing +uint32_t tud_printer_n_write_available(uint8_t itf); + // Clear the received FIFO void tud_printer_n_read_flush(uint8_t itf); // Get a byte from FIFO without removing it bool tud_printer_n_peek(uint8_t itf, uint8_t *ui8); +// Write data to host +uint32_t tud_printer_n_write(uint8_t itf, const void *buffer, uint32_t bufsize); + +// Force sending data in the TX FIFO +uint32_t tud_printer_n_write_flush(uint8_t itf); + +// Clear the transmit FIFO +bool tud_printer_n_write_clear(uint8_t itf); + +//--------------------------------------------------------------------+ +// Application API (Single Port) +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_printer_read_available(void) { + return tud_printer_n_read_available(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_printer_write_available(void) { + return tud_printer_n_write_available(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_printer_read(void *buffer, uint32_t bufsize) { + return tud_printer_n_read(0, buffer, bufsize); +} + +TU_ATTR_ALWAYS_INLINE static inline void tud_printer_read_flush(void) { + tud_printer_n_read_flush(0); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_printer_peek(uint8_t *ui8) { + return tud_printer_n_peek(0, ui8); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_printer_write(const void *buffer, uint32_t bufsize) { + return tud_printer_n_write(0, buffer, bufsize); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_printer_write_flush(void) { + return tud_printer_n_write_flush(0); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_printer_write_clear(void) { + return tud_printer_n_write_clear(0); +} + //--------------------------------------------------------------------+ // Application Callback API (weak is optional) //--------------------------------------------------------------------+ // Invoked when received new data -void tud_printer_rx_cb(uint8_t itf, size_t n); +void tud_printer_rx_cb(uint8_t itf); + +// Invoked when last write transfer is completed +void tud_printer_tx_complete_cb(uint8_t itf); // Invoked when host requests device ID string (IEEE 1284). // Application returns pointer to device ID buffer (must remain valid until transfer completes). -- cgit v1.3.1 From 73cd53129529f2dce70072953bfd50ec9dc6b8ea Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 6 Mar 2026 17:22:38 +0700 Subject: replace printer_to_hid example with printer_to_cdc example fix printer GET_DEVICE_ID request weird wIndex (interface high, alt low) --- examples/device/CMakeLists.txt | 2 +- examples/device/printer_to_cdc/CMakeLists.txt | 29 +++ examples/device/printer_to_cdc/Makefile | 11 ++ examples/device/printer_to_cdc/src/main.c | 115 +++++++++++ examples/device/printer_to_cdc/src/tusb_config.h | 117 +++++++++++ .../device/printer_to_cdc/src/usb_descriptors.c | 208 ++++++++++++++++++++ .../device/printer_to_cdc/src/usb_descriptors.h | 37 ++++ examples/device/printer_to_hid/CMakeLists.txt | 29 --- examples/device/printer_to_hid/CMakePresets.json | 6 - examples/device/printer_to_hid/Makefile | 11 -- examples/device/printer_to_hid/README.md | 0 examples/device/printer_to_hid/src/main.c | 175 ----------------- examples/device/printer_to_hid/src/tusb_config.h | 113 ----------- .../device/printer_to_hid/src/usb_descriptors.c | 215 --------------------- .../device/printer_to_hid/src/usb_descriptors.h | 41 ---- src/class/printer/printer.h | 6 +- src/class/printer/printer_device.c | 77 ++++---- src/device/usbd.c | 24 ++- 18 files changed, 587 insertions(+), 629 deletions(-) create mode 100644 examples/device/printer_to_cdc/CMakeLists.txt create mode 100644 examples/device/printer_to_cdc/Makefile create mode 100644 examples/device/printer_to_cdc/src/main.c create mode 100644 examples/device/printer_to_cdc/src/tusb_config.h create mode 100644 examples/device/printer_to_cdc/src/usb_descriptors.c create mode 100644 examples/device/printer_to_cdc/src/usb_descriptors.h delete mode 100644 examples/device/printer_to_hid/CMakeLists.txt delete mode 100644 examples/device/printer_to_hid/CMakePresets.json delete mode 100644 examples/device/printer_to_hid/Makefile delete mode 100644 examples/device/printer_to_hid/README.md delete mode 100644 examples/device/printer_to_hid/src/main.c delete mode 100644 examples/device/printer_to_hid/src/tusb_config.h delete mode 100644 examples/device/printer_to_hid/src/usb_descriptors.c delete mode 100644 examples/device/printer_to_hid/src/usb_descriptors.h (limited to 'src') diff --git a/examples/device/CMakeLists.txt b/examples/device/CMakeLists.txt index dbcb8df6a..7173f455e 100644 --- a/examples/device/CMakeLists.txt +++ b/examples/device/CMakeLists.txt @@ -30,7 +30,7 @@ set(EXAMPLE_LIST msc_dual_lun mtp net_lwip_webserver - printer_to_hid + printer_to_cdc uac2_headset uac2_speaker_fb usbtmc diff --git a/examples/device/printer_to_cdc/CMakeLists.txt b/examples/device/printer_to_cdc/CMakeLists.txt new file mode 100644 index 000000000..3c8ab3653 --- /dev/null +++ b/examples/device/printer_to_cdc/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.20) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) + +project(printer_to_cdc C CXX ASM) + +# Checks this example is valid for the family and initializes the project +family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + +add_executable(${PROJECT_NAME}) + +# Example source +target_sources(${PROJECT_NAME} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c + ) + +# Example include +target_include_directories(${PROJECT_NAME} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src + ) + +# Configure compilation flags and libraries for the example without RTOS. +# See the corresponding function in hw/bsp/FAMILY/family.cmake for details. +family_configure_device_example(${PROJECT_NAME} noos) diff --git a/examples/device/printer_to_cdc/Makefile b/examples/device/printer_to_cdc/Makefile new file mode 100644 index 000000000..1a4b428dc --- /dev/null +++ b/examples/device/printer_to_cdc/Makefile @@ -0,0 +1,11 @@ +include ../../../hw/bsp/family_support.mk + +INC += \ + src \ + + +# Example source +EXAMPLE_SOURCE += $(wildcard src/*.c) +SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) + +include ../../../hw/bsp/family_rules.mk diff --git a/examples/device/printer_to_cdc/src/main.c b/examples/device/printer_to_cdc/src/main.c new file mode 100644 index 000000000..aba79025c --- /dev/null +++ b/examples/device/printer_to_cdc/src/main.c @@ -0,0 +1,115 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2026 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +/* This example demonstrates a USB Printer + CDC composite device. + * Data received on the Printer interface is forwarded to the CDC serial port, + * and data received on the CDC serial port is forwarded back to the Printer interface. + * + * To test: + * 1. Flash the device + * 2. Open a serial terminal on the CDC port (e.g. /dev/ttyACM0) + * 3. Send data to the printer: echo "hello" > /dev/usb/lp0 + * 4. The data appears on the CDC serial terminal + * 5. Type in the serial terminal to send data back through the printer TX + */ + +#include +#include +#include + +#include "bsp/board_api.h" +#include "tusb.h" + +#include "usb_descriptors.h" + +// -------------------------------------------------------------------+ +// Tasks +// -------------------------------------------------------------------+ + +// Forward data from Printer RX to CDC TX +static void printer_to_cdc_task(void) { + if (tud_printer_read_available() == 0 || !tud_cdc_write_available()) { + return; + } + + uint8_t buf[64]; + uint32_t count = tud_printer_read(buf, sizeof(buf)); + if (count > 0) { + tud_cdc_write(buf, count); + tud_cdc_write_flush(); + } +} + +// Forward data from CDC RX to Printer TX +static void cdc_to_printer_task(void) { + if (tud_cdc_available() == 0 || !tud_printer_write_available()) { + return; + } + + uint8_t buf[64]; + uint32_t count = tud_cdc_read(buf, sizeof(buf)); + if (count > 0) { + tud_printer_write(buf, count); + tud_printer_write_flush(); + } +} + +int main(void) { + board_init(); + // init device stack on configured roothub port + tusb_rhport_init_t dev_init = {.role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; + tusb_init(BOARD_TUD_RHPORT, &dev_init); + board_init_after_tusb(); + + while (1) { + tud_task(); // tinyusb device task + printer_to_cdc_task(); // forward printer data to CDC + cdc_to_printer_task(); // forward CDC data to printer + } +} + +//--------------------------------------------------------------------+ +// Printer callbacks +//--------------------------------------------------------------------+ + +void tud_printer_rx_cb(uint8_t itf) { + (void)itf; +} + +// IEEE 1284 Device ID: first 2 bytes are big-endian total length (including the 2 length bytes). +// The rest is the Device ID string using standard abbreviated keys. +static const char printer_device_id[] = + "\x00\x34" // total length = 52 = 0x0034 (big-endian) + "MFG:TinyUSB;" + "MDL:Printer to CDC;" + "CMD:PS;" + "CLS:PRINTER;"; + +TU_VERIFY_STATIC(sizeof(printer_device_id) - 1 == 52, "device ID length mismatch"); + +uint8_t const *tud_printer_get_device_id_cb(uint8_t itf) { + (void)itf; + return (uint8_t const *)printer_device_id; +} diff --git a/examples/device/printer_to_cdc/src/tusb_config.h b/examples/device/printer_to_cdc/src/tusb_config.h new file mode 100644 index 000000000..50ef41762 --- /dev/null +++ b/examples/device/printer_to_cdc/src/tusb_config.h @@ -0,0 +1,117 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2026 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Board Specific Configuration +//--------------------------------------------------------------------+ + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_TUD_RHPORT + #define BOARD_TUD_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUD_MAX_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU + #error CFG_TUSB_MCU must be defined +#endif + +#ifndef CFG_TUSB_OS + #define CFG_TUSB_OS OPT_OS_NONE +#endif + +#ifndef CFG_TUSB_DEBUG + #define CFG_TUSB_DEBUG 0 +#endif + +// Enable Device stack +#define CFG_TUD_ENABLED 1 + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION + #define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN + #define CFG_TUSB_MEM_ALIGN __attribute__((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE + #define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +//------------- CLASS -------------// +#define CFG_TUD_HID 0 +#define CFG_TUD_CDC 1 +#define CFG_TUD_MSC 0 +#define CFG_TUD_MIDI 0 +#define CFG_TUD_VENDOR 0 +#define CFG_TUD_PRINTER 1 + +// CDC FIFO size of TX and RX +#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + +// CDC Endpoint transfer buffer size +#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + +// Printer buffer sizes +#define CFG_TUD_PRINTER_RX_BUFSIZE 512 +#define CFG_TUD_PRINTER_TX_BUFSIZE 512 +#define CFG_TUD_PRINTER_EP_BUFSIZE 512 + +#ifdef __cplusplus +} +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/printer_to_cdc/src/usb_descriptors.c b/examples/device/printer_to_cdc/src/usb_descriptors.c new file mode 100644 index 000000000..30d309ed4 --- /dev/null +++ b/examples/device/printer_to_cdc/src/usb_descriptors.c @@ -0,0 +1,208 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2026 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "bsp/board_api.h" +#include "tusb.h" + +#include "usb_descriptors.h" + +#define USB_VID 0xCafe +#define USB_PID 0x4005 +#define USB_BCD 0x0200 + +//--------------------------------------------------------------------+ +// Device Descriptors +//--------------------------------------------------------------------+ +static tusb_desc_device_t const desc_device = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = USB_BCD, + + // Use Interface Association Descriptor (IAD) for CDC + // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = USB_VID, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 +}; + +uint8_t const *tud_descriptor_device_cb(void) { + return (uint8_t const *) &desc_device; +} + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ + +// Endpoint numbers +#if defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x83 + #define EPNUM_PRINTER_OUT 0x04 + #define EPNUM_PRINTER_IN 0x85 +#else + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x82 + #define EPNUM_PRINTER_OUT 0x03 + #define EPNUM_PRINTER_IN 0x83 +#endif + +// full speed configuration +static uint8_t const desc_fs_configuration[] = { + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + + // Interface number, string index, EP notification address and size, EP data address (out, in) and size. + TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 16, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), + + // Interface number, string index, EP Bulk Out address, EP Bulk In address, EP size + TUD_PRINTER_DESCRIPTOR(ITF_NUM_PRINTER, 5, EPNUM_PRINTER_OUT, EPNUM_PRINTER_IN, 64), +}; + +#if TUD_OPT_HIGH_SPEED +// high speed configuration +static uint8_t const desc_hs_configuration[] = { + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + + TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 16, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512), + + TUD_PRINTER_DESCRIPTOR(ITF_NUM_PRINTER, 5, EPNUM_PRINTER_OUT, EPNUM_PRINTER_IN, 512), +}; + +// other speed configuration +static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; + +// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed +static tusb_desc_device_qualifier_t const desc_device_qualifier = { + .bLength = sizeof(tusb_desc_device_qualifier_t), + .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, + .bcdUSB = USB_BCD, + + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + .bNumConfigurations = 0x01, + .bReserved = 0x00 +}; + +uint8_t const *tud_descriptor_device_qualifier_cb(void) { + return (uint8_t const *) &desc_device_qualifier; +} + +uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { + (void) index; + + // if link speed is high return fullspeed config, and vice versa + memcpy(desc_other_speed_config, + (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration, + CONFIG_TOTAL_LEN); + + desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; + + return desc_other_speed_config; +} + +#endif // TUD_OPT_HIGH_SPEED + +uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { + (void) index; + +#if TUD_OPT_HIGH_SPEED + return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; +#else + return desc_fs_configuration; +#endif +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, + STRID_CDC, + STRID_PRINTER, +}; + +static char const *string_desc_arr[] = { + (const char[]) { 0x09, 0x04 }, // 0: supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + NULL, // 3: Serial, use unique ID if possible + "TinyUSB CDC", // 4: CDC Interface + "TinyUSB Printer", // 5: Printer Interface +}; + +static uint16_t _desc_str[32 + 1]; + +uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { + (void) langid; + size_t chr_count; + + switch (index) { + case STRID_LANGID: + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + break; + + case STRID_SERIAL: + chr_count = board_usb_get_serial(_desc_str + 1, 32); + break; + + default: + if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } + + const char *str = string_desc_arr[index]; + + chr_count = strlen(str); + size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; + if (chr_count > max_count) { chr_count = max_count; } + + for (size_t i = 0; i < chr_count; i++) { + _desc_str[1 + i] = str[i]; + } + break; + } + + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); + return _desc_str; +} diff --git a/examples/device/printer_to_cdc/src/usb_descriptors.h b/examples/device/printer_to_cdc/src/usb_descriptors.h new file mode 100644 index 000000000..830593b4d --- /dev/null +++ b/examples/device/printer_to_cdc/src/usb_descriptors.h @@ -0,0 +1,37 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2026 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef USB_DESCRIPTORS_H_ +#define USB_DESCRIPTORS_H_ + +enum { + ITF_NUM_CDC, + ITF_NUM_CDC_DATA, + ITF_NUM_PRINTER, + ITF_NUM_TOTAL, +}; + +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_PRINTER_DESC_LEN) + +#endif /* USB_DESCRIPTORS_H_ */ diff --git a/examples/device/printer_to_hid/CMakeLists.txt b/examples/device/printer_to_hid/CMakeLists.txt deleted file mode 100644 index f58759059..000000000 --- a/examples/device/printer_to_hid/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -cmake_minimum_required(VERSION 3.20) - -include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) - -project(printer_to_hid C CXX ASM) - -# Checks this example is valid for the family and initializes the project -family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) -# Espressif has its own cmake build system -if(FAMILY STREQUAL "espressif") - return() -endif() - -add_executable(${PROJECT_NAME}) - -# Example source -target_sources(${PROJECT_NAME} PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c - ) - -# Example include -target_include_directories(${PROJECT_NAME} PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/src - ) - -# Configure compilation flags and libraries for the example without RTOS. -# See the corresponding function in hw/bsp/FAMILY/family.cmake for details. -family_configure_device_example(${PROJECT_NAME} noos) diff --git a/examples/device/printer_to_hid/CMakePresets.json b/examples/device/printer_to_hid/CMakePresets.json deleted file mode 100644 index 5cd8971e9..000000000 --- a/examples/device/printer_to_hid/CMakePresets.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": 6, - "include": [ - "../../../hw/bsp/BoardPresets.json" - ] -} diff --git a/examples/device/printer_to_hid/Makefile b/examples/device/printer_to_hid/Makefile deleted file mode 100644 index 1a4b428dc..000000000 --- a/examples/device/printer_to_hid/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include ../../../hw/bsp/family_support.mk - -INC += \ - src \ - - -# Example source -EXAMPLE_SOURCE += $(wildcard src/*.c) -SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) - -include ../../../hw/bsp/family_rules.mk diff --git a/examples/device/printer_to_hid/README.md b/examples/device/printer_to_hid/README.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/printer_to_hid/src/main.c b/examples/device/printer_to_hid/src/main.c deleted file mode 100644 index 0d14147b4..000000000 --- a/examples/device/printer_to_hid/src/main.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2026 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -#include -#include -#include - -#include "bsp/board_api.h" -#include "tusb.h" - -#include "usb_descriptors.h" - -// -------------------------------------------------------------------+ -// Variables -// -------------------------------------------------------------------+ - -// next keycode to send on usb/hid -static uint8_t next_keycode = 0; -// next key modifiers to send on usb/hid -static uint8_t next_modifiers = 0; -// whether the next usb/hid report must be NULL to release the last keystroke -static bool next_keycode_is_release = false; - - -// -------------------------------------------------------------------+ -// Tasks -// -------------------------------------------------------------------+ - -// Every 10ms, we will place HID data in the usb/hid endpoint, ready to -// sent to the host when required. The tasks will read the keycode in -// next_keycode and place it in the HID report, then set next_is_null -// such that the key is released by the next report. This seem to help -// stroking the same key twice when the character is repeated in the data. -static void hid_tx_task(void) { - // Poll every 10ms - const uint32_t interval_ms = 10; - static uint32_t start_ms = 0; - - if (!tud_hid_ready()) { - return; - } - - if (tusb_time_millis_api() - start_ms < interval_ms) { - return; // not enough time - } - start_ms += interval_ms; - - if (next_keycode_is_release || next_keycode == 0) { - tud_hid_keyboard_report(1, 0, NULL); - next_keycode_is_release = false; - return; - } - - uint8_t keycode_array[6] = {0}; - keycode_array[0] = next_keycode; - tud_hid_keyboard_report(1, next_modifiers, keycode_array); - next_keycode_is_release = true; - next_keycode = 0; -} - -// Read one byte from printer FIFO and translate to HID keycode. -// Only a-zA-Z0-9 are translated; everything else becomes space. -static void printer_to_hid_task(void) { - if (next_keycode != 0) { - return; // previous key not yet sent - } - - uint8_t ch; - if (tud_printer_read(&ch, 1) == 0) { - return; // no data available - } - - uint8_t m = 0; - if ('a' <= ch && ch <= 'z') { - ch = (uint8_t)(ch - 'a' + HID_KEY_A); - } else if ('A' <= ch && ch <= 'Z') { - ch = (uint8_t)(ch - 'A' + HID_KEY_A); - m = KEYBOARD_MODIFIER_LEFTSHIFT; - } else if ('1' <= ch && ch <= '9') { - ch = (uint8_t)(ch - '1' + HID_KEY_1); - } else if (ch == '0') { - ch = HID_KEY_0; - } else { - ch = HID_KEY_SPACE; - } - - next_keycode = ch; - next_modifiers = m; -} - -int main(void) { - board_init(); - // init device and host stack on configured roothub port - tusb_rhport_init_t dev_init = {.role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; - tusb_init(BOARD_TUD_RHPORT, &dev_init); - board_init_after_tusb(); - - while (1) { - tud_task(); // tinyusb device task - printer_to_hid_task(); // read printer data and translate to HID keycodes - hid_tx_task(); // send keycodes to host via HID - } -} - - -//--------------------------------------------------------------------+ -// Printer callbacks -//--------------------------------------------------------------------+ - -void tud_printer_rx_cb(uint8_t itf) { - (void)itf; -} - -// IEEE 1284 Device ID: first 2 bytes are big-endian total length (including the 2 length bytes). -// The rest is the Device ID string using standard abbreviated keys. -static const char printer_device_id[] = - "\x00\x34" // total length = 52 = 0x0034 (big-endian) - "MFG:TinyUSB;" - "MDL:Printer to HID;" - "CMD:PS;" - "CLS:PRINTER;"; - -TU_VERIFY_STATIC(sizeof(printer_device_id) - 1 == 52, "device ID length mismatch"); - -uint8_t const *tud_printer_get_device_id_cb(uint8_t itf) { - (void)itf; - return (uint8_t const *)printer_device_id; -} - - -//--------------------------------------------------------------------+ -// HID callbacks -//--------------------------------------------------------------------+ - -uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, - uint16_t reqlen) { - (void)instance; - (void)report_id; - (void)report_type; - (void)buffer; - (void)reqlen; - return 0; -} - -void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, const uint8_t *buffer, - uint16_t bufsize) { - (void)instance; - (void)report_id; - (void)report_type; - (void)buffer; - (void)bufsize; - return; -} diff --git a/examples/device/printer_to_hid/src/tusb_config.h b/examples/device/printer_to_hid/src/tusb_config.h deleted file mode 100644 index 0988be166..000000000 --- a/examples/device/printer_to_hid/src/tusb_config.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2026 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -//--------------------------------------------------------------------+ -// Board Specific Configuration -//--------------------------------------------------------------------+ - -// RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_TUD_RHPORT - #define BOARD_TUD_RHPORT 0 -#endif - -// RHPort max operational speed can defined by board.mk -#ifndef BOARD_TUD_MAX_SPEED - #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - -//-------------------------------------------------------------------- -// COMMON CONFIGURATION -//-------------------------------------------------------------------- - -// defined by compiler flags for flexibility -#ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -#ifndef CFG_TUSB_OS - #define CFG_TUSB_OS OPT_OS_NONE -#endif - -#ifndef CFG_TUSB_DEBUG - #define CFG_TUSB_DEBUG 0 -#endif - -// Enable Device stack -#define CFG_TUD_ENABLED 1 - -// Default is max speed that hardware controller could support with on-chip PHY -#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED - -/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. - * Tinyusb use follows macros to declare transferring memory so that they can be put - * into those specific section. - * e.g - * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) - * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) - */ -#ifndef CFG_TUSB_MEM_SECTION - #define CFG_TUSB_MEM_SECTION -#endif - -#ifndef CFG_TUSB_MEM_ALIGN - #define CFG_TUSB_MEM_ALIGN __attribute__((aligned(4))) -#endif - -//-------------------------------------------------------------------- -// DEVICE CONFIGURATION -//-------------------------------------------------------------------- - -#ifndef CFG_TUD_ENDPOINT0_SIZE - #define CFG_TUD_ENDPOINT0_SIZE 64 -#endif - -//------------- CLASS -------------// -#define CFG_TUD_HID 1 -#define CFG_TUD_CDC 0 -#define CFG_TUD_MSC 0 -#define CFG_TUD_MIDI 0 -#define CFG_TUD_VENDOR 0 -#define CFG_TUD_PRINTER 1 - -// HID buffer size Should be sufficient to hold ID (if any) + Data -#define CFG_TUD_HID_EP_BUFSIZE 16 - -// Printer buffer sizes -#define CFG_TUD_PRINTER_RX_BUFSIZE 512 -#define CFG_TUD_PRINTER_TX_BUFSIZE 512 -#define CFG_TUD_PRINTER_EP_BUFSIZE 512 - -#ifdef __cplusplus -} -#endif - -#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/printer_to_hid/src/usb_descriptors.c b/examples/device/printer_to_hid/src/usb_descriptors.c deleted file mode 100644 index 1cbabb02e..000000000 --- a/examples/device/printer_to_hid/src/usb_descriptors.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -#include "bsp/board_api.h" -#include "tusb.h" - -#include "usb_descriptors.h" - -#define USB_VID 0xCafe -#define USB_PID 0x4004 -#define USB_BCD 0x0200 - -//--------------------------------------------------------------------+ -// Device Descriptors -//--------------------------------------------------------------------+ -static tusb_desc_device_t const desc_device = { - .bLength = sizeof(tusb_desc_device_t), - .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = USB_BCD, - .bDeviceClass = 0x00, - .bDeviceSubClass = 0x00, - .bDeviceProtocol = 0x00, - .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - - .idVendor = USB_VID, - .idProduct = USB_PID, - .bcdDevice = 0x0100, - - .iManufacturer = 0x01, - .iProduct = 0x02, - .iSerialNumber = 0x03, - - .bNumConfigurations = 0x01 -}; - -uint8_t const *tud_descriptor_device_cb(void) { - return (uint8_t const *) &desc_device; -} - -//--------------------------------------------------------------------+ -// HID Report Descriptor -//--------------------------------------------------------------------+ -static uint8_t const desc_hid_report[] = { - TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(REPORT_ID_KEYBOARD)) -}; - -uint8_t const *tud_hid_descriptor_report_cb(uint8_t instance) { - (void)instance; - return desc_hid_report; -} - -//--------------------------------------------------------------------+ -// Configuration Descriptor -//--------------------------------------------------------------------+ - -// Endpoint numbers -#if defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) - #define EPNUM_HID 0x81 - #define EPNUM_PRINTER_OUT 0x02 - #define EPNUM_PRINTER_IN 0x83 -#else - #define EPNUM_HID 0x81 - #define EPNUM_PRINTER_OUT 0x02 - #define EPNUM_PRINTER_IN 0x82 -#endif - -// full speed configuration -static uint8_t const desc_fs_configuration[] = { - // Config number, interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), - - // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval - TUD_HID_DESCRIPTOR(ITF_NUM_HID, 4, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, - CFG_TUD_HID_EP_BUFSIZE, 5), - - // Interface number, string index, EP Bulk Out address, EP Bulk In address, EP size - TUD_PRINTER_DESCRIPTOR(ITF_NUM_PRINTER, 5, EPNUM_PRINTER_OUT, EPNUM_PRINTER_IN, 64), -}; - -#if TUD_OPT_HIGH_SPEED -// high speed configuration -static uint8_t const desc_hs_configuration[] = { - TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), - - TUD_HID_DESCRIPTOR(ITF_NUM_HID, 4, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, - CFG_TUD_HID_EP_BUFSIZE, 5), - - TUD_PRINTER_DESCRIPTOR(ITF_NUM_PRINTER, 5, EPNUM_PRINTER_OUT, EPNUM_PRINTER_IN, 512), -}; - -// other speed configuration -static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; - -// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed -static tusb_desc_device_qualifier_t const desc_device_qualifier = { - .bLength = sizeof(tusb_desc_device_qualifier_t), - .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, - .bcdUSB = USB_BCD, - - .bDeviceClass = 0x00, - .bDeviceSubClass = 0x00, - .bDeviceProtocol = 0x00, - - .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - .bNumConfigurations = 0x01, - .bReserved = 0x00 -}; - -uint8_t const *tud_descriptor_device_qualifier_cb(void) { - return (uint8_t const *) &desc_device_qualifier; -} - -uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { - (void) index; - - // if link speed is high return fullspeed config, and vice versa - memcpy(desc_other_speed_config, - (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration, - CONFIG_TOTAL_LEN); - - desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; - - return desc_other_speed_config; -} - -#endif // TUD_OPT_HIGH_SPEED - -uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { - (void) index; - -#if TUD_OPT_HIGH_SPEED - return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; -#else - return desc_fs_configuration; -#endif -} - -//--------------------------------------------------------------------+ -// String Descriptors -//--------------------------------------------------------------------+ - -enum { - STRID_LANGID = 0, - STRID_MANUFACTURER, - STRID_PRODUCT, - STRID_SERIAL, - STRID_HID, - STRID_PRINTER, -}; - -static char const *string_desc_arr[] = { - (const char[]) { 0x09, 0x04 }, // 0: supported language is English (0x0409) - "TinyUSB", // 1: Manufacturer - "TinyUSB Device", // 2: Product - NULL, // 3: Serial, use unique ID if possible - "TinyUSB HID", // 4: HID Interface - "TinyUSB Printer", // 5: Printer Interface -}; - -static uint16_t _desc_str[32 + 1]; - -uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { - (void) langid; - size_t chr_count; - - switch (index) { - case STRID_LANGID: - memcpy(&_desc_str[1], string_desc_arr[0], 2); - chr_count = 1; - break; - - case STRID_SERIAL: - chr_count = board_usb_get_serial(_desc_str + 1, 32); - break; - - default: - if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } - - const char *str = string_desc_arr[index]; - - chr_count = strlen(str); - size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; - if (chr_count > max_count) { chr_count = max_count; } - - for (size_t i = 0; i < chr_count; i++) { - _desc_str[1 + i] = str[i]; - } - break; - } - - _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); - return _desc_str; -} diff --git a/examples/device/printer_to_hid/src/usb_descriptors.h b/examples/device/printer_to_hid/src/usb_descriptors.h deleted file mode 100644 index 20c34f151..000000000 --- a/examples/device/printer_to_hid/src/usb_descriptors.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef USB_DESCRIPTORS_H_ -#define USB_DESCRIPTORS_H_ - -// HID report ID -enum { - REPORT_ID_KEYBOARD = 1, -}; - -enum { - ITF_NUM_HID, - ITF_NUM_PRINTER, - ITF_NUM_TOTAL, -}; - -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN + TUD_PRINTER_DESC_LEN) - -#endif /* USB_DESCRIPTORS_H_ */ diff --git a/src/class/printer/printer.h b/src/class/printer/printer.h index b32543077..09d1a8956 100644 --- a/src/class/printer/printer.h +++ b/src/class/printer/printer.h @@ -35,9 +35,9 @@ extern "C" { /// Printer Class Specific Control Request typedef enum { - TUSB_PRINTER_REQUEST_GET_DEVICE_ID = 0x01, ///< Get device ID - TUSB_PRINTER_REQUEST_GET_PORT_STATUS = 0x02, ///< Get port status - TUSB_PRINTER_REQUEST_SOFT_RESET = 0x03, ///< Soft reset + TUSB_PRINTER_REQUEST_GET_DEVICE_ID = 0x00, ///< Get device ID + TUSB_PRINTER_REQUEST_GET_PORT_STATUS = 0x01, ///< Get port status + TUSB_PRINTER_REQUEST_SOFT_RESET = 0x02, ///< Soft reset } tusb_printer_request_type_t; /// Printer Port Status (returned by GET_PORT_STATUS request) diff --git a/src/class/printer/printer_device.c b/src/class/printer/printer_device.c index 05d3f28eb..f5bb33795 100644 --- a/src/class/printer/printer_device.c +++ b/src/class/printer/printer_device.c @@ -242,43 +242,54 @@ uint16_t printerd_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, ui } bool printerd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t *request) { - TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); - uint8_t const itf_num = (uint8_t)request->wIndex; + TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); - if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) { - if (stage != CONTROL_STAGE_SETUP) { - return true; + // GET_DEVICE_ID: wIndex = (interface_number << 8) | alt_setting + // GET_PORT_STATUS / SOFT_RESET: wIndex = interface_number + uint8_t itf_num; + if (TUSB_PRINTER_REQUEST_GET_DEVICE_ID == request->bRequest) { + itf_num = tu_u16_high(request->wIndex); + } else { + itf_num = tu_u16_low(request->wIndex); + } + + // Find the printer instance index from the USB interface number + uint8_t itf = TUSB_INDEX_INVALID_8; + for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { + if (_printer_itf[i].itf_num == itf_num) { + itf = i; + break; } - } else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) { - // https://www.usb.org/sites/default/files/usbprint11a021811.pdf - if (stage == CONTROL_STAGE_SETUP) { - switch (request->bRequest) { - case TUSB_PRINTER_REQUEST_GET_DEVICE_ID: { - const uint8_t *device_id = tud_printer_get_device_id_cb(itf_num); - TU_VERIFY(device_id); - const uint16_t total_len = (uint16_t)((device_id[0] << 8) | device_id[1]); - return tud_control_xfer(rhport, request, (void *)(uintptr_t)device_id, total_len); - } - - case TUSB_PRINTER_REQUEST_GET_PORT_STATUS: { - static uint8_t port_status; - port_status = tud_printer_get_port_status_cb(itf_num); - return tud_control_xfer(rhport, request, &port_status, sizeof(port_status)); - } - - case TUSB_PRINTER_REQUEST_SOFT_RESET: - tud_printer_soft_reset_cb(itf_num); - tud_control_status(rhport, request); - return true; - - default: - return false; + } + TU_VERIFY(itf < CFG_TUD_PRINTER); + + // https://www.usb.org/sites/default/files/usbprint11a021811.pdf + if (stage == CONTROL_STAGE_SETUP) { + switch (request->bRequest) { + case TUSB_PRINTER_REQUEST_GET_DEVICE_ID: { + const uint8_t *device_id = tud_printer_get_device_id_cb(itf); + TU_VERIFY(device_id); + const uint16_t total_len = (uint16_t)((device_id[0] << 8) | device_id[1]); + return tud_control_xfer(rhport, request, (void *)(uintptr_t)device_id, total_len); + } + + case TUSB_PRINTER_REQUEST_GET_PORT_STATUS: { + static uint8_t port_status; + port_status = tud_printer_get_port_status_cb(itf); + return tud_control_xfer(rhport, request, &port_status, sizeof(port_status)); } - } else if (stage == CONTROL_STAGE_ACK) { - tud_printer_request_complete_cb(itf_num, request); + + case TUSB_PRINTER_REQUEST_SOFT_RESET: + tud_printer_soft_reset_cb(itf); + tud_control_status(rhport, request); + return true; + + default: + return false; } - } else { - return false; + } else if (stage == CONTROL_STAGE_ACK) { + tud_printer_request_complete_cb(itf, request); } return true; diff --git a/src/device/usbd.c b/src/device/usbd.c index 8d5f94313..42903576c 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -836,7 +836,9 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL if (TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type && p_request->bRequest <= TUSB_REQ_SYNCH_FRAME) { TU_LOG_USBD(" %s", tu_str_std_request[p_request->bRequest]); - if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) TU_LOG_USBD("\r\n"); + if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) { + TU_LOG_USBD("\r\n"); + } } #endif @@ -972,7 +974,25 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const //------------- Class/Interface Specific Request -------------// case TUSB_REQ_RCPT_INTERFACE: { - uint8_t const itf = tu_u16_low(p_request->wIndex); + uint8_t itf; + #if CFG_TUD_PRINTER + // Printer GET_DEVICE_ID has a weird wIndex = interface (high) | alt (low) + // attempt to interpret this as a printer request if matched + if (TUSB_REQ_TYPE_CLASS == p_request->bmRequestType_bit.type && + TUSB_DIR_IN == p_request->bmRequestType_bit.direction && + TUSB_PRINTER_REQUEST_GET_DEVICE_ID == p_request->bRequest) { + itf = tu_u16_high(p_request->wIndex); + if (itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv)) { + const usbd_class_driver_t * driver = get_driver(_usbd_dev.itf2drv[itf]); + if (driver != NULL && driver->control_xfer_cb == printerd_control_xfer_cb) { + if (invoke_class_control(rhport, driver, p_request)) { + return true; + } + } + } + } + #endif + itf = tu_u16_low(p_request->wIndex); TU_VERIFY(itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv)); usbd_class_driver_t const * driver = get_driver(_usbd_dev.itf2drv[itf]); -- cgit v1.3.1 From ee6f4f6f2a1f07db7c145551b779ce8cf878c2ac Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 6 Mar 2026 11:59:20 +0100 Subject: cleanup Signed-off-by: HiFiPhile --- src/portable/microchip/samx7x/dcd_samx7x.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c index 8dd333e0f..9f62781bb 100644 --- a/src/portable/microchip/samx7x/dcd_samx7x.c +++ b/src/portable/microchip/samx7x/dcd_samx7x.c @@ -570,9 +570,6 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t const uint8_t dir = tu_edpt_dir(ep_addr); xfer_ctl_t *xfer = &xfer_status[epnum]; - if (epnum == 0x80) { - xfer = &xfer_status[EP_MAX]; - } xfer->buffer = NULL; xfer->total_len = total_bytes; -- cgit v1.3.1 From 6a190546e68c55f81d865dfddee6205ddc6fa941 Mon Sep 17 00:00:00 2001 From: Zixun LI Date: Fri, 6 Mar 2026 12:47:21 +0100 Subject: Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/portable/microchip/samx7x/dcd_samx7x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c index 9f62781bb..bd158b47d 100644 --- a/src/portable/microchip/samx7x/dcd_samx7x.c +++ b/src/portable/microchip/samx7x/dcd_samx7x.c @@ -321,7 +321,7 @@ static void dcd_dma_handler(uint8_t ep_ix) { if (USB_REG->DEVEPTCFG[ep_ix] & DEVEPTCFG_EPDIR) { dcd_event_xfer_complete(0, 0x80 + ep_ix, count, XFER_RESULT_SUCCESS, true); } else { - dcd_dcache_invalidate(xfer->buffer, xfer->total_len); + dcd_dcache_invalidate(xfer->buffer, count); dcd_event_xfer_complete(0, ep_ix, count, XFER_RESULT_SUCCESS, true); } } @@ -600,6 +600,6 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; const uint8_t epnum = tu_edpt_number(ep_addr); USB_REG->DEVEPTIDR[epnum] = DEVEPTIDR_CTRL_STALLRQC; - USB_REG->DEVEPTIER[epnum] = HSTPIPIER_RSTDTS; + USB_REG->DEVEPTIER[epnum] = DEVEPTIER_RSTDTS; } #endif -- cgit v1.3.1 From 40ae5bddbe88c0bb5810efa354c43c082df6b640 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 13 Dec 2025 21:22:10 +0100 Subject: usbh: support MTT hub Signed-off-by: HiFiPhile --- src/host/hub.c | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/host/hub.c b/src/host/hub.c index 3baaff30f..b32e996a0 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -48,7 +48,7 @@ typedef struct { uint8_t bNbrPorts; uint8_t bPwrOn2PwrGood_2ms; // port power on to good, in 2ms unit // uint16_t wHubCharacteristics; - + bool mtt; hub_port_status_response_t port_status; } hub_interface_t; @@ -223,11 +223,19 @@ uint16_t hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const TU_VERIFY(TUSB_CLASS_HUB == itf_desc->bInterfaceClass && 0 == itf_desc->bInterfaceSubClass, 0); - TU_VERIFY(itf_desc->bInterfaceProtocol <= 1, 0); // not support multiple TT yet - const uint16_t drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t); + uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t); TU_ASSERT(drv_len <= max_len, 0); + tusb_desc_device_t desc_dev; + tuh_descriptor_get_device_local(dev_addr, &desc_dev); + // Skip STT interface of MTT hub + if (desc_dev.bDeviceProtocol == 2 && itf_desc->bInterfaceProtocol == 1) { + hub_interface_t* p_hub = get_hub_itf(dev_addr); + p_hub->mtt = true; + return drv_len; + } + // Interrupt Status endpoint tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc); TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && @@ -269,12 +277,26 @@ bool hub_edpt_status_xfer(uint8_t daddr) { //--------------------------------------------------------------------+ static void config_set_port_power (tuh_xfer_t* xfer); static void config_port_power_complete (tuh_xfer_t* xfer); +static void config_get_hub_descriptor(tuh_xfer_t* xfer); bool hub_set_config(uint8_t daddr, uint8_t itf_num) { hub_interface_t* p_hub = get_hub_itf(daddr); TU_ASSERT(itf_num == p_hub->itf_num); - hub_epbuf_t* p_epbuf = get_hub_epbuf(daddr); + if (p_hub->mtt) { + // Set Alternate Setting 1 for MTT hub + TU_ASSERT(tuh_interface_set(daddr, itf_num, 1, config_get_hub_descriptor, 0)); + } else { + tuh_xfer_t xfer; + xfer.daddr = daddr; + xfer.ep_addr = 0; + config_get_hub_descriptor(&xfer); + } + + return true; +} + +static void config_get_hub_descriptor(tuh_xfer_t* xfer) { // Get Hub Descriptor tusb_control_request_t const request = { .bmRequestType_bit = { @@ -288,17 +310,11 @@ bool hub_set_config(uint8_t daddr, uint8_t itf_num) { .wLength = sizeof(hub_desc_cs_t) }; - tuh_xfer_t xfer = { - .daddr = daddr, - .ep_addr = 0, - .setup = &request, - .buffer = p_epbuf->ctrl_buf, - .complete_cb = config_set_port_power, - .user_data = 0 - }; + xfer->setup = &request; + xfer->buffer = get_hub_epbuf(xfer->daddr)->ctrl_buf; + xfer->complete_cb = config_set_port_power; - TU_ASSERT(tuh_control_xfer(&xfer)); - return true; + TU_ASSERT(tuh_control_xfer(xfer), ); } static void config_set_port_power (tuh_xfer_t* xfer) { -- cgit v1.3.1 From 5817f0d2eb285d058a1aa416abaefe29cb858093 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 6 Mar 2026 15:44:26 +0100 Subject: fix ci Signed-off-by: HiFiPhile --- src/host/hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/host/hub.c b/src/host/hub.c index b32e996a0..ded851a09 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -228,7 +228,7 @@ uint16_t hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const TU_ASSERT(drv_len <= max_len, 0); tusb_desc_device_t desc_dev; - tuh_descriptor_get_device_local(dev_addr, &desc_dev); + TU_ASSERT(tuh_descriptor_get_device_local(dev_addr, &desc_dev)); // Skip STT interface of MTT hub if (desc_dev.bDeviceProtocol == 2 && itf_desc->bInterfaceProtocol == 1) { hub_interface_t* p_hub = get_hub_itf(dev_addr); -- cgit v1.3.1 From e658e2343589d2f37afbf62c0a6766038739b84d Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 6 Mar 2026 15:47:19 +0100 Subject: fix CI Signed-off-by: HiFiPhile --- examples/host/bare_api/skip.txt | 1 + examples/host/bare_api/src/main.c | 16 ++++++++-------- examples/host/cdc_msc_hid/skip.txt | 1 + examples/host/cdc_msc_hid_freertos/skip.txt | 1 + examples/host/device_info/skip.txt | 1 + examples/host/hid_controller/skip.txt | 1 + examples/host/midi_rx/skip.txt | 1 + examples/host/msc_file_explorer/skip.txt | 1 + hw/bsp/lpc54/boards/lpcxpresso54114/board.cmake | 6 ++---- hw/bsp/lpc54/boards/lpcxpresso54608/board.cmake | 7 +++++-- hw/bsp/lpc54/boards/lpcxpresso54628/board.cmake | 7 +++++-- hw/bsp/lpc54/iar/LPC54608_flash.icf | 1 - hw/bsp/lpc54/iar/LPC54628_flash.icf | 1 - hw/bsp/lpc55/family.mk | 4 ++-- src/common/tusb_mcu.h | 13 +++++++++---- tools/codespell/ignore-words.txt | 1 + tools/get_deps.py | 2 +- 17 files changed, 40 insertions(+), 25 deletions(-) create mode 100644 examples/host/bare_api/skip.txt create mode 100644 examples/host/cdc_msc_hid/skip.txt create mode 100644 examples/host/device_info/skip.txt create mode 100644 examples/host/hid_controller/skip.txt create mode 100644 examples/host/midi_rx/skip.txt create mode 100644 examples/host/msc_file_explorer/skip.txt (limited to 'src') diff --git a/examples/host/bare_api/skip.txt b/examples/host/bare_api/skip.txt new file mode 100644 index 000000000..308796869 --- /dev/null +++ b/examples/host/bare_api/skip.txt @@ -0,0 +1 @@ +board:lpcxpresso54114 diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 87f612588..544f38102 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -384,12 +384,12 @@ static int _count_utf8_bytes(const uint16_t *buf, size_t len) { return (int) total_bytes; } -static void print_utf16(uint16_t *temp_buf, size_t buf_len) { - if ((temp_buf[0] & 0xff) == 0) return;// empty - size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); - size_t utf8_len = (size_t) _count_utf8_bytes(temp_buf + 1, utf16_len); - _convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t *) temp_buf, sizeof(uint16_t) * buf_len); - ((uint8_t *) temp_buf)[utf8_len] = '\0'; - - printf("%s", (char *) temp_buf); +static void print_utf16(uint16_t *buf, size_t buf_len) { + if ((buf[0] & 0xff) == 0) return;// empty + size_t utf16_len = ((buf[0] & 0xff) - 2) / sizeof(uint16_t); + size_t utf8_len = (size_t) _count_utf8_bytes(buf + 1, utf16_len); + _convert_utf16le_to_utf8(buf + 1, utf16_len, (uint8_t *) buf, sizeof(uint16_t) * buf_len); + ((uint8_t *) buf)[utf8_len] = '\0'; + + printf("%s", (char *) buf); } diff --git a/examples/host/cdc_msc_hid/skip.txt b/examples/host/cdc_msc_hid/skip.txt new file mode 100644 index 000000000..308796869 --- /dev/null +++ b/examples/host/cdc_msc_hid/skip.txt @@ -0,0 +1 @@ +board:lpcxpresso54114 diff --git a/examples/host/cdc_msc_hid_freertos/skip.txt b/examples/host/cdc_msc_hid_freertos/skip.txt index 2ba4438fd..54e7be1ba 100644 --- a/examples/host/cdc_msc_hid_freertos/skip.txt +++ b/examples/host/cdc_msc_hid_freertos/skip.txt @@ -1 +1,2 @@ mcu:RP2040 +board:lpcxpresso54114 diff --git a/examples/host/device_info/skip.txt b/examples/host/device_info/skip.txt new file mode 100644 index 000000000..308796869 --- /dev/null +++ b/examples/host/device_info/skip.txt @@ -0,0 +1 @@ +board:lpcxpresso54114 diff --git a/examples/host/hid_controller/skip.txt b/examples/host/hid_controller/skip.txt new file mode 100644 index 000000000..308796869 --- /dev/null +++ b/examples/host/hid_controller/skip.txt @@ -0,0 +1 @@ +board:lpcxpresso54114 diff --git a/examples/host/midi_rx/skip.txt b/examples/host/midi_rx/skip.txt new file mode 100644 index 000000000..308796869 --- /dev/null +++ b/examples/host/midi_rx/skip.txt @@ -0,0 +1 @@ +board:lpcxpresso54114 diff --git a/examples/host/msc_file_explorer/skip.txt b/examples/host/msc_file_explorer/skip.txt new file mode 100644 index 000000000..308796869 --- /dev/null +++ b/examples/host/msc_file_explorer/skip.txt @@ -0,0 +1 @@ +board:lpcxpresso54114 diff --git a/hw/bsp/lpc54/boards/lpcxpresso54114/board.cmake b/hw/bsp/lpc54/boards/lpcxpresso54114/board.cmake index c0bbeecd5..b306f885a 100644 --- a/hw/bsp/lpc54/boards/lpcxpresso54114/board.cmake +++ b/hw/bsp/lpc54/boards/lpcxpresso54114/board.cmake @@ -6,10 +6,8 @@ set(PYOCD_TARGET LPC54114) set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/LPC54114J256_cm4_flash.ld) -# Device port default to PORT1 Highspeed -if (NOT DEFINED PORT) - set(PORT 1) -endif() +# Only Port 0 Full-Speed +set(RHPORT_DEVICE 0) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC diff --git a/hw/bsp/lpc54/boards/lpcxpresso54608/board.cmake b/hw/bsp/lpc54/boards/lpcxpresso54608/board.cmake index f0715fa12..aea608e60 100644 --- a/hw/bsp/lpc54/boards/lpcxpresso54608/board.cmake +++ b/hw/bsp/lpc54/boards/lpcxpresso54608/board.cmake @@ -8,8 +8,11 @@ set(NXPLINK_DEVICE LPC54608:LPCXpresso54608) set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/LPC54608J512_flash.ld) # Device port default to PORT1 Highspeed -if (NOT DEFINED PORT) - set(PORT 1) +if (NOT DEFINED RHPORT_DEVICE) + set(RHPORT_DEVICE 1) +endif() +if (NOT DEFINED RHPORT_HOST) + set(RHPORT_HOST 0) endif() function(update_board TARGET) diff --git a/hw/bsp/lpc54/boards/lpcxpresso54628/board.cmake b/hw/bsp/lpc54/boards/lpcxpresso54628/board.cmake index 1dea6f353..b0d0d404f 100644 --- a/hw/bsp/lpc54/boards/lpcxpresso54628/board.cmake +++ b/hw/bsp/lpc54/boards/lpcxpresso54628/board.cmake @@ -8,8 +8,11 @@ set(NXPLINK_DEVICE LPC54628:LPCXpresso54628) set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/LPC54628J512_flash.ld) # Device port default to PORT1 Highspeed -if (NOT DEFINED PORT) - set(PORT 1) +if (NOT DEFINED RHPORT_DEVICE) + set(RHPORT_DEVICE 1) +endif() +if (NOT DEFINED RHPORT_HOST) + set(RHPORT_HOST 0) endif() function(update_board TARGET) diff --git a/hw/bsp/lpc54/iar/LPC54608_flash.icf b/hw/bsp/lpc54/iar/LPC54608_flash.icf index 2a7885541..408ab90ed 100644 --- a/hw/bsp/lpc54/iar/LPC54608_flash.icf +++ b/hw/bsp/lpc54/iar/LPC54608_flash.icf @@ -82,4 +82,3 @@ place in DATA_region { block RW }; place in DATA_region { block ZI }; place in DATA_region { last block HEAP }; place in CSTACK_region { block CSTACK }; - diff --git a/hw/bsp/lpc54/iar/LPC54628_flash.icf b/hw/bsp/lpc54/iar/LPC54628_flash.icf index 7cca18159..cc6615bd6 100644 --- a/hw/bsp/lpc54/iar/LPC54628_flash.icf +++ b/hw/bsp/lpc54/iar/LPC54628_flash.icf @@ -80,4 +80,3 @@ place in DATA_region { block RW }; place in DATA_region { block ZI }; place in DATA_region { last block HEAP }; place in CSTACK_region { block CSTACK }; - diff --git a/hw/bsp/lpc55/family.mk b/hw/bsp/lpc55/family.mk index 7b1ab6b09..a7d06d70a 100644 --- a/hw/bsp/lpc55/family.mk +++ b/hw/bsp/lpc55/family.mk @@ -2,8 +2,8 @@ UF2_FAMILY_ID = 0x2abc77ec include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m33 -MCUX_DIR = /hw/mcu/nxp/mcuxsdk-core -SDK_DIR = /hw/mcu/nxp/mcux-devices-lpc +MCUX_DIR = hw/mcu/nxp/mcuxsdk-core +SDK_DIR = hw/mcu/nxp/mcux-devices-lpc # Default to Highspeed PORT1 PORT ?= 1 diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 0e5233bbe..c4615a87b 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -71,12 +71,17 @@ #define TUP_DCD_ENDPOINT_MAX 5 #elif TU_CHECK_MCU(OPT_MCU_LPC54) + #include "fsl_device_registers.h" + // TODO USB0 has 5, USB1 has 6 #define TUP_USBIP_IP3511 - #define TUP_USBIP_IP3516 - #define TUP_USBIP_OHCI - #define TUP_USBIP_OHCI_NXP - #define TUP_OHCI_RHPORTS 1 // 1 downstream port + + #if !defined(LPC54114_cm4_SERIES) && !defined(LPC54114_cm0plus_SERIES) + #define TUP_USBIP_IP3516 + #define TUP_USBIP_OHCI + #define TUP_USBIP_OHCI_NXP + #define TUP_OHCI_RHPORTS 1 // 1 downstream port + #endif #define TUP_DCD_ENDPOINT_MAX 6 diff --git a/tools/codespell/ignore-words.txt b/tools/codespell/ignore-words.txt index 5b6e2e98b..7ce778fab 100644 --- a/tools/codespell/ignore-words.txt +++ b/tools/codespell/ignore-words.txt @@ -7,6 +7,7 @@ hsi inout mot pris +ptd ser sie synopsys diff --git a/tools/get_deps.py b/tools/get_deps.py index 2f37901c8..bf91428f4 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -66,7 +66,7 @@ deps_optional = { 'lpc51 lpc55 mcx'], 'hw/mcu/nxp/mcux-sdk': ['https://github.com/nxp-mcuxpresso/mcux-sdk', 'a1bdae309a14ec95a4f64a96d3315a4f89c397c6', - 'kinetis_k kinetis_k32l2 kinetis_kl rw61x imxrt'], + 'kinetis_k kinetis_k32l2 kinetis_kl lpc54 rw61x imxrt'], 'hw/mcu/nxp/mcux-devices-lpc': ['https://github.com/nxp-mcuxpresso/mcux-devices-lpc', '8096b783ec09d0d1c8629025a5f9d8e7df26e520', 'lpc51 lpc55'], -- cgit v1.3.1 From fe26e45e64dc0c356ddba3470343244c7544b3ac Mon Sep 17 00:00:00 2001 From: YixingShen Date: Sat, 7 Mar 2026 02:03:50 +0800 Subject: fixed _open_vc_itf parsing Standard Interface Descriptor (Video Control) Video Control Header Descriptor Video Control Camera Terminal Descriptor Video Control Output Terminal Descriptor Standard Endpoint Descriptor Class-Specific VC Interrupt Endpoint Descriptor Video Control Header Descriptor's wTotalLength = Header Descriptor + Camera Terminal Descriptor + Output Terminal Descriptor _end_of_control_descriptor is Output Terminal Descriptor End the "end" should +7 for _find_desc searchig Standard Endpoint Descriptor --- src/class/video/video_device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index b2375def9..24f31c6ad 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -771,7 +771,10 @@ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t TU_ASSERT(vc->ctl.bInCollection <= CFG_TUD_VIDEO_STREAMING); /* Update to point the end of the video control interface descriptor. */ - end = _end_of_control_descriptor(cur); + end = _end_of_control_descriptor(cur) + 7; + //tusb_desc_video_control_header wTotalLength = + // tusb_desc_video_control_header + tusb_desc_video_control_camera_terminal_t + tusb_desc_video_control_output_terminal_t + // has no status Interrupt EP desc, then "end" should +7 for _find_desc searchig EP desc /* Advance to the next descriptor after the class-specific VC interface header descriptor. */ cur += vc->std.bLength + vc->ctl.bLength; -- cgit v1.3.1 From e4a55152be9ae5fb8efebbb5ef197a2d3097b6cc Mon Sep 17 00:00:00 2001 From: YixingShen Date: Sat, 7 Mar 2026 02:05:12 +0800 Subject: cleanup --- src/class/video/video_device.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 24f31c6ad..0f7d6b53b 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -772,9 +772,6 @@ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t /* Update to point the end of the video control interface descriptor. */ end = _end_of_control_descriptor(cur) + 7; - //tusb_desc_video_control_header wTotalLength = - // tusb_desc_video_control_header + tusb_desc_video_control_camera_terminal_t + tusb_desc_video_control_output_terminal_t - // has no status Interrupt EP desc, then "end" should +7 for _find_desc searchig EP desc /* Advance to the next descriptor after the class-specific VC interface header descriptor. */ cur += vc->std.bLength + vc->ctl.bLength; -- cgit v1.3.1 From 0a45308a296251e4376815b21f89f0038c75a60e Mon Sep 17 00:00:00 2001 From: 沈玴興 Date: Sat, 7 Mar 2026 10:46:38 +0800 Subject: Update src/class/video/video_device.c Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/class/video/video_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 0f7d6b53b..85ffcd627 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -771,7 +771,7 @@ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t TU_ASSERT(vc->ctl.bInCollection <= CFG_TUD_VIDEO_STREAMING); /* Update to point the end of the video control interface descriptor. */ - end = _end_of_control_descriptor(cur) + 7; + end = (uint8_t const *) _end_of_control_descriptor(cur) + sizeof(tusb_desc_endpoint_t); /* Advance to the next descriptor after the class-specific VC interface header descriptor. */ cur += vc->std.bLength + vc->ctl.bLength; -- cgit v1.3.1 From 1c53009dc70e8535347f83cd9f3024ea495a085c Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 7 Mar 2026 13:07:13 +0700 Subject: remove dma_desc_t --- src/portable/microchip/samx7x/dcd_samx7x.c | 8 -------- src/portable/microchip/samx7x/samx7x_common.h | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) (limited to 'src') diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c index bd158b47d..6da1e9778 100644 --- a/src/portable/microchip/samx7x/dcd_samx7x.c +++ b/src/portable/microchip/samx7x/dcd_samx7x.c @@ -50,14 +50,6 @@ #define EP_GET_FIFO_PTR(ep, scale) \ (((TU_XSTRCAT(TU_STRCAT(uint, scale), _t)(*)[0x8000 / ((scale) / 8)]) FIFO_RAM_ADDR)[(ep)]) -// DMA Channel Transfer Descriptor -typedef struct { - volatile uint32_t next_desc; - volatile uint32_t buff_addr; - volatile uint32_t chnl_ctrl; - uint32_t padding; -} dma_desc_t; - // Transfer control context typedef struct { uint8_t *buffer; diff --git a/src/portable/microchip/samx7x/samx7x_common.h b/src/portable/microchip/samx7x/samx7x_common.h index 4fd63b7f8..5e3c20c0f 100644 --- a/src/portable/microchip/samx7x/samx7x_common.h +++ b/src/portable/microchip/samx7x/samx7x_common.h @@ -1,4 +1,4 @@ - /* +/* * The MIT License (MIT) * * Copyright (c) 2019 Microchip Technology Inc. -- cgit v1.3.1 From f17da1c66e53a05e7d400efc98cbfe4faa820ae4 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 7 Mar 2026 15:25:05 +0700 Subject: open hub mtt interface in 1 call --- .idea/cmake.xml | 1 + src/host/hub.c | 45 ++++++++++++++++++++++++++------------------- src/host/hub.h | 7 +++++++ 3 files changed, 34 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 822a70236..6f87e2a29 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -96,6 +96,7 @@ + diff --git a/src/host/hub.c b/src/host/hub.c index ded851a09..7c6735ed4 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -218,31 +218,37 @@ bool hub_deinit(void) { return true; } -uint16_t hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { - (void) rhport; +uint16_t hub_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { + (void)rhport; + TU_VERIFY(TUSB_CLASS_HUB == itf_desc->bInterfaceClass && 0 == itf_desc->bInterfaceSubClass, 0); - TU_VERIFY(TUSB_CLASS_HUB == itf_desc->bInterfaceClass && - 0 == itf_desc->bInterfaceSubClass, 0); - - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t); + const uint16_t itf_ep_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t); + uint16_t drv_len = itf_ep_len; TU_ASSERT(drv_len <= max_len, 0); + hub_interface_t *p_hub = get_hub_itf(dev_addr); + const tusb_desc_interface_t *desc_itf_use = itf_desc; // interface to use for endpoint open + + // Check device descriptor for MTT hub (bDeviceProtocol == 2) + // MTT hub has 2 alt settings: alt 0 is STT (protocol 1), alt 1 is MTT (protocol 2) + // Consume both alt settings and use alt setting 1 for endpoint tusb_desc_device_t desc_dev; - TU_ASSERT(tuh_descriptor_get_device_local(dev_addr, &desc_dev)); - // Skip STT interface of MTT hub - if (desc_dev.bDeviceProtocol == 2 && itf_desc->bInterfaceProtocol == 1) { - hub_interface_t* p_hub = get_hub_itf(dev_addr); - p_hub->mtt = true; - return drv_len; + if (tuh_descriptor_get_device_local(dev_addr, &desc_dev) && desc_dev.bDeviceProtocol == HUB_PROTOCOL_HIGH_SPEED_MTT) { + drv_len += itf_ep_len; + TU_ASSERT(drv_len <= max_len, 0); + const tusb_desc_interface_t *desc_alt1 = (const tusb_desc_interface_t *)((const uint8_t *)itf_desc + itf_ep_len); + TU_ASSERT(desc_alt1->bDescriptorType == TUSB_DESC_INTERFACE && desc_alt1->bInterfaceClass == TUSB_CLASS_HUB && + desc_alt1->bInterfaceProtocol == HUB_PROTOCOL_HIGH_SPEED_MTT, + 0); + p_hub->mtt = true; + desc_itf_use = desc_alt1; } // Interrupt Status endpoint - tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc); - TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && - TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0); + const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(desc_itf_use); + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0); TU_ASSERT(tuh_edpt_open(dev_addr, desc_ep), 0); - hub_interface_t* p_hub = get_hub_itf(dev_addr); p_hub->itf_num = itf_desc->bInterfaceNumber; p_hub->ep_in = desc_ep->bEndpointAddress; @@ -288,8 +294,9 @@ bool hub_set_config(uint8_t daddr, uint8_t itf_num) { TU_ASSERT(tuh_interface_set(daddr, itf_num, 1, config_get_hub_descriptor, 0)); } else { tuh_xfer_t xfer; - xfer.daddr = daddr; - xfer.ep_addr = 0; + xfer.daddr = daddr; + xfer.ep_addr = 0; + xfer.user_data = 0; config_get_hub_descriptor(&xfer); } @@ -324,7 +331,7 @@ static void config_set_port_power (tuh_xfer_t* xfer) { hub_interface_t* p_hub = get_hub_itf(daddr); hub_epbuf_t* p_epbuf = get_hub_epbuf(daddr); - // only use number of ports in hub descriptor + // only use the number of ports in the hub descriptor hub_desc_cs_t const* desc_hub = (hub_desc_cs_t const*) p_epbuf->ctrl_buf; p_hub->bNbrPorts = desc_hub->bNbrPorts; p_hub->bPwrOn2PwrGood_2ms = desc_hub->bPwrOn2PwrGood; diff --git a/src/host/hub.h b/src/host/hub.h index d9750f8a5..8a7feda70 100644 --- a/src/host/hub.h +++ b/src/host/hub.h @@ -92,6 +92,13 @@ enum { HUB_CHARS_OVER_CURRENT_INDIVIDUAL = 1, }; +// Hub Interface Protocol (USB 2.0 spec Table 11-16) +typedef enum { + HUB_PROTOCOL_FULL_SPEED = 0, // Full speed hub + HUB_PROTOCOL_HIGH_SPEED_STT = 1, // Hi-speed hub with single TT + HUB_PROTOCOL_HIGH_SPEED_MTT = 2, // Hi-speed hub with multiple TTs +} hub_protocol_t; + typedef struct TU_ATTR_PACKED{ uint8_t bLength ; ///< Size of descriptor uint8_t bDescriptorType ; ///< Other_speed_Configuration Type -- cgit v1.3.1 From 2a0802c6a56dc3849fe21d376908aff07131a111 Mon Sep 17 00:00:00 2001 From: YixingShen Date: Sat, 7 Mar 2026 22:56:28 +0800 Subject: fixed _end_of_control_descriptor logic. wTotalLength does not include Standard Endpoint Descriptor and Class-specific VC Interrupt Endpoint Descriptor, so fix that _end_of_control_descriptor include Standard Endpoint Descriptor and Class-specific VC Interrupt Endpoint Descriptor. It will also fix _close_vc_itf, _open_vc_itf. _find_desc_entity parsing. --- src/class/video/video_device.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 85ffcd627..a65d83d8f 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -392,7 +392,13 @@ static void const* _find_desc_ep(void const *beg, void const *end) static inline void const* _end_of_control_descriptor(void const *desc) { tusb_desc_vc_itf_t const *vc = (tusb_desc_vc_itf_t const *)desc; - return ((uint8_t const*) desc) + vc->std.bLength + tu_le16toh(vc->ctl.wTotalLength); + uint8_t const *end = (uint8_t const*)desc + vc->std.bLength + + tu_le16toh(vc->ctl.wTotalLength); + if (vc->std.bNumEndpoints) { + end += sizeof(tusb_desc_endpoint_t); // standard EP descriptor + end += 5; // class-specific EP descriptor (fixed 5 bytes per UVC spec) + } + return end; } /** Find the first entity descriptor with the entity ID @@ -771,7 +777,7 @@ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t TU_ASSERT(vc->ctl.bInCollection <= CFG_TUD_VIDEO_STREAMING); /* Update to point the end of the video control interface descriptor. */ - end = (uint8_t const *) _end_of_control_descriptor(cur) + sizeof(tusb_desc_endpoint_t); + end = _end_of_control_descriptor(cur); /* Advance to the next descriptor after the class-specific VC interface header descriptor. */ cur += vc->std.bLength + vc->ctl.bLength; -- cgit v1.3.1 From 11a3c3b712eb97e5c05ed3df20dcde9451fe158d Mon Sep 17 00:00:00 2001 From: gab-k Date: Sat, 7 Mar 2026 21:53:01 +0100 Subject: Fix ep_ctrl_mask() corrupting opposite direction's ENDPTCTRL bits --- src/portable/chipidea/ci_hs/dcd_ci_hs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index b9f6a8a7b..9ed75ffd9 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -388,7 +388,7 @@ TU_ATTR_ALWAYS_INLINE static inline void ep_ctrl_mask(volatile uint32_t *epctrl, uint32_t or_mask) { uint32_t value = *epctrl; if (and_mask != 0) { - value &= (dir == TUSB_DIR_OUT) ? and_mask : (and_mask << 16u); + value &= (dir == TUSB_DIR_OUT) ? (and_mask | 0xFFFF0000u) : ((and_mask << 16u) | 0x0000FFFFu); } if (or_mask != 0) { value |= (dir == TUSB_DIR_OUT) ? or_mask : (or_mask << 16u); -- cgit v1.3.1 From 2a4b82e3e12b68705f394bf8d800c64ab81ab1c0 Mon Sep 17 00:00:00 2001 From: Siddharth Chandrasekaran Date: Sun, 8 Mar 2026 00:08:40 +0100 Subject: tinyusb: fix hwfifo PMA pointer advance on ring buffer wrap In hwff_push_n() and hwff_pull_n(), the HWFIFO_ADDR_NEXT_N call after processing the linear part of a wrap-around read/write used the data byte count (lin_even) as the address stride increment. On STM32 FSDEV PMA, data_stride=2 and addr_stride=4, so the pointer must advance by (lin_even / data_stride) * addr_stride bytes, not lin_even bytes. Fixes: 74e59e433 ("fix hwfifo pull/push n with address stride > 0") Signed-off-by: Siddharth Chandrasekaran --- src/common/tusb_fifo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 8bd79e56d..991ee18ff 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -280,7 +280,7 @@ static void hwff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uin const uint32_t odd_mask = data_stride - 1; uint16_t lin_even = lin_bytes & ~odd_mask; tu_hwfifo_read(hwfifo, ff_buf, lin_even, access_mode); - HWFIFO_ADDR_NEXT_N(hwfifo, const, lin_even); + HWFIFO_ADDR_NEXT_N(hwfifo, const, (lin_even / data_stride) * CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE); ff_buf += lin_even; // There could be odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary @@ -337,7 +337,7 @@ static void hwff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t const uint32_t odd_mask = data_stride - 1; uint16_t lin_even = lin_bytes & ~odd_mask; tu_hwfifo_write(hwfifo, ff_buf, lin_even, access_mode); - HWFIFO_ADDR_NEXT_N(hwfifo, , lin_even); + HWFIFO_ADDR_NEXT_N(hwfifo, , (lin_even / data_stride) * CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE); ff_buf += lin_even; // There could be odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary -- cgit v1.3.1 From 3e22de0a4782d6062959aec27e5304f1b4d4a557 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 9 Mar 2026 10:49:04 +0700 Subject: extend video control parsing to include class-specific VC endpoint descriptor --- src/class/video/video_device.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index a65d83d8f..d1c699940 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -70,6 +70,13 @@ typedef struct TU_ATTR_PACKED { uint8_t bEntityId; } tusb_desc_cs_video_entity_itf_t; +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint16_t wMaxTransferSize; +} tusb_desc_cs_video_vc_ep_t; + typedef union { struct TU_ATTR_PACKED { uint8_t bLength; @@ -746,6 +753,9 @@ static bool _close_vc_itf(uint8_t rhport, videod_interface_t *self) /* The end of the video control interface descriptor. */ void const *end = _end_of_control_descriptor(vc); if (vc->std.bNumEndpoints != 0) { + /* Extend end to cover the standard endpoint and class-specific endpoint descriptors + * that follow wTotalLength */ + end = (uint8_t const*)end + sizeof(tusb_desc_endpoint_t) + sizeof(tusb_desc_cs_video_vc_ep_t); /* Find the notification endpoint descriptor. */ cur = _find_desc(cur, end, TUSB_DESC_ENDPOINT); TU_ASSERT(cur < end); @@ -786,6 +796,9 @@ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t if (vc->std.bNumEndpoints != 0) { /* Support for 1 endpoint only. */ TU_VERIFY(1 == vc->std.bNumEndpoints); + /* Extend end to cover the standard endpoint and class-specific endpoint descriptors + * that follow wTotalLength */ + end = (uint8_t const*)end + sizeof(tusb_desc_endpoint_t) + sizeof(tusb_desc_cs_video_vc_ep_t); /* Find the notification endpoint descriptor. */ cur = _find_desc(cur, end, TUSB_DESC_ENDPOINT); TU_VERIFY(cur < end); -- cgit v1.3.1 From 0d4feff0eb01511d413e79109656dd76bf42e77a Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 9 Mar 2026 14:15:20 +0700 Subject: usbh device descriptor validation, also check ep size > 0 --- src/common/tusb_private.h | 3 +-- src/host/usbh.c | 30 ++++++++++++++++++++---------- src/tusb.c | 3 ++- 3 files changed, 23 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 5a51dfc37..17ab267c3 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -81,9 +81,8 @@ typedef struct { bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed); #else TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed) { - (void)desc_ep; (void)speed; - return true; + return tu_edpt_packet_size(desc_ep) > 0; } #endif diff --git a/src/host/usbh.c b/src/host/usbh.c index 33d74862f..0fa9b6646 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1150,7 +1150,7 @@ static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) { } bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const* desc_ep) { - // HACK: some device incorrectly always report 512 bulk regardless of link speed, overwrite descriptor to force 64 + // HACK: some device incorrectly always reports 512 bulk regardless of link speed, overwrite descriptor to force 64 if (desc_ep->bmAttributes.xfer == TUSB_XFER_BULK && tu_edpt_packet_size(desc_ep) > 64 && tuh_speed_get(dev_addr) == TUSB_SPEED_FULL) { TU_LOG1(" WARN: EP max packet size is 512 in fullspeed, force to 64\r\n"); @@ -1655,6 +1655,7 @@ static void process_enumeration(tuh_xfer_t *xfer) { TU_ASSERT(dev != NULL,); } uint16_t langid = 0x0409; // default is English + bool is_enum_failed = false; switch (state) { #if CFG_TUH_HUB @@ -1664,11 +1665,11 @@ static void process_enumeration(tuh_xfer_t *xfer) { if (0 == port_status.status.connection) { TU_LOG_USBH("Device unplugged from hub while debouncing\r\n"); - enum_full_complete(false); - return; + is_enum_failed = true; + } else { + TU_ASSERT(hub_port_reset(dev0_bus->hub_addr, dev0_bus->hub_port, process_enumeration, + ENUM_HUB_RESET_COMPLETE), ); } - - TU_ASSERT(hub_port_reset(dev0_bus->hub_addr, dev0_bus->hub_port, process_enumeration, ENUM_HUB_RESET_COMPLETE), ); break; } @@ -1691,7 +1692,7 @@ static void process_enumeration(tuh_xfer_t *xfer) { usbh_defer_func_ms_async(ENUM_RESET_HUB_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_HUB_DELAY_RETRY); } else { // retry but still not set --> failed - enum_full_complete(false); + is_enum_failed = true; } break; } @@ -1702,14 +1703,13 @@ static void process_enumeration(tuh_xfer_t *xfer) { if (0 == port_status.status.connection) { TU_LOG_USBH("Device unplugged from hub (not addressed yet)\r\n"); - enum_full_complete(false); - return; + is_enum_failed = true; + break; } dev0_bus->speed = (port_status.status.high_speed) ? TUSB_SPEED_HIGH : (port_status.status.low_speed) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; - TU_ATTR_FALLTHROUGH; } #endif @@ -1720,6 +1720,12 @@ static void process_enumeration(tuh_xfer_t *xfer) { case ENUM_SET_ADDR: { const tusb_desc_device_t *desc_device = (const tusb_desc_device_t *) _usbh_epbuf.ctrl; + if (!(desc_device->bDescriptorType == TUSB_DESC_DEVICE && desc_device->bMaxPacketSize0 >= 8)) { + TU_LOG_USBH("Invalid Device descriptor\r\n"); + is_enum_failed = true; + break; + } + const uint8_t new_addr = enum_get_new_address(desc_device->bDeviceClass == TUSB_CLASS_HUB); TU_ASSERT(new_addr != 0,); @@ -1910,9 +1916,13 @@ static void process_enumeration(tuh_xfer_t *xfer) { } default: - enum_full_complete(false); // stop enumeration if unknown state + is_enum_failed = true; break; } + + if (is_enum_failed) { + enum_full_complete(false); + } } static uint8_t enum_get_new_address(bool is_hub) { diff --git a/src/tusb.c b/src/tusb.c index 5241fcf3d..4ea396715 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -260,6 +260,7 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) { bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed) { const uint16_t max_packet_size = tu_edpt_packet_size(desc_ep); TU_LOG2(" Open EP %02X with Size = %u\r\n", desc_ep->bEndpointAddress, max_packet_size); + TU_ASSERT(max_packet_size > 0); switch (desc_ep->bmAttributes.xfer) { case TUSB_XFER_ISOCHRONOUS: { @@ -279,7 +280,7 @@ bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed) { break; case TUSB_XFER_INTERRUPT: { - uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 64); + const uint16_t spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 64); TU_ASSERT(max_packet_size <= spec_size); break; } -- cgit v1.3.1 From 4c7bfc4dbec60fb12d542562fd3843005c24300b Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 9 Mar 2026 14:28:59 +0700 Subject: refactor: add desc_device_noheader_t to simplify get device descriptor local --- src/common/tusb_types.h | 2 -- src/host/usbh.c | 86 ++++++++++++++++++++----------------------------- 2 files changed, 35 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 7d26ac74e..8a48a0f04 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -341,12 +341,10 @@ typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< DEVICE Descriptor Type. uint16_t bcdUSB ; ///< BUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). - uint8_t bDeviceClass ; ///< Class code (assigned by the USB-IF). uint8_t bDeviceSubClass ; ///< Subclass code (assigned by the USB-IF). uint8_t bDeviceProtocol ; ///< Protocol code (assigned by the USB-IF). uint8_t bMaxPacketSize0 ; ///< Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid). For HS devices is fixed to 64. - uint16_t idVendor ; ///< Vendor ID (assigned by the USB-IF). uint16_t idProduct ; ///< Product ID (assigned by the manufacturer). uint16_t bcdDevice ; ///< Device release number in binary-coded decimal. diff --git a/src/host/usbh.c b/src/host/usbh.c index 0fa9b6646..6574e7819 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -104,10 +104,9 @@ TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr) { //--------------------------------------------------------------------+ // Data Structure //--------------------------------------------------------------------+ -typedef struct { - tuh_bus_info_t bus_info; - // Device Descriptor +// Device Descriptor (without bLength and bDescriptorType header) +typedef struct TU_ATTR_PACKED { uint16_t bcdUSB; uint8_t bDeviceClass; uint8_t bDeviceSubClass; @@ -120,6 +119,13 @@ typedef struct { uint8_t iProduct; uint8_t iSerialNumber; uint8_t bNumConfigurations; +} desc_device_noheader_t; + +TU_VERIFY_STATIC( sizeof(desc_device_noheader_t) == 16u, "size is not correct"); + +typedef struct { + tuh_bus_info_t bus_info; + desc_device_noheader_t desc_device; // Device State struct TU_ATTR_PACKED { @@ -413,10 +419,10 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t *vid, uint16_t *pid) { *vid = *pid = 0; usbh_device_t const *dev = get_device(dev_addr); - TU_VERIFY(dev && dev->addressed && dev->idVendor != 0); + TU_VERIFY(dev && dev->addressed && dev->desc_device.idVendor != 0); - *vid = dev->idVendor; - *pid = dev->idProduct; + *vid = dev->desc_device.idVendor; + *pid = dev->desc_device.idProduct; return true; } @@ -427,18 +433,7 @@ bool tuh_descriptor_get_device_local(uint8_t daddr, tusb_desc_device_t* desc_dev desc_device->bLength = sizeof(tusb_desc_device_t); desc_device->bDescriptorType = TUSB_DESC_DEVICE; - desc_device->bcdUSB = dev->bcdUSB; - desc_device->bDeviceClass = dev->bDeviceClass; - desc_device->bDeviceSubClass = dev->bDeviceSubClass; - desc_device->bDeviceProtocol = dev->bDeviceProtocol; - desc_device->bMaxPacketSize0 = dev->bMaxPacketSize0; - desc_device->idVendor = dev->idVendor; - desc_device->idProduct = dev->idProduct; - desc_device->bcdDevice = dev->bcdDevice; - desc_device->iManufacturer = dev->iManufacturer; - desc_device->iProduct = dev->iProduct; - desc_device->iSerialNumber = dev->iSerialNumber; - desc_device->bNumConfigurations = dev->bNumConfigurations; + memcpy(&desc_device->bcdUSB, &dev->desc_device, sizeof(dev->desc_device)); return true; } @@ -1275,24 +1270,24 @@ bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { usbh_device_t const* dev = get_device(daddr); - TU_VERIFY(dev && dev->iManufacturer); - return tuh_descriptor_get_string(daddr, dev->iManufacturer, language_id, buffer, len, complete_cb, user_data); + TU_VERIFY(dev && dev->desc_device.iManufacturer); + return tuh_descriptor_get_string(daddr, dev->desc_device.iManufacturer, language_id, buffer, len, complete_cb, user_data); } // Get product string descriptor bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { usbh_device_t const* dev = get_device(daddr); - TU_VERIFY(dev && dev->iProduct); - return tuh_descriptor_get_string(daddr, dev->iProduct, language_id, buffer, len, complete_cb, user_data); + TU_VERIFY(dev && dev->desc_device.iProduct); + return tuh_descriptor_get_string(daddr, dev->desc_device.iProduct, language_id, buffer, len, complete_cb, user_data); } // Get serial string descriptor bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { usbh_device_t const* dev = get_device(daddr); - TU_VERIFY(dev && dev->iSerialNumber); - return tuh_descriptor_get_string(daddr, dev->iSerialNumber, language_id, buffer, len, complete_cb, user_data); + TU_VERIFY(dev && dev->desc_device.iSerialNumber); + return tuh_descriptor_get_string(daddr, dev->desc_device.iSerialNumber, language_id, buffer, len, complete_cb, user_data); } // Get HID report descriptor @@ -1614,7 +1609,7 @@ static void enum_delay_async(uintptr_t state) { const uint8_t new_addr = _usbh_data.enumerating_daddr; usbh_device_t *new_dev = get_device(new_addr); TU_ASSERT(new_dev, ); - if (!usbh_edpt_control_open(new_addr, new_dev->bMaxPacketSize0)) { + if (!usbh_edpt_control_open(new_addr, new_dev->desc_device.bMaxPacketSize0)) { TU_LOG_USBH("Failed to open new device's control endpoint\r\n"); clear_device(new_dev); enum_full_complete(false); @@ -1732,7 +1727,7 @@ static void process_enumeration(tuh_xfer_t *xfer) { usbh_device_t* new_dev = get_device(new_addr); new_dev->bus_info = *dev0_bus; new_dev->connected = 1; - new_dev->bMaxPacketSize0 = desc_device->bMaxPacketSize0; + new_dev->desc_device.bMaxPacketSize0 = desc_device->bMaxPacketSize0; TU_ASSERT(tuh_address_set(0, new_addr, process_enumeration, ENUM_GET_DEVICE_DESC), ); break; @@ -1756,18 +1751,7 @@ static void process_enumeration(tuh_xfer_t *xfer) { // save the received device descriptor tusb_desc_device_t const *desc_device = (tusb_desc_device_t const *) _usbh_epbuf.ctrl; - dev->bcdUSB = desc_device->bcdUSB; - dev->bDeviceClass = desc_device->bDeviceClass; - dev->bDeviceSubClass = desc_device->bDeviceSubClass; - dev->bDeviceProtocol = desc_device->bDeviceProtocol; - dev->bMaxPacketSize0 = desc_device->bMaxPacketSize0; - dev->idVendor = desc_device->idVendor; - dev->idProduct = desc_device->idProduct; - dev->bcdDevice = desc_device->bcdDevice; - dev->iManufacturer = desc_device->iManufacturer; - dev->iProduct = desc_device->iProduct; - dev->iSerialNumber = desc_device->iSerialNumber; - dev->bNumConfigurations = desc_device->bNumConfigurations; + memcpy(&dev->desc_device, &desc_device->bcdUSB, sizeof(dev->desc_device)); tuh_enum_descriptor_device_cb(daddr, desc_device); // callback tuh_descriptor_get_string_langid(daddr, _usbh_epbuf.ctrl, 2, @@ -1787,8 +1771,8 @@ static void process_enumeration(tuh_xfer_t *xfer) { if (desc_langid->bLength >= 4) { langid = tu_le16toh(desc_langid->utf16le[0]); // previous request is langid } - if (dev->iManufacturer != 0) { - tuh_descriptor_get_string(daddr, dev->iManufacturer, langid, _usbh_epbuf.ctrl, 2, + if (dev->desc_device.iManufacturer != 0) { + tuh_descriptor_get_string(daddr, dev->desc_device.iManufacturer, langid, _usbh_epbuf.ctrl, 2, process_enumeration, ENUM_GET_STRING_MANUFACTURER); break; } @@ -1796,10 +1780,10 @@ static void process_enumeration(tuh_xfer_t *xfer) { } case ENUM_GET_STRING_MANUFACTURER: { - if (dev->iManufacturer != 0) { + if (dev->desc_device.iManufacturer != 0) { langid = tu_le16toh(xfer->setup->wIndex); // langid from length's request const uint8_t str_len = xfer->buffer[0]; - tuh_descriptor_get_string(daddr, dev->iManufacturer, langid, _usbh_epbuf.ctrl, str_len, + tuh_descriptor_get_string(daddr, dev->desc_device.iManufacturer, langid, _usbh_epbuf.ctrl, str_len, process_enumeration, ENUM_GET_STRING_PRODUCT_LEN); break; } @@ -1807,22 +1791,22 @@ static void process_enumeration(tuh_xfer_t *xfer) { } case ENUM_GET_STRING_PRODUCT_LEN: { - if (dev->iProduct != 0) { + if (dev->desc_device.iProduct != 0) { if (state == ENUM_GET_STRING_PRODUCT_LEN) { langid = tu_le16toh(xfer->setup->wIndex); // get langid from previous setup packet if not fall through } tuh_descriptor_get_string( - daddr, dev->iProduct, langid, _usbh_epbuf.ctrl, 2, process_enumeration, ENUM_GET_STRING_PRODUCT); + daddr, dev->desc_device.iProduct, langid, _usbh_epbuf.ctrl, 2, process_enumeration, ENUM_GET_STRING_PRODUCT); break; } TU_ATTR_FALLTHROUGH; } case ENUM_GET_STRING_PRODUCT: { - if (dev->iProduct != 0) { + if (dev->desc_device.iProduct != 0) { langid = tu_le16toh(xfer->setup->wIndex); // langid from length's request const uint8_t str_len = xfer->buffer[0]; - tuh_descriptor_get_string(daddr, dev->iProduct, langid, _usbh_epbuf.ctrl, str_len, + tuh_descriptor_get_string(daddr, dev->desc_device.iProduct, langid, _usbh_epbuf.ctrl, str_len, process_enumeration, ENUM_GET_STRING_SERIAL_LEN); break; } @@ -1830,22 +1814,22 @@ static void process_enumeration(tuh_xfer_t *xfer) { } case ENUM_GET_STRING_SERIAL_LEN: { - if (dev->iSerialNumber != 0) { + if (dev->desc_device.iSerialNumber != 0) { if (state == ENUM_GET_STRING_SERIAL_LEN) { langid = tu_le16toh(xfer->setup->wIndex); // get langid from previous setup packet if not fall through } tuh_descriptor_get_string( - daddr, dev->iSerialNumber, langid, _usbh_epbuf.ctrl, 2, process_enumeration, ENUM_GET_STRING_SERIAL); + daddr, dev->desc_device.iSerialNumber, langid, _usbh_epbuf.ctrl, 2, process_enumeration, ENUM_GET_STRING_SERIAL); break; } TU_ATTR_FALLTHROUGH; } case ENUM_GET_STRING_SERIAL: { - if (dev->iSerialNumber != 0) { + if (dev->desc_device.iSerialNumber != 0) { langid = tu_le16toh(xfer->setup->wIndex); // langid from length's request const uint8_t str_len = xfer->buffer[0]; - tuh_descriptor_get_string(daddr, dev->iSerialNumber, langid, _usbh_epbuf.ctrl, str_len, + tuh_descriptor_get_string(daddr, dev->desc_device.iSerialNumber, langid, _usbh_epbuf.ctrl, str_len, process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC); break; } @@ -1884,7 +1868,7 @@ static void process_enumeration(tuh_xfer_t *xfer) { TU_ASSERT(tuh_configuration_set(daddr, config_idx+1u, process_enumeration, ENUM_CONFIG_DRIVER),); } else { config_idx++; - TU_ASSERT(config_idx < dev->bNumConfigurations,); + TU_ASSERT(config_idx < dev->desc_device.bNumConfigurations,); TU_LOG_USBH("Get Configuration[%u] Descriptor (9 bytes)\r\n", config_idx); TU_ASSERT(tuh_descriptor_get_configuration(daddr, config_idx, _usbh_epbuf.ctrl, 9, process_enumeration, ENUM_GET_FULL_CONFIG_DESC),); -- cgit v1.3.1 From 3ca7ad1573e4931d430cc3b6412a7a31da6072c2 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 9 Mar 2026 14:37:55 +0700 Subject: fix(usbh): correct memcpy usage to ensure proper alignment with `offsetof` in device descriptor handling --- src/host/usbh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/host/usbh.c b/src/host/usbh.c index 6574e7819..75df6bf60 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -433,7 +433,7 @@ bool tuh_descriptor_get_device_local(uint8_t daddr, tusb_desc_device_t* desc_dev desc_device->bLength = sizeof(tusb_desc_device_t); desc_device->bDescriptorType = TUSB_DESC_DEVICE; - memcpy(&desc_device->bcdUSB, &dev->desc_device, sizeof(dev->desc_device)); + memcpy((uint8_t*) desc_device + offsetof(tusb_desc_device_t, bcdUSB), &dev->desc_device, sizeof(desc_device_noheader_t)); return true; } @@ -1751,7 +1751,7 @@ static void process_enumeration(tuh_xfer_t *xfer) { // save the received device descriptor tusb_desc_device_t const *desc_device = (tusb_desc_device_t const *) _usbh_epbuf.ctrl; - memcpy(&dev->desc_device, &desc_device->bcdUSB, sizeof(dev->desc_device)); + memcpy(&dev->desc_device, (const uint8_t*) desc_device + offsetof(tusb_desc_device_t, bcdUSB), sizeof(desc_device_noheader_t)); tuh_enum_descriptor_device_cb(daddr, desc_device); // callback tuh_descriptor_get_string_langid(daddr, _usbh_epbuf.ctrl, 2, -- cgit v1.3.1 From ce305af6534e098ee98ab2d8bc2229e2300dc2f0 Mon Sep 17 00:00:00 2001 From: YixingShen Date: Mon, 9 Mar 2026 22:13:59 +0800 Subject: revert _end_of_control_descriptor to Revision: 0a45308a296251e4376815b21f89f0038c75a60e --- src/class/video/video_device.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src') diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index d1c699940..bbcfe45d5 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -399,13 +399,7 @@ static void const* _find_desc_ep(void const *beg, void const *end) static inline void const* _end_of_control_descriptor(void const *desc) { tusb_desc_vc_itf_t const *vc = (tusb_desc_vc_itf_t const *)desc; - uint8_t const *end = (uint8_t const*)desc + vc->std.bLength - + tu_le16toh(vc->ctl.wTotalLength); - if (vc->std.bNumEndpoints) { - end += sizeof(tusb_desc_endpoint_t); // standard EP descriptor - end += 5; // class-specific EP descriptor (fixed 5 bytes per UVC spec) - } - return end; + return ((uint8_t const*) desc) + vc->std.bLength + tu_le16toh(vc->ctl.wTotalLength); } /** Find the first entity descriptor with the entity ID -- cgit v1.3.1 From 3eb2b1fe52cdca89be082295e5ff8c4fed43cc39 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Mar 2026 17:17:59 +0700 Subject: fix typo --- src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c | 44 +++++++++++++++++----------- src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.h | 2 +- 2 files changed, 28 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c b/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c index 32ef99418..c9810f51c 100644 --- a/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c +++ b/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c @@ -72,11 +72,15 @@ #define USBHSH_PORTSC1_W1C_MASK (USBHSH_PORTSC1_CSC_MASK | USBHSH_PORTSC1_PEDC_MASK | USBHSH_PORTSC1_OCC_MASK) +#define IP3516_PSPD_LOW 0 +#define IP3516_PSPD_FULL 1 +#define IP3516_PSPD_HIGH 2 + //--------------------------------------------------------------------+ // Proprietary Transfer Descriptor //--------------------------------------------------------------------+ -CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(1024) static ip3516_ptd_t _ptd; +CFG_TUH_MEM_SECTION TU_ATTR_ALIGNED(1024) static ip3516_ptd_t _ptd; static struct { uint32_t uframe_number; @@ -92,7 +96,7 @@ static inline bool is_ptd_free(const ptd_ctrl1_t ctrl1) { return ctrl1.mps == 0; } -static inline bool is_xfer_asyc(tusb_xfer_type_t xfer_type) { +static inline bool is_xfer_async(tusb_xfer_type_t xfer_type) { return (xfer_type == TUSB_XFER_CONTROL || xfer_type == TUSB_XFER_BULK); } @@ -132,7 +136,7 @@ static inline uint8_t ptd_find_free(tusb_xfer_type_t xfer_type) { for (uint8_t i = 0; i < max_count; i++) { // For ATL: stride is sizeof(ip3516_atl_t) = 16 bytes = 4 words // For PTL: stride is sizeof(ip3516_ptl_t) = 32 bytes = 8 words - uint8_t stride = is_xfer_asyc(xfer_type) ? sizeof(ip3516_atl_t) : sizeof(ip3516_ptl_t); + uint8_t stride = is_xfer_async(xfer_type) ? sizeof(ip3516_atl_t) : sizeof(ip3516_ptl_t); ptd_ctrl1_t *ctrl1 = (ptd_ctrl1_t *)(ptd_array + i * stride); if (is_ptd_free(*ctrl1)) { @@ -161,11 +165,14 @@ static void close_ptds_by_device(uint8_t dev_addr, intptr_t ptd_array, uint8_t m } if (skip_mask) { - // Wait 1 uframe for PTDs to be inactive + // Wait 1 uframe for PTDs to be inactive (with timeout) uint32_t start_uframe = (USBHSH->FLADJ_FRINDEX & USBHSH_FLADJ_FRINDEX_FRINDEX_MASK) >> USBHSH_FLADJ_FRINDEX_FRINDEX_SHIFT; + uint32_t timeout = 10000; while (((USBHSH->FLADJ_FRINDEX & USBHSH_FLADJ_FRINDEX_FRINDEX_MASK) >> USBHSH_FLADJ_FRINDEX_FRINDEX_SHIFT) == - start_uframe) {} + start_uframe && timeout > 0) { + timeout--; + } // Clear PTDs for (uint8_t i = 0; i < max_count; i++) { @@ -220,11 +227,14 @@ static bool find_and_close_ptd(uint8_t dev_addr, uint8_t ep_num, uint8_t ep_dir, if (skip_reg) { *skip_reg |= (1 << i); - // Wait 1 uframe for PTD to be inactive + // Wait 1 uframe for PTD to be inactive (with timeout) uint32_t start_uframe = (USBHSH->FLADJ_FRINDEX & USBHSH_FLADJ_FRINDEX_FRINDEX_MASK) >> USBHSH_FLADJ_FRINDEX_FRINDEX_SHIFT; + uint32_t timeout = 10000; while (((USBHSH->FLADJ_FRINDEX & USBHSH_FLADJ_FRINDEX_FRINDEX_MASK) >> USBHSH_FLADJ_FRINDEX_FRINDEX_SHIFT) == - start_uframe) {} + start_uframe && timeout > 0) { + timeout--; + } // Just clear state ptd_ctrl1_t *ptd_ctrl1 = (ptd_ctrl1_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl1)); @@ -272,7 +282,7 @@ static intptr_t find_opened_ptd(uint8_t dev_addr, uint8_t ep_addr) { } } - return TUSB_INDEX_INVALID_8; + return 0; } static bool edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen, bool is_setup) { @@ -280,7 +290,7 @@ static bool edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16 const uint8_t ep_dir = tu_edpt_dir(ep_addr); intptr_t ptd_ptr = find_opened_ptd(dev_addr, ep_addr); - TU_ASSERT(ptd_ptr != TUSB_INDEX_INVALID_8); + TU_ASSERT(ptd_ptr != 0); ptd_ctrl1_t *ptd_ctrl1 = (ptd_ctrl1_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl1)); ptd_ctrl2_t *ptd_ctrl2 = (ptd_ctrl2_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl2)); @@ -305,7 +315,7 @@ static bool edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16 } } - // Interrupt split transfer needs to be relauched manually if NAKed + // Interrupt split transfer needs to be relaunched manually if NAKed if (ptd_ctrl2->split && ptd_state->ep_type == TUSB_XFER_INTERRUPT) { ptd_ctrl2->reload = 0x0f; ptd_state->nak_cnt = 0x0f; @@ -422,7 +432,7 @@ void hcd_port_reset_end(uint8_t rhport) { while (USBHSH->PORTSC1 & USBHSH_PORTSC1_PR_MASK) {} #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) uint32_t pspd = (USBHSH->PORTSC1 & USBHSH_PORTSC1_PSPD_MASK) >> USBHSH_PORTSC1_PSPD_SHIFT; - if (pspd == 2) { + if (pspd == IP3516_PSPD_HIGH) { // enable phy disconnection for high speed USBPHY->CTRL |= USBPHY_CTRL_ENHOSTDISCONDETECT_MASK; } @@ -440,11 +450,11 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void)rhport; uint32_t pspd = (USBHSH->PORTSC1 & USBHSH_PORTSC1_PSPD_MASK) >> USBHSH_PORTSC1_PSPD_SHIFT; switch (pspd) { - case 0: + case IP3516_PSPD_LOW: return TUSB_SPEED_LOW; - case 1: + case IP3516_PSPD_FULL: return TUSB_SPEED_FULL; - case 2: + case IP3516_PSPD_HIGH: return TUSB_SPEED_HIGH; default: return TUSB_SPEED_INVALID; @@ -473,7 +483,7 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { //--------------------------------------------------------------------+ static inline intptr_t get_ptd_from_index(tusb_xfer_type_t xfer_type, uint8_t ptd_index) { - if (is_xfer_asyc(xfer_type)) { + if (is_xfer_async(xfer_type)) { return (intptr_t)&_ptd.atl[ptd_index]; } else { if (xfer_type == TUSB_XFER_INTERRUPT) { @@ -522,7 +532,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_endpoint_t state->ep_type = (uint32_t)xfer_type; state->token = tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN ? IP3516_PTD_TOKEN_IN : IP3516_PTD_TOKEN_OUT; - if (!is_xfer_asyc(xfer_type)) { + if (!is_xfer_async(xfer_type)) { ip3516_ptl_t *ptd = (ip3516_ptl_t *)ptd_ptr; uint32_t uframe_interval; @@ -709,7 +719,7 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void)rhport; intptr_t ptd_ptr = find_opened_ptd(dev_addr, ep_addr); - TU_ASSERT(ptd_ptr != TUSB_INDEX_INVALID_8); + TU_ASSERT(ptd_ptr != 0); ptd_state_t *ptd_state = (ptd_state_t *)(ptd_ptr + offsetof(ip3516_atl_t, state)); ptd_clear_state(ptd_state); diff --git a/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.h b/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.h index 38c3a3224..5214c18ae 100644 --- a/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.h +++ b/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.h @@ -57,7 +57,7 @@ extern "C" { //--------------------------------------------------------------------+ -// OHCI Data Structure +// IP3516 PTD Data Structure //--------------------------------------------------------------------+ // Control Word 1 -- cgit v1.3.1